UNPKG

@truenewx/tnxcore

Version:

互联网技术解决方案:Web核心扩展支持

186 lines (169 loc) 5.37 kB
/** * 枚举类型<br/> * 注意1:子类声明后务必确保init()被调用一次,方可正常使用 * 注意2:由于枚举常量作为对象可能被代理,所以枚举常量的比较不要使用===操作符,而应该用equals()方法 */ const DEFAULT_KEYS = ['ordinal', 'name', 'caption', 'scenes']; export default class Enum { ordinal = 0; name = ''; caption = ''; scenes = {}; // {sceneName: sceneCaption} /** * @param caption 显示名称 * @param {Object|Array=} [scenes] 场景集 */ constructor(caption, scenes) { this.caption = caption; if (scenes) { if (Array.isArray(scenes)) { for (let scene of scenes) { this.scenes[scene] = this.caption; } } else if (typeof scenes === 'object') { Object.assign(this.scenes, scenes); } } } /** * @param {?Object} [tnx] tnx */ static init(tnx) { let sceneNameSet = new Set(); this.forEach((constant, ordinal, name) => { constant.ordinal = ordinal; constant.name = name; Object.keys(constant.scenes).forEach(sceneName => sceneNameSet.add(sceneName)); }); if (tnx && tnx.app && tnx.app.rpc && typeof tnx.app.rpc.addEnumType === 'function') { tnx.app.rpc.addEnumType({ name: this.name, items: this.getItems(), }); // 加入场景子类型 for (let sceneName of sceneNameSet) { tnx.app.rpc.addEnumType({ name: this.name, subname: sceneName, items: this.getItems(sceneName), }); } } } static forEach(consumer) { let names = Object.keys(this); let ordinal = 0; for (let name of names) { const constant = this[name]; if (constant.constructor === this) { consumer(constant, ordinal++, name); } } } /** * @param {?String} [sceneName] 场景名称 */ static values(sceneName) { let values = []; this.forEach(constant => { if (!sceneName || constant.scenes[sceneName]) { values.push(constant); } }); return values; } static valueOf(name) { let result = undefined; this.forEach(constant => { if (constant.name === name) { result = constant; } }); return result; } /** * 校验指定常量合法性 * @param {String|Enum} constant 常量或常量名 * @param {?String} [sceneName] 场景名称 * @return {Enum} 常量 */ static validate(constant, sceneName) { let result = undefined; if (constant) { if (typeof constant === 'string') { result = this.valueOf(constant); } else if (constant.constructor === this) { result = constant; } if (result && sceneName) { if (!result.scenes[sceneName]) { result = undefined; } } } if (!result) { let message = `无效的 ${this.name} 常量: ${constant}`; if (sceneName) { message += `,于场景 ${sceneName} 中`; } throw new Error(message); } return result; } static caption(name) { let constant = this.values(name); return constant ? constant.caption : undefined; } /** * @param {?String} [sceneName] 场景名称 */ static getItems(sceneName) { let items = []; this.forEach(constant => { let caption = constant.caption; if (sceneName) { let sceneCaption = constant.scenes[sceneName]; if (sceneCaption) { caption = sceneCaption; } else { return; } } let item = { key: constant.name, caption: caption, }; Object.keys(constant).forEach(key => { if (!DEFAULT_KEYS.includes(key)) { item[key] = constant[key]; } }); items.push(item); }); return items; } toString() { return this.name; } equals(other) { return !!(other && other.constructor === this.constructor && other.name === this.name); } clone() { const constant = new Enum(this.caption, this.scenes); constant.ordinal = this.ordinal; constant.name = this.name; return constant; } supports(sceneName) { return !!this.scenes[sceneName]; } localeCompare(other) { if (this.ordinal < other.ordinal) { return -1; } else if (this.ordinal > other.ordinal) { return 1; } else { return 0; } } }