mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
273 lines (249 loc) • 7.25 kB
JavaScript
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;