UNPKG

mm_os

Version:

MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。

502 lines (478 loc) 12.8 kB
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;