@microi.net/cli 5.8.5 → 5.8.6

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 (211) 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/.mcp.json +1 -1
  5. package/.workbuddy-plugin/marketplace.json +2 -2
  6. package/.workbuddy-plugin/plugin.json +1 -1
  7. package/LICENSE +21 -21
  8. package/README.md +71 -71
  9. package/assets/build-meta.json +6 -6
  10. package/assets/feature-matrix.json +138 -138
  11. package/assets/logo.svg +4 -4
  12. package/cordis.patch.yml +1 -1
  13. package/package.json +1 -1
  14. package/scripts/codex-marketplace.json +20 -20
  15. package/scripts/mcp-codex-stdio-adapter.js +189 -189
  16. package/scripts/mcp-trae-windows-launcher.cmd +21 -21
  17. package/scripts/microi-cli-mcp.js +7 -7
  18. package/scripts/microi-cli.js +66 -65
  19. package/scripts/microi-codex-broker.js +450 -450
  20. package/scripts/microi-codex-router.js +618 -618
  21. package/scripts/microi-skills.meta.json +384 -384
  22. package/skills/.microi-skills-version.json +2 -2
  23. package/skills/.progressive-disclosure-manifest.json +3566 -3566
  24. package/skills/README.md +287 -287
  25. package/skills/ai-engine/SKILL.md +269 -265
  26. package/skills/ai-engine/agents/openai.yaml +4 -4
  27. package/skills/ai-engine/references/ai-employees.md +48 -48
  28. package/skills/ai-engine/references/self-hosted-digital-human.md +59 -59
  29. package/skills/ai-platform-governance/SKILL.md +177 -177
  30. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -190
  31. package/skills/app-store/SKILL.md +525 -525
  32. package/skills/app-store/agents/openai.yaml +4 -4
  33. package/skills/business-blueprint/SKILL.md +193 -193
  34. package/skills/datasource-engine/SKILL.md +93 -93
  35. package/skills/datasource-engine/agents/openai.yaml +4 -4
  36. package/skills/dos-orm/SKILL.md +97 -97
  37. package/skills/dos-orm/references/api-reference.md +229 -229
  38. package/skills/email-engine/SKILL.md +81 -81
  39. package/skills/email-engine/references/v8-email.md +34 -34
  40. package/skills/job-engine/SKILL.md +176 -176
  41. package/skills/job-engine/agents/openai.yaml +4 -4
  42. package/skills/message-notification/SKILL.md +156 -156
  43. package/skills/message-notification/agents/openai.yaml +5 -5
  44. package/skills/message-notification/references/contracts.md +102 -102
  45. package/skills/microi/SKILL.md +14 -14
  46. package/skills/microi-ai-app-auth.js +652 -652
  47. package/skills/microi-ai-application/SKILL.md +115 -115
  48. package/skills/microi-ai-application/agents/openai.yaml +4 -4
  49. package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
  50. package/skills/microi-client-frontend/SKILL.md +244 -244
  51. 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 +144 -144
  52. package/skills/microi-client-frontend/references/progressive-02-8-/350/277/220/350/241/214/346/227/266/351/253/230/351/242/221/345/235/221/345/244/215/347/233/230.md +196 -196
  53. package/skills/microi-client-frontend/references/progressive-03-vue3-/345/211/215/347/253/257/345/276/256/346/234/215/345/212/241/345/256/277/344/270/273/350/247/204/345/210/231.md +167 -167
  54. package/skills/microi-codex/SKILL.md +102 -102
  55. package/skills/microi-codex-installer/SKILL.md +231 -231
  56. package/skills/microi-codex-installer/agents/openai.yaml +7 -7
  57. package/skills/microi-datasource-mapping/SKILL.md +122 -122
  58. package/skills/microi-db-schema/SKILL.md +175 -175
  59. package/skills/microi-db-schema/agents/openai.yaml +4 -4
  60. package/skills/microi-db-schema/references/core-tables.md +695 -695
  61. package/skills/microi-db-schema/references/form-component-options.md +256 -256
  62. package/skills/microi-db-schema/references/schema-overview.md +202 -202
  63. package/skills/microi-db-schema/references/schema.md +646 -646
  64. package/skills/microi-db-schema/references/table-catalog.md +1599 -1599
  65. package/skills/microi-deployment/SKILL.md +221 -221
  66. package/skills/microi-deployment/references/deployment-matrix.md +109 -109
  67. package/skills/microi-docs-coverage/SKILL.md +133 -133
  68. package/skills/microi-docs-coverage/references/capability-map.md +91 -91
  69. package/skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +894 -894
  70. package/skills/microi-form-engine/SKILL.md +333 -333
  71. package/skills/microi-form-engine/references/component-catalog.md +218 -218
  72. package/skills/microi-form-engine/references/data-source-events.md +124 -124
  73. package/skills/microi-form-layout/SKILL.md +205 -205
  74. package/skills/microi-form-layout/references/progressive-01-3-/344/270/211/347/247/215/345/210/206/347/273/204/347/232/204/345/255/230/345/202/250/344/270/216/351/205/215/347/275/256.md +235 -235
  75. package/skills/microi-frontend-sdk/SKILL.md +194 -194
  76. package/skills/microi-frontend-sdk/references/progressive-01-token-/345/275/223/345/211/215/347/231/273/345/275/225/347/224/250/346/210/267/344/270/216/345/275/223/345/211/215/347/273/210/347/253/257/347/231/273/345/275/225/345/215/217/350/256/256.md +176 -176
  77. package/skills/microi-left-right-layout/SKILL.md +141 -141
  78. package/skills/microi-microservice/SKILL.md +326 -324
  79. package/skills/microi-microservice/references/runtime-delivery.md +278 -278
  80. package/skills/microi-mobile-app-quality/SKILL.md +185 -185
  81. package/skills/microi-mobile-app-quality/references/progressive-01-4-/351/207/215/350/246/201/346/214/211/351/222/256/345/277/205/351/241/273/345/270/246/345/233/276/346/240/207.md +213 -213
  82. package/skills/microi-mobile-app-quality/references/progressive-02-9-/344/270/273/351/242/230/345/210/207/346/215/242/345/277/205/351/241/273/347/234/237/345/256/236/344/270/224/345/205/250/345/261/200/347/224/237/346/225/210.md +128 -128
  83. package/skills/microi-solution-quotation/SKILL.md +78 -78
  84. package/skills/microi-solution-quotation/agents/openai.yaml +4 -4
  85. package/skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -296
  86. package/skills/microi-sso/SKILL.md +92 -92
  87. package/skills/microi-sso/references/acceptance.md +49 -49
  88. package/skills/microi-sso/references/configuration-and-security.md +53 -53
  89. package/skills/microi-sso/references/inbound.md +53 -53
  90. package/skills/microi-sso/references/outbound.md +39 -39
  91. package/skills/microi-system-delivery/SKILL.md +137 -137
  92. package/skills/microi-system-delivery/references/progressive-01-/346/240/207/345/207/206/345/267/245/344/275/234/346/265/201.md +193 -193
  93. package/skills/microi-system-delivery/references/progressive-02-/350/207/252/345/212/250/345/214/226/346/265/213/350/257/225/345/277/205/351/241/273/350/246/206/347/233/226/347/232/204/345/235/221.md +217 -217
  94. package/skills/microi-ui/SKILL.md +192 -192
  95. package/skills/microi-ui/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/234/272/346/231/257/350/223/235/345/233/276.md +183 -183
  96. package/skills/microi-uniapp-frontend/SKILL.md +193 -193
  97. package/skills/microi-uniapp-frontend/references/progressive-01-/347/247/273/345/212/250/347/253/257/345/210/206/347/261/273-/345/217/214/346/240/217/345/210/227/350/241/250/347/213/254/347/253/213/346/273/232/345/212/250.md +225 -225
  98. package/skills/microi-uniapp-frontend/references/progressive-02-/345/205/263/351/224/256/344/270/232/345/212/241/350/265/204/344/272/247/344/270/215/345/276/227/351/273/230/350/256/244/351/200/211/344/270/255.md +154 -154
  99. package/skills/microi.v8.js +1921 -1921
  100. package/skills/module-engine/SKILL.md +255 -255
  101. package/skills/module-engine/references/module-config.md +204 -204
  102. package/skills/ocr-engine/SKILL.md +113 -113
  103. package/skills/ocr-engine/agents/openai.yaml +4 -4
  104. package/skills/page-engine/SKILL.md +206 -206
  105. package/skills/page-engine/examples/compact-dashboard.json +1444 -1444
  106. package/skills/page-engine/references/progressive-01-/346/211/200/346/234/211/347/273/204/344/273/266/347/261/273/345/236/213.md +234 -234
  107. package/skills/page-engine/references/progressive-02-/347/211/210/346/234/254/345/216/206/345/217/262-/345/271/266/345/217/221/344/277/235/345/255/230/344/270/216/345/233/236/346/273/232.md +60 -60
  108. package/skills/performance-testing/SKILL.md +221 -221
  109. package/skills/playwright-e2e/SKILL.md +196 -196
  110. package/skills/playwright-e2e/references/progressive-01-/345/205/250/350/207/252/345/212/250/347/231/273/345/275/225-/345/205/215/351/252/214/350/257/201/347/240/201-/344/275/206/344/270/215/345/205/215/345/257/206/347/240/201-/345/277/205/350/257/273.md +173 -173
  111. package/skills/playwright-e2e/references/progressive-02-/346/226/207/345/255/227/345/257/271/346/257/224/345/272/246/344/270/216/345/217/257/350/257/273/346/200/247/350/207/252/345/212/250/345/214/226/346/243/200/346/237/245-/345/277/205/345/201/232.md +183 -183
  112. package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +221 -221
  113. package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +115 -115
  114. package/skills/print-engine/SKILL.md +259 -259
  115. package/skills/production-readonly-audit/SKILL.md +41 -41
  116. package/skills/report-engine/SKILL.md +71 -71
  117. package/skills/report-engine/agents/openai.yaml +4 -4
  118. package/skills/scripts/optimize-progressive-disclosure.mjs +204 -204
  119. package/skills/scripts/refresh-progressive-disclosure.mjs +64 -64
  120. package/skills/scripts/sync-embedded-skills.mjs +46 -46
  121. package/skills/scripts/validate-progressive-disclosure.mjs +57 -57
  122. package/skills/search-engine/SKILL.md +75 -75
  123. package/skills/search-engine/agents/openai.yaml +4 -4
  124. package/skills/spider-engine/SKILL.md +190 -190
  125. package/skills/system-observability/SKILL.md +248 -248
  126. package/skills/system-observability/references/memory-incident-triage.md +77 -77
  127. package/skills/translate-engine/SKILL.md +140 -140
  128. package/skills/translate-engine/agents/openai.yaml +4 -4
  129. package/skills/ui-design/SKILL.md +223 -223
  130. package/skills/ui-design/assets/pattern-showcase/app.js +54 -54
  131. package/skills/ui-design/assets/pattern-showcase/index.html +163 -163
  132. package/skills/ui-design/assets/pattern-showcase/styles.css +311 -311
  133. package/skills/ui-design/assets/templates/MCI-DESIGN.md +206 -206
  134. package/skills/ui-design/references/design-pattern-library.md +184 -184
  135. package/skills/ui-design/references/mci-design-contract.md +163 -163
  136. package/skills/ui-design/references/motion-and-media.md +78 -78
  137. package/skills/ui-design/references/product-flow-recipes.md +94 -94
  138. package/skills/ui-design/references/progressive-01-/351/242/234/350/211/262/344/275/223/347/263/273-css-variables-/346/224/257/346/214/201/344/270/273/351/242/230/345/210/207/346/215/242.md +218 -218
  139. package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +164 -164
  140. package/skills/ui-design/references/progressive-03-/345/212/250/346/225/210/350/247/204/350/214/203-/344/270/260/345/257/214/344/275/206/344/270/215/345/215/241.md +235 -235
  141. package/skills/ui-design/references/progressive-04-/347/273/204/344/273/266/351/243/216/346/240/274/351/200/237/346/237/245.md +152 -152
  142. package/skills/ui-design/references/progressive-05-/347/247/273/345/212/250/347/253/257/344/270/223/347/224/250/350/247/204/350/214/203.md +238 -238
  143. package/skills/ui-design/references/progressive-06-/344/270/273/351/242/230/345/210/207/346/215/242/345/256/236/347/216/260.md +194 -194
  144. package/skills/ui-design/references/progressive-07-/351/200/237/346/237/245-/344/273/216/345/244/264/346/220/255/345/273/272/344/270/200/344/270/252/347/247/273/345/212/250/347/253/257/351/241/265/351/235/242.md +207 -207
  145. package/skills/ui-design/references/progressive-08-/350/241/250/345/215/225/345/210/206/347/273/204/350/247/204/350/214/203-tabs-vs-collapsegroup-/345/274/272/345/210/266.md +142 -142
  146. package/skills/uniapp-mall-assets/SKILL.md +176 -176
  147. package/skills/unity-integration/SKILL.md +171 -171
  148. package/skills/unity-integration/agents/openai.yaml +4 -4
  149. package/skills/unity-integration/references/ai-app-delivery.md +119 -119
  150. package/skills/unity-integration/references/sdk-api.md +82 -82
  151. package/skills/unity-integration/references/toolbox-migration.md +66 -66
  152. package/skills/unity-integration/references/webgl-hosting.md +57 -57
  153. package/skills/v8-api-config/SKILL.md +388 -388
  154. package/skills/v8-cache-pattern/SKILL.md +312 -312
  155. package/skills/v8-crud-api/SKILL.md +178 -178
  156. package/skills/v8-crud-api/references/progressive-01-/346/237/245/350/257/242/345/210/227/350/241/250-/345/210/206/351/241/265.md +226 -226
  157. package/skills/v8-crud-api/references/progressive-02-where-/346/235/241/344/273/266/350/257/255/346/263/225/351/200/237/346/237/245.md +49 -49
  158. package/skills/v8-debugging/SKILL.md +284 -284
  159. package/skills/v8-explorer-tree/SKILL.md +228 -228
  160. package/skills/v8-export-import/SKILL.md +219 -219
  161. package/skills/v8-export-import/references/progressive-01-excellayout-/351/253/230/347/272/247/350/207/252/347/224/261/345/270/203/345/261/200.md +211 -211
  162. package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +202 -202
  163. package/skills/v8-export-import/references/progressive-03-/345/256/211/345/205/250-/346/200/247/350/203/275/346/263/250/346/204/217.md +42 -42
  164. package/skills/v8-file-upload/SKILL.md +284 -284
  165. package/skills/v8-file-upload/references/progressive-01-/345/205/254/346/234/211/346/241/266-vs-/347/247/201/346/234/211/346/241/266.md +263 -263
  166. package/skills/v8-file-upload/references/progressive-02-office-/346/226/207/344/273/266/345/234/250/347/272/277/347/274/226/350/276/221/347/211/210/346/234/254/345/217/267/350/247/204/345/210/231.md +161 -161
  167. package/skills/v8-formengine-http/SKILL.md +238 -238
  168. package/skills/v8-frontend-events/SKILL.md +180 -180
  169. package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
  170. package/skills/v8-frontend-events/references/bluetooth-print.md +258 -258
  171. package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +219 -219
  172. package/skills/v8-http-integration/SKILL.md +182 -182
  173. package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +220 -220
  174. package/skills/v8-http-integration/references/progressive-02-/351/224/231/350/257/257/345/244/204/347/220/206/346/250/241/345/274/217.md +44 -44
  175. package/skills/v8-image-processing/SKILL.md +190 -190
  176. package/skills/v8-image-processing/agents/openai.yaml +4 -4
  177. package/skills/v8-image-processing/references/api-reference.md +623 -623
  178. package/skills/v8-menu-buttons/SKILL.md +186 -186
  179. package/skills/v8-menu-buttons/references/progressive-01-2-/346/214/211/351/222/256/345/257/271/350/261/241-schema.md +222 -222
  180. package/skills/v8-menu-buttons/references/progressive-02-8-/346/250/241/345/274/217-f-/345/220/216/345/217/260/344/273/273/345/212/241/346/214/211/351/222/256-/351/225/277/344/273/273/345/212/241.md +228 -228
  181. package/skills/v8-menu-buttons/references/progressive-03-10-/345/217/215/346/250/241/345/274/217-/351/201/277/345/205/215.md +104 -104
  182. package/skills/v8-mongodb/SKILL.md +200 -200
  183. package/skills/v8-mq-mqtt/SKILL.md +176 -176
  184. package/skills/v8-mq-mqtt/references/mqtt-production.md +342 -342
  185. package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +181 -181
  186. package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +203 -203
  187. package/skills/v8-saas-multi-tenant/SKILL.md +305 -305
  188. package/skills/v8-security/SKILL.md +210 -210
  189. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +200 -200
  190. package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +160 -160
  191. package/skills/v8-sql-query/SKILL.md +302 -302
  192. package/skills/v8-table-event/SKILL.md +176 -176
  193. package/skills/v8-table-event/references/progressive-01-informv8-js-/350/241/250/345/215/225/346/211/223/345/274/200/344/272/213/344/273/266.md +216 -216
  194. 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 +46 -46
  195. package/skills/v8-tcp-integration/SKILL.md +147 -147
  196. package/skills/v8-tcp-integration/agents/openai.yaml +4 -4
  197. package/skills/v8-template-engine/SKILL.md +167 -167
  198. package/skills/v8-utilities/SKILL.md +104 -104
  199. package/skills/v8-utilities/references/client-api-index.md +143 -143
  200. package/skills/v8-utilities/references/platform-http-routes.md +83 -83
  201. package/skills/v8-utilities/references/server-api-index.md +188 -188
  202. package/skills/v8-workflow/SKILL.md +252 -252
  203. package/skills/v8-workflow/references/progressive-01-/350/212/202/347/202/271/345/274/200/345/247/213-v8-/344/272/213/344/273/266.md +180 -180
  204. package/skills/v8-workflow/references/workflow-configuration.md +49 -49
  205. package/skills/vision-engine/SKILL.md +160 -160
  206. package/skills/vision-engine/agents/openai.yaml +4 -4
  207. package/skills/vision-engine/references/architecture-and-acceptance.md +194 -194
  208. package/skills/workspace-conventions/SKILL.md +273 -273
  209. package/skills/workspace-conventions/references/progressive-01-/347/211/210/346/234/254/346/233/264/346/226/260/346/227/245/345/277/227/344/277/235/346/212/244/350/247/204/345/210/231-/345/274/272/345/210/266.md +209 -209
  210. 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 +217 -217
  211. package/skills/workspace-conventions/references/progressive-03-cli-/344/270/216-ide-/346/217/222/344/273/266/351/224/231/347/211/210/345/205/261/345/255/230/347/272/246/345/256/232.md +27 -27
@@ -1,228 +1,228 @@
1
- # v8-menu-buttons 详细参考 2
2
-
3
- > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
-
5
- <!-- microi-progressive:chunk id=v8-menu-buttons-008 sha256=495161c95d321f2937486db3fecc4e27d2e38c6d7a21587b5028d04ea6491b90 -->
6
- ## 8. 模式 F:后台任务按钮(长任务)
7
-
8
- 应用安装、初始化多语言、批量导入、批量修复、跨系统同步等可能超过浏览器或网关等待时间的操作,必须优先设计为后台任务。判断阈值:预计超过 2 分钟、500 条以上、1000 个以上扇出子操作、100 次以上外部调用,或总量未知且可能持续运行。前端按钮只负责提交任务,后台任务列表通过 WebSocket/SignalR 推送并以轮询兜底。
9
-
10
- 少量数据也可能因为单次 V8 根执行的累计分配量过大而需要拆分。如果业务天然支持“每片独立事务提交、失败后按剩余量安全恢复”,按钮可以在前端发起多个独立 HTTP 请求,并声明客户端分片协议:
11
-
12
- ```jsonc
13
- {
14
- "Name": "批量生成主构件码",
15
- "Workload": {
16
- "ExecutionMode": "ClientChunked",
17
- "MaxItemsPerChunk": 40,
18
- "Resumable": true,
19
- "ExpectedItems": 200
20
- },
21
- "V8Code": "// 按 MaxItemsPerChunk 构造切片,并逐片 await V8.ApiEngine.Run(...)"
22
- }
23
- ```
24
-
25
- 逐条独立调用可使用 `ExecutionMode: "ClientSequential"` 和 `MaxItemsPerChunk: 1`。该声明必须与真实代码一致,且每片是新的 HTTP 请求;在同一次接口引擎调用中仅把大数组切成多个循环,不会重置 Jint 累计内存。缺少明确单片上限、不能恢复、预计总耗时超过 2 分钟或总量未知时,仍应使用后台任务和持久化检查点。
26
-
27
- 推荐直接使用按钮字段:
28
-
29
- ```jsonc
30
- {
31
- "Name": "安装",
32
- "BtnStyle": "primary",
33
- "ShowRow": true,
34
- "RunBackground": true,
35
- "ApiEngineKey": "import-microi-store-package",
36
- "Workload": { "ExpectedItems": 2000, "FanOutOperations": 10000, "ExpectedSeconds": 3000 },
37
- "BackgroundTaskOptions": {
38
- "IdempotencyKeyFields": ["Id", "Version"],
39
- "ConcurrencyKey": "microi-store-install",
40
- "BusinessTable": "sys_microistore",
41
- "BusinessStatusField": "TaskStatus",
42
- "BusinessTaskIdField": "BackgroundTaskId",
43
- "BusinessProgressField": "TaskProgress",
44
- "BusinessEtaField": "EstimatedEndTime"
45
- },
46
- "V8Code": "return { Package: V8.Form, _BackgroundTaskTitle: '安装应用:' + (V8.Form.Name || '') };"
47
- }
48
- ```
49
-
50
- 也可以在 V8Code 中显式调用:
51
-
52
- ```js
53
- V8.ApiEngine.RunBackground('import-microi-store-package', {
54
- Package: V8.Form
55
- }, '安装应用:' + (V8.Form.Name || ''), {
56
- IdempotencyKey: 'install:' + V8.Form.Id + ':' + (V8.Form.Version || ''),
57
- ConcurrencyKey: 'microi-store-install',
58
- BusinessTable: 'sys_microistore',
59
- BusinessId: V8.Form.Id,
60
- BusinessStatusField: 'TaskStatus',
61
- BusinessTaskIdField: 'BackgroundTaskId',
62
- BusinessProgressField: 'TaskProgress',
63
- BusinessEtaField: 'EstimatedEndTime'
64
- });
65
- ```
66
-
67
- `Business*` 字段用于业务关联与受权限保护的状态标记。按钮提交成功后,前端使用当前用户的 `V8.FormEngine` 权限写入“后台处理中”和任务 Id;通用后台服务不会信任客户端传来的任意表名/字段名去绕过权限。接口引擎应在成功、失败和取消补偿路径用固定业务表/字段更新最终状态,任务 Id 始终保留用于打开通知中心详情。
68
-
69
- 接口引擎中必须上报真实进度。平台创建后台任务时会自动把 `_BackgroundTaskId` 注入 `V8.Param`,V8 代码不要自己生成任务 Id,也不要只在结束时写一个固定百分比。
70
-
71
- ```js
72
- var backgroundTaskId = V8.Param._BackgroundTaskId || V8.Param.BackgroundTaskId || V8.Param.TaskId || '';
73
- var backgroundTask = V8.Param._BackgroundTask || {};
74
- if (backgroundTask.BusinessTable && backgroundTask.BusinessId) {
75
- var taskPatch = { Id: backgroundTask.BusinessId };
76
- taskPatch[backgroundTask.BusinessStatusField] = '后台处理中';
77
- taskPatch[backgroundTask.BusinessTaskIdField] = backgroundTaskId;
78
- V8.FormEngine.UptFormData(backgroundTask.BusinessTable, taskPatch);
79
- }
80
- var reportProgress = function(current, total, msg) {
81
- if (!backgroundTaskId || !V8.Method || !V8.Method.UpdateBackgroundTask) return;
82
- V8.Method.UpdateBackgroundTask({
83
- _BackgroundTaskId: backgroundTaskId,
84
- Current: current,
85
- Total: total,
86
- Msg: msg,
87
- Message: msg
88
- });
89
- };
90
-
91
- reportProgress(1, 5, '正在读取数据');
92
- // ...执行第 1 阶段
93
- reportProgress(2, 5, '正在写入表结构');
94
- // ...执行第 2 阶段
95
- ```
96
-
97
- 推荐用“已提交条数 / 总条数”上报 `Current/Total`,平台以共享数据库为事实源,Redis/SignalR 仅作缓存和推送,并根据真实吞吐估算结束时间。总量未知时只上报 `Current + Msg`,通知中心显示“计算进度中”,不要填写假的 `Total=100`。耗时循环中每提交一批数据调用一次,例如每 50 或 100 条更新;不能用计时器匀速增加百分比。
98
-
99
- 后台任务不能隐藏真实失败。失败时返回 `Code:0` 和清晰 `Msg`,并把关键阶段写入任务进度或系统日志。只有最终成功才显示 100%;失败/取消保留最后真实进度。
100
-
101
- 预计超过 10 分钟的任务必须分页/分片。每片只处理可在较短事务内提交的一批,仍有后续时返回 `Data.BackgroundTask.HasMore=true + Checkpoint + Current/Total`,平台持久化检查点并重新入队;最后一片返回普通 `Code:1`。重试副作用必须用稳定幂等键、数据库唯一约束和 `_BackgroundTaskFencingToken` 条件写入,不能依赖锁本身。
102
-
103
- 后台接口同时启用 `LockKey` 时,平台可信持久后台上下文会把接口 `Timeout` 作为单次 Redis 租期并按唯一持有者令牌自动续租;当前默认最长续租边界为 12 小时,显式配置得更长的单次租期不会被缩短。客户端自行传入 `_BackgroundTaskId`、`_TrustedServerInvocation` 或用户对象不能取得该能力。自动续租只防止正常长任务因短 TTL 自然过期,不能取消本节的检查点、幂等和 fencing token 要求。
104
-
105
- 持有者令牌不匹配、锁已过期、Redis 所有权/续租确认失败或达到最长租约时,任务必须失败关闭并保留最后真实进度与原始错误。V8 代码不得捕获“分布式锁租约已丢失”后返回 `Code:1`;旧执行者后续的业务条件写入必须因 `_BackgroundTaskFencingToken` 过期而被拒绝。完整配置语义见 `../../v8-api-config/SKILL.md`。
106
-
107
- ### 复盘:主租户默认值误清空子租户后台任务身份
108
-
109
- - 触发场景:同一套前后端中,独立部署的主租户可正常执行后台安装,挂在平台主库下的子租户却间歇性提示“只有超级管理员才能安装”;数据库中的 admin 实际已经是最高等级。
110
- - 根因:任务提交时虽然已从登录令牌保存可信用户快照,但后台线程脱离 HTTP 请求后再次调用 `GetCurrentToken()`,得到的只是服务默认主租户;普通接口的跨租户保护发现默认租户与任务 `OsClient` 不同,误把可信用户快照清空。线程是否赶在原请求上下文释放前运行还会造成偶发成功、偶发失败。
111
- - 通用规则:后台任务必须在提交阶段由服务端读取并克隆 `CurrentUser + OsClient`,通过不暴露给客户端/V8 的可信执行入口传给接口引擎;客户端参数中的 `_CurrentUser` 必须删除。普通 HTTP 接口继续执行跨租户身份清空,但不得用无真实 Token 的默认租户结果覆盖后台任务可信身份。
112
- - 自动化检查:使用“服务默认租户 A + 子租户 B”的部署配置,以 B 的超级管理员连续提交多次后台接口任务,并在原请求结束后才放行执行;断言每次 V8 的 `CurrentUser.Id/Level` 与提交者一致,同时验证携带 A Token 调用 B 普通接口仍会按匿名处理。
113
-
114
- ---
115
-
116
- <!-- /microi-progressive:chunk -->
117
- <!-- microi-progressive:chunk id=v8-menu-buttons-009 sha256=8cb7f4d399068549be662cc47bd4add8b3d3bbdb6e7a74832e4c63b7768e136b -->
118
- ## 9. 通过 MCP 创建菜单 + 按钮(一次到位)
119
-
120
- > AI 在 `microi_create_module` 调用时,把按钮 JSON **作为字符串** 传入对应字段。
121
-
122
- ```js
123
- var moreBtns = [
124
- {
125
- Id: "01K...",
126
- Name: "指派",
127
- BtnStyle: "primary",
128
- IsVisible: true,
129
- ShowRow: true,
130
- V8CodeShow: "V8.Result = (V8.Form.Status == '待指派');",
131
- V8Code: `
132
- var assignResult = await V8.ApiEngine.Run({
133
- ApiEngineKey: "aftersale_assign",
134
- Id: V8.Form.Id,
135
- AssigneeId: V8.Form.AssigneeId
136
- });
137
-
138
- V8.Tips(assignResult.Code == 1 ? "指派成功" : assignResult.Msg, assignResult.Code == 1);
139
- V8.RefreshTable({ _PageIndex: 1 });
140
- `
141
- }
142
- ];
143
-
144
- var modulePayload = {
145
- name: "售后任务",
146
- diyTableId: "<TableId>",
147
- icon: "fab fa-first-order",
148
- moreBtns: JSON.stringify(moreBtns),
149
- formBtns: JSON.stringify([]),
150
- pageTabs: JSON.stringify([]),
151
- batchSelectMoreBtns: JSON.stringify([])
152
- };
153
- ```
154
-
155
- > ⚠️ 真实调用 `microi_create_module` 时传 `modulePayload.moreBtns` 这样的 JSON 字符串。不要为了“看起来短”把 `V8Code` 压成一行。
156
-
157
- ---
158
-
159
- <!-- /microi-progressive:chunk -->
160
- <!-- microi-progressive:chunk id=v8-menu-buttons-010 sha256=0398a9fc35520d4b17b990efc565ba1d9f6050303e122dc128207adf08434aee -->
161
- ## 前端 FormEngine 权限与兼容
162
-
163
- - 当前按钮所在菜单绑定表会由 scoped facade 自动补真实 `_SysMenuId`,历史按钮不需要逐个修改。
164
- - 按钮跨表调用时不要把当前菜单 Id 传播给目标表;后端按当前用户对目标表的有效菜单权限缓存推断。
165
- - 显式 `_SysMenuId`/`ModuleEngineKey` 会严格校验,伪造或借用其它表菜单不会回退兼容推断。
166
- - 平台敏感表仍对普通客户端硬拒绝;Import/Export 必须走独立端点和专项菜单权限。
167
- - TableChild 的 `_TableChildAuth` 由标准子表自动维护,业务按钮不得构造或跨父记录复用。
168
- - 前端真实批量方法名是 `AddFormDataBatch/UptFormDataBatch/DelFormDataBatch`,没有 `AddTableData/UptTableData/DelTableData`。
169
- - 状态推进、资产、库存、审批、批量副作用等业务动作必须调用 ApiEngine;FormEngine 只适合权限范围内的简单单表 CRUD。
170
-
171
- ---
172
-
173
- <!-- /microi-progressive:chunk -->
174
- <!-- microi-progressive:chunk id=v8-menu-buttons-011 sha256=16414969be47116a51bab1c6a7e1482bb987b278430e0fb8daaf7d6ecf41bf94 -->
175
- ## 10. 与接口引擎配套的工作流
176
-
177
- 业务按钮通常与接口引擎配套:
178
-
179
- 1. **microi_create_engine** 先创建 ApiEngineKey(如 `aftersale_assign`),写好后端事务/校验/通知逻辑
180
- 2. **microi_create_module** 创建菜单时把按钮的 `V8Code` 设为 `V8.ApiEngine.Run({ApiEngineKey:'aftersale_assign',...})`
181
- 3. AI 在生成菜单时**应主动**:
182
- - 识别业务动作(指派/接单/审核/完成/驳回/导出/批量处理/状态推进)
183
- - 为每个动作创建一个接口引擎
184
- - 在 `moreBtns` / `formBtns` 中绑定按钮 → 接口
185
-
186
- ---
187
-
188
- <!-- /microi-progressive:chunk -->
189
- <!-- microi-progressive:chunk id=v8-menu-buttons-012 sha256=086e02210a949cc0a2c343e7f50c54c48079667999e9264ea5282c9caa951222 -->
190
- ## 10.1 后台直充/调账类行按钮
191
-
192
- 会员积分、余额、库存、额度等会改动资产的后台行按钮,必须采用“前端按钮只收参数,后端接口负责事务”的模式。
193
-
194
- 规则:
195
- - `MoreBtns` 使用 `ShowRow:true`,按钮只负责 `V8.ConfirmTips` 弹窗、读取金额/备注、调用接口和刷新表格。
196
- - 不要在 `V8Code` 里直接写 `V8.FormEngine.UptFormData` 改余额;余额更新、订单/流水生成、幂等校验都放到 ApiEngine。
197
- - 后端接口必须校验 `MemberId/Amount`,金额必须大于 0,并同时写资产主表和对应流水表;如系统已有订单表参与统计,也要同步生成已完成/已支付订单。
198
- - 资产主表更新、`SELECT ... FOR UPDATE` 和流水写入必须全部使用同一个 `V8.DbTrans`;禁止一部分用 `V8.Db`、另一部分写流水,否则后半段报错时可能留下单边余额变化。
199
- - 备注字段要有默认值,例如 `平台直充积分`,并允许管理员在弹窗中修改。
200
- - 验证时至少做一次小额测试,读回主表余额、订单表和流水表;测试备注要明确标识,方便审计。
201
- - 还必须做一次回滚验收:故意让流水写入失败,回读资产主表确认余额完全未变,再修正输入完成成功验收。
202
-
203
- 按钮 V8Code 骨架。充值包含金额、备注、联动校验,属于可维护业务表单,应使用在线微服务页面,不要在 `ConfirmTips` 中拼接 `<input>/<textarea>`:
204
-
205
- ```js
206
- var row = V8.Form || {};
207
- V8.OpenAppDialog({
208
- AppKey: 'member_asset_admin',
209
- RoutePath: '/recharge',
210
- Title: '后台充值积分',
211
- Width: 'min(720px, calc(100vw - 32px))',
212
- Data: {
213
- MemberId: row.Id,
214
- MemberName: row.NickName || row.Phone || row.Id || ''
215
- },
216
- OnSuccess: function (result) {
217
- V8.Tips((result && result.message) || '充值成功', true);
218
- V8.RefreshTable({ _PageIndex: -1 });
219
- },
220
- OnError: function (error) {
221
- V8.Tips((error && error.message) || '充值失败', false);
222
- }
223
- });
224
- ```
225
-
226
- ---
227
-
228
- <!-- /microi-progressive:chunk -->
1
+ # v8-menu-buttons 详细参考 2
2
+
3
+ > 按需读取;本文件由 SKILL.md 的原章节无损拆分。
4
+
5
+ <!-- microi-progressive:chunk id=v8-menu-buttons-008 sha256=495161c95d321f2937486db3fecc4e27d2e38c6d7a21587b5028d04ea6491b90 -->
6
+ ## 8. 模式 F:后台任务按钮(长任务)
7
+
8
+ 应用安装、初始化多语言、批量导入、批量修复、跨系统同步等可能超过浏览器或网关等待时间的操作,必须优先设计为后台任务。判断阈值:预计超过 2 分钟、500 条以上、1000 个以上扇出子操作、100 次以上外部调用,或总量未知且可能持续运行。前端按钮只负责提交任务,后台任务列表通过 WebSocket/SignalR 推送并以轮询兜底。
9
+
10
+ 少量数据也可能因为单次 V8 根执行的累计分配量过大而需要拆分。如果业务天然支持“每片独立事务提交、失败后按剩余量安全恢复”,按钮可以在前端发起多个独立 HTTP 请求,并声明客户端分片协议:
11
+
12
+ ```jsonc
13
+ {
14
+ "Name": "批量生成主构件码",
15
+ "Workload": {
16
+ "ExecutionMode": "ClientChunked",
17
+ "MaxItemsPerChunk": 40,
18
+ "Resumable": true,
19
+ "ExpectedItems": 200
20
+ },
21
+ "V8Code": "// 按 MaxItemsPerChunk 构造切片,并逐片 await V8.ApiEngine.Run(...)"
22
+ }
23
+ ```
24
+
25
+ 逐条独立调用可使用 `ExecutionMode: "ClientSequential"` 和 `MaxItemsPerChunk: 1`。该声明必须与真实代码一致,且每片是新的 HTTP 请求;在同一次接口引擎调用中仅把大数组切成多个循环,不会重置 Jint 累计内存。缺少明确单片上限、不能恢复、预计总耗时超过 2 分钟或总量未知时,仍应使用后台任务和持久化检查点。
26
+
27
+ 推荐直接使用按钮字段:
28
+
29
+ ```jsonc
30
+ {
31
+ "Name": "安装",
32
+ "BtnStyle": "primary",
33
+ "ShowRow": true,
34
+ "RunBackground": true,
35
+ "ApiEngineKey": "import-microi-store-package",
36
+ "Workload": { "ExpectedItems": 2000, "FanOutOperations": 10000, "ExpectedSeconds": 3000 },
37
+ "BackgroundTaskOptions": {
38
+ "IdempotencyKeyFields": ["Id", "Version"],
39
+ "ConcurrencyKey": "microi-store-install",
40
+ "BusinessTable": "sys_microistore",
41
+ "BusinessStatusField": "TaskStatus",
42
+ "BusinessTaskIdField": "BackgroundTaskId",
43
+ "BusinessProgressField": "TaskProgress",
44
+ "BusinessEtaField": "EstimatedEndTime"
45
+ },
46
+ "V8Code": "return { Package: V8.Form, _BackgroundTaskTitle: '安装应用:' + (V8.Form.Name || '') };"
47
+ }
48
+ ```
49
+
50
+ 也可以在 V8Code 中显式调用:
51
+
52
+ ```js
53
+ V8.ApiEngine.RunBackground('import-microi-store-package', {
54
+ Package: V8.Form
55
+ }, '安装应用:' + (V8.Form.Name || ''), {
56
+ IdempotencyKey: 'install:' + V8.Form.Id + ':' + (V8.Form.Version || ''),
57
+ ConcurrencyKey: 'microi-store-install',
58
+ BusinessTable: 'sys_microistore',
59
+ BusinessId: V8.Form.Id,
60
+ BusinessStatusField: 'TaskStatus',
61
+ BusinessTaskIdField: 'BackgroundTaskId',
62
+ BusinessProgressField: 'TaskProgress',
63
+ BusinessEtaField: 'EstimatedEndTime'
64
+ });
65
+ ```
66
+
67
+ `Business*` 字段用于业务关联与受权限保护的状态标记。按钮提交成功后,前端使用当前用户的 `V8.FormEngine` 权限写入“后台处理中”和任务 Id;通用后台服务不会信任客户端传来的任意表名/字段名去绕过权限。接口引擎应在成功、失败和取消补偿路径用固定业务表/字段更新最终状态,任务 Id 始终保留用于打开通知中心详情。
68
+
69
+ 接口引擎中必须上报真实进度。平台创建后台任务时会自动把 `_BackgroundTaskId` 注入 `V8.Param`,V8 代码不要自己生成任务 Id,也不要只在结束时写一个固定百分比。
70
+
71
+ ```js
72
+ var backgroundTaskId = V8.Param._BackgroundTaskId || V8.Param.BackgroundTaskId || V8.Param.TaskId || '';
73
+ var backgroundTask = V8.Param._BackgroundTask || {};
74
+ if (backgroundTask.BusinessTable && backgroundTask.BusinessId) {
75
+ var taskPatch = { Id: backgroundTask.BusinessId };
76
+ taskPatch[backgroundTask.BusinessStatusField] = '后台处理中';
77
+ taskPatch[backgroundTask.BusinessTaskIdField] = backgroundTaskId;
78
+ V8.FormEngine.UptFormData(backgroundTask.BusinessTable, taskPatch);
79
+ }
80
+ var reportProgress = function(current, total, msg) {
81
+ if (!backgroundTaskId || !V8.Method || !V8.Method.UpdateBackgroundTask) return;
82
+ V8.Method.UpdateBackgroundTask({
83
+ _BackgroundTaskId: backgroundTaskId,
84
+ Current: current,
85
+ Total: total,
86
+ Msg: msg,
87
+ Message: msg
88
+ });
89
+ };
90
+
91
+ reportProgress(1, 5, '正在读取数据');
92
+ // ...执行第 1 阶段
93
+ reportProgress(2, 5, '正在写入表结构');
94
+ // ...执行第 2 阶段
95
+ ```
96
+
97
+ 推荐用“已提交条数 / 总条数”上报 `Current/Total`,平台以共享数据库为事实源,Redis/SignalR 仅作缓存和推送,并根据真实吞吐估算结束时间。总量未知时只上报 `Current + Msg`,通知中心显示“计算进度中”,不要填写假的 `Total=100`。耗时循环中每提交一批数据调用一次,例如每 50 或 100 条更新;不能用计时器匀速增加百分比。
98
+
99
+ 后台任务不能隐藏真实失败。失败时返回 `Code:0` 和清晰 `Msg`,并把关键阶段写入任务进度或系统日志。只有最终成功才显示 100%;失败/取消保留最后真实进度。
100
+
101
+ 预计超过 10 分钟的任务必须分页/分片。每片只处理可在较短事务内提交的一批,仍有后续时返回 `Data.BackgroundTask.HasMore=true + Checkpoint + Current/Total`,平台持久化检查点并重新入队;最后一片返回普通 `Code:1`。重试副作用必须用稳定幂等键、数据库唯一约束和 `_BackgroundTaskFencingToken` 条件写入,不能依赖锁本身。
102
+
103
+ 后台接口同时启用 `LockKey` 时,平台可信持久后台上下文会把接口 `Timeout` 作为单次 Redis 租期并按唯一持有者令牌自动续租;当前默认最长续租边界为 12 小时,显式配置得更长的单次租期不会被缩短。客户端自行传入 `_BackgroundTaskId`、`_TrustedServerInvocation` 或用户对象不能取得该能力。自动续租只防止正常长任务因短 TTL 自然过期,不能取消本节的检查点、幂等和 fencing token 要求。
104
+
105
+ 持有者令牌不匹配、锁已过期、Redis 所有权/续租确认失败或达到最长租约时,任务必须失败关闭并保留最后真实进度与原始错误。V8 代码不得捕获“分布式锁租约已丢失”后返回 `Code:1`;旧执行者后续的业务条件写入必须因 `_BackgroundTaskFencingToken` 过期而被拒绝。完整配置语义见 `../../v8-api-config/SKILL.md`。
106
+
107
+ ### 复盘:主租户默认值误清空子租户后台任务身份
108
+
109
+ - 触发场景:同一套前后端中,独立部署的主租户可正常执行后台安装,挂在平台主库下的子租户却间歇性提示“只有超级管理员才能安装”;数据库中的 admin 实际已经是最高等级。
110
+ - 根因:任务提交时虽然已从登录令牌保存可信用户快照,但后台线程脱离 HTTP 请求后再次调用 `GetCurrentToken()`,得到的只是服务默认主租户;普通接口的跨租户保护发现默认租户与任务 `OsClient` 不同,误把可信用户快照清空。线程是否赶在原请求上下文释放前运行还会造成偶发成功、偶发失败。
111
+ - 通用规则:后台任务必须在提交阶段由服务端读取并克隆 `CurrentUser + OsClient`,通过不暴露给客户端/V8 的可信执行入口传给接口引擎;客户端参数中的 `_CurrentUser` 必须删除。普通 HTTP 接口继续执行跨租户身份清空,但不得用无真实 Token 的默认租户结果覆盖后台任务可信身份。
112
+ - 自动化检查:使用“服务默认租户 A + 子租户 B”的部署配置,以 B 的超级管理员连续提交多次后台接口任务,并在原请求结束后才放行执行;断言每次 V8 的 `CurrentUser.Id/Level` 与提交者一致,同时验证携带 A Token 调用 B 普通接口仍会按匿名处理。
113
+
114
+ ---
115
+
116
+ <!-- /microi-progressive:chunk -->
117
+ <!-- microi-progressive:chunk id=v8-menu-buttons-009 sha256=8cb7f4d399068549be662cc47bd4add8b3d3bbdb6e7a74832e4c63b7768e136b -->
118
+ ## 9. 通过 MCP 创建菜单 + 按钮(一次到位)
119
+
120
+ > AI 在 `microi_create_module` 调用时,把按钮 JSON **作为字符串** 传入对应字段。
121
+
122
+ ```js
123
+ var moreBtns = [
124
+ {
125
+ Id: "01K...",
126
+ Name: "指派",
127
+ BtnStyle: "primary",
128
+ IsVisible: true,
129
+ ShowRow: true,
130
+ V8CodeShow: "V8.Result = (V8.Form.Status == '待指派');",
131
+ V8Code: `
132
+ var assignResult = await V8.ApiEngine.Run({
133
+ ApiEngineKey: "aftersale_assign",
134
+ Id: V8.Form.Id,
135
+ AssigneeId: V8.Form.AssigneeId
136
+ });
137
+
138
+ V8.Tips(assignResult.Code == 1 ? "指派成功" : assignResult.Msg, assignResult.Code == 1);
139
+ V8.RefreshTable({ _PageIndex: 1 });
140
+ `
141
+ }
142
+ ];
143
+
144
+ var modulePayload = {
145
+ name: "售后任务",
146
+ diyTableId: "<TableId>",
147
+ icon: "fab fa-first-order",
148
+ moreBtns: JSON.stringify(moreBtns),
149
+ formBtns: JSON.stringify([]),
150
+ pageTabs: JSON.stringify([]),
151
+ batchSelectMoreBtns: JSON.stringify([])
152
+ };
153
+ ```
154
+
155
+ > ⚠️ 真实调用 `microi_create_module` 时传 `modulePayload.moreBtns` 这样的 JSON 字符串。不要为了“看起来短”把 `V8Code` 压成一行。
156
+
157
+ ---
158
+
159
+ <!-- /microi-progressive:chunk -->
160
+ <!-- microi-progressive:chunk id=v8-menu-buttons-010 sha256=0398a9fc35520d4b17b990efc565ba1d9f6050303e122dc128207adf08434aee -->
161
+ ## 前端 FormEngine 权限与兼容
162
+
163
+ - 当前按钮所在菜单绑定表会由 scoped facade 自动补真实 `_SysMenuId`,历史按钮不需要逐个修改。
164
+ - 按钮跨表调用时不要把当前菜单 Id 传播给目标表;后端按当前用户对目标表的有效菜单权限缓存推断。
165
+ - 显式 `_SysMenuId`/`ModuleEngineKey` 会严格校验,伪造或借用其它表菜单不会回退兼容推断。
166
+ - 平台敏感表仍对普通客户端硬拒绝;Import/Export 必须走独立端点和专项菜单权限。
167
+ - TableChild 的 `_TableChildAuth` 由标准子表自动维护,业务按钮不得构造或跨父记录复用。
168
+ - 前端真实批量方法名是 `AddFormDataBatch/UptFormDataBatch/DelFormDataBatch`,没有 `AddTableData/UptTableData/DelTableData`。
169
+ - 状态推进、资产、库存、审批、批量副作用等业务动作必须调用 ApiEngine;FormEngine 只适合权限范围内的简单单表 CRUD。
170
+
171
+ ---
172
+
173
+ <!-- /microi-progressive:chunk -->
174
+ <!-- microi-progressive:chunk id=v8-menu-buttons-011 sha256=16414969be47116a51bab1c6a7e1482bb987b278430e0fb8daaf7d6ecf41bf94 -->
175
+ ## 10. 与接口引擎配套的工作流
176
+
177
+ 业务按钮通常与接口引擎配套:
178
+
179
+ 1. **microi_create_engine** 先创建 ApiEngineKey(如 `aftersale_assign`),写好后端事务/校验/通知逻辑
180
+ 2. **microi_create_module** 创建菜单时把按钮的 `V8Code` 设为 `V8.ApiEngine.Run({ApiEngineKey:'aftersale_assign',...})`
181
+ 3. AI 在生成菜单时**应主动**:
182
+ - 识别业务动作(指派/接单/审核/完成/驳回/导出/批量处理/状态推进)
183
+ - 为每个动作创建一个接口引擎
184
+ - 在 `moreBtns` / `formBtns` 中绑定按钮 → 接口
185
+
186
+ ---
187
+
188
+ <!-- /microi-progressive:chunk -->
189
+ <!-- microi-progressive:chunk id=v8-menu-buttons-012 sha256=086e02210a949cc0a2c343e7f50c54c48079667999e9264ea5282c9caa951222 -->
190
+ ## 10.1 后台直充/调账类行按钮
191
+
192
+ 会员积分、余额、库存、额度等会改动资产的后台行按钮,必须采用“前端按钮只收参数,后端接口负责事务”的模式。
193
+
194
+ 规则:
195
+ - `MoreBtns` 使用 `ShowRow:true`,按钮只负责 `V8.ConfirmTips` 弹窗、读取金额/备注、调用接口和刷新表格。
196
+ - 不要在 `V8Code` 里直接写 `V8.FormEngine.UptFormData` 改余额;余额更新、订单/流水生成、幂等校验都放到 ApiEngine。
197
+ - 后端接口必须校验 `MemberId/Amount`,金额必须大于 0,并同时写资产主表和对应流水表;如系统已有订单表参与统计,也要同步生成已完成/已支付订单。
198
+ - 资产主表更新、`SELECT ... FOR UPDATE` 和流水写入必须全部使用同一个 `V8.DbTrans`;禁止一部分用 `V8.Db`、另一部分写流水,否则后半段报错时可能留下单边余额变化。
199
+ - 备注字段要有默认值,例如 `平台直充积分`,并允许管理员在弹窗中修改。
200
+ - 验证时至少做一次小额测试,读回主表余额、订单表和流水表;测试备注要明确标识,方便审计。
201
+ - 还必须做一次回滚验收:故意让流水写入失败,回读资产主表确认余额完全未变,再修正输入完成成功验收。
202
+
203
+ 按钮 V8Code 骨架。充值包含金额、备注、联动校验,属于可维护业务表单,应使用在线微服务页面,不要在 `ConfirmTips` 中拼接 `<input>/<textarea>`:
204
+
205
+ ```js
206
+ var row = V8.Form || {};
207
+ V8.OpenAppDialog({
208
+ AppKey: 'member_asset_admin',
209
+ RoutePath: '/recharge',
210
+ Title: '后台充值积分',
211
+ Width: 'min(720px, calc(100vw - 32px))',
212
+ Data: {
213
+ MemberId: row.Id,
214
+ MemberName: row.NickName || row.Phone || row.Id || ''
215
+ },
216
+ OnSuccess: function (result) {
217
+ V8.Tips((result && result.message) || '充值成功', true);
218
+ V8.RefreshTable({ _PageIndex: -1 });
219
+ },
220
+ OnError: function (error) {
221
+ V8.Tips((error && error.message) || '充值失败', false);
222
+ }
223
+ });
224
+ ```
225
+
226
+ ---
227
+
228
+ <!-- /microi-progressive:chunk -->