@microi.net/cli 5.1.8 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codebuddy-plugin/marketplace.json +2 -2
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.workbuddy-plugin/marketplace.json +2 -2
- package/.workbuddy-plugin/plugin.json +1 -1
- package/assets/build-meta.json +6 -6
- package/cordis.patch.yml +1 -1
- package/package.json +1 -1
- package/scripts/mcp-server.js +85 -85
- package/scripts/microi-cli.js +2 -2
- package/scripts/microi-skills.meta.json +216 -201
- package/skills/.microi-skills-version.json +2 -2
- package/skills/.progressive-disclosure-manifest.json +17 -17
- package/skills/README.md +2 -1
- package/skills/ai-engine/SKILL.md +7 -2
- package/skills/app-store/SKILL.md +81 -81
- package/skills/job-engine/SKILL.md +1 -1
- package/skills/microi-client-frontend/references/progressive-01-3-/345/212/250/346/200/201/346/214/211/351/222/256/347/263/273/347/273/237.md +1 -1
- package/skills/microi-docs-coverage/references/capability-map.md +1 -0
- package/skills/microi-form-layout/SKILL.md +191 -191
- package/skills/microi-frontend-sdk/SKILL.md +189 -182
- package/skills/microi-left-right-layout/SKILL.md +2 -0
- package/skills/microi-sso/SKILL.md +82 -0
- package/skills/microi-sso/references/acceptance.md +49 -0
- package/skills/microi-sso/references/configuration-and-security.md +53 -0
- package/skills/microi-sso/references/inbound.md +53 -0
- package/skills/microi-sso/references/outbound.md +39 -0
- package/skills/microi-ui/SKILL.md +11 -7
- package/skills/microi.v8.js +5 -2
- package/skills/module-engine/SKILL.md +184 -180
- package/skills/module-engine/references/module-config.md +4 -2
- package/skills/ui-design/SKILL.md +34 -30
- package/skills/v8-crud-api/SKILL.md +2 -2
- package/skills/v8-debugging/SKILL.md +3 -1
- package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +3 -2
- package/skills/v8-security/SKILL.md +69 -69
- package/skills/v8-table-event/SKILL.md +1 -1
- package/skills/v8-table-event/references/progressive-02-/345/211/215/347/253/257/344/272/213/344/273/266/345/220/215-v8-eventname-/345/217/257/350/203/275/347/232/204/345/200/274.md +1 -1
- package/skills/v8-utilities/references/server-api-index.md +135 -135
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# 外部身份源登录吾码
|
|
2
|
+
|
|
3
|
+
## 目标流程
|
|
4
|
+
|
|
5
|
+
外部身份源只证明主体身份。回调完成后按当前租户查找绑定/受控 JIT 用户,重新确认 `sys_user` 仍启用,再签发 DiyToken。菜单、表、字段、角色、部门与数据范围不从外部 Token 直接继承。
|
|
6
|
+
|
|
7
|
+
## OIDC RP
|
|
8
|
+
|
|
9
|
+
必须覆盖:
|
|
10
|
+
|
|
11
|
+
- Authorization Code;公共客户端使用 PKCE S256。
|
|
12
|
+
- 随机 state、nonce、短时效、一次性消费和原始 Origin 绑定。
|
|
13
|
+
- Discovery 与 JWKS 的 HTTPS、SSRF、issuer 一致性和缓存更新。
|
|
14
|
+
- id_token 签名、算法、issuer、audience、有效期、nonce;必要时再请求 UserInfo。
|
|
15
|
+
- code 不能写日志、URL 清理、回调错误不泄露 Token/Secret。
|
|
16
|
+
- `client_secret_basic`、`client_secret_post` 或 `none` 与伙伴注册一致。
|
|
17
|
+
|
|
18
|
+
禁止 Implicit、Password Grant、宽松回调前缀、关闭签名或仅解码 JWT 不验签。
|
|
19
|
+
|
|
20
|
+
## SAML SP
|
|
21
|
+
|
|
22
|
+
必须覆盖:
|
|
23
|
+
|
|
24
|
+
- SP Metadata、AuthnRequest、RelayState、ACS 与可选 SLO。
|
|
25
|
+
- 浏览器回调使用 `/api/Sso/SamlCallback`,Assertion Consumer Service 使用 `/api/Sso/SamlAcs`。
|
|
26
|
+
- Response/Assertion 签名、Destination、Issuer、Audience、时间窗口、InResponseTo。
|
|
27
|
+
- Request ID 与 Assertion/Response 重放保护。
|
|
28
|
+
- 加密断言时使用本租户解密私钥;验签只用伙伴公开证书。
|
|
29
|
+
- NameID/Claim 到稳定 Subject 的明确规则。
|
|
30
|
+
|
|
31
|
+
不能因为伙伴证书配置困难而在生产关闭签名校验。
|
|
32
|
+
|
|
33
|
+
## CAS Client
|
|
34
|
+
|
|
35
|
+
- service 必须是精确、受控的吾码回调 URL。
|
|
36
|
+
- CAS 1.0 `/validate`、2.0 `/serviceValidate`、3.0 `/p3/serviceValidate` 按配置解析。
|
|
37
|
+
- Service Ticket 单次使用、短时效、绑定 service;失败响应不能当作用户属性。
|
|
38
|
+
- CAS 根地址生产使用 HTTPS,并经过 SSRF 检查。
|
|
39
|
+
|
|
40
|
+
## 用户解析顺序
|
|
41
|
+
|
|
42
|
+
1. 规范化 `OsClient`、连接方向和协议。
|
|
43
|
+
2. 提取稳定 Subject;拒绝空值、控制字符和不稳定昵称。
|
|
44
|
+
3. 先查 `mci_user_external_identity` 的精确绑定。
|
|
45
|
+
4. `BoundOnly` 未绑定即拒绝;`JitMatch/JitCreate` 仅按已审核映射运行。
|
|
46
|
+
5. 重新读取 `sys_user`,确认未删除、未停用。
|
|
47
|
+
6. 签发 DiyToken,写不含凭据的 SSO 审计。
|
|
48
|
+
|
|
49
|
+
步骤 2–5 固定由 `sso_resolve_federated_identity` 执行;协议 Controller 只把已经验签、归一化且不含原始 Token/断言的 Claim 交给该引擎。步骤 6 由 `sso_complete_login` 编排并调用一次性票据/DiyToken 原子。不要在 OIDC、SAML、CAS 三个 Controller 中各复制一套用户查询、JIT 和角色映射。
|
|
50
|
+
|
|
51
|
+
## 浏览器回调
|
|
52
|
+
|
|
53
|
+
弹窗消息必须同时校验 `event.source`、精确 `event.origin`、消息类型和 ConnectionKey。回调只传 90 秒左右的一次性票据;登录页再用该票据换 DiyToken。不要通过 `postMessage('*')`、URL fragment 或 Query 传 DiyToken。
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 吾码向第三方提供登录
|
|
2
|
+
|
|
3
|
+
## 共同边界
|
|
4
|
+
|
|
5
|
+
先验证当前交互式 DiyToken,再生成第三方协议票据。访问密钥会话不能替代用户交互授权。外部 Client/SP/service 只能读取按 Scope/映射允许的最小资料,不能获得 DiyToken、菜单权限对象或内部角色策略。
|
|
6
|
+
|
|
7
|
+
## OIDC Provider
|
|
8
|
+
|
|
9
|
+
应提供:
|
|
10
|
+
|
|
11
|
+
- Discovery、JWKS、Authorize、Token、UserInfo。
|
|
12
|
+
- 机密客户端认证与公共客户端 PKCE S256。
|
|
13
|
+
- 一次性授权码,绑定 ClientId、Redirect URI、Scope、PKCE、用户、租户和过期时间。
|
|
14
|
+
- 签名 id_token,校验 nonce;按客户端派生 pairwise subject。
|
|
15
|
+
- 高熵不透明 Access/Refresh Token;仅保存哈希索引。
|
|
16
|
+
- Refresh Token rotation/reuse detection,family 撤销。
|
|
17
|
+
- Introspection、Revocation、RP-Initiated Logout 与精确 post-logout redirect。
|
|
18
|
+
|
|
19
|
+
Client Secret 轮换动作只显示一次明文,持久化 PBKDF2-SHA256 哈希。签名 Key 必须有 `kid`,轮换时保留验证重叠窗口。
|
|
20
|
+
|
|
21
|
+
对外 Claim 固定由 `sso_outbound_claims` 从启用用户与连接白名单生成;OIDC/SAML/CAS 协议网关只负责把同一投影编码成对应协议。Client Secret 轮换由 `sso_rotate_client_secret` 编排,并调用精确受限的可信原子生成一次性明文与持久哈希,不能恢复为 Controller 定制动作。
|
|
22
|
+
|
|
23
|
+
## SAML IdP
|
|
24
|
+
|
|
25
|
+
应提供 IdP Metadata、SSO、签名 Response/Assertion、可选加密和 SLO。必须校验 SP Entity ID、ACS、Destination、AuthnRequest 签名/重放;Attribute 只来自白名单映射。每个伙伴独立证书/配置,不把私钥放进应用包或前端。
|
|
26
|
+
|
|
27
|
+
## CAS Server
|
|
28
|
+
|
|
29
|
+
应提供 `/login`、CAS 1.0 `/validate`、CAS 2.0 `/serviceValidate`、CAS 3.0 `/p3/serviceValidate` 和 `/logout`。Service Ticket 必须:
|
|
30
|
+
|
|
31
|
+
- 随机、短时、单次使用。
|
|
32
|
+
- 绑定当前租户、连接、用户和精确 service。
|
|
33
|
+
- 校验成功才返回用户属性;CAS 1.0 使用协议规定的 yes/no 文本。
|
|
34
|
+
|
|
35
|
+
当前不实现 CAS Proxy Ticket;需要代理链时先评估改用 OIDC。
|
|
36
|
+
|
|
37
|
+
## 授权页面
|
|
38
|
+
|
|
39
|
+
第三方发起 Authorize/SAML/CAS 登录后,若没有有效 Provider Session,先跳到吾码登录页;登录成功回到一次性 handoff。页面必须说明目标系统、请求 Scope 和退出影响。即使后续加入 Consent,仍不能把第三方请求的任意 Scope 自动映射为吾码管理员能力。
|
|
@@ -11,15 +11,19 @@ Microi.UI 是 Microi 产品共享前端设计系统。Vue 3 网站、响应式
|
|
|
11
11
|
|
|
12
12
|
当用户要求制作 Microi 移动端应用、H5、小程序、客户门户、员工端、会员中心、官网、产品站、活动页、仪表盘或报告页,且没有指定其它设计系统时,默认使用 Microi.UI。
|
|
13
13
|
|
|
14
|
-
这是自动规则。不要等用户明确说“遵循 `microi.skills/microi-ui/SKILL.md`”。只要仓库、需求、文件路径或项目上下文属于 Microi 生态,且工作涉及前端界面、网站界面、H5、uni-app、小程序、客户/员工/会员页面、报告、仪表盘或视觉打磨,就默认读取并应用本 skill。
|
|
15
|
-
|
|
16
|
-
<!-- microi-progressive:begin -->
|
|
17
|
-
<!-- microi-progressive:chunk id=microi-ui-000 sha256=
|
|
14
|
+
这是自动规则。不要等用户明确说“遵循 `microi.skills/microi-ui/SKILL.md`”。只要仓库、需求、文件路径或项目上下文属于 Microi 生态,且工作涉及前端界面、网站界面、H5、uni-app、小程序、客户/员工/会员页面、报告、仪表盘或视觉打磨,就默认读取并应用本 skill。
|
|
15
|
+
|
|
16
|
+
<!-- microi-progressive:begin -->
|
|
17
|
+
<!-- microi-progressive:chunk id=microi-ui-000 sha256=1fdfec21b03bf209a64b65bc4c1d22cf443b065125d3fb7700d8e1751694394b -->
|
|
18
18
|
## 核心承诺
|
|
19
19
|
|
|
20
|
-
Microi.UI 不只是组件集合,它是 AI 构建软件的视觉交付标准:
|
|
21
|
-
|
|
22
|
-
-
|
|
20
|
+
Microi.UI 不只是组件集合,它是 AI 构建软件的视觉交付标准:
|
|
21
|
+
|
|
22
|
+
- 首要产品气质是清爽、清新、易读:减少重复标题、说明、统计卡和无业务意义的装饰层,用清晰层级、稳定间距与真实内容建立品质。
|
|
23
|
+
- 清爽不等于大面积空白或固定白底;页面必须在信息密度与可扫读性之间取得平衡,核心任务和主要操作应在首屏内清楚可见。
|
|
24
|
+
- 每个组件和页面都必须消费语义 token,适配任意租户主题色,并同时支持亮色、暗色模式;禁止把某一种主色、白色表面或深色背景写成唯一正确外观。
|
|
25
|
+
- 新增视觉验收至少覆盖一个浅色主题、一个暗色主题和一个非默认租户主题色,并检查文字、边界、状态色及焦点态的可读性。
|
|
26
|
+
- 每个首屏都必须有明确视觉锚点。
|
|
23
27
|
- 每个页面都必须使用有品牌意识的色彩和组件层级。
|
|
24
28
|
- 每个重要操作都必须明显、美观且容易触达。
|
|
25
29
|
- 每个列表、详情、表单都应基于可复用场景模式构建,而不是复制一次性 CSS。
|
package/skills/microi.v8.js
CHANGED
|
@@ -1083,8 +1083,11 @@ export function createMicroiV8(options = {}) {
|
|
|
1083
1083
|
if (rowModelMode) {
|
|
1084
1084
|
data._RowModel = {};
|
|
1085
1085
|
Object.keys(source).forEach((key) => {
|
|
1086
|
-
if (key === 'Id')
|
|
1087
|
-
|
|
1086
|
+
if (key === 'Id') {
|
|
1087
|
+
// zhy:新增接口的外层 Id 用于请求寻址,行模型中的 Id 才会进入表单 V8 上下文。
|
|
1088
|
+
data.Id = source[key];
|
|
1089
|
+
data._RowModel.Id = source[key];
|
|
1090
|
+
} else data._RowModel[key] = source[key];
|
|
1088
1091
|
});
|
|
1089
1092
|
} else {
|
|
1090
1093
|
data = { ...data, ...source };
|
|
@@ -1,182 +1,186 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: module-engine
|
|
3
|
-
description: Microi 模块引擎与 sys_menu 配置指南。用于创建或修改后台菜单、菜单统计角标、模块标题指标、复合列表列、移动端业务卡片、查询列、接口替换、跨端 ViewSchema、动态按钮、PageTabs、树形加表格布局和 MicroService 菜单。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
> **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
|
|
7
|
-
|
|
8
|
-
# Microi 模块引擎
|
|
9
|
-
|
|
10
|
-
模块引擎决定同一张表在某个菜单、角色和终端中“如何查询、展示和操作”。
|
|
11
|
-
配置实体是 `sys_menu`,不是 `sys_module`;表结构与字段仍属于
|
|
12
|
-
`diy_table/diy_field`。
|
|
13
|
-
|
|
14
|
-
## 必读参考
|
|
15
|
-
|
|
16
|
-
- 字段、打开方式、查询配置、ViewSchema 和接口替换:
|
|
17
|
-
`references/module-config.md`
|
|
18
|
-
- 动态按钮 JSON 与后台任务:`../v8-menu-buttons/SKILL.md`
|
|
19
|
-
- 树形+表格:`../microi-left-right-layout/SKILL.md`
|
|
20
|
-
- 表单控件:`../microi-form-engine/SKILL.md`
|
|
21
|
-
- 表单平铺、CollapseGroup 与 Tabs 决策:`../microi-form-layout/SKILL.md`
|
|
22
|
-
- MicroService 菜单:`../microi-microservice/SKILL.md`
|
|
23
|
-
|
|
24
|
-
## 创建/修改标准流程
|
|
25
|
-
|
|
26
|
-
1. `microi_get_db_schema` 读取真实 `diy_table`、字段、已有菜单和父菜单。
|
|
27
|
-
2. 绑定表的菜单使用 `microi_create_module`/Manifest,不直接写 `sys_menu`。
|
|
28
|
-
3. 明确 `openType`、父菜单、路由、PC/移动端显隐和角色范围。
|
|
29
|
-
4. 用字段名配置 `listFields/searchFields/sortFields/hiddenFields/mobileFields`;
|
|
30
|
-
MCP 解析为字段 Id 和 `SelectFields/SearchFieldIds/...`。
|
|
31
|
-
5. 同一次创建配齐业务按钮、FormBtns、PageTabs 和批量按钮。
|
|
32
|
-
6. 写后回读模块,检查字段映射、按钮 JSON、路由和目标页面。
|
|
33
|
-
|
|
34
|
-
### 新模块表单打开方式(强制默认)
|
|
35
|
-
|
|
36
|
-
- AI 新建 `diy_table` / 业务模块时,`FormOpenType` 默认写 `Dialog`,`FormOpenWidth`
|
|
37
|
-
默认写 `80%`;缺省值也必须按这组语义处理,不能再把所有模块统一生成为 Drawer。
|
|
38
|
-
- 只有表单确实非常庞大时才使用 `Drawer`:通常是 36 个以上业务字段、至少 2 个
|
|
39
|
-
`TableChild`、28 个以上字段且含大型子表,或 7 个以上子表/富文本/代码编辑/上传/地图等
|
|
40
|
-
重型控件。达到阈值仍应先用 `diy_table.Tabs` 与 CollapseGroup 整理信息架构。
|
|
41
|
-
- 用户显式指定 `Dialog/Drawer/Page` 或宽度时以用户配置为准。Drawer 是贴边直角容器;
|
|
42
|
-
Dialog 使用平台统一大圆角、可拖动、居中弹层,遮罩服从正向开关 `sys_config.FormMaskBlur`,缺失或 `0/false` 默认关闭毛玻璃。
|
|
43
|
-
7. 为管理员/目标角色分配菜单权限,并以真实登录用户验收。
|
|
44
|
-
|
|
45
|
-
## 绑定表菜单不能只写两个字段
|
|
46
|
-
|
|
47
|
-
除 `Name` 和 `DiyTableId` 外,至少配置或允许平台推断:
|
|
48
|
-
|
|
49
|
-
- `TableDiyFieldIds`
|
|
50
|
-
- `SelectFields`
|
|
51
|
-
- `SearchFieldIds`
|
|
52
|
-
- `SortFieldIds`
|
|
53
|
-
- `NotShowFields`
|
|
54
|
-
- `StatisticsFields`
|
|
55
|
-
- `MobileListFields`
|
|
56
|
-
- `CardTitleTagFields`
|
|
57
|
-
- `CardBottomTagFields`
|
|
58
|
-
- `DefaultOrderBy`
|
|
59
|
-
|
|
60
|
-
普通状态、开关等低基数字段不能机械创建单列索引。只有真实查询、关联、唯一约束
|
|
61
|
-
或扫描需要的索引才进入 Manifest 并通过 MCP 创建、回读。
|
|
62
|
-
|
|
63
|
-
## AI 模块视觉交付门禁(强制)
|
|
64
|
-
|
|
65
|
-
对每个 `Display=1` 或 `AppDisplay=1` 且绑定业务表的 Diy 模块,AI 不能只依赖 CRUD
|
|
66
|
-
默认页,也不能只写 `Name/DiyTableId` 后结束。至少完成以下设计和回读:
|
|
67
|
-
|
|
68
|
-
1. 每个列表字段都给出符合内容长度的 `TableWidth`;标题/名称/地址较宽,日期/编码居中,
|
|
69
|
-
金额/数量/状态较紧凑。PC 复合列必须另给合理的 `MinWidth`,不得让末列自适应覆盖它。
|
|
70
|
-
2. 每个模块都配置紧凑 Hero 的业务标题、简短副标题和 2~4 个动态指标。优先统计待处理、
|
|
71
|
-
逾期、金额、容量、风险、完成率等当前表真正有意义的业务数据,不能全部退化为总记录数。
|
|
72
|
-
3. 指标只能来自 `StatisticsFields`、当前列表 `DataCount/PageCount` 或一个批量聚合接口。
|
|
73
|
-
禁止随机数、伪统计、静态演示数字和没有口径的“看起来好看”数值。无法推断时允许用
|
|
74
|
-
`DataCount + PageCount` 做诚实最低兜底,并在后续由业务人员补充口径。
|
|
75
|
-
4. 左侧菜单角标只给少量有行动含义的重要菜单,例如待办、未读、逾期、低库存;禁止每个
|
|
76
|
-
菜单都加。`PageTabs` 的状态数量、`MoreBtns/PageBtns/FormBtns/BatchSelectMoreBtns/
|
|
77
|
-
ExportMoreBtns` 的有用数量也应设计角标,但同页统计必须批量返回,禁止 N+1。
|
|
78
|
-
5. PC 至少设计一个 `Field + Lines + TrailingFields` 复合主列。已放入次要行或右侧图标/
|
|
79
|
-
状态的字段必须从普通独立列去重;主字段、次要行、右侧字段及其 `RequiredFields` 都要
|
|
80
|
-
进入查询结果,宽度必须足以容纳多行和尾随标签。一般情况下每个复合列最多两行,即
|
|
81
|
-
一个主字段加一个 `Lines` 次要字段;可以配置多个各自两行的复合列,但不要在同一列放
|
|
82
|
-
两个 `Lines` 形成三行高表格。确有特殊层级价值时才允许三行,并必须完成桌面视觉验收。
|
|
83
|
-
6. 移动端卡片按真实字段规划图片/头像、标题、副标题、顶部标签、状态、右侧金额、正文、
|
|
84
|
-
Meta、底部区域;同一字段不得在多个区域机械重复,空区域应隐藏而不是留下占位。
|
|
85
|
-
7. `EnableViewSchema` 只控制 Detail/Edit 自定义表单。Hero、指标、列表密度、PC 复合列、
|
|
86
|
-
移动端卡片只要有配置就始终生效;设计器必须提供独立的“自定义表单”Tab。
|
|
87
|
-
|
|
88
|
-
平台自动生成的 List/Card 配置只是防止空白界面的最低值,不能替代 AI 对业务状态、金额、
|
|
89
|
-
时效和操作路径的分析。显式配置优先于自动值;写后用 `microi_get_module` 回读 ViewSchema、
|
|
90
|
-
列宽、统计列、卡片区域和角标配置。
|
|
91
|
-
|
|
92
|
-
## 打开方式
|
|
93
|
-
|
|
94
|
-
| OpenType | 用途 |
|
|
95
|
-
|---|---|
|
|
96
|
-
| `Diy` | 标准表单引擎列表/表单 |
|
|
97
|
-
| `Component` | 主前端已注册 Vue 组件 |
|
|
98
|
-
| `Iframe` | 受控外部页面 |
|
|
99
|
-
| `SecondMenu` | 仅作为父菜单 |
|
|
100
|
-
| `Report` | 虚拟报表 |
|
|
101
|
-
| `MicroService` | 已发布前端微服务页面 |
|
|
102
|
-
|
|
103
|
-
Iframe 不把长期 Token、密码或连接串放 URL。第三方单点登录使用短期、一次性、
|
|
104
|
-
可撤销的服务端交换票据,限制 redirect/scope,并在落地后清理地址栏。
|
|
105
|
-
|
|
106
|
-
## 数据与业务逻辑
|
|
107
|
-
|
|
108
|
-
- 单表 CRUD 已由绑定表菜单提供,不额外创建重复接口引擎。
|
|
109
|
-
- 后端 V8 可用 `V8.ModuleEngine.GetTableData({...})`,通过
|
|
110
|
-
`ModuleEngineKey` 应用模块的关联表查询配置;标准前端 V8 不挂载
|
|
111
|
-
`V8.ModuleEngine`。
|
|
112
|
-
- 查询接口替换、导入/导出替换和跨表动作属于复杂逻辑时,使用接口引擎。
|
|
113
|
-
- 前端按钮只做确认、收集少量参数、调用接口和刷新;事务与最终校验在后端。
|
|
114
|
-
- 预计超过 2 分钟、500 条、1000 个扇出或 100 次外部调用时使用真实后台任务。
|
|
115
|
-
- 不复制官网旧“Redis 文本进度 + 长事务循环”导入示例作为新实现;必须有稳定
|
|
116
|
-
幂等键、业务任务状态、真实 Current/Total、失败恢复和必要的 checkpoint 分片。
|
|
117
|
-
|
|
118
|
-
## 跨端 ViewSchema
|
|
119
|
-
|
|
120
|
-
顶层 PC 数据列表默认使用紧凑的新模块标题样式;即使未启用自定义表单视图,也不能退回无标题的旧外观。无指标头部固定 `44px`、含指标头部固定 `62px`,连同间距总纵向占用约 `50px / 68px`。子表、关联表、嵌入表不重复显示,移动端由固定导航栏承载标题。`Scene=List/Card` 的个性化标题、指标、复合列和卡片配置存在时必须直接生效;`EnableViewSchema` 只控制 Detail/Edit 自定义表单视图。
|
|
121
|
-
|
|
1
|
+
---
|
|
2
|
+
name: module-engine
|
|
3
|
+
description: Microi 模块引擎与 sys_menu 配置指南。用于创建或修改后台菜单、菜单统计角标、模块标题指标、复合列表列、移动端业务卡片、查询列、接口替换、跨端 ViewSchema、动态按钮、PageTabs、树形加表格布局和 MicroService 菜单。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
|
|
7
|
+
|
|
8
|
+
# Microi 模块引擎
|
|
9
|
+
|
|
10
|
+
模块引擎决定同一张表在某个菜单、角色和终端中“如何查询、展示和操作”。
|
|
11
|
+
配置实体是 `sys_menu`,不是 `sys_module`;表结构与字段仍属于
|
|
12
|
+
`diy_table/diy_field`。
|
|
13
|
+
|
|
14
|
+
## 必读参考
|
|
15
|
+
|
|
16
|
+
- 字段、打开方式、查询配置、ViewSchema 和接口替换:
|
|
17
|
+
`references/module-config.md`
|
|
18
|
+
- 动态按钮 JSON 与后台任务:`../v8-menu-buttons/SKILL.md`
|
|
19
|
+
- 树形+表格:`../microi-left-right-layout/SKILL.md`
|
|
20
|
+
- 表单控件:`../microi-form-engine/SKILL.md`
|
|
21
|
+
- 表单平铺、CollapseGroup 与 Tabs 决策:`../microi-form-layout/SKILL.md`
|
|
22
|
+
- MicroService 菜单:`../microi-microservice/SKILL.md`
|
|
23
|
+
|
|
24
|
+
## 创建/修改标准流程
|
|
25
|
+
|
|
26
|
+
1. `microi_get_db_schema` 读取真实 `diy_table`、字段、已有菜单和父菜单。
|
|
27
|
+
2. 绑定表的菜单使用 `microi_create_module`/Manifest,不直接写 `sys_menu`。
|
|
28
|
+
3. 明确 `openType`、父菜单、路由、PC/移动端显隐和角色范围。
|
|
29
|
+
4. 用字段名配置 `listFields/searchFields/sortFields/hiddenFields/mobileFields`;
|
|
30
|
+
MCP 解析为字段 Id 和 `SelectFields/SearchFieldIds/...`。
|
|
31
|
+
5. 同一次创建配齐业务按钮、FormBtns、PageTabs 和批量按钮。
|
|
32
|
+
6. 写后回读模块,检查字段映射、按钮 JSON、路由和目标页面。
|
|
33
|
+
|
|
34
|
+
### 新模块表单打开方式(强制默认)
|
|
35
|
+
|
|
36
|
+
- AI 新建 `diy_table` / 业务模块时,`FormOpenType` 默认写 `Dialog`,`FormOpenWidth`
|
|
37
|
+
默认写 `80%`;缺省值也必须按这组语义处理,不能再把所有模块统一生成为 Drawer。
|
|
38
|
+
- 只有表单确实非常庞大时才使用 `Drawer`:通常是 36 个以上业务字段、至少 2 个
|
|
39
|
+
`TableChild`、28 个以上字段且含大型子表,或 7 个以上子表/富文本/代码编辑/上传/地图等
|
|
40
|
+
重型控件。达到阈值仍应先用 `diy_table.Tabs` 与 CollapseGroup 整理信息架构。
|
|
41
|
+
- 用户显式指定 `Dialog/Drawer/Page` 或宽度时以用户配置为准。Drawer 是贴边直角容器;
|
|
42
|
+
Dialog 使用平台统一大圆角、可拖动、居中弹层,遮罩服从正向开关 `sys_config.FormMaskBlur`,缺失或 `0/false` 默认关闭毛玻璃。
|
|
43
|
+
7. 为管理员/目标角色分配菜单权限,并以真实登录用户验收。
|
|
44
|
+
|
|
45
|
+
## 绑定表菜单不能只写两个字段
|
|
46
|
+
|
|
47
|
+
除 `Name` 和 `DiyTableId` 外,至少配置或允许平台推断:
|
|
48
|
+
|
|
49
|
+
- `TableDiyFieldIds`
|
|
50
|
+
- `SelectFields`
|
|
51
|
+
- `SearchFieldIds`
|
|
52
|
+
- `SortFieldIds`
|
|
53
|
+
- `NotShowFields`
|
|
54
|
+
- `StatisticsFields`
|
|
55
|
+
- `MobileListFields`
|
|
56
|
+
- `CardTitleTagFields`
|
|
57
|
+
- `CardBottomTagFields`
|
|
58
|
+
- `DefaultOrderBy`
|
|
59
|
+
|
|
60
|
+
普通状态、开关等低基数字段不能机械创建单列索引。只有真实查询、关联、唯一约束
|
|
61
|
+
或扫描需要的索引才进入 Manifest 并通过 MCP 创建、回读。
|
|
62
|
+
|
|
63
|
+
## AI 模块视觉交付门禁(强制)
|
|
64
|
+
|
|
65
|
+
对每个 `Display=1` 或 `AppDisplay=1` 且绑定业务表的 Diy 模块,AI 不能只依赖 CRUD
|
|
66
|
+
默认页,也不能只写 `Name/DiyTableId` 后结束。至少完成以下设计和回读:
|
|
67
|
+
|
|
68
|
+
1. 每个列表字段都给出符合内容长度的 `TableWidth`;标题/名称/地址较宽,日期/编码居中,
|
|
69
|
+
金额/数量/状态较紧凑。PC 复合列必须另给合理的 `MinWidth`,不得让末列自适应覆盖它。
|
|
70
|
+
2. 每个模块都配置紧凑 Hero 的业务标题、简短副标题和 2~4 个动态指标。优先统计待处理、
|
|
71
|
+
逾期、金额、容量、风险、完成率等当前表真正有意义的业务数据,不能全部退化为总记录数。
|
|
72
|
+
3. 指标只能来自 `StatisticsFields`、当前列表 `DataCount/PageCount` 或一个批量聚合接口。
|
|
73
|
+
禁止随机数、伪统计、静态演示数字和没有口径的“看起来好看”数值。无法推断时允许用
|
|
74
|
+
`DataCount + PageCount` 做诚实最低兜底,并在后续由业务人员补充口径。
|
|
75
|
+
4. 左侧菜单角标只给少量有行动含义的重要菜单,例如待办、未读、逾期、低库存;禁止每个
|
|
76
|
+
菜单都加。`PageTabs` 的状态数量、`MoreBtns/PageBtns/FormBtns/BatchSelectMoreBtns/
|
|
77
|
+
ExportMoreBtns` 的有用数量也应设计角标,但同页统计必须批量返回,禁止 N+1。
|
|
78
|
+
5. PC 至少设计一个 `Field + Lines + TrailingFields` 复合主列。已放入次要行或右侧图标/
|
|
79
|
+
状态的字段必须从普通独立列去重;主字段、次要行、右侧字段及其 `RequiredFields` 都要
|
|
80
|
+
进入查询结果,宽度必须足以容纳多行和尾随标签。一般情况下每个复合列最多两行,即
|
|
81
|
+
一个主字段加一个 `Lines` 次要字段;可以配置多个各自两行的复合列,但不要在同一列放
|
|
82
|
+
两个 `Lines` 形成三行高表格。确有特殊层级价值时才允许三行,并必须完成桌面视觉验收。
|
|
83
|
+
6. 移动端卡片按真实字段规划图片/头像、标题、副标题、顶部标签、状态、右侧金额、正文、
|
|
84
|
+
Meta、底部区域;同一字段不得在多个区域机械重复,空区域应隐藏而不是留下占位。
|
|
85
|
+
7. `EnableViewSchema` 只控制 Detail/Edit 自定义表单。Hero、指标、列表密度、PC 复合列、
|
|
86
|
+
移动端卡片只要有配置就始终生效;设计器必须提供独立的“自定义表单”Tab。
|
|
87
|
+
|
|
88
|
+
平台自动生成的 List/Card 配置只是防止空白界面的最低值,不能替代 AI 对业务状态、金额、
|
|
89
|
+
时效和操作路径的分析。显式配置优先于自动值;写后用 `microi_get_module` 回读 ViewSchema、
|
|
90
|
+
列宽、统计列、卡片区域和角标配置。
|
|
91
|
+
|
|
92
|
+
## 打开方式
|
|
93
|
+
|
|
94
|
+
| OpenType | 用途 |
|
|
95
|
+
|---|---|
|
|
96
|
+
| `Diy` | 标准表单引擎列表/表单 |
|
|
97
|
+
| `Component` | 主前端已注册 Vue 组件 |
|
|
98
|
+
| `Iframe` | 受控外部页面 |
|
|
99
|
+
| `SecondMenu` | 仅作为父菜单 |
|
|
100
|
+
| `Report` | 虚拟报表 |
|
|
101
|
+
| `MicroService` | 已发布前端微服务页面 |
|
|
102
|
+
|
|
103
|
+
Iframe 不把长期 Token、密码或连接串放 URL。第三方单点登录使用短期、一次性、
|
|
104
|
+
可撤销的服务端交换票据,限制 redirect/scope,并在落地后清理地址栏。
|
|
105
|
+
|
|
106
|
+
## 数据与业务逻辑
|
|
107
|
+
|
|
108
|
+
- 单表 CRUD 已由绑定表菜单提供,不额外创建重复接口引擎。
|
|
109
|
+
- 后端 V8 可用 `V8.ModuleEngine.GetTableData({...})`,通过
|
|
110
|
+
`ModuleEngineKey` 应用模块的关联表查询配置;标准前端 V8 不挂载
|
|
111
|
+
`V8.ModuleEngine`。
|
|
112
|
+
- 查询接口替换、导入/导出替换和跨表动作属于复杂逻辑时,使用接口引擎。
|
|
113
|
+
- 前端按钮只做确认、收集少量参数、调用接口和刷新;事务与最终校验在后端。
|
|
114
|
+
- 预计超过 2 分钟、500 条、1000 个扇出或 100 次外部调用时使用真实后台任务。
|
|
115
|
+
- 不复制官网旧“Redis 文本进度 + 长事务循环”导入示例作为新实现;必须有稳定
|
|
116
|
+
幂等键、业务任务状态、真实 Current/Total、失败恢复和必要的 checkpoint 分片。
|
|
117
|
+
|
|
118
|
+
## 跨端 ViewSchema
|
|
119
|
+
|
|
120
|
+
顶层 PC 数据列表默认使用紧凑的新模块标题样式;即使未启用自定义表单视图,也不能退回无标题的旧外观。无指标头部固定 `44px`、含指标头部固定 `62px`,连同间距总纵向占用约 `50px / 68px`。子表、关联表、嵌入表不重复显示,移动端由固定导航栏承载标题。`Scene=List/Card` 的个性化标题、指标、复合列和卡片配置存在时必须直接生效;`EnableViewSchema` 只控制 Detail/Edit 自定义表单视图。
|
|
121
|
+
|
|
122
122
|
PC 列表的固定结构顺序是“模块 Hero(标题/副标题/动态指标)→ PageTabs → 查询与表格”,Hero 必须渲染在页面多 Tab 上方。头部只使用一次性入场和一次性轻量光效,禁止持续循环动画;`prefers-reduced-motion: reduce` 必须关闭动画和过渡。
|
|
123
123
|
|
|
124
|
-
`
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
- Hero
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
`
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
180
|
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
124
|
+
PageTabs 通过 `TargetSysMenuId` 切换不同模块/表时,入口模块必须作为稳定宿主:客户端在同一个 `diy-table` 实例内加载目标模块的菜单、表、字段与列表数据,只更新当前 URL 的 `Tab` 查询参数,不替换路由、面包屑、顶部访问标签或宿主 Hero。入口模块只配置一组 PageTabs;目标菜单可隐藏导航,但只需保留目标表格设计和角色权限,不得复制同一组 PageTabs。隐藏目标菜单统一设置 `ParentId=入口菜单Id、Display=0、AppDisplay=0、HasChild=0、PageTabs=[]`,入口菜单保持 `HasChild=0` 以继续作为可点击业务入口。模块设计器必须用可搜索菜单树显示 `TargetSysMenuId` 的模块名称,不能只在运行时 JSON 中保存不可见 Id。切换时必须中止旧请求并以模块上下文版本丢弃迟到响应,失败时回滚原模块。
|
|
125
|
+
|
|
126
|
+
模块首屏或跨模块切换期间,Hero 标题/指标、PageTabs、工具栏与列表必须显示与最终布局同尺寸的主题化骨架屏;不能先渲染空白旧布局再整体位移。骨架屏同样遵守 `prefers-reduced-motion: reduce`,并在无指标或无 PageTabs 时按元数据提示隐藏对应占位。
|
|
127
|
+
|
|
128
|
+
`ViewSchema` 是模块级视图,不写入已废弃的通用 `DiyConfig`。优先通过 sys_menu“跨端视图”的 `DiyModulePresentationDesigner` 配置;Detail/Edit 使用独立的“自定义表单视图 JSON”,需要完整协议、角色优先级或未知扩展字段时再使用高级 JSON。启用自定义表单视图后仍须:
|
|
129
|
+
|
|
130
|
+
- 配置 `EnableViewSchema=1`;`ViewSchemaVersion/ViewConfigVersion` 可为空,分别按 `1.0/1` 处理并在后续变更时递增配置版本。
|
|
131
|
+
- 按 Scene、Device、RoleIds、Priority 选择视图。
|
|
132
|
+
- 配置损坏或客户端不支持时回退标准 `sys_menu + diy_table + diy_field`,不能白屏。
|
|
133
|
+
- 小程序只消费声明式动作,不执行 PC 的任意 `V8Code`。
|
|
134
|
+
- 声明式动作中的 ParamMap/VisibleWhen 只允许白名单字段,不使用 `eval`。
|
|
135
|
+
|
|
136
|
+
### 重要模块的统计与信息层级
|
|
137
|
+
|
|
138
|
+
- 待办、库存预警、未读、逾期、待收/待付等有行动含义的菜单,主动询问并配置
|
|
139
|
+
`MenuBadgeEnabled=1` 与 `MenuBadgeApiEngineKey`。接口统一返回
|
|
140
|
+
`{ Code:1, Data:{ Value: number } }`,并按当前用户权限统计。
|
|
141
|
+
- `Scene=List` 的 `Layout.Hero` 用 `Eyebrow/Title/Description/Metrics` 建立模块标题与
|
|
142
|
+
指标条。相同 `ApiEngineKey` 的指标必须由一个聚合接口批量返回,使用 `ValuePath`
|
|
143
|
+
取值;禁止一个指标一次请求。
|
|
144
|
+
- PC Hero 有指标时采用“左侧标题说明约 25%~30% + 右侧指标区弹性占满”的信息层级,
|
|
145
|
+
中间只允许一条弱化渐变分隔;指标条容器和单个指标不得叠加多层描边。无指标时标题说明
|
|
146
|
+
自动占满整行,不保留空指标区。每个指标必须显式配置 `Icon`,并通过不同的 `Tone` 或
|
|
147
|
+
`Color` 形成可辨识的图标色块与轻背景;同一 Hero 内不得让全部指标使用相同图标和颜色。
|
|
148
|
+
- Hero 指标可用 `Source=DataCount` 读取当前筛选总记录数、用 `Source=PageCount` 读取本页
|
|
149
|
+
已加载记录数;两者复用列表结果,不调用额外接口。字段汇总继续用 `Field`,跨表或复合
|
|
150
|
+
统计才用 `ApiEngineKey + ValuePath`。
|
|
151
|
+
- `Layout.List.Columns[]` 用 `Field + Lines + TrailingFields` 配置复合列和右侧图标状态;
|
|
152
|
+
默认按 `Field + 1 个 Lines` 形成双行,多个信息组应拆成多个双行复合列,避免单列三行
|
|
153
|
+
抬高整张表。声明支持 `Tone/Color/Icon/ShowLabel/Prefix/Suffix`,引用字段必须进入查询列。
|
|
154
|
+
- `Scene=Card, Device=Mobile` 用 `Layout.Card` 配置 `AvatarTextField/TitleField/TopFields/
|
|
155
|
+
SubtitleFields/RightFields/Fields/MetaFields/BottomFields`。未配置时继续兼容
|
|
156
|
+
`MobileListFields/CardTitleTagFields/CardBottomTagFields`。
|
|
157
|
+
- `PageTabs/MoreBtns/PageBtns/BatchSelectMoreBtns/ExportMoreBtns/FormBtns` 需要数量时配置
|
|
158
|
+
`BadgeEnabled/BadgeApiEngineKey`;一个接口接收当前页 `Ids + ButtonKeys` 并一次返回
|
|
159
|
+
`Data.Buttons` 与 `Data.Rows`,禁止逐行调用。
|
|
160
|
+
- 能直接用字段表达的信息优先配置复合列/卡片字段;只有确需 HTML 样式或组合逻辑时
|
|
161
|
+
才使用字段的 `V8TmpEngineTable`,且仍需遵守 DOMPurify 和查询字段范围。
|
|
162
|
+
- 存量菜单没有 Hero.Metrics 时,客户端只允许根据真实后端汇总、当前筛选总数、本页加载数
|
|
163
|
+
和本页真实状态分布生成兜底指标;不得用随机值装饰页面。字段聚合缺少全量口径时必须明确
|
|
164
|
+
标注“本页”,不能把当前页求和冒充全表汇总。
|
|
165
|
+
|
|
166
|
+
### 表单布局协同
|
|
167
|
+
|
|
168
|
+
- `<=6` 个核心可见字段优先平铺;`7~29` 个字段按基础、业务、状态、附件等信息域使用
|
|
169
|
+
`CollapseGroup`;`30+` 个字段,或存在多个大型子表、扫码/代码编辑等强任务域时使用
|
|
170
|
+
表级 `diy_table.Tabs`。最终还要按有效表单行校正,避免产生只有少量字段的空洞 Tab。
|
|
171
|
+
- 新增 `Tabs/CollapseGroup/Divider/Alert` 等布局节点必须走明确的“仅元数据”专用路径。
|
|
172
|
+
普通新增字段接口可能同步对业务表执行物理 DDL,不能把向 `diy_field` 新增一行误认为
|
|
173
|
+
仅保存布局配置;写入后要同时回读元数据并核对业务表结构未新增实体列。
|
|
174
|
+
|
|
175
|
+
## 验收
|
|
176
|
+
|
|
177
|
+
- `Display/AppDisplay` 除明确隐藏外为 1,父子菜单层级正确。
|
|
178
|
+
- 路由刷新、直接访问、切换菜单均不 404/白屏。
|
|
179
|
+
- 列表字段、筛选、排序、统计、移动端卡片与预期一致。
|
|
180
|
+
- 权限用户可访问,未授权用户不能靠 URL、`_SysMenuId` 或前端字段绕过。
|
|
181
|
+
- MoreBtns/FormBtns/PageTabs/BatchSelectMoreBtns 显隐、调用和刷新正确;PageTabs 数字角标使用稳定 Tab Id 取 `Data.Buttons`。
|
|
182
|
+
- 菜单角标、模块指标和按钮角标按真实权限返回,零值/超限/接口失败降级正确且无 N+1。
|
|
183
|
+
- Hero 在有指标、无指标、长标题和 3~5 个指标时均层级清晰;指标无多层线框,同一组图标与
|
|
184
|
+
语义色可区分,并在浅色/深色主题下保持可读。
|
|
185
|
+
- PC 复合列和 Mobile Card 引用的附加字段均在查询结果中;长文本、空值、模板值不破版。
|
|
186
|
+
- PC 和移动端分别验证;MicroService 还要验证运行时、页面路由和宿主上下文。
|
|
@@ -185,13 +185,15 @@ ApiEngineKey、Workload、幂等字段、并发 Key、业务状态/任务 Id/进
|
|
|
185
185
|
## PageTabs 两种模式
|
|
186
186
|
|
|
187
187
|
- 无目标菜单:在当前模块执行 V8,通常 `V8.SearchSet(...)`。
|
|
188
|
-
- 有 `TargetSysMenuId
|
|
188
|
+
- 有 `TargetSysMenuId`:在当前 `diy-table` 实例内加载目标模块的菜单、表、字段和列表数据。目标菜单即使隐藏导航,也必须给角色权限。
|
|
189
189
|
|
|
190
190
|
PageTabs 可以通过 `BadgeApiEngineKey` 显示数字角标。接口按 `ButtonKeys` 一次返回所有 Tab 数量到 `Data.Buttons`,`BadgeValuePath` 可显式指定 `Data.Buttons.{TabId}`;失败只隐藏角标,不能阻断页签切换。
|
|
191
191
|
|
|
192
192
|
PageTabs 只表达当前模块的数据类别/状态,不能取代模块 Hero,也不能渲染到 Hero 上方。
|
|
193
193
|
|
|
194
|
-
跨表 Tab
|
|
194
|
+
跨表 Tab 由入口模块统一配置一组 PageTabs,目标菜单只保留各自的模块设计、表绑定和角色权限,不复制 PageTabs。隐藏目标菜单统一设置 `ParentId=入口菜单Id、Display=0、AppDisplay=0、HasChild=0、PageTabs=[]`,入口菜单继续保持 `HasChild=0` 作为可直接点击的业务入口。模块设计器用【关联模块】可搜索菜单树展示名称、保存 `TargetSysMenuId`。切换只更新当前 URL 的 `Tab` 查询参数;路由、面包屑、顶部访问标签和入口模块 Hero 保持稳定,表格上下文在原实例中切换。实现时必须取消旧请求、丢弃迟到响应并在失败时回滚,禁止按菜单名或业务表名写死。
|
|
195
|
+
|
|
196
|
+
首屏和跨模块切换应为 Hero 标题/统计、PageTabs、工具栏和列表提供与最终几何尺寸一致的主题化骨架屏;根据模块元数据判断是否预留指标区和 PageTabs,并支持 `prefers-reduced-motion: reduce`。
|
|
195
197
|
|
|
196
198
|
## URL 参数
|
|
197
199
|
|