1 Star 0 Fork 30

冰河 / BaseCloud

forked from BASE / BaseCloud 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

项目简介

BaseCloud是一套基于uniapp、uniCloud、uni-id的全栈开发框架,不依赖任何第三方框架,极度精简轻巧。

在开发前端界面时,除了适配移动端外,它对PC端也做了良好的适配;

在开发云函数时,它可以为您提供拦截器配置、路由管理、分页、列表、单数据快速查询等功能。除此之外,对于一些业务开发中的常用函数也已做好封装,拿来即用。

在BaseCloud的初始化项目模板中,为您实现了贯穿前后端的业务模块:管理员登录、用户管理、菜单管理、角色与权限管理、操作日志、系统参数配置等项目通用的基础后台管理功能,这一切全都基于云函数开发。

项目价值

基于BaseCloud的快速开发UI样式库,可以快速拼装前端界面,高还原度实现设计图效果,兼顾高效与灵活。

基于BaseCloud的云函数公用模块,你可以轻松实现单云函数、多云函数的路由管理、请求拦截管理与权限控制、常用业务函数快速开发。

基于BaseCloud的客户端缓存管理机制,你可以大幅度减少应用的云函数重复调用请求,未来云函数开始计费后,至少节省应用50%的流量费用。

基于BaseCloud的管理后台项目模板,你可以快速初始化一套自带用户、菜单、角色、权限、操作日志、系统参数管理的管理后台项目,在此基础上开始你的项目开发。

当然,这一切都只是刚刚开始,未来我们会基于BaseCloud推出更多贯穿前后端的业务模板,只要您的项目是基于BaseCloud框架,所有的业务模板拿来即用,5分钟快速集成到项目内,无需重复开发前端和后端。

对于开发者而言,基于BaseCloud的全栈快速开发框架,你可以封装自己的贯穿前后端的业务模块,发布到付费业务模块插件市场。

#业务模块快速集成

用户端-手机号码登录业务模块 <<

BaseCloud项目构成

  1. common>base-cloud.scss 基础样式库,适配移动端和PC端,22kb。
  2. common>js>base-cloud-client.js 客户端SDK,14.2kb。
  3. cloudfunctions>common>base-cloud 云函数公共模块,13.9kb。
  4. components PC端常用业务组件目录

项目预览

用户端手机号登录业务模块:

管理后台业务模块:

管理后台演示项目地址:https://base-cloud.joiny.cn <<

账号:admin 密码:123123123

快速开始

  1. 请先下载BaseCloud管理后台项目模板,并导入到Hbuilder中
  2. 右键点击cloudfunctions目录,选择一个服务空间,支持阿里云、腾讯云。
  3. 找到cloudfunctions目录下的db_init.json数据库初始化文件,右键选择“初始化数据库”。
  4. 右键点击cloudfunctions目录,选择上传所有云函数以及公共模块。
  5. 点击运行到浏览器,运行成功后,在浏览器中进入登录页,初始账号:admin ,初始密码:123123123

使用过程中如有问题或建议,请移步gitee提交issue。

提交问题、建议

项目结构介绍

请务必对照仔细浏览项目目录介绍,您阅读本项目的文档将会事半功倍。

服务端项目目录

├── cloudfunctions───────────# 云函数目录
│ 		└── admin──────────────────# 管理后台业务函数
│			  └── controller──────────────────# 管理后台业务函数根目录
│					└── menu.js────────────────────────# 菜单管理业务函数
│					└── operateLog.js──────────────────# 操作日志业务函数与接口
│					└── paramConfig.js─────────────────# 系统参数配置业务函数
│					└── role.js────────────────────────# 角色管理业务函数
│					└── user.js────────────────────────# 用户管理业务函数
│			  └── node_modules──────────────────# admin函数依赖公共模块
│			  └── index.js──────────────────────# admin函数入口文件
│ 		└── api────────────────────# uni-id官方公共模块
│ 		└── clearlogs──────────────# 过期操作日志清理定时任务函数
│ 		└── common─────────────────# 公共模块
│				└── base-cloud──────────────────# base-cloud公共模块
│						└── intercepters──────────────────# 拦截器函数目录
│								└── authInter.js──────────────────# 用户权限拦截拦截函数
│						└── config.js─────────────────────# 公共模块配置文件,注册全局拦截器(重要!)		
│						└── index.js──────────────────────# BaseCloud公共模块源码,开发阶段无需关心	
│		└── db_init.json───────────# 数据库初始化文件,包含数据表和初始化数据

客户端项目目录

├── cloudfunctions────────# 云函数目录...
├── common────────────────# 静态资源文件目录
│ 		└── js──────────────────# js文件目录
│			  └── base-cloud-client.js─────────────────# BaseCloud客户端SDK
│			  └── clipBoard.js─────────────────────────# 支持web端复制API
│			  └── md5.js───────────────────────────────# MD5加密函数,用于密码加密传输,客户端数据缓存等场景
│ 		└── base.scss────────────────────# BaseCloud样式类库入口文件
│ 		└── base-font.scss───────────────# BaseCloud图标样式文件
│ 		└── base-mobile.scss─────────────# BaseCloud移动端样式文件
│ 		└── base-pc.scss─────────────────# BaseCloud适配PC端样式文件
├── pages────────────────# 页面
├── static───────────────# 图片静态资源文件目录
├── uni.scss─────────────# scss变量配置文件

管理后台业务模块云函数目录结构

├── cloudfunctions─────────────────# 云函数目录
│ 		└── admin──────────────────# 管理后台业务函数
│				└── controller──────────────────# 管理后台业务函数根目录
│						└── menu.js────────────────────────# 菜单管理业务函数
│								└── getParentList()──────────────────# 查询上级菜单列表接口
│								└── globalData()─────────────────────# 查询登录用户信息、权限菜单列表接口
│								└── info()───────────────────────────# 查询菜单信息接口
│								└── save()───────────────────────────# 保存、更新菜单信息接口
│								└── delete()─────────────────────────# 删除菜单信息接口
│								└── list()───────────────────────────# 菜单列表查询接口
│						└── operateLog.js──────────────────# 操作日志业务函数与接口
│						└── paramConfig.js─────────────────# 系统参数配置业务函数
│								└── info()───────────────────────────# 查询参数配置项信息接口
│								└── save()───────────────────────────# 保存、更新参数配置项信息接口
│								└── delete()─────────────────────────# 删除参数配置项接口
│								└── list()───────────────────────────# 参数配置项列表查询接口
│						└── role.js────────────────────────# 角色管理业务函数
│								└── info()───────────────────────────# 查询角色信息接口
│								└── save()───────────────────────────# 保存、更新角色信息接口
│								└── delete()─────────────────────────# 删除角色接口
│								└── list()───────────────────────────# 角色列表查询接口
│								└── options()────────────────────────# 角色选项列表查询接口(供用户角色选择时使用)
│						└── user.js────────────────────────# 用户管理业务函数
│								└── login()──────────────────────────# 登录接口
│								└── checkToken()─────────────────────# token验证接口
│								└── logout()─────────────────────────# 退出登录接口
│								└── changeStatus()───────────────────# 切换用户禁用状态接口
│								└── info()───────────────────────────# 用户信息查询接口
│								└── save()───────────────────────────# 保存、更新用户信息接口
│								└── myInfo()─────────────────────────# 当前用户信息接口
│								└── modify()─────────────────────────# 修改当前用户信息(含密码)接口
│								└── list()───────────────────────────# 用户列表查询接口
│								└── delete()─────────────────────────# 删除用户接口
│				└── node_modules──────────────────# admin函数依赖公共模块
│				└── index.js──────────────────────# admin函数入口文件

=====================================================================

服务端公共模块使用说明文档

【使用公共模块来接管云函数,定义多个访问路径】

  1. 根据公共模块引入说明来引入base-cloud公共模块;
  2. 在云函数的入口文件index.js中引入公共模块,并接管云函数。
'use strict';
const BaseCloud = require("base-cloud");

exports.main = async ( event , ctx ) => {
	var fnName = "admin" ; //当前云函数的名称
	var controlerDir = `${__dirname}/controller` ; //存放业务函数根目录的绝对路径
	return await new BaseCloud({ event, ctx , fnName }).invoke(controlerDir);
};
  1. 在云函数中指定的业务函数根目录(此处是controller,你也可以指定其他的目录),创建js文件。 并通过module.exports来导出业务处理的函数,可以导出一个或多个。
  2. 客户端访问云函数的路径规则为:云函数名称/根目录下的js函数文件名称/js函数文件导出的函数名称; 如果js函数文件直接导出的是一个函数,则路径规则为:云函数名称/根目录下的js函数文件名称。

如下示例为在admin云函数中的controller>operateLog.js文件中导出一个函数:

'use strict';
const db = uniCloud.database();
const dbCmd = db.command ;
const $ = db.command.aggregate ;
const OperateLog = db.collection("t_operate_log");

module.exports = async function(res){
	var {pageNumber , pageSize} = this.params ;
	
	var page = await this.paginate({
		pageNumber , pageSize ,
		collection : OperateLog ,
		eq : ["actionName","userName"],
		like : ["name"],
		orderBy : "createTime desc" 
	});
	
	var list = page.list ;
	list.forEach(item=>{
		item.createTime = this.DateKit.toStr( item.createTime ,'seconds');
	});
	
	return {page};
};

此时客户端访问路径为: admin/operateLog ,客户端调用示例如下:

this.bcc.call({
	url : "admin/operateLog" ,
	data : {pageNumber: 1 , pageSize : 20},
	success : e=>{}
});

如下示例为在admin云函数中的controller>role.js文件中导出多个函数:

'use strict';
const db = uniCloud.database();
const dbCmd = db.command ;
const $ = db.command.aggregate ;
const Role = db.collection("t_role");

module.exports = {
	info : async function(e){
		var id = this.params.id ;
		var typeList = TYPE_LIST ;
		if (!id) {
			return { typeList };
		}
		var data = this.findFirst( await Role.doc(id).get() );
		return { data , typeList };
	},
	
	save : async function(e){
		var data = this.getModel();
		if (data.menuIds) {
			data.menuIds = data.menuIds.split(',');
		}
		if (!data._id) {
			data.createTime = this.DateKit.now();
			await Role.add(data);
			return this.ok();
		}
		data.updateTime = this.DateKit.now() ;
		await this.updateById(Role , data);
		return this.ok();
	}
};

此时,通过admin/role/infoadmin/role/save 两个路径可以分别访问 controller>role.js>info()controller>role.js>save(),客户端调用示例如下:

this.bcc.call({
	url : "admin/role/info" ,
	data : {_id : 1},
	success : e=>{}
});

【使用公共模块来配置全局的拦截器,以及拦截器的清理】

  1. cloudfunctions > common > base-cloud 目录下,找到 config.js 文件,
  2. 如下代码所示,在inters中配置了两个拦截器,你可以直接在此处定义拦截器函数(如loginInter),也可以通过文件引入的方式来定义拦截器(如authInter),具体的使用说明,请看注释:
//通过文件来引入拦截器函数
const authInter = require("./intercepters/authInter") ;

module.exports = {
	isDebug : true , //会输出一些日志到控制台,方便调试
	inters:{ //配置全局拦截器
		loginInter: { //直接在此处定义拦截器函数
			isGlobal : true , //是否全局拦截,拦截所有的云函数,不配置默认是全局拦截
			handle : [] , //拦截的路径,此处留空表示拦截全部的路径
			clear : [ //配置要清除拦截器的路径,注意:如果配置了handle则此处的配置无效。
				"admin/user/login", //支持字符串、也支持正则表达式(详见示例项目中的authInter的配置规则)
				"admin/user/checkToken",
			] , 
			invoke:async function(attrs){//拦截器函数,入参为上一个拦截器通过setAttr方法传递的所有的键值对
				const {event , ctx , uniID } = this ;
				var res = await uniID.checkToken(event.uniIdToken);
				if(res.code){
					return {
						state : 'needLogin',
						msg : "请登录"
					};
				}
				//将user传入下一个拦截器,在拦截器函数的入参中可以获取到,也可以通过this.getAttr("user")来取到该值。
				this.setAttr({user : res.userInfo}); 
				//当前拦截器放行,不调用这个,拦截器不会放行,此次请求到此终止
				this.next();
			}
		},
		authInter  ,
	}
}

也就是说,你可以把你所有要配置的拦截器放到 config.js > inters中去,每个拦截器注册时, 通过isGlobal属性配置是否对所有云函数都拦截,不配置该属性默认为true; 在 handle 属性中定义要拦截的路径,路径支持正则表达式; 在clear属性中,定义要清理拦截器的路径; 使用invoke属性来定义拦截器的函数。 特别注意:如果在handle中定义了拦截的路径,则clear中的配置会被忽略。

在拦截器函数中,接收的参数为一个json,为所有拦截器通过this.setAttr(key , value)方法存入的键值对。

在拦截器中,可以使用this.setAttr(key , value)方法,将当前拦截器中的变量传递到下一个拦截器或者业务函数。 在下一个拦截器或业务函数的入参中可以接收,也可以使用this.getAttr(key)方法,来取到指定的值。

如果拦截器拦截成功,不再继续执行,直接返回响应结果即可。如果拦截器放行,则需要主动调用this.next()方法,来放行本次拦截。

公共模块配置的拦截器对所有引入base-cloud公共模块,并由base-cloud接管的云函数都有效,请合理配置拦截与清理拦截的规则。

修改公共模块后,除了上传公共模块,也需要上传依赖公共模块的云函数哦~

【在业务函数中可以使用的变量】

还是以一个云函数中的业务函数为例:

'use strict';
const db = uniCloud.database();
const dbCmd = db.command ;
const $ = db.command.aggregate ;
const OperateLog = db.collection("t_operate_log");

module.exports = async function(attrs){ //此处的attr是所有拦截器中通过 this.setAttr(key,value)方法存入的键值对
	var user = attrs.user ; //在loginInter拦截器中存入的user变量
	var ctx = this.ctx ; //上下文,为入口函数的入参context
	var event = this.event ; //为入口函数的入参event,本次请求云函数携带的event参数
	var params = this.params ; //本次请求客户端通过data或url传递所有的参数
	var fullPath = this.fullPath ; //本次请求的路径,如: admin/user/info
	var actionName = this.action ; //本次请求的action,不含云函数名称,如: user/info
	var fnName = this.fnName ; //本次请求的云函数的名称
	var token = this.token ; //本次请求携带的token
	var uniID = this.uniID ; //依赖的uniID模块,可以直接使用uniID的API
};

【在业务函数中可以使用的方法】

this.getModel(prefix , keepKeys) ;

  1. 第一个参数为prefix参数,指定要获取的参数的前缀符,未指定时,默认为x
  2. 第二个参数为keepKeys,指定一个或多个键名进行接收,多个使用英文逗号分开,如未指定则接收所有带有指定前缀的参数。

举个例子,比如用户修改个人信息的功能,在客户端传参示例:


this.bcc.call({
	url : "admin/user/modify" ,
	data : {
		"x.password" : "123123123" ,
		"x.mobile" : "15688585858" ,
		"x.realAuth.contact_name" : "王大成" ,
		"x.username" : "想改个名字能改吗" ,
		"remark" : "个人的喜好"
	}
})

此时我们需要只接收带x.前缀的参数,统一存放到data变量中,以便直接更新用户表的数据。 更新时,我们假设只允许用户修改passwordmobile字段,不允许修改username字段, 那么使用 this.getModel() 方法可以获取到符合我们条件的参数。

this.keep( jsonData , keepKeys) ;

保留jsonData中指定的键值对,用法同上。


module.exports = async function(e){
	var data = this.getModel("x" , "mobile,password,realAuth");
};

this.findFirst(dataInDB);

从数据库返回的结果中获取一条数据,如果没有数据则返回null


var user = this.findFirst( await User.doc(id).get() );
if(null == user){
	return {} ;
}

var {username , mobile} = user ;
//...

this.find(dataInDB);

从数据库返回的结果中获取列表数据,如果没有数据则返回 [] ;


var dataInDB = await Role.orderBy("createTime","asc").get() ;
var list = this.find( dataInDB );
if(list.length == 0){
	//..do something
}

async this.updateById( collection , updateData ) ;

根据主键_id来更新一条数据,updateData中包含_id字段和要更新的字段


var Role = uniCloud.database().collection("t_role") ;
await this.updateById( Role , data);

async this.paginate({ collection , where = {} , field = {} , orderBy , eq , gte , lte , gt , lt , like , pageNumber = 1, pageSize = 10 });

使用数据库普通查询方法(暂不支持聚合查询)来获取分页数据。参数说明见下方的示例代码中的注释:


'use strict';
const db = uniCloud.database();
const dbCmd = db.command ;
const $ = db.command.aggregate ;
const OperateLog = db.collection("t_operate_log");

module.exports = async function(res){
	var {pageNumber , pageSize , createTimeStart , createTimeEnd } = this.params ;
	
	this.params.createTimeStart = this.Datekit.parse(createTimeStart); //字符串的日期转时间戳
	this.params.createTimeEnd = this.Datekit.parse(createTimeEnd);
	
	var page = await this.paginate({
		pageNumber , //分页页码,不传入默认为1
		pageSize , //每页数据条数,不传入默认为10
		collection : OperateLog , //要查询数据的集合对象
		field:{ userName : true }, //指定返回字段,具体用法参见官方文档
		where:{},//自定义的固定查询条件
		eq : ["actionName","userName"], //筛选的相等条件,如果请求参数中该参数不为空则进行相等条件筛选
		like : ["name"],//筛选的模糊查询条件,如果请求参数中该参数不为空则进行模糊查询筛选
		gte : ["createTimeStart,createTime"], //如果this.params.createTimeStart值不为空,追加{createTime:dbCmd.gte(this.params.createTimeStart)}筛选条件
		lte : ["createTimeEnd,createTime"],//如果this.params.createTimeEnd值不为空,追加{createTime:dbCmd.gte(this.params.createTimeEnd)}筛选条件
		orderBy : "createTime desc" 
	});
	
	var list = page.list ;
	list.forEach(item=>{
		item.createTime = this.DateKit.toStr( item.createTime ,'seconds');
	});
	
	return {page};
};

分页查询方法返回的数据结构如下:


page: {
	pageNumber: 1,//页码
	lastPage: true,//是否最后一页
	totalPage: 1,//总页码
	list: [], //当前页数据
	totalRow: 0, //总数据条数
	pageSize: 10 //每页数据条数
}

this.ok(msg);

返回请求成功的响应结果,msg不传入时,默认提示信息为:

{
	state : "ok" ,
	msg : "操作成功"
}

this.fail(msg, state)

返回请求成功的响应结果,msg不传入时,默认提示信息为:

{
	state : "fail" ,
	msg : "系统异常,请稍后再试"
}

this.isRepeat( dataInDB , _id );

做保存更新一体的业务接口时,我们经常会判断某个字段是否已在数据库中存在值。 先根据该字段查询数据中的一条数据,然后使用该方法,来快速判断是否有重复的值。

如下为保存更新用户数据接口代码示例:


var data = this.getModel(); 
var {username , password , _id , roleIds , mobile } = data ;
var sameNameUser = this.findFirst(await User.where({username}).limit(1).get());
if(  this.isRepeat(sameNameUser , _id) ){
	return this.fail("用户名已存在");
}

async this.setMaxOrderNum(data, collection, where);

适用于具有orderNum字段的数据表,自动生成最大的orderNum的业务场景。

  1. data 参数为即将要保存、更新的json数据,必填
  2. collection为要更新的集合对象,必填
  3. where为限定排序的条件,可选项
var Menu = uniCloud.database().collection("t_menu");
var data = this.getModel();
await this.setMaxOrderNum(data , Menu , {parentId : data.parentId } );

console.log(data.orderNum) ; //输出最大的orderNum

this.log(...arguments);

方便调试的方法,如果在 base-cloud > config.js 中配置了 isDebug 参数为 true ,使用该方法时,可以输出日志,否则不输出日志。

this.isNull(obj);

判断是否为空

this.isObject(obj);

判断是否为json对象

this.isEmptyObject(obj);

判断是否值为{}的json对象,不含有任何键值对的json

this.isFn(fn);

判断是否为函数

this.isNumber(number);

判断是否为数字

this.isArray(array);

判断是否为数组

this.isString(string);

判断是否为字符串

this.isDate(date);

判断是否为日期类型

this.isReg(reg);

判断是否为正则表达式

this.Datekit.now()

uniCloud默认是0时区的时间,使用该方法可以获取东八区当前时间的时间戳,符合国内的习惯。

this.DateKit.addMinutes(minutes , date);

date为可选参数,时间戳类型,不传入则使用东八区的当前时间时间戳,增加或减少指定分钟数量,返回时间戳。

this.DateKit.addHours(hours , date);

date为可选参数,时间戳类型,不传入则使用东八区的当前时间时间戳,增加或减少指定小时数量,返回时间戳。

this.DateKit.addDays(days , date);

date为可选参数,时间戳类型,不传入则使用东八区的当前时间时间戳,增加或减少指定天数,返回时间戳。

this.DateKit.addMonths(months , date);

date为可选参数,时间戳类型,不传入则使用东八区的当前时间时间戳,增加或减少指定月份,返回时间戳。

this.Datekit.toStr( timestamp , fileds );

传入一个时间戳时间,格式化为字符串,fileds 来指定格式化的时间精度,支持:second、minute、hour、day、month、year,不传默认为minute

this.DateKit.friendlyDate(timestamp);

传入一个时间戳时间,返回距离东八区当前时间的有多少天、时、分、秒。如:3天前、24分钟后


【服务端响应结果的约定】

一般操作类的接口,服务端会返回如下结果:

{
	state : 'ok' ,
	msg : "操作成功"
}

数据查询类的,正常情况下,服务端不再返回state、msg字段,直接返回要查询的数据结果,如:

{
	list : [],
	data :{}
}
state 说明
ok 请求成功
fail 请求失败,失败时需要返回msg字段,作为失败的说明信息
noAuth 无操作权限
needLogin 需要登录
... 其他特殊场景下的状态描述

=====================================================================

客户端SDK使用说明文档

使用客户端sdk前,请确保已按如下方式,在 main.js 中注册全局对象。

import Vue from 'vue'
import App from './App'

import bcc from "./common/js/base-cloud-client.js" //引入客户端sdk文件
Vue.prototype.bcc = bcc ; //注册为全局对象

Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
    ...App
})
app.$mount()

【调用云函数】

var data = e.detail.value ;
this.bcc.call({
	url : 'admin/user/save' , //请求路径,直接以函数名称开头,开头不要加/,后面跟着路径
	data : data , //请求参数
	success : res => { 
		//当服务端返回state == 'ok' 或无state字段时,进入success回调
	},
	fail : res => { 
		//当服务端返回state == 'fail' 时,进入fail回调;
		//如未定义fail回调,则默认提示服务端返回的msg字段
	},
	complete : res => {
		//请求完成后的回调
	},
});

【通过客户端本地缓存调用云函数】

本地没有缓存则请求云函数数据并将请求到的数据缓存至本地,否则直接使用本地缓存数据。

var data = e.detail.value ;
this.bcc.callInCache({
	url : 'admin/user/list' , //请求路径,直接以函数名称开头,开头不要加/,后面跟着路径
	data : data , //请求参数
	success : res => {
		//当服务端返回state == 'ok' 或无state字段时,进入success回调,并且将数据缓存至本地
	},
	fail : res => { 
		//当服务端返回state == 'fail' 时,进入fail回调;
		//如未定义fail回调,则默认提示服务端返回的msg字段
	},
	complete : res => {
		//请求完成后的回调
	},
});

【主动清理客户端本地缓存】

当本地数据已经发生变更时,需要主动清理本地缓存数据,下次去请求最新的数据。

清理缓存时,将直接清理所有指定请求地址下的缓存(一个请求地址下,因参数不同可能会有多个本地缓存数据)。

应用场景示例:将用户列表数据存入本地缓存,当编辑用户信息、删除用户数据、更改用户状态等三个操作发生时。直接清理本地的用户列表数据缓存:

//传入要清理缓存的请求地址的路径
this.bcc.clearCache("admin/user/list");

【表单数据校验】

表单校验无须配置各种校验规则,直接将校验规则写入name即可。

表单的name一共分成四个部分,用|符号分割:

  1. 要传入服务端的name
  2. 表单的标题,如果标题为空表示该表单可以为空。标题内可以含有:请输入、请上传、请选择 这三类提示文字。
  3. 校验规则,目前支持:mobile、email、idcard、count(整数)、amount(金额)、字符长度与长度范围等六种常见的表单验证和非空验证。
  4. empty :表示可以为空,如果有值则进行校验,无值则放行。

示例代码:

/* 要传入服务端的name为:x.name ,角色名称不可为空,校验规则为:字符长度2~20之间。 */
<inputs name="x.name|角色名称|2~20" title="角色名称" :value="data.name"></inputs>

/* 要传入服务端的name为:x.type ,该字段可以为空 */
<radios title="类型" name="x.type" :list="typeList" :value="data.type"></radios>

/* 要传入服务端的name为:x.remark ,该字段可以为空, 如果有值时,校验字符长度在2~200之间*/
<textareas title="角色描述" name="x.remark|角色描述|0~200|empty" 
:value="data.remark?data.remark:''" :maxlength="200" placeholder="选填"></textareas>

/* 要传入服务端的name为:x.mobile ,校验手机号码*/
<inputs name="x.mobile|联系电话|mobile" title="联系电话" :value="data.name"></inputs>

/* 要传入服务端的name为:code ,校验规则为长度为6的字符*/
<inputs name="code|验证码|6" title="验证码"></inputs>

/* 要传入服务端的name为:avatar ,未上传头像提交表单时会提示:请上传头像*/
<upload-images name="avatar|请上传头像" title="头像"></upload-images>

【提交表单数据】

直接将@submit接收到的参数e,传递给this.bbc.submit()函数即可,自动做表单校验,验证通过后,提交表单。

通过给form配置data-action属性来定义表单提交的地址;

给form配置data-back来定义请求成功后返回的页面的地址;

给form配置data-confirm来定义提交表单之前的确认弹窗的文字,未定义则不显示确认弹窗;

给form配置data-alert来定义提交表单成功以后的弹窗的文字,未定义则不显示弹窗;

给form配置data-redirect来定义请求成功后跳转的页面的地址;

给form配置data-clear来定义请求成功后清理本地缓存的请求url(不可含参数)。

vue:


<form @submit="submit" data-action="admin/role/save" data-back="/pages/role/roleList" data-clear="admin/role/list">

	<inputs name="x.name|角色名称" title="角色名称" :value="data.name"></inputs>
	
	<radios title="类型" name="x.type" :list="typeList" :value="data.type"></radios>
	
	<textareas title="角色描述" name="x.remark|角色描述|empty" 
	:value="data.remark?data.remark:''" :maxlength="200" placeholder="选填"></textareas>
	
	<labels :isTop="true" title="权限配置">
		<menu-groups :list="menuList" name="x.menuIds" :value="data.menuIds"></menu-groups>
	</labels>
	
	<labels class="mt40">
		<inputs type="hidden" name="x._id" :value="id" v-if="id"></inputs>
		<button class="btn greenBg w80" form-type="submit">{{ !data._id ? '保存' : '修改'}}</button>
		<button class="btn grayBg line w80" @click="bcc.goBack()">取消</button>
	</labels>
	
</form>

js:

methods: {
	submit:function(e){
		this.bcc.submit(e , res=>{
			//如果配置了第二个参数:成功回调函数,则当服务端返回state == 'ok' 或无state字段时,进入请求成功的回调
		}, err=>{
			//如果配置了第三个参数:失败回调函数,则当服务端返回state == 'fail' 时,进入fail回调
		});
	}
}

【表单数据主动验证】

通过@submit接收到参数e后,直接用该参数进行表单验证。

submit:function(e){
	var res = this.bcc.checkData(e);
	if (res.fail) { //表单校验未通过
		return ;
	}
	uni.showLoading({
		title:"请稍后…",
		mask:true 
	});
	var data = res.data ; //表单校验通过后拿到要向服务端提交的处理过的数据
	if (data['x.password']) {
		data['x.password'] = this.bcc.sign(data['x.password']);
	}
	this.bcc.call({
		url : 'admin/user/save' ,
		data : data ,
		success : res => {
			uni.hideLoading();
			this.bcc.clearCache("admin/user/list");
			this.bcc.goSuccessBack("/pages/user/userList","保存成功");
		}
	});
},

【辅助工具类】


//向后返回2层页面,如果页面栈不足2个页面的话,就返回到/pages/index/index
this.bcc.goBack("/pages/index/index",2);

//返回上一历史页,如果上一历史页不存在则返回/pages/user/userList,然后提示“保存成功”
this.bcc.goSuccessBack("/pages/user/userList","保存成功");

//MD5加密字符串
var sign = this.bcc.sign('string...');

//判断某个变量是否为空
var isNull = this.bcc.isNull(a);

//判断某个变量是否是数字
var isNumber = this.bcc.isNumber(a);

=====================================================================

基础样式类库使用说明

基于BaseCloud的基础样式类库,您可以高度还原UI设计图,快速搭建客户端界面。与传统UI框架不同的是, 并不直接定义任何界面组件,它通过对高频基础样式类的封装,使用自由搭配组合的class样式类来快速、随心所欲的呈现千变万化的UI界面。

我们希望每个项目都有统一的主题色,以保证项目的界面的干净整洁,故而定义了一个主题色,你可以在uni.scss中,修改成自己喜欢的颜色,作为整个项目的主题色。 同时,由于部分组件的自定义颜色属性,我们也使用了默认主题色,所以,如果您有修改主题色的需求, 除了修改uni.scss中的主题色色值外,还可以在Hbulider中使用ctrl + alt + F快捷键,全项目搜索该色值并替换。

uni.scss

$main:#07c160;  //主背景色
$lightMain: #dff5e2;  //淡主色
$mainInverse:#fff;  //与主色搭配的反色
$mainGradual:linear-gradient(to top right,#67D79F,#00A28A); //渐变主色
$mainGradualInverse:#fff; //与渐变主色搭配的反色

修改完毕后,请确保在 App.vue 文件中通过如下方式引入样式库文件:

App.vue

<script>
	export default {
		onLaunch: function() {
			console.log('App Launch')
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

<style lang="scss">
	@import './common/base-cloud.scss';
</style>

样式类库详细使用说明文档,请点击此处链接查看: 《UI样式类库详细使用使用文档》

特别需要说明的是,基于该基础样式类库,您可以快速构建任何UI界面。 项目初始,目前我们仅对PC端一些常用组件进行了封装,供您使用,后续随着贯穿前后端的业务模块的开发,我们会逐步提供更多的组件。

=====================================================================

PC端组件使用说明文档

【auth 组件】

用于用户权限控制,当用户拥有操作权限时展现,否则不展现该元素。

关于权限控制的业务逻辑:用户登录成功后,读取该用户所属角色拥有的权限菜单列表,存储到本地,键名为menuList,权限判断就是基于menuList进行的判断。

属性 必填 默认值 可选值 示例值 说明
url admin/user/save 权限路径,该路径可包含参数,需在t_menu表中已添加数据
noAuth false true false 无权限时展现
isInline true true false 是否内联元素
<auth url="admin/user/save">

   <navigator url="/pages/user/userEdit">编辑</navigator>	
   
</auth>

【auth-btn 组件】

用于用户权限控制,当用户拥有操作权限时展现,否则不展现该元素。点击按钮时,会发送请求。

属性 必填 默认值 可选值 示例值 说明
url admin/user/changeStatus?id=1 发送请求的路径,可以携带参数
params json类型 :params="{id:1}" 发送请求时携带的参数
noAuth false true false 无权限时展现
isInline true true false 是否内联元素
confirm confirm="delete" 发送请求之前的确认文字,如果是删除类请求需要确认,可以简写为delete
alert 请求成功后弹窗的文字
showFail true 请求失败后,是否提示服务端返回的msg字段
@success 请求成功后回调函数
@fail 请求失败后回调函数
<auth-btn url="admin/user/changeStatus" :params="{id:1}">
   禁用
</auth-btn>

【auth-nav 组件】

用于用户权限控制,当用户拥有操作权限时展现,否则不展现该元素。点击按钮时,会进行页面跳转。

属性 必填 默认值 可选值 示例值 说明
url admin/user/changeStatus?id=1 是否具有权限的路径
noAuth false true false 无权限时展现
isInline true true false 是否内联元素
href 要跳转的页面的链接,可以包含参数
<auth-nav :href="`/pages/user/userEdit?id=${item._id}`" url="admin/user/save" >
   编辑
</auth-nav>

【switch-btn 组件】

用于权限控制的开关切换按钮,无权限仅展示,不可发送请求。

属性 类型 说明
url String 权限地址,也是点击切换时的请求地址,可以携带参数,如无地址或无权限,则不可点击
params json 请求参数,有权限时,点击切换即可发送请求
checked Boolean 开关是否打开
disabled Boolean 开关是否禁用
color String 颜色,默认#07c160

【switchs 组件】

属性 类型 说明
name String 表单的name
value Boolean 开关是否打开
tip String 开关右侧的提示文字
disabled Boolean 开关是否禁用
color String 颜色,默认#07c160
title
titleWidth 90
isVertical false

【checkboxs 组件】

复选框组件,用于多选,支持v-model

属性 必填 默认值 可选值 示例值 说明
title 表单标题,不要标题,请设置titleWidth=0
titleWidth 90 数值即可 100 复选框表单的左侧标题占位的宽度
name 表单的name
titleName 如果需要选中选项的标题也传服务端,请定义该字段
value value='1,2,3,5' 表单的value,支持v-model绑定,可以是数组,也可以是用英文逗号分开的多个值
list [{title:"搞笑",value:1},{title:"言情",value:2}] 选项列表,数组
titleKey title 选项列表中,对用户展示的文字的键值对的键名
valueKey value 选项列表中,对作为选项值的键值对的键名
disabledKey disabled 选项列表中,表示当前选项禁用的键值对的键名
color #07c160 复选框的颜色
isVertical false 标题和复选框是否垂直排列
@change 当选项发生改变时触发的回调函数
<checkboxs title="角色" :list="roleList" name="x.roleIds|请选择角色" :value="data.roleIds" 
titleName="x.roleNames" titleKey="name" valueKey="_id"></checkboxs>

【radios 组件】

单选框组件,用于单选,支持v-model

属性 必填 默认值 可选值 示例值 说明
title 表单标题
titleWidth 90 数值即可 100 左侧标题的宽度
name 表单的name
titleName 如果需要选中选项的标题也传服务端,请定义该字段
value 表单的value,支持v-model绑定
list [{title:"搞笑",value:1},{title:"言情",value:2}] 选项列表,数组
titleKey title 选项列表中,对用户展示的文字的键值对的键名
valueKey value 选项列表中,对作为选项值的键值对的键名
disabledKey disabled 选项列表中,表示当前选项禁用的键值对的键名
color #07c160 复选框的颜色
isVertical false 标题和复选框是否垂直排列
defaultFirst true 当value无值时,是否默认选中第一个选项
@change 当选项发生改变时触发的回调函数
<radios title="菜单类型" :list="menuTypeList" :value="data.type" 
name="x.type|菜单类型" @change="chooseMenuType"></radios>

【multi-selects 组件】

下拉多选组件,用于多选,支持v-model,可以搜索关键字筛选

属性 必填 默认值 可选值 示例值 说明
title 表单标题
titleWidth 90 数值即可 100 左侧标题的宽度
name 表单的name
titleName 如果需要选中选项的标题也传服务端,请定义该字段
value value='1,2,3,5' 表单的value,支持v-model绑定,可以是数组,也可以是用英文逗号分开的多个值
list [{title:"搞笑",value:1},{title:"言情",value:2}] 选项列表,数组
titleKey title 选项列表中,对用户展示的文字的键值对的键名
valueKey value 选项列表中,对作为选项值的键值对的键名
remarkKey remark 选项列表中,对作为副标题的键值对的键名
disabledKey disabled 选项列表中,表示当前选项禁用的键值对的键名
color #07c160 颜色
isVertical false 标题和选择框是否垂直排列
@change 当选项发生改变时触发的回调函数
<multi-selects title="角色" :list="roleList" name="x.roleIds|请选择角色" 
:value="data.roleIds" titleName="x.roleNames" titleKey="name" valueKey="_id"></multi-selects>

【selects 组件】

下拉单选组件,用于单选,支持v-model,可以搜索关键字筛选

属性 必填 默认值 可选值 示例值 说明
title 表单标题
titleWidth 90 数值即可 100 左侧标题的宽度
name 表单的name
titleName 如果需要选中选项的标题也传服务端,请定义该字段
value 表单的value,支持v-model绑定
list [{title:"搞笑",value:1},{title:"言情",value:2}] 选项列表,数组
titleKey title 选项列表中,对用户展示的文字的键值对的键名
valueKey value 选项列表中,对作为选项值的键值对的键名
remarkKey remark 选项列表中,对作为副标题的键值对的键名
disabledKey disabled 选项列表中,表示当前选项禁用的键值对的键名
color #07c160 颜色
isVertical false 标题和选择框是否垂直排列
@change 当选项发生改变时触发的回调函数
<selects title="父级菜单" :list="parentMenuList" name="x.parentId" 
:value="data.parentId" titleKey="name" valueKey="_id"></selects>

【inputs 组件】

输入框组件,type支持hidden类型,输入框有内容时,可以点击清空图标清空。

属性 必填 默认值 可选值 示例值 说明
title 表单标题
titleWidth 90 数值即可 100 左侧标题的宽度
name 表单的name
value 表单的value,支持v-model绑定
hiddenValue 传入该值时,输入框将变为禁用状态,对用户展示value的值,hiddenValue将会传到服务端
type text text、number、hidden 表单类型,支持hidden
addOn 输入框右侧的文字块的文字
addOnLeft 输入框左侧的文字块的文字
isVertical false 标题和输入框是否垂直排列
showClearIcon true 是否显示清空图标
@tapAddOn 当点击输入框右侧文字块时触发的回调函数
@tapAddOnLeft 当点击输入框左侧文字块时触发的回调函数
其他属性与事件 与input组件一致
<inputs name="x.name|用户名" title="用户名" :value="data.name" :hiddenValue="data._id"></inputs>

【textareas 组件】

属性 必填 默认值 可选值 示例值 说明
title 表单标题
titleWidth 90 数值即可 100 左侧标题的宽度
name 表单的name
value 表单的value,支持v-model绑定
isVertical false 标题和文本框是否垂直排列
showClearIcon true 是否显示清空图标
autoHeight false 是否自适应高度
height 100 非自适应高度时的高度
其他属性与事件 与textarea组件一致
<textareas title="权限地址" @blur="inputBlur" name="x.url|权限地址" 
:value="data.url" placeholder="多个权限地址请用英文分号隔开"></textareas>

【datepicker 组件】

属性 类型 说明
showIcon Boolean 是否显示右侧的日历图标,默认true
name String 表单的name
endName String 表单的endName,如果是时间范围,表示结束时间的name
value String,Array 默认选中的日期,也是提交表单时的默认值,支持数组,如果是字符串的话,可以是用英文逗号分开的两个时间(开始和结束时间)
name String 表单的name
placeholder String 未选择日期时,显示的文字
color String 日历的颜色
showSeconds Boolean 是否显示秒
type String 时间类型:rangetime、range、time、date、datetime
format String 初始日期格式
showHoliday Boolean 显示公历节日
showTips Boolean 显示提示
beginText String 开始时间的文字,默认为:开始
endText String 结束时间的文字,默认为:结束
title String 表单标题
titleWidth Number 左侧标题的宽度
isVertical Boolean 标题和文本框是否垂直排列

【conditions 组件】

分页筛选条件组件

属性 必填 默认值 可选值 示例值 说明
list {title:"用户名",name:"name"},{title:"状态",name:"status",type:"select",list:[]} 筛选条件,数组,基本属性为:name、title、type、list,详见/pages/user/userList示例
conditions {} json 当前的筛选条件
confirmText 筛选 筛选按钮的文字
showFirst false 是否对外显示第一个筛选项
@confirm 确认筛选时的回调事件,e.conditions
<conditions :conditions="conditions" :list="conditonList" @confirm="submitSearch"></conditions>
data() {
	return {
		conditonList:[
			{title:"用户名",name:"name"}, //默认是输入框类型的,只需提供这两个属性即可
			//如果是下拉选择类型的,则需要提供list属性,两个键值对:title、value
			{title:"状态",name:"status",type:"select",list:[{title:"正常",value:0},{title:"禁用",value:1}]}, 
			//日期类型的筛选条件:可以配置name和endName,表示开始和结束时间,timeType是指日期格式:
			/**
			 * rangetime 时间范围,精确到分钟
			 * range 时间范围,精确到天
			 * time 时间,小时:分钟
			 * date 日期,年-月-日
			 * datetime 日期时间,精确到分钟
			 */
			//showSeconds属性表示是否显示秒,任何日期格式都可以搭配这个属性使用。
			{title:"时间",name:"startTime",endName:"endTime",type:"time",timeType:"rangetime",showSeconds:true},
		],
		conditions:{
			name : ""
		}
	}
},

【copy 组件】

一键复制的功能

属性 说明
text 要复制的文字内容
showIcon 文字右侧是否显示复制图标,默认true
<copy :text="data.text" :showIcon="false"></copy>

【empty 组件】

属性 类型 说明
list Array 列表数据,用于判断是否为空,展示数据为空的提示
loading Boolean 是否加载中,加载中的时候,会显示加载中的动画
tips String 当数据为空时的提示文字,默认:抱歉,暂无数据~
<empty :list="list" :loading="loading"></empty>

【images 组件】

图片显示、预览组件

属性 类型 说明
width Number 图片的宽度
isRound Boolean 是否是圆形图片,否则是方形图片,默认false
list String,Array 要展示的图片列表,可以是图片链接数组,也可以是英文逗号分开的多个图片链接
count Number 要展示的图片的数量,超出数量不展示,-1为不限制,默认-1
disabled Boolean 是否显示右上角的删除按钮,是否可以编辑,默认false
@remove 当删除图片时触发回调

【labels 组件】

表单标题组件,主要为了对齐其他的表单布局使用

属性 必填 默认值 可选值 示例值 说明
title 表单标题
titleWidth 90 数值即可 100 左侧标题的宽度
isVertical false 标题和文本框是否垂直排列
isTop false 标题与右侧是否顶部对齐,否则垂直对齐

【layout 组件】

布局组件,所有页面使用

属性 类型 说明
title String 当前页面的标题
loading Boolean 是否加载中,加载中的时候,会显示加载中的动画
pageKey String 当前页面的唯一标识,用于左侧菜单显示选中状态
slot="titleLeft" 标题行左侧位置的插槽
slot="titleRight" 标题行右侧位置的插槽

【mores 组件】

当文本内容为多行时,只显示一行,点击该文字,可以展示显示全部,再次点击则收起。

<mores>{{item.content}}</mores>

【paginate 组件】

分页器组件,需要传入pageNumber(页码)属性和page(分页数据)属性。其中page属性详细结构如下,在BaseCloud的公共模块已对分页数据做了封装,直接调用即可返回该数据结构:

page: {
	pageNumber: 1, //页码
	lastPage: true, //是否最后一页
	totalPage: 1, //总页码
	list: [], //列表数据
	totalRow: 0, //总数据条数
	pageSize: 10 //每页条数
},

该组件会触发一个回调函数@switchPage,返回数据结构如下:

{
	pageSizeChanged : true , //每页数据条数是否切换
	pageNumber :  1 , //页码
	pageSize : 5 //每页数据条数
}

【tables 组件】

属性 类型 说明
list Array 列表数据
slot="thead" 表格的标题栏,无须写tr
slot="tbody" 表格的内容
<tables :list="list">
	<block slot="thead">
		<th>角色名称</th>
		<th>类型</th>
		<th class="autoWidth">权限描述</th>
		<th>操作</th>
	</block>
	<block slot="tbody">
		<tr v-for="( x , index) in list" :key="index">
			<td>{{x.name}}</td>
			<td>{{x.typeStr}}</td>
			<td>{{x.remark}}</td>
			<td>
				<auth-nav :href="`/pages/role/roleEdit?id=${x._id}`" 
				url="admin/role/info" class="main bold plr5">
					编辑
				</auth-nav>
				
				<auth-btn :url="`admin/role/delete?id=${x._id}`" confirm="delete" 
				@success="remove(index)" class="main bold plr5">
					删除
				</auth-btn>
			</td>
		</tr>
	</block>
</tables>

【upload-images 组件】

图片上传组件,直接上传到云储存,支持多张图片上传

属性 类型 说明
count Number 最多可以上传多少张图片,默认不限制-1
name String 表单的name
value Array 默认显示的图片列表,可以是数组,也可以是英文逗号分割的图片地址
deleteUrl String 当删除图片时,如果有配置删除的请求地址,则会向该地址发送请求,传入fileID参数,从云存储删掉该图片
@change 图片上传或删除时的回调
@delete 图片删除成功的回调
MIT License Copyright (c) 2020 phoooob Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

暂无描述 展开 收起
NodeJS
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
NodeJS
1
https://gitee.com/zyc21st/BaseCloud.git
git@gitee.com:zyc21st/BaseCloud.git
zyc21st
BaseCloud
BaseCloud
master

搜索帮助