@sunmi/m-sys
v1.0.3
Published
四层模型(Module → Feature → Config → Permission)的运行时门面,提供统一的能力判定链路。
Downloads
174
Readme
m-sys 系统配置
四层模型(Module → Feature → Config → Permission)的运行时门面,提供统一的能力判定链路。
- MSys:四层判定链路入口,回答「这个能力能不能用」
何时使用
每层由不同控制方决定,在对应决策点单独调用:
- 模块:判断某模块在当前版本是否存在 →
Sys.gate({ module }) - 功能点:渲染入口(tab / 菜单项)前,判断该功能是否开通 →
Sys.gate({ feature }) - 配置项:执行某个行为前,判断商户是否启用该行为 →
Sys.gate({ config }) - 权限点:用户触发操作前,判断当前角色是否有权执行 →
Sys.gate({ permission })
三层之间不互相包含:功能点开通不代表商户配置了,配置开启不代表当前用户有操作权限。
单层直接查询可用 Sys.hasModule() / Sys.hasFeature() / Sys.getConfig() / Sys.hasPermission()。
示例
const Sys = max.globalFn.MSys();
// 各层独立判定,按需单独调用
Sys.gate({ module: 'TAKEOUT' }); // 模块是否存在
Sys.gate({ feature: 'TAKEOUT.ORDER_MANAGEMENT' }); // 功能点是否开启
Sys.gate({ config: 'TAKEOUT.AUTO_ACCEPT_ENABLE' }); // 配置是否开启
Sys.gate({ permission: 'TAKEOUT.REJECT_ORDER' }); // 当前用户是否有权限
// → { pass: false, layer: 'module', reason: 'Feature "CHECKOUT.SCAN_PAY" does not belong to module "TAKEOUT"' }
// - 与 Permission.has 差异
// - Permission.has, 仅查权限点
// - Sys.hasPermission,查权限点+是否管控,总之,当前能不能用,无原因
// - Sys.matchPermission,查权限点+是否管控,返回原因
Sys.hasPermission('CODE') // => boolean 当前是否存在权限(查权限点+是否管控)
// Sys.matchPermission在过渡期存在,最终会被移除。新增的权限管控时,使用 Sys.gate({ permission: 'TAKEOUT.REJECT_ORDER' }) 代替
Sys.matchPermission('CODE') // => { hasAuth, reason, isControlled, fail } 权限及管控规则。
// 计费相关
if ([305001, 305002, 305003].includes(code)) {
// 305001
// 不存在在此计费点
// 不存在在此计费点
// 305002
// 资源超限(计费点为资源型)
// 资源超限(计费点为资源型)
// 305003
// 不存在生效中的套餐
// 不存在生效中的套餐
const Sys = max.globalFn.MSys();
const billInfo = Sys.Billing.fromJson(response?.body?.data);
Sys.Billing.showUpgradeDialog(billInfo);
}
MSys API
工厂函数,MSys() 返回 Sys 类(全部静态方法)。
宿主挂载:max.globalFn.MSys = MSys
| Layer | API | 说明 | 返回 |
| ---------- | ---------------------------- | ---------------------- | --------------------------------------------------- |
| Module | Sys.hasModule(code) | 判断模块是否存在 | boolean |
| Module | Sys.getModule(code) | 获取单个模块元信息 | { code, name, owner } \| null |
| Module | Sys.getModules() | 获取全部模块目录 | Array<{ code, name, owner }> |
| Feature | Sys.setFeatures(list) | 写入功能点列表 | void |
| Feature | Sys.getFeatures() | 读取当前功能点列表 | string[] |
| Feature | Sys.hasFeature(code) | 判断功能点是否开启 | boolean |
| Feature | Sys.getFeatureCatalog() | 获取功能点完整目录 | Array<FeatureCatalogItem> |
| Config | Sys.getConfig(key) | 读取配置项值 | any |
| Config | Sys.setConfig(key, value) | 写入配置项值 | void |
| Config | Sys.getConfigCatalog() | 获取配置项完整目录 | Array<ConfigCatalogItem> |
| Permission | Sys.hasPermission(code) | 判断当前用户是否有权限 | boolean |
| Permission | Sys.matchPermission(code) | 获取权限匹配详情 | { fail, hasAuth, isControlled, reason, disabled } |
| Permission | Sys.getPermissionCatalog() | 获取权限点完整目录 | Array<PermissionCatalogItem> |
| Gate | Sys.gate(options) | 执行四层联合判定 | { pass, layer, reason } |
目录数据(db/)
| 文件 | 内容 | 构建命令 |
| -------------------------- | ---------- | ------------------- |
| mods.catalog.json | 模块目录 | npm run build:sys |
| feats.catalog.json | 功能点目录 | npm run build:sys |
| config.catalog.json | 配置项目录 | npm run build:sys |
| permissions.catalog.json | 权限点目录 | npm run build:sys |
npm run build:sys 读取 db/*.catalog.json,注入到 MSys.js 的 #region db-catalogs 区域。
TODO: 功能点 code 去重
以下 code 在 feats.catalog.json 中出现了多次(跨模块重复),需要找产品确认后合并:
CATEGORY_SORTCREATE_COMBOPRODUCT_LISTDEVICE_MODEL_D3PROTIME_SLOT_MENUCUSTOMER_DISPLAY
测试
npm test # 单次运行
npm run test:watch # watch 模式测试使用 vitest + jsdom,__tests__/setup.js 提供 installMax() / resetMax() 模拟平台 max 全局对象。
依赖:运行时依赖
max.localStorage、max.globalFn.ConfigCenter、max.globalFn.MPermission。MSys 通过max.globalFn.MPermission延迟引用。
