mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
502 lines (478 loc) • 12.8 kB
JavaScript
const Item = require('mm_machine').Drive;
const Check = require('mm_check');
/**
* Param参数驱动类
* @augments {Item}
* @class
*/
class Drive extends Item {
static config = {
// 函数入口
'main': '',
// 参数过滤
'filter': true,
// 默认监听方法, 当查询参数中出现监听的关键词时,选择以该键值作为请求方式,否则默认为get
'method': 'method',
// 增
'add': {
// body参数
'body': [],
// body中的必填参数
'body_required': []
},
// 删
'del': {
// url中的query参数
'query': [],
// query中的必填参数
'query_required': []
},
// 改
'set': {
// url中的query参数
'query': [],
// query中的必填参数
'query_required': [],
// body参数
'body': [],
// body中的必填参数
'body_required': [],
// 不包含参数
'body_not': []
},
// 查
'get': {
// url中的query参数
'query': [],
// query中的必填参数
'query_required': []
},
// 导入
'import': {
// body中的参数
'body': ['name'],
// body中的必填参数
'body_required': ['file']
},
// 导出
'export': {
// url中的query参数
'query': [],
// query中的必填参数
'query_required': []
},
// 去重
'del_req': {
// query中的必填参数
'query_required': ['groupby', 'sort']
},
// 合计
'sum': {
// query中的必填参数
'query_required': ['field', 'groupby']
},
// 总数
'count': {
// query中的必填参数
'query_required': ['field', 'groupby']
},
// 提交
// "post": {
// // url中的query参数
// "query": [],
// // query中的必填参数
// "query_required": [],
// // body参数
// "body": [],
// // body中的必填参数
// "body_required": [],
// // 不包含参数
// "body_not": []
// },
// 验证参数集
'list': []
};
/**
* 构造函数
* @param {object} config 配置参数
* @param {object} parent 父对象
* @class
*/
constructor(config, parent) {
super({ ...Drive.config, ...config }, parent);
// 默认启用热更新
this.mode = 3;
}
}
/**
* 获取模板目录
* @returns {string} 模板目录
*/
Drive.prototype._getTplDir = function () {
return __dirname;
};
/**
* 更新验证对象
*/
Drive.prototype.updateCheck = function () {
var lt = this.config.list;
var len = lt.length;
for (var i = 0; i < len; i++) {
var o = lt[i];
if (!o.load_check) {
lt[i] = new Check(o);
lt[i].load_check = true;
}
}
};
/**
* 预设
*/
Drive.prototype._preset = function () {
this.updateCheck();
};
/// 新建配置参数模型, 用于动态创建配置时
Drive.prototype.model = function () {
return new Check({
// 参数名
'name': 'name',
// 参数介绍名
'title': '名称',
// 参数做用描述
'description': '用户名称,传入字符串',
// 函数入口
'main': '',
// 是否唯一值, 需配合数据库验证
'only': false,
// 分隔符号, 用于查询时判断多个传参
'splitter': '|',
// 是否主键
'key': false,
// 参数类型 string字符串、number数字、bool布尔、dateTime时间、object对象类型、array数组类型
'type': 'string',
// 数据存储类型 tinyint布尔型(0,1),smallint短整数型,mediumint中整数型,int长整数型,float浮点数型,double双精度型,timestamp时间戳型,date日期型,time时间型,varchar字符串型,text长文本型
'dataType': '',
// 字符串相关验证
'string': {
// 非空
'notEmpty': false,
// 最小长度
'min': 0,
// 最大长度
'max': 0,
// 验证字符串范围, 传入两个成员, 最小长度和最大长度。例如:[0, 0]
'range': [],
// 验证正则表达式
'regex': '',
// 验证与某个参数值是否相同
'identical': '',
// 验证与某个参数值是否不同
'different': '',
// 后缀名, 多个后缀名用“|”分隔
'extension': '',
// 格式验证 email、url、date、dateISO、number、digits、phone
'format': ''
},
// 数值相关验证
'number': {
// 最小值
'min': 0,
// 最大值
'max': 0,
// 验证字符串范围
'range': []
},
'default': ''
});
};
/**
* 验证值是否符合
* @param {object} model 验证模型
* @param {object} value 被验证的值
* @param {Array} requireds 必填项名称数组
* @returns {object} 没通过返回信息,否则返回空
*/
Drive.prototype.checkVal = function (model, value, requireds) {
var msg;
if (value === '' || value === undefined || value === null) {
if (requireds.has(model.name)) {
msg = model.msgHead(model) + model.msg('required');
}
} else {
msg = model.run(value);
if (!msg) {
msg = this.main(model, value);
}
if (msg) {
return msg;
}
}
return msg;
};
/**
* 获取模型
* @param {string} name 名称
* @returns {object} 配置模型
*/
Drive.prototype.getCheckModel = function (name) {
var model;
var lt = this.config.list;
for (var i = 0, o; o = lt[i++];) {
if (o['name'] === name) {
model = o;
break;
}
}
return model;
};
/**
* 执行验证
* @param {object} params 请求参数集合
* @param {Array} arr 要验证的参数名数组
* @param {Array} required 必填项名称数组
* @returns {string|undefined} 返回验证结果
*/
Drive.prototype.checkSub = function (params, arr, required) {
if (!params) {
return undefined;
}
for (var i = 0; i < arr.length; i++) {
var msg = this._checkParam(params, arr[i], required);
if (msg) {
return msg;
}
}
return undefined;
};
/**
* 检查单个参数
* @param {object} params 请求参数集合
* @param {string} key 参数名
* @param {Array} required 必填项名称数组
* @returns {string|undefined} 返回验证结果
* @private
*/
Drive.prototype._checkParam = function (params, key, required) {
var o = this.getCheckModel(key);
if (!o) {
return undefined;
}
var value = params[key];
var msg = this.checkVal(o, value, required);
if (msg) {
return msg;
}
if (value && o.string) {
return this._checkStringRules(o, value, params);
}
return undefined;
};
/**
* 检查字符串规则
* @param {object} model 验证模型
* @param {string} value 参数值
* @param {object} params 请求参数集合
* @returns {string|undefined} 返回验证结果
* @private
*/
Drive.prototype._checkStringRules = function (model, value, params) {
if (model.string.identical) {
return this._checkIdenRule(model, value, params);
} else if (model.string.different) {
return this._checkDiffRule(model, value, params);
}
return undefined;
};
/**
* 检查相同规则
* @param {object} model 验证模型
* @param {string} value 参数值
* @param {object} params 请求参数集合
* @returns {string|undefined} 返回验证结果
* @private
*/
Drive.prototype._checkIdenRule = function (model, value, params) {
var iden_key = model.string.identical;
var val = params[iden_key];
if (val !== value) {
var m = this.getCheckModel(iden_key);
if (m) {
return model.msg('identical', model.title + '(' + model.name + ')', m.title + '(' + m.name + ')');
} else {
return model.msg('identical', model.title + '(' + model.name + ')', iden_key);
}
}
return undefined;
};
/**
* 检查不同规则
* @param {object} model 验证模型
* @param {string} value 参数值
* @param {object} params 请求参数集合
* @returns {string|undefined} 返回验证结果
* @private
*/
Drive.prototype._checkDiffRule = function (model, value, params) {
var diff_key = model.string.different;
var val = params[diff_key];
if (val === value) {
var m = this.getCheckModel(diff_key);
if (m) {
return model.msg('different', model.title + '(' + model.name + ')', m.title + '(' + m.name + ')');
} else {
return model.msg('different', model.title + '(' + model.name + ')', diff_key);
}
}
return undefined;
};
/**
* 验证参数是否符合
* @param {object} query url参数集合
* @param {object} body 正文参数集合
* @param {string} method 请求方式,get增、del删、set改、get查、import导入、export导出
* @returns {object} 没通过返回信息,否则返回空
*/
Drive.prototype.check = function (query, body, method) {
var m = this._getMethodConfig(method, query);
var msg = this._checkQueryParams(query, m);
if (!msg) {
this._processBodyNot(m, body);
msg = this._checkBodyParams(body, m);
}
return msg;
};
/**
* 获取方法配置
* @param {string} method 请求方式
* @param {object} query url参数集合
* @returns {object} 方法配置
* @private
*/
Drive.prototype._getMethodConfig = function (method, query) {
var md = method;
if (md !== 'GET') {
md = md.toLowerCase();
}
var m = this.config[md];
if (!m) {
m = this._getConfigFromQuery(query);
}
if (!m) {
m = this.config['get'];
}
return m;
};
/**
* 从查询参数获取方法配置
* @param {object} query url参数集合
* @returns {object} 方法配置
* @private
*/
Drive.prototype._getConfigFromQuery = function (query) {
var m_key = this.config.method;
if (m_key) {
var md = query[m_key];
if (md) {
return this.config[md];
}
}
return null;
};
/**
* 检查查询参数
* @param {object} query url参数集合
* @param {object} config 方法配置
* @returns {string|undefined} 返回验证结果
* @private
*/
Drive.prototype._checkQueryParams = function (query, config) {
var arr = this._getParamList(config['query'], query);
var arr_query = config['query_required'] || [];
arr.addList(arr_query);
return this.checkSub(query, arr, arr_query);
};
/**
* 处理不需要的Body参数
* @param {object} config 方法配置
* @param {object} body 正文参数集合
* @private
*/
Drive.prototype._processBodyNot = function (config, body) {
var ar = config['body_not'];
if (ar && body && ar.length > 0) {
for (var i = 0; i < ar.length; i++) {
delete body[ar[i]];
}
}
};
/**
* 检查Body参数
* @param {object} body 正文参数集合
* @param {object} config 方法配置
* @returns {string|undefined} 返回验证结果
* @private
*/
Drive.prototype._checkBodyParams = function (body, config) {
var arr = this._getParamList(config['body'], body);
var arr_body = config['body_required'] || [];
arr.addList(arr_body);
return this.checkSub(body, arr, arr_body);
};
/**
* 获取参数列表
* @param {Array} configArr 配置中的参数数组
* @param {object} params 参数集合
* @returns {Array} 参数列表
* @private
*/
Drive.prototype._getParamList = function (configArr, params) {
if (configArr && configArr.length > 0) {
return configArr;
}
var arr = [];
for (var k in params) {
if (arr.indexOf(k) === -1) {
arr.push(k);
}
}
return arr;
};
/**
* 取字段
* @param {object} model 验证模型
* @returns {string} 返回名称
*/
Drive.prototype.title = function (model) {
if (!model.title) {
return model.name + ' ';
} else {
return model.title + '(' + model.name + ') ';
}
};
/**
* 验证回调函数
* @param {object} model 当前的验证模型
* @param {object} value 当前的验证值
* @returns {object} 没通过返回信息,否则返回空
*/
Drive.prototype.main = function (model, value) {
return null;
};
/**
* 获取模型
* @param {string} type 模型类型
* @returns {object} 返回获取到的模型
*/
Drive.prototype.getModel = function (type) {
let model = { ...this.config };
let dir = this.getDir();
let l = $.slash;
let app_name = dir.between('app' + l, l);
let plugin_name = dir.between('plugin' + l, l);
let name = dir.basename();
model.app = app_name;
model.plugin = plugin_name;
model.name = model.name || app_name + '_' + name;
return model;
};
module.exports = Drive;