@microi.net/cli 6.3.0 → 6.3.2

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.
Files changed (57) hide show
  1. package/.codebuddy-plugin/marketplace.json +2 -2
  2. package/.codebuddy-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.workbuddy-plugin/marketplace.json +2 -2
  5. package/.workbuddy-plugin/plugin.json +1 -1
  6. package/assets/build-meta.json +5 -5
  7. package/cordis.patch.yml +1 -1
  8. package/package.json +1 -1
  9. package/scripts/mcp-server.js +114 -114
  10. package/scripts/microi-cli.js +63 -58
  11. package/scripts/microi-skills.meta.json +283 -262
  12. package/skills/.microi-skills-version.json +2 -2
  13. package/skills/.progressive-disclosure-manifest.json +35 -35
  14. package/skills/ai-engine/SKILL.md +32 -2
  15. package/skills/ai-engine/references/cpu-timeline-export.md +31 -0
  16. package/skills/ai-engine/references/local-speech-s2v.md +35 -0
  17. package/skills/app-store/SKILL.md +15 -3
  18. package/skills/dos-orm/SKILL.md +3 -0
  19. package/skills/job-engine/SKILL.md +12 -0
  20. package/skills/microi-client-frontend/SKILL.md +2 -2
  21. package/skills/microi-codex/SKILL.md +3 -0
  22. package/skills/microi-codex-installer/SKILL.md +18 -2
  23. package/skills/microi-deployment/SKILL.md +376 -373
  24. package/skills/microi-deployment/references/deployment-matrix.md +167 -145
  25. package/skills/microi-deployment/references/offline-installer.md +66 -64
  26. package/skills/microi-docs-coverage/SKILL.md +1 -1
  27. package/skills/microi-docs-coverage/references/capability-map.md +10 -4
  28. package/skills/microi-form-engine/references/form-generation-quality.md +12 -0
  29. package/skills/microi-frontend-sdk/SKILL.md +12 -1
  30. package/skills/microi-left-right-layout/SKILL.md +176 -163
  31. package/skills/microi-microservice/SKILL.md +5 -0
  32. package/skills/microi-microservice/references/runtime-delivery.md +6 -0
  33. package/skills/microi-microservice/references/v3-committed-status-read.md +13 -0
  34. package/skills/microi-ui/SKILL.md +13 -1
  35. package/skills/module-engine/SKILL.md +27 -2
  36. package/skills/ocr-engine/SKILL.md +30 -0
  37. package/skills/system-observability/SKILL.md +24 -0
  38. package/skills/system-observability/references/framework-status-widgets.md +51 -0
  39. package/skills/system-observability/references/memory-incident-triage.md +14 -0
  40. package/skills/ui-design/SKILL.md +13 -0
  41. package/skills/ui-design/references/controls-and-motion-research.md +49 -0
  42. package/skills/ui-design/references/media-geometry-and-pointer.md +42 -0
  43. package/skills/ui-design/references/mobile-product-language.md +2 -0
  44. package/skills/ui-design/references/motion-and-media.md +4 -2
  45. package/skills/ui-design/references/product-flow-recipes.md +3 -0
  46. package/skills/uniapp-mall-assets/SKILL.md +2 -0
  47. package/skills/v8-api-config/SKILL.md +2 -2
  48. package/skills/v8-security/SKILL.md +22 -5
  49. package/skills/v8-security/references/payment-gateway.md +25 -0
  50. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +20 -0
  51. package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +19 -1
  52. package/skills/v8-sql-query/SKILL.md +2 -0
  53. package/skills/v8-table-event/SKILL.md +14 -2
  54. package/skills/v8-workflow/SKILL.md +8 -0
  55. package/skills/vision-engine/references/realtime-cpu-profiles.md +7 -0
  56. package/skills/vision-engine/references/video-timeline.md +13 -0
  57. package/skills/workspace-conventions/references/progressive-02-microi-net-api-/346/234/254/345/234/260/345/220/257/345/212/250/347/272/246/345/256/232.md +9 -9
@@ -1,163 +1,176 @@
1
- ---
2
- name: microi-left-right-layout
3
- description: Microi 吾码模块引擎“树形+表格/表单”左右结构配置规范。用于通过 MCP、模块引擎或源码配置 `diy_LeftJoinRightView`,把项目、分类、组织等主数据作为左树,并用主外键过滤右侧列表;覆盖字段语义、初始化 V8、移动端自适应、幂等写入和回读验收。
4
- ---
5
-
6
- > **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
7
-
8
- # Microi 左右树表配置规范
9
-
10
- 当需求是“左侧按项目/分类导航,右侧显示该节点的数据列表或表单”时,使用模块组件 `/diy/left-right/LeftTreeJoinRightForm`,配置表为 `diy_LeftJoinRightView`。不要为每个业务菜单复制定制 Vue 页面。
11
-
12
- ## 适用与禁用场景
13
-
14
- - 适用:项目及其成品、用料、请购、提料、锁料、文档,分类及商品,组织及人员。
15
- - 左侧必须是稳定的主数据;右侧必须能通过明确的主外键过滤。
16
- - 左右两边没有关联字段、左侧仅是装饰性筛选,或数据量极大却没有分页/搜索方案时,不应直接套用。
17
-
18
- ## 模块配置
19
-
20
- 目标 `sys_menu` 必须配置:
21
-
22
- ```json
23
- {
24
- "ComponentName": "树形+表格",
25
- "ComponentPath": "/diy/left-right/LeftTreeJoinRightForm"
26
- }
27
- ```
28
-
29
- 同一菜单只能有一条有效的 `diy_LeftJoinRightView` 配置。创建前先按 `GuanlianCD Like 菜单Id` 回读并复用,禁止重复插入。
30
-
31
- ## `diy_LeftJoinRightView` 字段
32
-
33
- | 字段 | 必填 | 含义与写法 |
34
- | --- | --- | --- |
35
- | `GuanlianCD` | 是 | 当前右侧业务菜单链,JSON 数组;末级必须是当前 `sys_menu.Id`。 |
36
- | `ShuxingGLCD` | 是 | 左侧主数据菜单链,JSON 数组;末级对应左表模块。 |
37
- | `GuanlianBD` | 是 | 左侧主表名,例如 `xiangmuguanli`。 |
38
- | `FubiaoGLZD` | 是 | 左表参与关联的字段,通常为 `Id`。 |
39
- | `ZibiaoGLZD` | 右表格必填 | 右表外键,例如 `XiangmuID`、`ProjectId`、`Guid`。必须以实时表结构为准。 |
40
- | `GuanlianPPLJ` | 右表格必填 | 匹配操作符,普通主外键使用 `=`。 |
41
- | `ZuobianZSZJ` | 是 | 左侧组件,通常为 `树形控件`。 |
42
- | `YoubianZSZJ` | 是 | `表格`、`表单` 或 `表单/表格`。 |
43
- | `ShuxianSZDM` | 是 | 左树显示字段,必须与初始化结果的属性名一致。 |
44
- | `ChushiHDM` | 是 | 初始化 V8。必须读取 `V8.Form._PageIndex/_PageSize/inputText`,最终返回 `Data` 和 `DataCount`。 |
45
- | `ZuoyouXSZB` | 否 | 24 栅格比例,例如 `6/18`、`4/20`,中间 `/` 必须保留。 |
46
- | `ShubiaoT` | 否 | 左树标题,例如 `项目目录`。 |
47
- | `ShumoHSS` | 否 | 模糊搜索开关。 |
48
- | `ShuxiaLSS` | 否 | 搜索字段下拉开关。 |
49
- | `ShusouSAN` | 否 | 搜索按钮开关。 |
50
- | `ShushuaX` | 否 | 刷新按钮开关。 |
51
- | `ShudingJXZ` | 否 | 是否允许新增顶级树节点。 |
52
- | `ShuxinZ`、`ShubianJ`、`ShushanC` | 否 | 树节点新增、编辑、删除开关。只在业务允许时开启。 |
53
- | `ShujieDDJSJ` | 否 | 节点点击 V8;可读取 `V8.Form`,异步结果写入 `V8.Result`。 |
54
- | `YincangBSF` | 否 | 节点命中该字段时隐藏右侧区域。 |
55
- | `TanchuangLX`、`TanchuangDX` | 否 | 树节点维护弹窗类型和尺寸。 |
56
- | `LanjiaZ`、`LanjiaZDM` | 否 | 懒加载开关和代码;大树优先使用。 |
57
- | `DefaultExpandLevel` | 否 | 左树默认展开层级。未配置、空值或 `0` 均不展开;`1` 展开一级节点,`2` 再展开二级节点,以此类推。 |
58
-
59
- ## 初始化 V8 与分页契约
60
-
61
- 左树按数据表对待,默认每页 20 条,允许 10/20/50/100 条切换。无论当前只有多少数据,都不能用 `_PageSize:500` 一次拉完整主表。搜索时把页码重置为 1,并在服务端按关键字过滤后返回真实总数。
62
-
63
- 当初始化 V8 使用 `V8.FormEngine.GetTableTree/GetTableDataTree` 时,左侧来源 `diy_table.IsTree` 必须为 `1`,并显式配置真实存在的 `TreeParentField`(通常是 `ParentId`);否则接口会成功返回 `Code=0`,页面只显示“暂无数据”。应用包必须同时携带这两项表元数据,并在发布前通过真实树接口回读,不能只验收 `diy_LeftJoinRightView` 配置行。
64
-
65
- ```js
66
- var form = V8.Form || {};
67
- var pageIndex = Math.max(1, parseInt(form._PageIndex || 1, 10));
68
- var pageSize = Math.min(100, Math.max(1, parseInt(form._PageSize || 20, 10)));
69
- var keyword = String(form.inputText || '').trim();
70
- var query = {
71
- _SelectFields: ['Id', 'Code', 'Name'],
72
- _OrderBy: 'CreateTime',
73
- _OrderByType: 'DESC',
74
- _PageIndex: pageIndex,
75
- _PageSize: pageSize
76
- };
77
-
78
- if (keyword) {
79
- query._Where = [
80
- ['Code', 'Like', keyword],
81
- ['OR', 'Name', 'Like', keyword]
82
- ];
83
- }
84
-
85
- var result = await V8.FormEngine.GetTableData('xiangmuguanli', query);
86
-
87
- if (result.Code !== 1) {
88
- V8.Result = result;
89
- return;
90
- }
91
-
92
- V8.Result = {
93
- Code: 1,
94
- Data: (result.Data || []).map(function (item) {
95
- return {
96
- Id: item.Id,
97
- TreeTitle: [item.Code, item.Name].filter(Boolean).join(' '),
98
- Code: item.Code,
99
- Name: item.Name
100
- };
101
- }),
102
- DataCount: Number(result.DataCount || 0),
103
- PageIndex: pageIndex,
104
- PageSize: pageSize
105
- };
106
- ```
107
-
108
- 对应配置为 `ShuxianSZDM=TreeTitle`、`FubiaoGLZD=Id`。右侧新增时,组件会通过 `ParentDataAppend` 把父节点、父键和 `ZibiaoGLZD` 传给表格;业务字段仍需由表单事件兜底校验。
109
-
110
- ### 节点事件返回复合筛选
111
-
112
- 普通主外键继续使用 `ZibiaoGLZD/GuanlianPPLJ`。确需多个关系字段时,在已授权的配置
113
- `ShujieDDJSJ` 节点 V8 返回 `{ PropsWhere: [...] }`,例如主部门或兼职部门同时匹配:
114
-
115
- ```js
116
- var id = String(V8.Form.Id || '');
117
- V8.Result = { PropsWhere: [
118
- { Name: 'DeptId', Type: '=', Value: id, GroupStart: true },
119
- { AndOr: 'OR', Name: 'DeptIds', Type: 'Like', Value: '"' + id + '"', GroupEnd: true }
120
- ] };
121
- ```
122
-
123
- `GroupStart/GroupEnd` 使用布尔值。字段名、关系及存储格式必须先通过实时 Schema 回读,
124
- 示例不能用于任意业务表。这里只传结构化条件和值,禁止由前端传 SQL;服务端仍校验菜单、表和数据范围。
125
- 运行时只接受非数组对象中的 `PropsWhere` 数组并深复制;明确 `[]` 清空节点条件,未返回或类型非法
126
- 继续原单关联筛选。慢节点事件返回前再次核对节点代次,切节点后的旧结果不能覆盖当前筛选。
127
-
128
- 配置复用 `microi_get_module`、`microi_get_field_list` 和标准 `microi_admin_table_data`
129
- 读取/更新 `diy_LeftJoinRightView`,不新增通用 SQL 接口。系统账号与角色管理的组织树共同使用
130
- 现有 `RoleTreeWidth/RoleTreeCollapsed` 个人偏好;其它业务树保留各自比例。
131
-
132
- 加载请求期间必须显示明确的“正在加载项目...”状态,不能先渲染“暂无数据”;多次搜索或翻页并发返回时,只应用最后一次请求,防止旧结果覆盖新页。
133
-
134
- ## MCP 实施顺序
135
-
136
- 1. 调用实时 Schema/模块查询,确认左右表、菜单 Id、主键、外键和已有配置。
137
- 2. 读取一个已正常运行的左右结构作为基线,只复用结构,不复制租户或业务字段。
138
- 3. 按当前菜单回读 `diy_LeftJoinRightView`;有记录则更新,无记录才新增。
139
- 4. 更新模块 `ComponentName`、`ComponentPath`,随后回读模块和配置行。
140
- 5. 验证“全部”、单节点切换、右表筛选、右侧新增自动关联、刷新和搜索。
141
-
142
- ## 移动端要求
143
-
144
- - `<=767px` 时不在列表上方直接堆放左树。右侧业务列表占满宽度,顶部显示当前项目和“项目目录”按钮。
145
- - 点击“项目目录”后,从左向右打开全高抽屉;推荐宽度 `88%`,保留一段遮罩用于快速关闭。抽屉必须支持关闭按钮、点击遮罩和 Esc 关闭。
146
- - 左树在抽屉内独立滚动,搜索、分页和每页条数选择都必须可操作;关闭抽屉后右表筛选状态不得丢失。
147
- - 右表与页面使用正常纵向滚动,禁止祖先容器 `overflow:hidden` 截断内容。
148
- - 右侧卡片、表格 Tab、列表卡片在移动端必须使用 `height:auto` 和 `overflow:visible`;底部操作栏不得盖住最后一条数据。
149
- - 至少验收桌面 1440x900、手机 390x844;在手机上分别滚动左树和整页到末尾。
150
-
151
- ## 验收清单
152
-
153
- - 当前菜单只匹配一条配置,模块路径正确。
154
- - 使用树接口的左表已启用 `IsTree=1`,`TreeParentField` 与物理父级字段一致。
155
- - 左树标题无 `undefined`、`{}`、空白重复项。
156
- - 点击“全部”清空右侧外键条件;点击节点只显示该节点数据。
157
- - 后端 `_HasChild=true` 表示可展开,Element Plus 的 `isLeaf` 必须映射为独立 `_IsLeaf=!_HasChild`,不得把 `_HasChild` 直接当叶子标记。
158
- - `DefaultExpandLevel` 未配置时必须保持全部折叠;只展开有子节点且深度不超过配置值的节点,不能把平台默认值改成一级展开。
159
- - 页面初始已处于“全部”时,再次点击“全部”不得先清空已加载列表;只清除树节点外键条件并避免重复请求。
160
- - 右侧新增数据自动写入正确外键,切换节点后不会串数据。
161
- - 普通用户不出现仅管理员可用的“页面配置”。
162
- - 桌面左树每页默认 20 条,可翻页并切换 10/20/50/100;加载时不出现错误的空状态。
163
- - 手机初始不显示树,抽屉打开/节点选择自动关闭/遮罩关闭均正常;列表与操作区可滚动到底,无横向挤压和固定高度裁切。
1
+ ---
2
+ name: microi-left-right-layout
3
+ description: Microi 吾码模块引擎“树形+表格/表单”左右结构配置规范。用于通过 MCP、模块引擎或源码配置 `diy_LeftJoinRightView`,把项目、分类、组织等主数据作为左树,并用主外键过滤右侧列表;覆盖字段语义、初始化 V8、移动端自适应、幂等写入和回读验收。
4
+ ---
5
+
6
+ > **Microi吾码基础规范(强制):** 任何 AI 模型与宿主每次新建或接续吾码任务,先完整读取 `../workspace-conventions/SKILL.md`,必须执行版本播报、`@microi.net/cli` 后台自动升级、Skills/MCP 同步和进度播报。安装与诊断读取 `../microi-codex-installer/SKILL.md`;更新失败延后重试,不阻断当前工作。
7
+
8
+ # Microi 左右树表配置规范
9
+
10
+ 当需求是“左侧按项目/分类导航,右侧显示该节点的数据列表或表单”时,使用模块组件 `/diy/left-right/LeftTreeJoinRightForm`,配置表为 `diy_LeftJoinRightView`。不要为每个业务菜单复制定制 Vue 页面。
11
+
12
+ ## 适用与禁用场景
13
+
14
+ - 适用:项目及其成品、用料、请购、提料、锁料、文档,分类及商品,组织及人员。
15
+ - 左侧必须是稳定的主数据;右侧必须能通过明确的主外键过滤。
16
+ - 左右两边没有关联字段、左侧仅是装饰性筛选,或数据量极大却没有分页/搜索方案时,不应直接套用。
17
+
18
+ ## 模块配置
19
+
20
+ 目标 `sys_menu` 必须配置:
21
+
22
+ ```json
23
+ {
24
+ "ComponentName": "树形+表格",
25
+ "ComponentPath": "/diy/left-right/LeftTreeJoinRightForm"
26
+ }
27
+ ```
28
+
29
+ 同一菜单只能有一条有效的 `diy_LeftJoinRightView` 配置。创建前先按 `GuanlianCD Like 菜单Id` 回读并复用,禁止重复插入。
30
+
31
+ ## `diy_LeftJoinRightView` 字段
32
+
33
+ | 字段 | 必填 | 含义与写法 |
34
+ | --- | --- | --- |
35
+ | `GuanlianCD` | 是 | 当前右侧业务菜单链,JSON 数组;末级必须是当前 `sys_menu.Id`。 |
36
+ | `ShuxingGLCD` | 是 | 左侧主数据菜单链,JSON 数组;末级对应左表模块。 |
37
+ | `GuanlianBD` | 是 | 左侧主表名,例如 `xiangmuguanli`。 |
38
+ | `FubiaoGLZD` | 是 | 左表参与关联的字段,通常为 `Id`。 |
39
+ | `ZibiaoGLZD` | 右表格必填 | 右表外键,例如 `XiangmuID`、`ProjectId`、`Guid`。必须以实时表结构为准。 |
40
+ | `GuanlianPPLJ` | 右表格必填 | 匹配操作符,普通主外键使用 `=`。 |
41
+ | `ZuobianZSZJ` | 是 | 左侧组件,通常为 `树形控件`。 |
42
+ | `YoubianZSZJ` | 是 | `表格`、`表单` 或 `表单/表格`。 |
43
+ | `ShuxianSZDM` | 是 | 左树显示字段,必须与初始化结果的属性名一致。 |
44
+ | `ChushiHDM` | 是 | 初始化 V8。必须读取 `V8.Form._PageIndex/_PageSize/inputText`,最终返回 `Data` 和 `DataCount`。 |
45
+ | `ZuoyouXSZB` | 否 | 24 栅格比例,例如 `6/18`、`4/20`,中间 `/` 必须保留。 |
46
+ | `ShubiaoT` | 否 | 左树标题,例如 `项目目录`。 |
47
+ | `ShumoHSS` | 否 | 模糊搜索开关。 |
48
+ | `ShuxiaLSS` | 否 | 搜索字段下拉开关。 |
49
+ | `ShusouSAN` | 否 | 搜索按钮开关。 |
50
+ | `ShushuaX` | 否 | 刷新按钮开关。 |
51
+ | `ShudingJXZ` | 否 | 是否允许新增顶级树节点。 |
52
+ | `ShuxinZ`、`ShubianJ`、`ShushanC` | 否 | 树节点新增、编辑、删除开关。只在业务允许时开启。 |
53
+ | `ShujieDDJSJ` | 否 | 节点点击 V8;可读取 `V8.Form`,异步结果写入 `V8.Result`。 |
54
+ | `YincangBSF` | 否 | 节点命中该字段时隐藏右侧区域。 |
55
+ | `TanchuangLX`、`TanchuangDX` | 否 | 树节点维护弹窗类型和尺寸。 |
56
+ | `LanjiaZ`、`LanjiaZDM` | 否 | 懒加载开关和代码;大树优先使用。 |
57
+ | `DefaultExpandLevel` | 否 | 左树默认展开层级。未配置、空值或 `0` 均不展开;`1` 展开一级节点,`2` 再展开二级节点,以此类推。 |
58
+
59
+ ## 初始化 V8 与分页契约
60
+
61
+ 左树按数据表对待,默认每页 20 条,允许 10/20/50/100 条切换。无论当前只有多少数据,都不能用 `_PageSize:500` 一次拉完整主表。搜索时把页码重置为 1,并在服务端按关键字过滤后返回真实总数。
62
+
63
+ 当初始化 V8 使用 `V8.FormEngine.GetTableTree/GetTableDataTree` 时,左侧来源 `diy_table.IsTree` 必须为 `1`,并显式配置真实存在的 `TreeParentField`(通常是 `ParentId`);否则接口会成功返回 `Code=0`,页面只显示“暂无数据”。应用包必须同时携带这两项表元数据,并在发布前通过真实树接口回读,不能只验收 `diy_LeftJoinRightView` 配置行。
64
+
65
+ ```js
66
+ var form = V8.Form || {};
67
+ var pageIndex = Math.max(1, parseInt(form._PageIndex || 1, 10));
68
+ var pageSize = Math.min(100, Math.max(1, parseInt(form._PageSize || 20, 10)));
69
+ var keyword = String(form.inputText || '').trim();
70
+ var query = {
71
+ _SelectFields: ['Id', 'Code', 'Name'],
72
+ _OrderBy: 'CreateTime',
73
+ _OrderByType: 'DESC',
74
+ _PageIndex: pageIndex,
75
+ _PageSize: pageSize
76
+ };
77
+
78
+ if (keyword) {
79
+ query._Where = [
80
+ ['Code', 'Like', keyword],
81
+ ['OR', 'Name', 'Like', keyword]
82
+ ];
83
+ }
84
+
85
+ var result = await V8.FormEngine.GetTableData('xiangmuguanli', query);
86
+
87
+ if (result.Code !== 1) {
88
+ V8.Result = result;
89
+ return;
90
+ }
91
+
92
+ V8.Result = {
93
+ Code: 1,
94
+ Data: (result.Data || []).map(function (item) {
95
+ return {
96
+ Id: item.Id,
97
+ TreeTitle: [item.Code, item.Name].filter(Boolean).join(' '),
98
+ Code: item.Code,
99
+ Name: item.Name
100
+ };
101
+ }),
102
+ DataCount: Number(result.DataCount || 0),
103
+ PageIndex: pageIndex,
104
+ PageSize: pageSize
105
+ };
106
+ ```
107
+
108
+ 对应配置为 `ShuxianSZDM=TreeTitle`、`FubiaoGLZD=Id`。右侧新增时,组件会通过 `ParentDataAppend` 把父节点、父键和 `ZibiaoGLZD` 传给表格;业务字段仍需由表单事件兜底校验。
109
+
110
+ ### 节点事件返回复合筛选
111
+
112
+ 普通主外键继续使用 `ZibiaoGLZD/GuanlianPPLJ`。确需多个关系字段时,在已授权的配置
113
+ `ShujieDDJSJ` 节点 V8 返回 `{ PropsWhere: [...] }`,例如主部门或兼职部门同时匹配:
114
+
115
+ ```js
116
+ var id = String(V8.Form.Id || '');
117
+ V8.Result = { PropsWhere: [
118
+ { Name: 'DeptId', Type: '=', Value: id, GroupStart: true },
119
+ { AndOr: 'OR', Name: 'DeptIds', Type: 'Like', Value: '"' + id + '"', GroupEnd: true }
120
+ ] };
121
+ ```
122
+
123
+ `GroupStart/GroupEnd` 使用布尔值。字段名、关系及存储格式必须先通过实时 Schema 回读,
124
+ 示例不能用于任意业务表。这里只传结构化条件和值,禁止由前端传 SQL;服务端仍校验菜单、表和数据范围。
125
+ 运行时只接受非数组对象中的 `PropsWhere` 数组并深复制;明确 `[]` 清空节点条件,未返回或类型非法
126
+ 继续原单关联筛选。慢节点事件返回前再次核对节点代次,切节点后的旧结果不能覆盖当前筛选。
127
+
128
+ 配置复用 `microi_get_module`、`microi_get_field_list` 和标准 `microi_admin_table_data`
129
+ 读取/更新 `diy_LeftJoinRightView`,不新增通用 SQL 接口。系统账号与角色管理的组织树共同使用
130
+ 现有 `RoleTreeWidth/RoleTreeCollapsed` 个人偏好;其它业务树保留各自比例。
131
+
132
+ 加载请求期间必须显示明确的“正在加载项目...”状态,不能先渲染“暂无数据”;多次搜索或翻页并发返回时,只应用最后一次请求,防止旧结果覆盖新页。
133
+
134
+ ## MCP 实施顺序
135
+
136
+ 1. 调用实时 Schema/模块查询,确认左右表、菜单 Id、主键、外键和已有配置。
137
+ 2. 读取一个已正常运行的左右结构作为基线,只复用结构,不复制租户或业务字段。
138
+ 3. 按当前菜单回读 `diy_LeftJoinRightView`;有记录则更新,无记录才新增。
139
+ 4. 更新模块 `ComponentName`、`ComponentPath`,随后回读模块和配置行。
140
+ 5. 验证“全部”、单节点切换、右表筛选、右侧新增自动关联、刷新和搜索。
141
+
142
+ ## 移动端要求
143
+
144
+ - `<=767px` 时不在列表上方直接堆放左树。右侧业务列表占满宽度,顶部显示当前项目和“项目目录”按钮。
145
+ - 点击“项目目录”后,从左向右打开全高抽屉;推荐宽度 `88%`,保留一段遮罩用于快速关闭。抽屉必须支持关闭按钮、点击遮罩和 Esc 关闭。
146
+ - 左树在抽屉内独立滚动,搜索、分页和每页条数选择都必须可操作;关闭抽屉后右表筛选状态不得丢失。
147
+ - 右表与页面使用正常纵向滚动,禁止祖先容器 `overflow:hidden` 截断内容。
148
+ - 右侧卡片、表格 Tab、列表卡片在移动端必须使用 `height:auto` 和 `overflow:visible`;底部操作栏不得盖住最后一条数据。
149
+ - 至少验收桌面 1440x900、手机 390x844;在手机上分别滚动左树和整页到末尾。
150
+
151
+ ## 验收清单
152
+
153
+ - 当前菜单只匹配一条配置,模块路径正确。
154
+ - 使用树接口的左表已启用 `IsTree=1`,`TreeParentField` 与物理父级字段一致。
155
+ - 左树标题无 `undefined`、`{}`、空白重复项。
156
+ - 点击“全部”清空右侧外键条件;点击节点只显示该节点数据。
157
+ - 后端 `_HasChild=true` 表示可展开,Element Plus 的 `isLeaf` 必须映射为独立 `_IsLeaf=!_HasChild`,不得把 `_HasChild` 直接当叶子标记。
158
+ - `DefaultExpandLevel` 未配置时必须保持全部折叠;只展开有子节点且深度不超过配置值的节点,不能把平台默认值改成一级展开。
159
+ - 页面初始已处于“全部”时,再次点击“全部”不得先清空已加载列表;只清除树节点外键条件并避免重复请求。
160
+ - 右侧新增数据自动写入正确外键,切换节点后不会串数据。
161
+ - 普通用户不出现仅管理员可用的“页面配置”。
162
+ - 桌面左树每页默认 20 条,可翻页并切换 10/20/50/100;加载时不出现错误的空状态。
163
+ - 手机初始不显示树,抽屉打开/节点选择自动关闭/遮罩关闭均正常;列表与操作区可滚动到底,无横向挤压和固定高度裁切。
164
+
165
+ ## 右侧加载子级(9.0.5 配套能力)
166
+
167
+ RightLoadDescendants 默认0,缺失/NULL/false保持原单节点且无新范围请求;官方账号/角色可启用,其它配置保留。platform-left-tree-scope 只收 SysMenuId/SelectedId,从真实tenant/user和唯一末级菜单配置派生左菜单/树表,逐页100条走普通Client权限,完整有界≤10000节点。重复/缺页/计数变化/循环/超限拒绝;按Sort+Id稳定遍历,不跨不可读中间节点;右表仍执行原菜单/角色/租户数据权限交集。
168
+
169
+ 自定义节点事件显式消费 V8.TreeScope.Values 并返回 TreeScopeApplied:true、PropsWhere;禁止只加确认标记却仍只筛单节点。官方账号保持主/兼职部门OR,角色保持DeptIds JSON值关系;所有部门左树初始化按Sort ASC。旧事件必须fresh完整合并,不能覆盖客户定制。失败隐藏旧右表,不回退全部;旧请求/事件不覆盖新节点,保留全部/新增关联/手机抽屉。真实角色与桌面/手机仍需上线验收。
170
+
171
+ ### 应用更新与重复配置排查
172
+
173
+ - 后端存在 `platform-left-tree-scope` 不代表元数据已安装。须同时回读 `RightLoadDescendants` 字段、真实物理列、账号/角色配置的开关及完整节点事件。新租户的 SaaS 包和存量租户的系统账号包都应从官方母版标准导出树表闭包与各自拥有的种子,不能只发布接口。
174
+ - 返回“当前菜单的左右结构配置必须唯一”时,以 `GuanlianCD` 的末级菜单 Id 精确核对全部未删除记录。先保存完整自定义初始化/事件及原 Id,再按已授权范围合并到稳定配置并可逆退役重复项;禁止任取第一条、清空客户定制或让下一次安装重新制造重复。
175
+ - 节点事件是可执行脚本,须核验真实 `ShujieDDJSJ` 物理列为大文本;字段元数据声明 `mediumtext` 不能证明数据库已同步。出现 `Data too long` 时走标准字段/应用升级修复,并把真实物理定义纳入包,不能截断脚本后假报成功。
176
+ - 系统账号呈现规则通过 `platform-account-directory-tree-options`(Managed、登录后HTTP)调用 `platform-account-directory-tree-hook`(CreateIfMissing、StopHttp=1)。Hook阶段固定 `ReadPresentationOptions`,仅返回 `Data.ExcludedNodeIds`(最多100个稳定Id)和 `Data.IncludeInactive`(boolean);默认无定制。原定制隐藏规则迁入租户Hook,再可逆退役重复配置,并真实执行同版本重装证明Hook与唯一活动配置保留。账号初始化须同时检查 `ChushiHDM` 真实大文本列,保留祖先搜索与服务端分页完整性;导航隐藏不能缩窄或扩大右表授权范围。
@@ -50,6 +50,8 @@ description: Microi 前端微服务 MicroService 开发与交付指南。用于
50
50
 
51
51
  所有读写必须使用同一 MCP、ApiBase 和 OsClient。写操作先 dry-run,再按用户授权确认。
52
52
 
53
+ 头像、私有附件等字段的保存值与显示地址分开:上传回执同时返回 `Path/FilePathName` 与 `Url/PreviewUrl` 时,保存持久对象路径,临时签名 URL 只供预览。通用显示解析器的 URL 优先语义不能直接用于私有字段保存;缺少对象路径时应明确失败并保留旧值,不剥掉 URL 的域名或签名来猜对象标识。头像回归覆盖私有/公开、复合回执、URL-only、文件类型与大小拒绝、保存后重新读取及授权预览。
54
+
53
55
  ## 源码与产物分离
54
56
 
55
57
  - `sys_microistore`:应用主数据。
@@ -140,6 +142,7 @@ AppKey 稳定且只含安全字符。`microi.routes.json` 是页面事实源,
140
142
  - 创建/更新元数据:`microi_create_microservice`。
141
143
  - 同步私有源码:`microi_sync_microservice_source`;本地工程必须优先传 `directory`,不构造 Base64 文件数组。
142
144
  - 真实编译目录优先 `microi_publish_application_directory_stream` 流式发布。
145
+ - 已提交版本的只读回读使用同冻结请求的 `verificationOnly=true`,前提是已保存原 finalize 的 Committed 回执、fresh 应用双指针精确匹配,且保留原 CAS 不追认当前状态。已存在版本分支只取 Native 行版本,不重新上传或 finalize;此选项本身仍可能首次创建 stage,不能当作任意应用的通用只读开关。严格区分 phase 的 `Pending=false` 与 `ProjectionPending/RepairRequired`,并报告本地修复工具与 npm 已发布版本的区别,详见[已提交版本状态回读](references/v3-committed-status-read.md)。
143
146
  - 发布前读取 `microi_get_status`,分开报告服务器在线和 `ApplicationAssetStreamGateReady`。`Actual=0` 表示当前读取没有有效门禁行,不证明用户无权限或主控登记缺失。保持用户指定子租户,不索要主租户账号/SSH,不调用补登记接口,不复制业务库 `sys_osclients`,不降级绕过门禁;提交平台排查后端取数来源和版本。
144
147
  - 发布门禁由后端从启动主租户的主控库读取当前子租户 `OsClient + Type + Network` 的唯一有效 `sys_osclients` 行,文件、应用和版本仍在当前子租户。门禁转换审计在同一主控库事务中写入。缺少门禁列/审计结构属于平台侧 SaaS/应用商城责任包问题;缺少子租户的 `sys_microistore/mci_ai_app_version/mci_ai_app_file` 则通过该租户应用商城升级。不能因主控结构故障擅自更换业务连接。不执行已退役 Upgrade25,不手动 reset 锁、fence、Storage 或 active/committed 指针;缺少结构与真正 CAS 漂移分别诊断。
145
148
  - `changeSummary` 是最多 2000 字符的版本说明文本,不能传对象;v3 在首次 stage 创建版本时存入 `mci_ai_app_version.ChangeSummary`,后续同请求重放和恢复保留原说明。历史节点若发布完成但摘要仍为空,应报告后端版本缺口,不得把编译文件验证成功等同于日志验收通过。
@@ -306,6 +309,8 @@ AI 生成菜单微服务时,应优先封装一个 `callMicroiHost(action, data
306
309
 
307
310
  ### 菜单页签缓存与子应用生命周期(强制)
308
311
 
312
+ 支付配置/充值微服务的秘密只在页面内存、保存后清空,二维码本地生成;未知结果保留稳定原单查询。`afterhidden`/卸载停止轮询、撤销宿主遮罩,`aftershow`只恢复一套当前会话任务,迟到响应不覆盖新订单。原菜单与手机验收仍须先执行完整私有源码拉取、逐文件校验、三方合并和清单CAS,类型检查不能替代。
313
+
309
314
  - 菜单微服务只有一个缓存所有者:Vue 路由宿主固定 `meta.keepAlive=false`,`<micro-app keep-alive>` 独占子应用状态。禁止把外层 Vue `KeepAlive` 打开,也禁止子应用通过随机实例名规避运行时缓存;双层缓存会产生旧宿主与当前路由竞争、无数据、永久骨架屏和白屏。
310
315
  - 每个主框架 `fullPath` 使用稳定且不泄露查询参数/Token 的实例指纹。平台最多保留 5 个菜单运行时,超过后按 LRU 销毁最久未使用的隐藏实例;Tab 仍保留,再次进入允许冷启动。关闭当前/其它/全部 Tab、访问记录淘汰、退出登录、Token 重置、角色变化、同路由版本或入口变化时必须精确 `unmountApp(name,{destroy:true,clearData:true})`。
311
316
  - 恢复隐藏实例时,宿主用 `forceSetData` 同步当前 Token、OsClient、权限、主题、路由和视口,再复核 `micro-app-body/#app` 的真实可见 DOM;失败只允许自动销毁重建一次。`hostCapabilities.lifecycle` 暴露 `cacheOwner=micro-app`、`cacheMode=runtime-keep-alive`、`maxCachedTabs=5` 和状态事件。
@@ -280,6 +280,12 @@ function openPlatformPrint(printId, businessId) {
280
280
 
281
281
  公有桶的固定根与版本目录继续作为发布投影。数据库完成态的相对 `PreviewUrl/PublicPublishPath` 保留原值,由展示 consumer 转成公开固定入口,不通过批量改表统一 URL。固定入口 HTML 引用的清单内资产仍可独立经 CDN/NAS 分流。
282
282
 
283
+ V3 受信快照已经精确绑定 `microi/application-assets/v3/tenants/{tenant}/...` 的完整不可变对象键。
284
+ 提供商签名读取必须与原生发布器 `PutApplicationObject` 和验签回读使用同一键;不能再用普通表单文件的
285
+ `NormalizeStoragePath` 追加租户前缀,也不能接收调用方自由路径。公有编译资产仍可匿名经已提交清单交付,
286
+ 受限桶的签名仅在后端;源码、未提交、跨租户和清单外路径保持拒绝。回归用真实 MinIO/S3 HTTP 请求区分
287
+ 原始键成功与多余租户前缀 404,并独立保留大小/SHA/MIME、HEAD、Range 和取消验证;不靠开桶、移动对象或重发修复。
288
+
283
289
  历史目录必须已有完整清单与原始字节验证;对象缺失或摘要不符时报告未恢复,不能覆盖成当前版本或宣称可回滚。现有 `/{version}/...` 短 API 和 `?version=` 不能作为通用 V3 历史读取协议。用户显式选择的历史地址、签名地址与私有应用保留原访问语义,不规范化成 current,也不为获得公开入口改变权限。
284
290
 
285
291
  验收分别直接访问当前固定入口、精确历史入口及其 JS/CSS:当前入口 GET/HEAD 不应产生顶层 Location 跳转,实际浏览器最终地址仍为固定入口;历史版本核对其实际版本与文件摘要,不能只验证当前版本或数字版本字段。
@@ -0,0 +1,13 @@
1
+ # 已提交 V3 版本的状态回读
2
+
3
+ 只读状态查询先保存原 finalize 的完整原生回执,确认 `PointerState=Committed`,再从正常应用上下文核验同一 AppId、active/committed 双指针、manifest、fence/row。原业务 RequestId、requestFingerprint、源与运行清单、版本和原始 CAS 保持不变。不得因为回执是 ProjectionPending 就再次 finalize;不得用普通字典版本查询为 0 证明原生版本缺失。
4
+
5
+ 在上述前提成立时,同冻结 stage 请求的 `verificationOnly=true` 跳过全部资产上传。原生实现对已存在且不可变事实匹配的版本只回读 Native 版本行并返回:`PublishMode=stage`、`PhaseState=ReleaseVerified`、`Idempotent=true`、`PointerState=Committed`、`Pending=false`、`Completed=false`,并保留真实 `PublishState` 与 `VersionRowVersion/RowVersion`。这里 Completed=false 是 stage phase 的 DTO 语义,不能将它改成 true 或捏造另一份 finalize DTO。
6
+
7
+ Native PublishState 可以是 PointerCommitted、ProjectionPending、RepairRequired、Completed。前两个投影待完成状态的准确判断还应结合 fresh 应用状态,不能因为 phase Pending=false 就宣称整个应用发布完成。只有原生和应用均 Completed、应用 Published/Success、双指针/清单一致才进入下一步骤。真实版本 RowVersion 从这一受支持的 Native 回包读取,不能沿用 finalize Pending 回包中的旧行版本。
8
+
9
+ 客户端只允许 `verificationOnly===true` 的上述精确幂等回读。所有原 tenant/app、RequestId/指纹、版本、源与运行清单、路由、门禁与不可变路径校验继续执行。fence 必须大于原请求期望值,应用 row 必须精确前滚 1;Native FencingToken 必须等于当前 PublishFence,RowVersion 必须等于 VersionRowVersion。普通 stage 仍只能返回未提交的 Verifying/ReleaseVerified;字符串 true、未知状态、伪 Pending、状态/指针矛盾或任何身份漂移一律拒绝。
10
+
11
+ `verificationOnly` 并非任意应用的通用只读接口:没有已存在版本且原 CAS 仍匹配时,该正常发布动作可以首次持久化 stage。因此状态读取必须先以原 Committed 回执和 fresh 双指针限定到已存在版本,保留原 CAS;不得改成当前 CAS 再声称只查询。匹配分支会使用临时分布式租约和只读行锁,不创建/更新发布记录,也不上传、重新投影或重新提交指针。回执须如实区分业务数据 0 写与临时锁操作。
12
+
13
+ 旧 MCP 可能在后端正确回读之后,因旧客户端阶段断言拒绝合法 committed stage。保留真实 isError/evidenceMismatch 回执,修复并测试正式 MCP 校验器与调用点,使用新进程加载已测试的完整 MCP 入口;禁止用 wrapper 把错误改成功、伪造原生回包、越过工具拒绝调用原始 HTTP,或重发 finalize。已有连接、加密凭据、模型配置保持。npm 未发布时明确标注本地修复、源码/编译产物哈希与实际加载路径,不能称所有客户端已更新。
@@ -30,9 +30,11 @@ Microi.UI 不只是组件集合,它是 AI 构建软件的视觉交付标准:
30
30
  - 每个移动端页面都必须处理安全区、加载状态、按下反馈和底部操作。
31
31
 
32
32
  <!-- /microi-progressive:chunk -->
33
- <!-- microi-progressive:chunk id=microi-ui-001 sha256=cda04dc6f6e7b164ca2de2a7f7aeec711d629bf82a546849dc56b09bdb3aa64a -->
33
+ <!-- microi-progressive:chunk id=microi-ui-001 sha256=881ad77d07f02a6887d3814d3489c88ec313765bc1f2be7beb0877febe18180d -->
34
34
  ## 内置设计模式
35
35
 
36
+ 支付页面遵守[产品流程配方](../ui-design/references/product-flow-recipes.md#结算与支付):未知结果保留原单核实;秘密只在内存输入、不回填,二维码本地生成;宿主隐藏和卸载停止轮询。
37
+
36
38
  当需求只说“主流、高级、好看”时,先为页面确定一种主模式,再开始选组件和写样式:
37
39
 
38
40
  | 主模式 | 首要目标 | 推荐组合 |
@@ -193,3 +195,13 @@ Microi.UI 不只是组件集合,它是 AI 构建软件的视觉交付标准:
193
195
 
194
196
  - [references/progressive-01-移动端场景蓝图.md](references/progressive-01-移动端场景蓝图.md):移动端场景蓝图;网站/PC 站标准;后台菜单配套;AI 实施清单;禁止输出
195
197
  <!-- microi-progressive:end -->
198
+
199
+ ## 媒体比例与手机交付门禁(强制)
200
+
201
+ 含图片、图集、视频海报或鼠标跟随的页面,必须读取 [媒体比例、响应式与指针效果门禁](../ui-design/references/media-geometry-and-pointer.md)。图片只能等比缩放;图集的 `300% 100%` 不能充当任意宽高窗口的裁切方案。逐媒体检查人物/圆形主体与实际绘制比例,覆盖手机、平板和桌面;无横向溢出或构建通过不能替代视觉验收。鼠标跟随仅对精细指针按需运行,减少动效、隐藏、静止与卸载必须停止调度。
202
+
203
+ 按钮文字、主题/图标/持续动效或作品播放器有声交互涉及重设计时,另读取 [交互控件、动效与有声媒体](../ui-design/references/controls-and-motion-research.md)。悬停静音预览与用户点击后的有声播放分别实现;按钮可读性不能依赖悬停或动画。
204
+
205
+ ## MciButton 内容与状态(9.0.5)
206
+
207
+ Web内容层inline-flex双向居中、gap8/min-width0,default slot保持,装饰图标可用独立icon槽位继承前景且aria-hidden。loading原生禁用、aria-busy=true、spinner aria-hidden,不用新图标包或持续动画修可读性。默认/九色/明暗/五变体应检查default、hover、focus-visible、active的最差渐变文字≥4.5;disabled按inactive语义独立检查,不冒称全状态均达4.5。SSR/CSS计算与浏览器computed/1440+390截图分别记录,源修改不代表客户部署。
@@ -67,6 +67,28 @@ PC 卡片优先选择当前终端 Card 视图,没有时复用 Mobile Card;
67
67
 
68
68
  ## 创建/修改标准流程
69
69
 
70
+ ### 恢复软删除菜单身份(后端9.0.1)
71
+
72
+ 原菜单被误退役时使用正式 `microi_restore_module`,不重建菜单、不用临时维护引擎或任意SQL。
73
+ 仅真实当前租户平台管理员可调用,访问密钥和开发角色授权均不能替代。先传
74
+ `action:Inspect,moduleId:原Id`,必要时明确 `duplicateModuleId`;检查 `CanRestore`、引用、
75
+ `ExpectedHash` 和 `RetirePermissionIds`。再用 `action:Restore,expectedHash:原摘要,
76
+ retirePermissionIds:原返回数组,confirmExecution:RESTORE_MODULE:<原Id>:<摘要>`。
77
+ 摘要是按序键canonical JSON的SHA256,绑定两菜单完整行、权限和引用检查;不能只重取新摘要来重放旧意图。
78
+
79
+ 原生事务只恢复原行IsDeleted,保留Id/URL/配置/原权限。可选重复菜单必须同构、无子项/JSON/
80
+ 用户偏好等控制面引用,且仅关联明确的管理员Menu权限;只软退役该行及返回的权限链接,不改业务数据。
81
+ 单表/控制面扫描最多20000行,未知偏好容器、路由冲突、摘要变化或读取不全均失败关闭。
82
+ 范围是固定设计/导航控制面,含rpt_user_module_setting和rpt_user_setting;不会扫描或改写任意业务正文。
83
+ 后端9.0.2先检查真实物理表。历史`rpt_user_setting`可为仅有元数据的个人设置虚拟投影:
84
+ 仅当报告形状、两条旧接口的当前路由/启用状态和已审计源码摘要严格吻合时,才映射至已经完整扫描的
85
+ `sys_user`;报告完整定义和两接口事实同时绑定本次摘要。不执行报告/V8/外部数据源,不创建空表;
86
+ 实体存在则正常扫描,未知形状、改向或缺失其它引用容器继续拒绝。返回的`VirtualReferenceMappings`
87
+ 只显示虚拟名和物理背源。失败的`DiagnosticId`用于查询`MCP/ModuleRestoreFailed`安全阶段日志,
88
+ 日志只含异常形状和关联号;入队不等于已持久化。不得改用SQL恢复以绕过拒绝。
89
+ 丢响应先Inspect,保留同一原摘要和权限数组核对AlreadyApplied;已提交但缓存待失效时不再次改变删除位。
90
+ 源码、CLI工具和后端部署分别验收;旧MCP进程没有新工具时正常更新并新建进程,不临时绕过。
91
+
70
92
  1. `microi_get_db_schema` 读取真实 `diy_table`、字段、已有菜单和父菜单。
71
93
  2. 绑定表的菜单使用 `microi_create_module`/Manifest,不直接写 `sys_menu`。
72
94
  3. 明确 `openType`、父菜单、路由、PC/移动端显隐和角色范围。
@@ -79,10 +101,11 @@ PC 卡片优先选择当前终端 Card 视图,没有时复用 Mobile Card;
79
101
 
80
102
  - 每个新建或修改的菜单都必须设置与业务相关的图标;根目录、分类及子菜单不能批量使用同一个默认图标。优先按名称和实际功能选择,例如客户用 `UserFilled`、日程用 `Calendar`、仓储用 `Box`、办公用 `OfficeBuilding`。
81
103
  - 主后台侧栏读取 `sys_menu.IconClass`(CSS/组件图标),不是图片字段 `Icon`。优先填写当前前端已注册的 Element Plus 图标名;使用 FontAwesome/CSS 名称时先核对兼容映射,不能填入不存在的类名后让全部菜单回退为 `Document`。
82
- - 没有贴切图标时,从实际可用图标集合中随机选一个,并将选择结果保存;可以按稳定菜单 Id 生成确定的随机分配,避免每次刷新或重新发布都变图标。同组菜单应有适当差异,不强求不同业务绝对不重复。
104
+ - 先读当前运行前端实际注册的图标集合,并用真实兼容映射/组件解析验证候选。`fas fa-wand-magic-sparkles` 这类CSS语法合法但未映射的值可能全部回退成 `Document`;不能以数据库字符串不同当作图标不同。按名称、绑定页面与实际业务语义优先选择;只有没有贴切候选时,才按稳定菜单Id从未占用的真实图标集合确定性分配并保存,禁止每次渲染重新随机。
83
105
  - 通过 `microi_create_module` / `microi_update_module` 或 Manifest 的模块配置写入,并把图标纳入应用包。只修改图片字段、只检查数据库字符串或只改本地 Manifest 不算完成;必须回读 `IconClass`,在真实侧栏检查图标可见且有区别。
84
106
  - 创建菜单优先显式传 `iconClass`(Manifest 同名,保存为 `IconClass`);`icon`/`Icon` 保留桌面图片地址语义。历史调用把CSS图标传入 `icon` 时仅作为兼容输入,不能因此漏写侧栏字段。未指定时生成器按业务语义或稳定名称哈希从实际注册图标中补齐,禁止统一退为 `Document`。
85
- - 同一父菜单下逐项检查图标与功能对应,分类、客户、产品、商机、报价、合同、回款等应可辨识;无法精确匹配时使用稳定差异图标,不追求全系统绝对唯一。幂等重跑保留既有正确图标,只有明确授权修复空值/错误值时才更新。工具成功后独立回读,旧MCP缺参数时先升级工具,不能把不存在的字段当作已经生效。
107
+ - 同一父菜单下图标必须可辨识且不重复:先归一旧CSS别名和实际解析组件,必要时比较最终SVG形状,避免两个不同类名实际是同一图标。空/0/零GUID等等价根节点按同一同级集合检查。优先保留已有正确且唯一的语义图标;重复时选同义替代,无贴切项才稳定分配未用图标,候选耗尽应停止报告,不能回收同一默认图标。不要求跨不同父菜单全系统唯一。
108
+ - 存量批量修复先冻结完整菜单Id/ParentId/Url/显隐/绑定和权限基线,仅通过正常 `microi_update_module({module:{Id,IconClass}})` 更改已批准的图标字段,保留独立图片 `Icon`、路由、菜单身份和角色/按钮权限。每条未知结果先按原Id回读,不换Id或盲重放;完成后独立全量回读与同级去重,最后从真实侧栏验收明暗/移动可辨识性。源码、SSR或数据库回读不能替代客户浏览器验收。
86
109
 
87
110
  ### 新模块表单打开方式(强制默认)
88
111
 
@@ -243,6 +266,8 @@ Iframe 不把长期 Token、密码或连接串放 URL。第三方单点登录使
243
266
 
244
267
  ## 跨端 ViewSchema
245
268
 
269
+ 移动卡片人员电话组合使用独立的 `ViewSchema.MobileCard.PhoneBindings[]`,在【移动卡片】页签配置;复用详情绑定的字段和开关,不自动继承 `MobileDetail`。人员须已在卡片正文显示,电话须通过当前菜单字段权限且由当前查询实际返回;客户端按授权元数据补齐查询字段,组合成功才隐藏独立电话行。缺列、隐藏、损坏或冲突绑定回退原展示;格式化/脱敏号码优先,空值和非法号码不得拨号。通用模块列表、业务列表和售后任务专用卡片共用组合器,专用卡片只映射已有人员行。更新时保留原 ViewSchema、递增 ViewConfigVersion,PC/UniApp 源码与中文文档同步;现有 MCP 增量更新能力足够,无需新增后端接口或数据库物理列。
270
+
246
271
  移动端业务详情的人员电话组合使用 `ViewSchema.MobileDetail.PhoneBindings[]`,在模块展示设计器【移动端详情】中配置 `PersonField/PhoneField/Enabled/ShowNumber/EnableDial/HidePhoneRow`。这是标准详情的显式局部展示扩展,不依赖或修改 `EnableViewSchema`,不改变已有 Detail/Edit/List/Card。通过 `microi_update_module` 合并原 JSON、递增 `ViewConfigVersion` 并回读;不得覆盖其它视图或写入废弃 DiyConfig。只有同一可见分组的两个字段都存在、电话字段在当前查询中确实返回时才合并,缺失/隐藏/重复/交叉绑定回退原行;空值和脱敏值不得拨号,也不得另取电话原文。此功能需同时更新 PC 设计器和 UniApp `pages/business/detail`,保存菜单不等于客户端已更新。
247
272
 
248
273
  顶层 PC 数据列表默认使用紧凑的新模块标题样式;即使未启用自定义表单视图,也不能退回无标题的旧外观。无指标头部固定 `44px`、含指标头部固定 `62px`,连同间距总纵向占用约 `50px / 68px`。子表、关联表、嵌入表不重复显示,移动端由固定导航栏承载标题。`Scene=List/Card` 的个性化标题、指标、复合列和卡片配置存在时必须直接生效;`EnableViewSchema` 只控制 Detail/Edit 自定义表单视图。
@@ -81,6 +81,36 @@ return {
81
81
  - 由服务端限制文件大小、超时、PDF 页数、响应体大小和最低置信度。
82
82
  - 禁止接受调用方传入 endpoint、API key、任意请求头、代理地址或本地文件路径,防止 SSRF 和密钥绕过。
83
83
  - 日志只记录租户、提供方、状态码、耗时和安全裁剪后的错误,不记录文件 Base64、识别原文、API key 或完整响应。
84
+ - 9.0.8 的供应商 HTTP/处理错误、超时与取消使用本地关联号,错误消息与日志 `TraceId/TargetId` 一致;上游错误仅保留数值错误码、固定异常类别与有界请求号 SHA-256,不回显 `errorMsg` 或任意上游 Trace。合法成功请求号保持兼容,控制字符/分隔注入或超长编号改用安全回退。
85
+ - 用既有 `microi_query_system_observability` 的 `Logs` 按 `type/source=OCR`、实际月份和关联号分页查询;新版可用 32 位关联号查询 `Trace`。旧超时可能没有响应编号,旧日志 Trace 字段可能为空,应按 OCR 类型/时间/正文核对,不新增诊断引擎或读取供应商秘密。
86
+ - 处理选项省略不传,显式布尔值原样保留。小裁图成功、整页失败或约 60 秒超时仅是样本事实,不能直接归因复杂表格、Paddle 版本或盲升超时;先取得实际部署版本、脱敏日志及资源证据。
87
+
88
+ ## 有界扫描 PDF 预处理(需含此实现的新 API 镜像)
89
+
90
+ 复杂扫描 PDF 可以在第一次模型调用前显式选择 `RasterizePdf: true`。网关先以固定 Poppler 工具将每页按150 DPI、最长边2400栅格化,再按2×2、重叠64像素生成4块PNG,串行复用当前租户的同一 OCR 提供方与配置快照。`PdfRotation` 只接受0/90/180/270,表示顺时针旋转;未传为0。此模式须将 `UseDocOrientationClassify`、`UseDocUnwarping` 设为false,避免未知变换使区域坐标失真;文本行方向选项仍可按需要传入。
91
+
92
+ ```javascript
93
+ var result = await V8.OCR.Recognize({
94
+ FileByteBase64: V8.FilesByteBase64.document,
95
+ FileName: 'scan.pdf',
96
+ RasterizePdf: true,
97
+ PdfRotation: 270,
98
+ UseDocOrientationClassify: false,
99
+ UseDocUnwarping: false,
100
+ UseTextlineOrientation: false
101
+ });
102
+ return result;
103
+ ```
104
+
105
+ 这是请求开始前选择的处理路径,不会在整页超时或结果未知后自动重发。原图片和未启用此选项的PDF保持既有路径。每次最多8MiB、4页且不超过租户 `OcrMaxPages`,总栅格不超过24Mi像素,结果最多2000区域/256000字符。栅格、旋转和所有分片HTTP共用原 `OcrTimeoutSeconds` 的一个剩余预算,不给每块重新计时;任何失败/取消都立即停止,不返回部分成功、不自动重试。取消后外部provider是否已经停止仍需运行端独立确认。API节点只允许一个在途预处理文档,忙时立即拒绝;这是本节点内存保护,不是共享任务或跨节点provider租约。
106
+
107
+ `PageCount` 保留原PDF页数,不能把四块计成四页;同文且几何IoU≥0.6的跨块重叠项保高置信度,实际不同位置的重复字词仍保留。区域坐标映射回旋转前、最长边2400的原页栅格像素,不是PDF point/mm;按旋转后页面顺序合并全文,不承诺重建表格/流程图语义。缺少可信多边形时失败关闭。
108
+
109
+ Linux API运行镜像通过同一发行APT渠道包含 `poppler-utils` 和 `util-linux`,仅使用固定 `/usr/bin/pdfinfo`、`/usr/bin/pdftoppm`、`/usr/bin/prlimit`;不读客户PATH,不接受请求指定程序/目录/URL。每个原生渲染进程限制512MiB地址空间/60秒CPU/64文件描述符,同时受原请求取消令牌控制。必须在实际不可变镜像核对工具版本、包版权/来源记录、非root临时目录权限和取消退出;Windows需正式部署固定 `tools/ocr` 工具和受ACL保护的服务临时目录,不能借开发机Codex内置工具冒充生产依赖。
110
+
111
+ HTTP沿原 `platform-ocr-recognize` 传相同typed字段;Managed正文已完整转交 `V8.Param`,无需新增表、改权限或覆盖租户Hook。MCP通用 `microi_run_engine` 可调用同Managed入口并传相同参数,仍需明确文档处理授权;MCP源码已为 `microi_ocr_recognize` 支持 `rasterizePdf` 和 `pdfRotation` 两个选项;使用前必须通过 `describe_tool` 核对当前已安装CLI的实际Schema。源码合入和平台镜像发布不代表CLI/npm已经分发,未发布或未安装时不能声称专用工具可用,也不能传入未知字段后假定生效。批量/长耗时/持久幂等继续使用现有共享任务方案,本模式不伪造可恢复任务。
112
+
113
+ 本地真实PDF栅格和HTTP-handler合同测试不等于真实Paddle全页准确率通过。完成新API正常发行、实际Linux镜像和provider单次受控全页验收前,不宣称原扫描PDF已修复。
84
114
 
85
115
  ## Docker 与多节点
86
116
 
@@ -44,6 +44,15 @@ description: Microi 系统日志/监控查询、诊断与治理规范。用于
44
44
 
45
45
  ## 请求等待分层归因
46
46
 
47
+ ### 节点内存回压与 API 退出分别判断
48
+
49
+ - Linux `Memory.Current.MemoryEnvironment` 保留宿主余量/PSI及最多16层真实可见cgroup;同层current/limit配对,容量取可见有限上限与宿主较小值。
50
+ - `HierarchyVisibility/HiddenAncestorsPossible/HierarchyTruncated`明确namespace隐藏与层数缺口,未知不补零;不能拿API RSS代替共享池用量。
51
+ - 连续两次宿主低余量,或同组高用量伴PSI/高工作集,仅暂拒新请求。HTTP503的`NodeMemory/PressureReason`区分宿主、叶组和共享池;恢复有迟滞,不取消事务或据此停止API。
52
+ - API自身RSS95%回压、98%连续三次有界退出仍独立执行,外部压力不累计硬退出样本。PrivateAddressSpace和累计分配不能替代RSS。
53
+ - `Memory.Current.HostProcesses`复用五秒后台RSS前十,随有界事故保存;核Fresh、Scope、HostProcessesVisible及Pid/Start,无host proc挂载不代表宿主全进程。
54
+ - 详见[内存事故排查手册](references/memory-incident-triage.md)。需后端升级,无新增业务环境变量/SaaS字段/商城资源,现有Memory/Snapshot参数不变。
55
+
47
56
  - 用唯一 TraceId 对齐浏览器计时与 `RecentRequests[].Latency`,分别解释发出前排队、首字节等待、响应接收和服务端顺序阶段;不能将总耗时减 TTFB 当作下载时间。
48
57
  - `Latency.Parts` 是含子调用、可能并行的累计墙钟时间,不可相加或等同 CPU。连接打开/连接池等待与 SQL 命令分开;Reader 后续读行不计入 DatabaseCommand。
49
58
  - `RuntimeIntervals` 是当前节点最近 30 个约 1 秒同窗样本。分别核对 CPU 执行、I/O wait、steal、GC 暂停、线程池积压、采样唤醒延迟和 cgroup 节流;缺值按不可用处理。旧 Linux CPU 百分比包含 I/O wait,不能直接判定计算饱和。
@@ -285,3 +294,18 @@ OSS/CDN 高费用、文件下载榜单和 NAS 分流还须读取
285
294
  - 内存专项至少覆盖:V8 限制关闭的复杂执行、真实 Kestrel TraceId、500 个活动请求、异步嵌套归属、独立采集栈、Mongo 故障、执行中强杀、改名重启、跨节点补传、旧快照重放和租户隔离。
286
295
 
287
296
  - 原生签名状态必须先对原始 UTF-8 JSON 字节验 HMAC,再以保留小数精度及字符串日期的设置解析;禁止先解析重序列化后验签,否则 SaaS decimal 阈值 1.000000 变为 1.0 会使后台泵停摆。修复读取器时保留既有回执,不手工改写状态或 Ready。
297
+
298
+ ## 框架常驻运行状态
299
+
300
+ 实现/配置顶部和侧栏状态部件时读取[状态部件参考](references/framework-status-widgets.md)。区分WS定时快照、源scope和物理GPU;布局使用公开实体字段、版本哈希CAS,保留租户显式空值与CreateIfMissing扩展。源码、镜像、应用、宿主与浏览器验收分层记录。
301
+
302
+ 9.0.7 已发行的顶部、侧栏与基础快照继续保留。本轮后台 Mongo 遥测、128 项目录、GPU/多盘默认布局及新版展示依赖新版运行时,API/PC 发行目标为 9.0.9,当前尚未发布该版镜像;源码、应用包或本地验收不能证明镜像已发布或部署。系统设置 v8.6.21 的 ServerMinVersion/ClientMinVersion 均为 9.0.9;SaaS v8.8.31 为 ServerMinVersion=9.0.8、ClientMinVersion=9.0.9,不能用 SaaS 的结构门槛代替遥测运行时要求。
303
+
304
+ 使用这些新增能力前,逐项核对采样服务注册、存储实现、已安装的 Managed 动作及网页实测结果。
305
+
306
+ - 本轮资源历史由API节点后台统一采样写Mongo:CPU/RAM 5秒,GPU/固定盘/可读温度30秒;最新值覆盖,30秒历史桶保留30天。前端通过既有`ManageFrameworkStatus`与Managed引擎读取存储样本,不随浏览器数重复现采。Mongo故障保留未知/存储错误,不能回退现场采样假成功。
307
+ - 实时消息在 `V8.Param.Message`,连接元数据在 `V8.Param.Socket`;必须用真实同级信封回归。WS 非成功结果也要走同一只读 HTTP 降级,保持鉴权和快照验证。
308
+ - 顶部24px圆形漩涡每6秒轮播最多8个可用指标;默认含GPU/显存及多盘,按占用五档变色。资源详情采用圆仪表,磁盘统一为已用;缺总量不从可用字节推算。温度不可读保留null/unavailable。侧栏仅图标、名称与数值同排,不另列WS/时间或增加矩形填充卡片;页脚柔和CSS水波持续动画,页面隐藏及减少动态效果时暂停。
309
+ - 系统设置既有`HideFrameworkFunctions`追加`FrameworkStatusTop`、`FrameworkStatusSidebar`,两项独立,均隐藏时0状态请求;不抹版权/自定义内容或租户布局。通过`microi_get_field_list`、`microi_update_field`合并选项并回读,系统设置与SaaS包同时交付元数据,不携带运行选择值。
310
+ - 最新值/资源历史复用`platform-framework-status Action:Latest/History`到`ManageFrameworkStatus`的固定`TelemetryLatest/TelemetryHistory`原子,只读Mongo,不随请求现场采集;FromUtc/ToUtc/Take最多30天/720条,主租户主库管理员、当前节点、无客户端Tenant/Node/SQL/URL。后端必须再校验,截断明确标记;数据接口不冒充全部监控曲线已接入。
311
+ - 本轮指标目录最多128项,为内置多设备与已有租户扩展并存留容量,单次快照仍最多48项;两者不能混用。大目录须配套后端原子;租户硬件与业务provider分别登记,复用已核验固定来源,不能因另一页面已有数值就声称框架已经安装。