UNPKG

mm_os

Version:

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

273 lines (249 loc) 7.25 kB
const { Drive } = require('mm_machine'); const Comp = require('./component.js'); /** * 组件基类 * 纯粹的组件数据容器,不包含任何业务逻辑 * 只负责定义组件的数据结构和验证规则 */ class Component extends Drive { static config = { 'name': 'default', 'title': '组件', 'main': '', 'sort': 10 }; /** * 构造函数 * @param {object} config 配置参数 * @param {object} parent 父对象 */ constructor(config, parent) { super({ ...Component.config, ...config || {} }, parent); } } /** * 获取模板目录 * @returns {string} 模板目录 */ Component.prototype.getTplDir = function() { return __dirname; }; /** * 获取组件字段定义 * @returns {object} 组件字段定义 */ Component.prototype.getFields = function () { return this.config.fields || {}; }; /** * 创建组件数据实例 * @param {object} data 组件数据 * @returns {object} 组件数据实例 */ Component.prototype.create = function (data = {}) { if (typeof data !== 'object' || Array.isArray(data)) { throw new TypeError('组件数据必须是对象'); } let component = new Comp(); let fields = this.getFields(); for (let field_name in fields) { let rule = fields[field_name]; let field_value = data[field_name]; component[field_name] = this._getDefaultValue(field_value, rule); } component.isDirty(false); return component; }; /** * 获取字段默认值 * @param {*} field_value 字段值 * @param {object} rule 规则 * @returns {*} 默认值 */ Component.prototype._getDefaultValue = function(field_value, rule) { if (field_value !== undefined) { return field_value; } if (rule.default !== undefined) { return rule.default; } return this._getTypeDefault(rule.type); }; /** * 根据类型获取默认值 * @param {string} type 类型 * @returns {*} 默认值 */ Component.prototype._getTypeDefault = function(type) { const defaults = { 'number': 0, 'string': '', 'boolean': false, 'object': {}, 'array': [] }; return defaults[type] !== undefined ? defaults[type] : null; }; /** * 验证必填字段 * @param {string} field_name 字段名 * @param {*} field_value 字段值 * @param {object} rule 验证规则 * @returns {string|undefined} 错误信息 */ Component.prototype._validateRequired = function (field_name, field_value, rule) { if (rule.required && (field_value === undefined || field_value === null || field_value === '')) { return `${field_name} 是必填字段`; } }; /** * 验证字段类型 * @param {string} field_name 字段名 * @param {*} field_value 字段值 * @param {object} rule 验证规则 * @returns {string|undefined} 错误信息 */ Component.prototype._validateType = function (field_name, field_value, rule) { if (rule.type && typeof field_value !== rule.type) { return `${field_name} 必须是 ${rule.type} 类型`; } }; /** * 验证字段范围 * @param {string} field_name 字段名 * @param {*} field_value 字段值 * @param {object} rule 验证规则 * @returns {string|undefined} 错误信息 */ Component.prototype._validateRange = function (field_name, field_value, rule) { if (rule.min !== undefined && field_value < rule.min) { return `${field_name} 不能小于 ${rule.min}`; } if (rule.max !== undefined && field_value > rule.max) { return `${field_name} 不能大于 ${rule.max}`; } }; /** * 验证字段长度 * @param {string} field_name 字段名 * @param {*} field_value 字段值 * @param {object} rule 验证规则 * @returns {string|undefined} 错误信息 */ Component.prototype._validateLength = function (field_name, field_value, rule) { if (rule.min_length !== undefined && field_value.length < rule.min_length) { return `${field_name} 长度不能小于 ${rule.min_length}`; } if (rule.max_length !== undefined && field_value.length > rule.max_length) { return `${field_name} 长度不能大于 ${rule.max_length}`; } }; /** * 验证字段格式 * @param {string} field_name 字段名 * @param {*} field_value 字段值 * @param {object} rule 验证规则 * @returns {string|undefined} 错误信息 */ Component.prototype._validateFormat = function (field_name, field_value, rule) { if (rule.pattern && !rule.pattern.test(field_value)) { return `${field_name} 格式不正确`; } if (rule.enum && !rule.enum.includes(field_value)) { return `${field_name} 的值必须是 ${rule.enum.join('、')}`; } }; /** * 验证单个字段 * @param {string} field_name 字段名 * @param {*} field_value 字段值 * @param {object} rule 验证规则 * @returns {string|undefined} 错误信息 */ Component.prototype._validateField = function (field_name, field_value, rule) { var error = this._validateRequired(field_name, field_value, rule); if (error) return error; if (field_value === undefined || field_value === null) return; error = this._validateType(field_name, field_value, rule); if (error) return error; error = this._validateRange(field_name, field_value, rule); if (error) return error; error = this._validateLength(field_name, field_value, rule); if (error) return error; return this._validateFormat(field_name, field_value, rule); }; /** * 验证组件数据 * @param {object} data 组件数据 * @returns {object} 验证结果 */ Component.prototype.validate = function (data) { if (typeof data !== 'object' || Array.isArray(data)) { throw new TypeError('验证数据必须是对象'); } const errors = {}; let fields = this.getFields(); for (let field_name in fields) { let error = this._validateField(field_name, data[field_name], fields[field_name]); if (error) errors[field_name] = error; } return { valid: Object.keys(errors).length === 0, errors }; }; /** * 获取组件类型 * @returns {string} 组件类型 */ Component.prototype.getType = function () { return this.config.name; }; /** * 获取组件标题 * @returns {string} 组件标题 */ Component.prototype.getTitle = function () { return this.config.title; }; /** * 获取组件描述 * @returns {string} 组件描述 */ Component.prototype.getDescription = function () { return this.config.description || ''; }; /** * 转换为JSON字符串 * @param {object} component 组件数据 * @returns {string} JSON字符串 */ Component.prototype.toJson = function (component) { // 参数校验 if (typeof component !== 'object' || Array.isArray(component)) { throw new TypeError('组件数据必须是对象'); } return JSON.stringify(component); }; /** * 从JSON字符串创建组件数据 * @param {string} json_str JSON字符串 * @returns {object} 组件数据 */ Component.prototype.fromJson = function (json_str) { // 参数校验 if (typeof json_str !== 'string') { throw new TypeError('JSON字符串必须是字符串'); } let data = JSON.parse(json_str); return this.create(data); }; /** * 初始化组件核心 * @param {object} logger 日志对象 */ Component.prototype._initCore = async function (logger) { // 日志对象 if (logger) { this.setLogger(logger); } }; // 导出模块 exports.Component = Component;