@microi.net/cli 5.7.7 → 5.7.9

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 (191) 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/LICENSE +21 -21
  7. package/README.md +71 -71
  8. package/assets/build-meta.json +6 -6
  9. package/assets/feature-matrix.json +138 -138
  10. package/assets/logo.svg +4 -4
  11. package/cordis.patch.yml +1 -1
  12. package/package.json +1 -1
  13. package/scripts/mcp-codex-stdio-adapter.js +0 -0
  14. package/scripts/mcp-server.js +102 -101
  15. package/scripts/microi-cli.js +57 -57
  16. package/scripts/microi-codex-broker.js +450 -450
  17. package/scripts/microi-codex-router.js +0 -0
  18. package/scripts/microi-skills.meta.json +366 -366
  19. package/skills/.microi-skills-version.json +2 -2
  20. package/skills/.progressive-disclosure-manifest.json +27 -27
  21. package/skills/README.md +286 -286
  22. package/skills/ai-engine/SKILL.md +265 -265
  23. package/skills/ai-engine/agents/openai.yaml +4 -4
  24. package/skills/ai-platform-governance/SKILL.md +177 -177
  25. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -190
  26. package/skills/app-store/SKILL.md +392 -396
  27. package/skills/app-store/agents/openai.yaml +4 -4
  28. package/skills/business-blueprint/SKILL.md +193 -193
  29. package/skills/datasource-engine/SKILL.md +90 -90
  30. package/skills/datasource-engine/agents/openai.yaml +4 -4
  31. package/skills/dos-orm/references/api-reference.md +229 -229
  32. package/skills/email-engine/SKILL.md +78 -78
  33. package/skills/email-engine/references/v8-email.md +34 -34
  34. package/skills/job-engine/SKILL.md +171 -172
  35. package/skills/job-engine/agents/openai.yaml +4 -4
  36. package/skills/message-notification/SKILL.md +155 -156
  37. package/skills/message-notification/agents/openai.yaml +5 -5
  38. package/skills/message-notification/references/contracts.md +102 -102
  39. package/skills/microi-ai-app-auth.js +652 -652
  40. package/skills/microi-ai-application/SKILL.md +102 -106
  41. package/skills/microi-ai-application/agents/openai.yaml +4 -4
  42. package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
  43. package/skills/microi-client-frontend/SKILL.md +235 -240
  44. 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
  45. 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
  46. 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
  47. package/skills/microi-codex/SKILL.md +75 -75
  48. package/skills/microi-codex-installer/SKILL.md +225 -223
  49. package/skills/microi-codex-installer/agents/openai.yaml +7 -7
  50. package/skills/microi-datasource-mapping/SKILL.md +107 -111
  51. package/skills/microi-db-schema/SKILL.md +175 -175
  52. package/skills/microi-db-schema/agents/openai.yaml +4 -4
  53. package/skills/microi-db-schema/references/core-tables.md +695 -695
  54. package/skills/microi-db-schema/references/form-component-options.md +256 -256
  55. package/skills/microi-db-schema/references/schema-overview.md +202 -202
  56. package/skills/microi-db-schema/references/schema.md +646 -646
  57. package/skills/microi-db-schema/references/table-catalog.md +1599 -1599
  58. package/skills/microi-deployment/references/deployment-matrix.md +101 -101
  59. package/skills/microi-docs-coverage/references/capability-map.md +0 -1
  60. package/skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +894 -894
  61. package/skills/microi-form-engine/SKILL.md +226 -226
  62. package/skills/microi-form-engine/references/component-catalog.md +216 -216
  63. package/skills/microi-form-engine/references/data-source-events.md +124 -124
  64. package/skills/microi-form-layout/SKILL.md +205 -205
  65. 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
  66. package/skills/microi-frontend-sdk/SKILL.md +188 -188
  67. 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
  68. package/skills/microi-left-right-layout/SKILL.md +141 -141
  69. package/skills/microi-microservice/SKILL.md +322 -323
  70. package/skills/microi-microservice/references/runtime-delivery.md +278 -278
  71. package/skills/microi-mobile-app-quality/SKILL.md +181 -181
  72. 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
  73. 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
  74. package/skills/microi-solution-quotation/SKILL.md +78 -78
  75. package/skills/microi-solution-quotation/agents/openai.yaml +4 -4
  76. package/skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -296
  77. package/skills/microi-sso/references/acceptance.md +49 -49
  78. package/skills/microi-sso/references/configuration-and-security.md +53 -53
  79. package/skills/microi-sso/references/inbound.md +53 -53
  80. package/skills/microi-sso/references/outbound.md +39 -39
  81. package/skills/microi-system-delivery/SKILL.md +134 -134
  82. 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
  83. 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 +189 -189
  84. package/skills/microi-ui/SKILL.md +174 -174
  85. 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
  86. package/skills/microi-uniapp-frontend/SKILL.md +193 -193
  87. 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
  88. 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
  89. package/skills/microi.v8.js +1921 -1921
  90. package/skills/module-engine/SKILL.md +237 -250
  91. package/skills/module-engine/references/module-config.md +204 -204
  92. package/skills/ocr-engine/SKILL.md +113 -113
  93. package/skills/ocr-engine/agents/openai.yaml +4 -4
  94. package/skills/page-engine/SKILL.md +180 -191
  95. 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
  96. 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
  97. package/skills/performance-testing/SKILL.md +221 -221
  98. package/skills/playwright-e2e/SKILL.md +197 -197
  99. 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
  100. 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
  101. package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +221 -221
  102. package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +115 -115
  103. package/skills/print-engine/SKILL.md +259 -259
  104. package/skills/production-readonly-audit/SKILL.md +41 -41
  105. package/skills/report-engine/SKILL.md +71 -71
  106. package/skills/report-engine/agents/openai.yaml +4 -4
  107. package/skills/scripts/optimize-progressive-disclosure.mjs +204 -204
  108. package/skills/scripts/refresh-progressive-disclosure.mjs +64 -64
  109. package/skills/search-engine/SKILL.md +75 -75
  110. package/skills/search-engine/agents/openai.yaml +4 -4
  111. package/skills/spider-engine/SKILL.md +190 -190
  112. package/skills/system-observability/SKILL.md +238 -238
  113. package/skills/system-observability/references/memory-incident-triage.md +70 -70
  114. package/skills/translate-engine/SKILL.md +140 -140
  115. package/skills/translate-engine/agents/openai.yaml +4 -4
  116. package/skills/ui-design/SKILL.md +191 -191
  117. package/skills/ui-design/assets/templates/MCI-DESIGN.md +198 -198
  118. package/skills/ui-design/references/design-pattern-library.md +184 -184
  119. package/skills/ui-design/references/mci-design-contract.md +163 -163
  120. 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
  121. package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +137 -137
  122. 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
  123. 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
  124. 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
  125. 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
  126. 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
  127. 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 +117 -117
  128. package/skills/uniapp-mall-assets/SKILL.md +176 -176
  129. package/skills/unity-integration/SKILL.md +155 -155
  130. package/skills/unity-integration/agents/openai.yaml +4 -4
  131. package/skills/unity-integration/references/ai-app-delivery.md +103 -103
  132. package/skills/unity-integration/references/sdk-api.md +82 -82
  133. package/skills/unity-integration/references/toolbox-migration.md +66 -66
  134. package/skills/unity-integration/references/webgl-hosting.md +57 -57
  135. package/skills/v8-cache-pattern/SKILL.md +306 -306
  136. package/skills/v8-crud-api/SKILL.md +175 -175
  137. 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
  138. 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
  139. package/skills/v8-debugging/SKILL.md +284 -284
  140. package/skills/v8-explorer-tree/SKILL.md +228 -228
  141. package/skills/v8-export-import/SKILL.md +209 -209
  142. 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
  143. package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +202 -202
  144. 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
  145. package/skills/v8-file-upload/SKILL.md +256 -263
  146. 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 +101 -101
  147. 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 +150 -150
  148. package/skills/v8-formengine-http/SKILL.md +219 -219
  149. package/skills/v8-frontend-events/SKILL.md +178 -178
  150. package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
  151. package/skills/v8-frontend-events/references/bluetooth-print.md +246 -246
  152. package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +219 -219
  153. package/skills/v8-http-integration/SKILL.md +182 -182
  154. package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +220 -220
  155. 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
  156. package/skills/v8-image-processing/SKILL.md +190 -190
  157. package/skills/v8-image-processing/agents/openai.yaml +4 -4
  158. package/skills/v8-image-processing/references/api-reference.md +623 -623
  159. package/skills/v8-menu-buttons/SKILL.md +180 -180
  160. 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
  161. 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
  162. 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
  163. package/skills/v8-mongodb/SKILL.md +192 -192
  164. package/skills/v8-mq-mqtt/SKILL.md +175 -176
  165. package/skills/v8-mq-mqtt/references/mqtt-production.md +342 -342
  166. package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +181 -181
  167. package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +203 -203
  168. package/skills/v8-saas-multi-tenant/SKILL.md +219 -219
  169. package/skills/v8-security/SKILL.md +168 -168
  170. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +198 -198
  171. package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +158 -158
  172. package/skills/v8-sql-query/SKILL.md +302 -302
  173. package/skills/v8-table-event/SKILL.md +144 -144
  174. 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 +197 -197
  175. 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
  176. package/skills/v8-tcp-integration/SKILL.md +147 -147
  177. package/skills/v8-tcp-integration/agents/openai.yaml +4 -4
  178. package/skills/v8-template-engine/SKILL.md +167 -167
  179. package/skills/v8-utilities/SKILL.md +90 -90
  180. package/skills/v8-utilities/references/client-api-index.md +143 -143
  181. package/skills/v8-utilities/references/platform-http-routes.md +83 -83
  182. package/skills/v8-utilities/references/server-api-index.md +188 -188
  183. package/skills/v8-workflow/SKILL.md +216 -243
  184. 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
  185. package/skills/vision-engine/SKILL.md +159 -159
  186. package/skills/vision-engine/agents/openai.yaml +4 -4
  187. package/skills/vision-engine/references/architecture-and-acceptance.md +194 -194
  188. package/skills/workspace-conventions/SKILL.md +261 -261
  189. 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 +208 -208
  190. 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 +216 -216
  191. 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,95 +1,95 @@
1
- ---
2
- name: v8-formengine-http
3
- description: 移动端 / 外部系统通过 HTTP 直接调用 Microi FormEngine(GetTableData / GetFormData / Add / Upt / Del)的 RESTful 路由约定与排错指南
4
- ---
5
-
6
- > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
-
8
- # FormEngine HTTP 路由约定(外部系统调用)
9
-
10
- > 适用于:uni-app H5、原生 App、Postman、第三方系统、Playwright/Cypress 自动化测试等任何**没有进入 V8 引擎**的客户端。
11
- > 不适用于:服务器端 V8 接口引擎内部 — 那种情况请直接 `V8.FormEngine.GetTableData(...)`。
12
-
13
- ## ⚠️ 最常见错误
14
-
15
- ```text
16
- ❌ POST /formengine/{表名}/gettabledata → 404
17
- ❌ POST /api/formengine/{表名}/gettabledata → 404
18
- ✅ POST /api/formengine/gettabledata-{表名} → OK (动态短路由)
19
- ✅ POST /api/formengine/GetTableData body 中带 FormEngineKey → OK (标准路由)
20
- ```
21
-
22
- 平台路由由 `Microi.Server/Microi.net.Api/Handler/DynamicApiEngine.cs` 的 `FormEngineRoutes` 字典决定,**只认上面两种形式**。
23
-
24
- ## 路由总表
25
-
26
- ### 形式一:标准 Controller 路由 — 推荐
27
- 全部为 `POST`,URL 不含表名,`FormEngineKey` 放在 Body 中。
28
-
29
- | URL | 动作 |
30
- | --- | --- |
31
- | `/api/formengine/GetFormData` | 取一条 |
32
- | `/api/formengine/GetTableData` | 取列表(分页) |
33
- | `/api/formengine/AddFormData` | 新增 |
34
- | `/api/formengine/UptFormData` | 按 Id 修改 |
35
- | `/api/formengine/UptFormDataByWhere` | 按 _Where 批量改 |
36
- | `/api/formengine/DelFormData` | 删除(Id / Ids) |
37
- | `/api/formengine/DelFormDataByWhere` | 按 _Where 批量删 |
38
- | `/api/formengine/GetFormDataAnonymous` | 匿名取一条 |
39
- | `/api/formengine/GetTableDataAnonymous` | 匿名取列表 |
40
- | `/api/formengine/AddFormDataAnonymous` | 匿名新增 |
41
-
42
- ### 形式二:动态短路由(表名写进 URL,URL-friendly)
43
- | URL 前缀 | 等价于 |
44
- | --- | --- |
45
- | `/api/formengine/getformdata-{table}` | `/api/formengine/GetFormData` |
46
- | `/api/formengine/get-formdata-{table}` | `/api/formengine/GetFormData` |
47
- | `/api/formengine/gettabledata-{table}` | `/api/formengine/GetTableData` |
48
- | `/api/formengine/get-tabledata-{table}` | `/api/formengine/GetTableData` |
49
- | `/api/formengine/addformdata-{table}` | `/api/formengine/AddFormData` |
50
- | `/api/formengine/add-formdata-{table}` | `/api/formengine/AddFormData` |
51
- | `/api/formengine/uptformdata-{table}` | `/api/formengine/UptFormData` |
52
- | `/api/formengine/upt-formdata-{table}` | `/api/formengine/UptFormData` |
53
- | `/api/formengine/delformdata-{table}` | `/api/formengine/DelFormData` |
54
- | `/api/formengine/del-formdata-{table}` | `/api/formengine/DelFormData` |
55
-
56
- URL 中的表名小写最稳,平台不区分大小写。匿名版本目前**只在形式一上有**(`GetTableDataAnonymous` 等)。
57
-
58
- ## 请求 Header
59
-
60
- | Header | 是否必填 | 说明 |
61
- | --- | --- | --- |
62
- | `Content-Type` | 必填 | `application/json` 推荐 |
63
- | `OsClient` | 必填 | 租户标识;亦可放 querystring `?OsClient=xxx` 或 body |
64
- | `authorization` | 鉴权接口必填 | `Bearer <Token>`;兼容旧客户端的 `Token` Header |
65
- | `did` | 登录及鉴权接口推荐 | 当前终端稳定设备标识;首次生成后持久化,不能每次请求随机变化 |
66
-
67
- 注意:上表是 FormEngine 路由约定。ApiEngine HTTP 复测和移动端 `callEngine` 使用稳定路径 `/apiengine/{key}`,租户通过唯一的 `osclient` Header 传递,JSON/Form Body 可冗余携带 `OsClient`。普通 POST/PUT/PATCH/DELETE 禁止追加 `--OsClient--...--`;特殊路径只用于无法设置 Header/Form/Query 的 GET/HEAD 或第三方回调。
68
-
69
- 平台可能通过响应 Header `authorization`(兼容 `token`)续签或替换 Token。客户端必须立即保存新 Token,并保证并发旧响应不能覆盖已经写入的新 Token。跨域部署还必须在 CORS 中暴露 `authorization`、`token` 等需要读取的响应 Header。Token 属于凭据,禁止写入 URL、日志、错误上报和页面源码。
70
-
71
- ## FormEngine 数据授权边界
72
-
73
- “Token 有效”只代表身份有效,不代表可以访问任意表。客户端 FormEngine CRUD 还会经过表、菜单、角色和行级范围授权:
74
-
75
- 1. 受保护的平台敏感表优先拒绝普通用户;匿名接口也不能绕过。
76
- 2. 标准菜单页应携带真实 `_SysMenuId`,或使用 `ModuleEngineKey`。服务器会严格校验该菜单是否绑定目标表、当前角色是否拥有菜单及对应操作权限;列表、计数、导出追加该菜单的数据范围。
77
- 3. 列表、写入、导入、导出显式传错 `_SysMenuId` / `ModuleEngineKey` 会直接拒绝,不会降级为其它菜单或表权限。单行详情只要当前角色拥有至少一个直接绑定同表的菜单(或精确表级 `Read` 权限)即可读取,不应用菜单 `SqlWhere` / `SqlJoin`;旧客户端携带过期菜单 Id 时也按该规则恢复。
78
- 4. 为兼容历史前端 V8/外部客户端,普通 CRUD 未传菜单上下文时,服务器会从当前用户的版本化授权缓存中查找“当前角色已获授权且直接绑定目标表”的菜单。无菜单列表仍安全合并候选菜单的数据范围,不能靠漏参绕过;详情按同表菜单访问,写入按 `Add/Edit/Del` 动作权限。也可以使用角色的精确表级 `Read/Add/Edit/Del` 授权。`JoinTables` 不是独立访问授权。
79
- 5. 导入、导出必须锚定具体菜单,不能依赖无菜单兼容推断。
80
- 6. `TableChild` 子表委托由标准表单运行时生成 `_TableChildAuth`,服务器重新校验父菜单、父记录、字段绑定、子表和外键,并强制父子范围。它是内部不透明上下文,外部客户端不要手工拼装。
81
- 7. `_InvokeType:'Client'` 只决定是否执行客户端语义的表单事件,不是权限开关。可信服务器调用标记也不能通过 HTTP Body 伪造。
82
-
83
- 因此:
84
-
85
- - 标准模块、详情页和其字段元数据请求优先传真实 `_SysMenuId`,使服务器确定菜单绑定与操作权限;其中只有列表、计数、导出应用菜单查询范围。
86
- - 历史无 `_SysMenuId` 请求可继续工作,但前提是当前用户确实拥有目标表对应的菜单或精确表权限;不能把兼容推断理解为“有 Token 即可查表”。
87
- - 历史单表字段请求可在菜单缺失/过期时回退到当前角色另一个引用同表的已授权菜单;`GetDiyFieldByDiyTables` 批量字段请求按“第一张主表必须授权、后续表逐张授权并过滤”兼容。后续未授权/保护表不会导致主表失败,也不会返回其字段配置;这些规则不授予数据行权限。
88
- - 表单设计器 `/api/DiyField/UptDiyFieldList` 属于 `Level >= 9999` 控制面:外层一次授权、字段归属校验、同事务批量更新、批次末一次缓存/版本刷新。禁止在 100+ 字段循环中逐条调用完整 `UptFormDataAsync("diy_field", ...)`,否则会重复执行授权、V8、日志及 SaaS/Redis 缓存工作。
89
- - 接口引擎内的 `V8.FormEngine.*` 属于服务器端调用,不要求客户端 `_SysMenuId`。但接口引擎本身必须正确限制谁能调用,并在服务端校验业务对象范围,不能把表名和条件原样交给不可信客户端。
90
- - 客户端新增、修改、删除分别校验真实菜单的 `Add`、`Edit`、`Del` 权限。`SqlWhere` / `SqlJoin` 是模块查询过滤,不是行级写权限:不得把它们追加到写入 SQL,也不得因查询包含 Join 拒绝已获授权的主表写入。
91
- - 进入 `SubmitBeforeServerV8` / `SubmitAfterServerV8` 后,事件内 FormEngine/数据库调用与接口引擎一样属于可信服务器执行,可实现当前租户内的跨表事务。需要“只能修改本人数据”等业务约束以及归属字段写入时,应在这里或专用接口引擎中完成。
92
-
1
+ ---
2
+ name: v8-formengine-http
3
+ description: 移动端 / 外部系统通过 HTTP 直接调用 Microi FormEngine(GetTableData / GetFormData / Add / Upt / Del)的 RESTful 路由约定与排错指南
4
+ ---
5
+
6
+ > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
+
8
+ # FormEngine HTTP 路由约定(外部系统调用)
9
+
10
+ > 适用于:uni-app H5、原生 App、Postman、第三方系统、Playwright/Cypress 自动化测试等任何**没有进入 V8 引擎**的客户端。
11
+ > 不适用于:服务器端 V8 接口引擎内部 — 那种情况请直接 `V8.FormEngine.GetTableData(...)`。
12
+
13
+ ## ⚠️ 最常见错误
14
+
15
+ ```text
16
+ ❌ POST /formengine/{表名}/gettabledata → 404
17
+ ❌ POST /api/formengine/{表名}/gettabledata → 404
18
+ ✅ POST /api/formengine/gettabledata-{表名} → OK (动态短路由)
19
+ ✅ POST /api/formengine/GetTableData body 中带 FormEngineKey → OK (标准路由)
20
+ ```
21
+
22
+ 平台路由由 `Microi.Server/Microi.net.Api/Handler/DynamicApiEngine.cs` 的 `FormEngineRoutes` 字典决定,**只认上面两种形式**。
23
+
24
+ ## 路由总表
25
+
26
+ ### 形式一:标准 Controller 路由 — 推荐
27
+ 全部为 `POST`,URL 不含表名,`FormEngineKey` 放在 Body 中。
28
+
29
+ | URL | 动作 |
30
+ | --- | --- |
31
+ | `/api/formengine/GetFormData` | 取一条 |
32
+ | `/api/formengine/GetTableData` | 取列表(分页) |
33
+ | `/api/formengine/AddFormData` | 新增 |
34
+ | `/api/formengine/UptFormData` | 按 Id 修改 |
35
+ | `/api/formengine/UptFormDataByWhere` | 按 _Where 批量改 |
36
+ | `/api/formengine/DelFormData` | 删除(Id / Ids) |
37
+ | `/api/formengine/DelFormDataByWhere` | 按 _Where 批量删 |
38
+ | `/api/formengine/GetFormDataAnonymous` | 匿名取一条 |
39
+ | `/api/formengine/GetTableDataAnonymous` | 匿名取列表 |
40
+ | `/api/formengine/AddFormDataAnonymous` | 匿名新增 |
41
+
42
+ ### 形式二:动态短路由(表名写进 URL,URL-friendly)
43
+ | URL 前缀 | 等价于 |
44
+ | --- | --- |
45
+ | `/api/formengine/getformdata-{table}` | `/api/formengine/GetFormData` |
46
+ | `/api/formengine/get-formdata-{table}` | `/api/formengine/GetFormData` |
47
+ | `/api/formengine/gettabledata-{table}` | `/api/formengine/GetTableData` |
48
+ | `/api/formengine/get-tabledata-{table}` | `/api/formengine/GetTableData` |
49
+ | `/api/formengine/addformdata-{table}` | `/api/formengine/AddFormData` |
50
+ | `/api/formengine/add-formdata-{table}` | `/api/formengine/AddFormData` |
51
+ | `/api/formengine/uptformdata-{table}` | `/api/formengine/UptFormData` |
52
+ | `/api/formengine/upt-formdata-{table}` | `/api/formengine/UptFormData` |
53
+ | `/api/formengine/delformdata-{table}` | `/api/formengine/DelFormData` |
54
+ | `/api/formengine/del-formdata-{table}` | `/api/formengine/DelFormData` |
55
+
56
+ URL 中的表名小写最稳,平台不区分大小写。匿名版本目前**只在形式一上有**(`GetTableDataAnonymous` 等)。
57
+
58
+ ## 请求 Header
59
+
60
+ | Header | 是否必填 | 说明 |
61
+ | --- | --- | --- |
62
+ | `Content-Type` | 必填 | `application/json` 推荐 |
63
+ | `OsClient` | 必填 | 租户标识;亦可放 querystring `?OsClient=xxx` 或 body |
64
+ | `authorization` | 鉴权接口必填 | `Bearer <Token>`;兼容旧客户端的 `Token` Header |
65
+ | `did` | 登录及鉴权接口推荐 | 当前终端稳定设备标识;首次生成后持久化,不能每次请求随机变化 |
66
+
67
+ 注意:上表是 FormEngine 路由约定。ApiEngine HTTP 复测和移动端 `callEngine` 使用稳定路径 `/apiengine/{key}`,租户通过唯一的 `osclient` Header 传递,JSON/Form Body 可冗余携带 `OsClient`。普通 POST/PUT/PATCH/DELETE 禁止追加 `--OsClient--...--`;特殊路径只用于无法设置 Header/Form/Query 的 GET/HEAD 或第三方回调。
68
+
69
+ 平台可能通过响应 Header `authorization`(兼容 `token`)续签或替换 Token。客户端必须立即保存新 Token,并保证并发旧响应不能覆盖已经写入的新 Token。跨域部署还必须在 CORS 中暴露 `authorization`、`token` 等需要读取的响应 Header。Token 属于凭据,禁止写入 URL、日志、错误上报和页面源码。
70
+
71
+ ## FormEngine 数据授权边界
72
+
73
+ “Token 有效”只代表身份有效,不代表可以访问任意表。客户端 FormEngine CRUD 还会经过表、菜单、角色和行级范围授权:
74
+
75
+ 1. 受保护的平台敏感表优先拒绝普通用户;匿名接口也不能绕过。
76
+ 2. 标准菜单页应携带真实 `_SysMenuId`,或使用 `ModuleEngineKey`。服务器会严格校验该菜单是否绑定目标表、当前角色是否拥有菜单及对应操作权限;列表、计数、导出追加该菜单的数据范围。
77
+ 3. 列表、写入、导入、导出显式传错 `_SysMenuId` / `ModuleEngineKey` 会直接拒绝,不会降级为其它菜单或表权限。单行详情只要当前角色拥有至少一个直接绑定同表的菜单(或精确表级 `Read` 权限)即可读取,不应用菜单 `SqlWhere` / `SqlJoin`;旧客户端携带过期菜单 Id 时也按该规则恢复。
78
+ 4. 为兼容历史前端 V8/外部客户端,普通 CRUD 未传菜单上下文时,服务器会从当前用户的版本化授权缓存中查找“当前角色已获授权且直接绑定目标表”的菜单。无菜单列表仍安全合并候选菜单的数据范围,不能靠漏参绕过;详情按同表菜单访问,写入按 `Add/Edit/Del` 动作权限。也可以使用角色的精确表级 `Read/Add/Edit/Del` 授权。`JoinTables` 不是独立访问授权。
79
+ 5. 导入、导出必须锚定具体菜单,不能依赖无菜单兼容推断。
80
+ 6. `TableChild` 子表委托由标准表单运行时生成 `_TableChildAuth`,服务器重新校验父菜单、父记录、字段绑定、子表和外键,并强制父子范围。它是内部不透明上下文,外部客户端不要手工拼装。
81
+ 7. `_InvokeType:'Client'` 只决定是否执行客户端语义的表单事件,不是权限开关。可信服务器调用标记也不能通过 HTTP Body 伪造。
82
+
83
+ 因此:
84
+
85
+ - 标准模块、详情页和其字段元数据请求优先传真实 `_SysMenuId`,使服务器确定菜单绑定与操作权限;其中只有列表、计数、导出应用菜单查询范围。
86
+ - 历史无 `_SysMenuId` 请求可继续工作,但前提是当前用户确实拥有目标表对应的菜单或精确表权限;不能把兼容推断理解为“有 Token 即可查表”。
87
+ - 历史单表字段请求可在菜单缺失/过期时回退到当前角色另一个引用同表的已授权菜单;`GetDiyFieldByDiyTables` 批量字段请求按“第一张主表必须授权、后续表逐张授权并过滤”兼容。后续未授权/保护表不会导致主表失败,也不会返回其字段配置;这些规则不授予数据行权限。
88
+ - 表单设计器 `/api/DiyField/UptDiyFieldList` 属于 `Level >= 9999` 控制面:外层一次授权、字段归属校验、同事务批量更新、批次末一次缓存/版本刷新。禁止在 100+ 字段循环中逐条调用完整 `UptFormDataAsync("diy_field", ...)`,否则会重复执行授权、V8、日志及 SaaS/Redis 缓存工作。
89
+ - 接口引擎内的 `V8.FormEngine.*` 属于服务器端调用,不要求客户端 `_SysMenuId`。但接口引擎本身必须正确限制谁能调用,并在服务端校验业务对象范围,不能把表名和条件原样交给不可信客户端。
90
+ - 客户端新增、修改、删除分别校验真实菜单的 `Add`、`Edit`、`Del` 权限。`SqlWhere` / `SqlJoin` 是模块查询过滤,不是行级写权限:不得把它们追加到写入 SQL,也不得因查询包含 Join 拒绝已获授权的主表写入。
91
+ - 进入 `SubmitBeforeServerV8` / `SubmitAfterServerV8` 后,事件内 FormEngine/数据库调用与接口引擎一样属于可信服务器执行,可实现当前租户内的跨表事务。需要“只能修改本人数据”等业务约束以及归属字段写入时,应在这里或专用接口引擎中完成。
92
+
93
93
  ## 原生详情关联数据
94
94
 
95
95
  - `POST /api/FormEngine/GetFormRelatedData` 接收父表 `ParentFormEngineKey`、父记录
@@ -109,130 +109,130 @@ URL 中的表名小写最稳,平台不区分大小写。匿名版本目前**
109
109
  安全评论绑定写入及旧数据处理须独立交付后才能宣称评论完整可用。
110
110
 
111
111
  ## Body 结构(POST JSON)
112
-
113
- ```jsonc
114
- {
115
- "OsClient": "demo",
116
- "FormEngineKey": "mall_product", // 形式一必填;形式二可选(已在 URL 中)
117
- "_SysMenuId": "目标菜单Id", // 标准模块推荐;必须是真实绑定目标表且当前角色有权访问的菜单
118
- "_Where": [["Status","=","OnSale"], ["AND","Stock",">",0]],
119
- "_SelectFields": ["Id","Title","CurrentPrice","MainImg"],
120
- "_OrderBy": "SoldCount",
121
- "_OrderByType": "DESC",
122
- "_PageIndex": 1,
123
- "_PageSize": 20
124
- }
125
- ```
126
-
127
- 写操作(Add/Upt)将业务字段平铺到 body:
128
- ```jsonc
129
- { "OsClient":"demo", "FormEngineKey":"biz_order",
130
- "Id":"01ABC...", "Quantity": 2, "Selected": 1 }
131
- ```
132
-
133
- ## 响应 DosResult 标准格式
134
-
135
- ```jsonc
136
- { "Code": 1, "Data": [...], "DataCount": 123, "Msg": "" }
137
- ```
138
- | Code | 含义 |
139
- | --- | --- |
140
- | 1 | 成功 |
141
- | 0 | 业务失败(看 `Msg`) |
142
- | 1001 | 登录身份已过期 / Token 无效 |
143
- | 1002 | 身份验证失败(OsClient 与 Token 不匹配) |
144
-
145
- ## 客户端封装样板(uni-app)
146
-
147
- ```javascript
148
- const BASE = 'https://api.itdos.com';
149
- const OS_CLIENT = runtimeConfig.osClient;
150
- const TOKEN_KEY = 'mall_token';
151
- const DID_KEY = 'mall_did';
152
-
153
- function normalizeToken(value) {
154
- return String(value || '').replace(/^Bearer\s+/i, '').trim();
155
- }
156
- function getToken() {
157
- return normalizeToken(uni.getStorageSync(TOKEN_KEY));
158
- }
159
- function getDid() {
160
- let did = uni.getStorageSync(DID_KEY);
161
- if (!did) {
162
- did = `uni-${Date.now()}-${Math.random().toString(36).slice(2)}`;
163
- uni.setStorageSync(DID_KEY, did);
164
- }
165
- return did;
166
- }
167
- function readHeader(headers, name) {
168
- const key = Object.keys(headers || {}).find(k => k.toLowerCase() === name);
169
- return key ? headers[key] : '';
170
- }
171
- function applyResponseToken(headers, requestToken) {
172
- const responseToken = normalizeToken(
173
- readHeader(headers, 'authorization') || readHeader(headers, 'token')
174
- );
175
- if (!responseToken) return;
176
-
177
- const currentToken = getToken();
178
- // 旧请求若只回显旧 Token,不得覆盖其它请求/标签页已保存的新 Token。
179
- if (currentToken && requestToken && currentToken !== requestToken && responseToken === requestToken) {
180
- return;
181
- }
182
- uni.setStorageSync(TOKEN_KEY, responseToken);
183
- }
184
-
185
- function formEngineRequest(action, table, body = {}) {
186
- return new Promise((resolve, reject) => {
187
- const requestToken = getToken();
188
- uni.request({
189
- url: `${BASE}/api/formengine/${action}-${table}`,
190
- method: 'POST',
191
- header: {
192
- 'Content-Type': 'application/json',
193
- 'OsClient': OS_CLIENT,
194
- 'authorization': requestToken ? `Bearer ${requestToken}` : '',
195
- 'did': getDid()
196
- },
197
- data: { OsClient: OS_CLIENT, FormEngineKey: table, ...body },
198
- success: (res) => {
199
- applyResponseToken(res.header || res.headers, requestToken);
200
- resolve(res.data || {});
201
- },
202
- fail: reject
203
- });
204
- });
205
- }
206
- export const formEngineGet = (t, w) => formEngineRequest('gettabledata', t, w);
207
- export const formEngineGetOne = (t, w) => formEngineRequest('getformdata', t, w);
208
- export const formEngineAdd = (t, d) => formEngineRequest('addformdata', t, d);
209
- export const formEngineUpt = (t, d) => formEngineRequest('uptformdata', t, d);
210
- export const formEngineDel = (t, d) => formEngineRequest('delformdata', t, d);
211
- ```
212
-
213
- ## 排错速查
214
-
215
- | 现象 | 真实原因 |
216
- | --- | --- |
217
- | 404 Not Found | URL 缺 `/api/` 前缀,或表名/动作之间用 `/` 而不是 `-` |
218
- | 405 Method Not Allowed | 用了 GET(FormEngine 全部为 POST) |
219
- | 1001 登录身份已过期 | 没传 Token / Token 过期 / Redis 重启 |
220
- | 1002 身份验证失败 | OsClient 不匹配 |
221
- | `NoAuth` / `您没有权限做此操作` | Token 有效但菜单、表操作权限、表绑定角色、行级范围或敏感表策略不允许 |
222
- | 显式传 `_SysMenuId` 后无权限 | 列表/写入使用错误菜单会严格拒绝;唯一详情在当前角色仍拥有另一个同表菜单时可恢复,不应用菜单查询范围 |
223
- | 无 `_SysMenuId` 仍无权限 | 当前角色没有直接绑定该表的菜单授权,也没有精确表级授权 |
224
- | 并发后提示 TokenReplaced / MissingToken | 客户端没有接收响应新 Token,或旧请求/其它标签页覆盖或清除了共享新 Token |
225
- | Code:0 表不存在 | `FormEngineKey` 在 `diy_table` 不存在 |
226
- | Code:0 字段不存在 | `_Where` / `_SelectFields` 写了表上没有的字段 |
227
- | 返回 `null` 而不是 DosResult | Controller 抛了异常被吞,到后端日志看 `Microi.Core` 报错 |
228
-
229
- ## 与服务器端 V8 的对照
230
-
231
- | 客户端 HTTP 路由 | V8 内等价写法 |
232
- | --- | --- |
233
- | POST `/api/formengine/gettabledata-mall_product` | `V8.FormEngine.GetTableData('mall_product', {...})` |
234
- | POST `/api/formengine/getformdata-mall_member` | `V8.FormEngine.GetFormData('mall_member', {...})` |
235
- | POST `/api/formengine/uptformdata-mall_shopping_cart` | `V8.FormEngine.UptFormData('mall_shopping_cart', {...})` |
236
-
237
- > 客户端 HTTP 调用**会**触发 `SubmitBeforeServerV8`、`SubmitAfterServerV8`、`DataFilterV8` 等服务端事件;
238
- > 而 V8 引擎内调用 `V8.FormEngine.*` 默认**不**触发,除非显式传 `_InvokeType:'Client'`。`_InvokeType` 只影响事件语义,不授予任何客户端表权限。
112
+
113
+ ```jsonc
114
+ {
115
+ "OsClient": "demo",
116
+ "FormEngineKey": "mall_product", // 形式一必填;形式二可选(已在 URL 中)
117
+ "_SysMenuId": "目标菜单Id", // 标准模块推荐;必须是真实绑定目标表且当前角色有权访问的菜单
118
+ "_Where": [["Status","=","OnSale"], ["AND","Stock",">",0]],
119
+ "_SelectFields": ["Id","Title","CurrentPrice","MainImg"],
120
+ "_OrderBy": "SoldCount",
121
+ "_OrderByType": "DESC",
122
+ "_PageIndex": 1,
123
+ "_PageSize": 20
124
+ }
125
+ ```
126
+
127
+ 写操作(Add/Upt)将业务字段平铺到 body:
128
+ ```jsonc
129
+ { "OsClient":"demo", "FormEngineKey":"biz_order",
130
+ "Id":"01ABC...", "Quantity": 2, "Selected": 1 }
131
+ ```
132
+
133
+ ## 响应 DosResult 标准格式
134
+
135
+ ```jsonc
136
+ { "Code": 1, "Data": [...], "DataCount": 123, "Msg": "" }
137
+ ```
138
+ | Code | 含义 |
139
+ | --- | --- |
140
+ | 1 | 成功 |
141
+ | 0 | 业务失败(看 `Msg`) |
142
+ | 1001 | 登录身份已过期 / Token 无效 |
143
+ | 1002 | 身份验证失败(OsClient 与 Token 不匹配) |
144
+
145
+ ## 客户端封装样板(uni-app)
146
+
147
+ ```javascript
148
+ const BASE = 'https://api.itdos.com';
149
+ const OS_CLIENT = runtimeConfig.osClient;
150
+ const TOKEN_KEY = 'mall_token';
151
+ const DID_KEY = 'mall_did';
152
+
153
+ function normalizeToken(value) {
154
+ return String(value || '').replace(/^Bearer\s+/i, '').trim();
155
+ }
156
+ function getToken() {
157
+ return normalizeToken(uni.getStorageSync(TOKEN_KEY));
158
+ }
159
+ function getDid() {
160
+ let did = uni.getStorageSync(DID_KEY);
161
+ if (!did) {
162
+ did = `uni-${Date.now()}-${Math.random().toString(36).slice(2)}`;
163
+ uni.setStorageSync(DID_KEY, did);
164
+ }
165
+ return did;
166
+ }
167
+ function readHeader(headers, name) {
168
+ const key = Object.keys(headers || {}).find(k => k.toLowerCase() === name);
169
+ return key ? headers[key] : '';
170
+ }
171
+ function applyResponseToken(headers, requestToken) {
172
+ const responseToken = normalizeToken(
173
+ readHeader(headers, 'authorization') || readHeader(headers, 'token')
174
+ );
175
+ if (!responseToken) return;
176
+
177
+ const currentToken = getToken();
178
+ // 旧请求若只回显旧 Token,不得覆盖其它请求/标签页已保存的新 Token。
179
+ if (currentToken && requestToken && currentToken !== requestToken && responseToken === requestToken) {
180
+ return;
181
+ }
182
+ uni.setStorageSync(TOKEN_KEY, responseToken);
183
+ }
184
+
185
+ function formEngineRequest(action, table, body = {}) {
186
+ return new Promise((resolve, reject) => {
187
+ const requestToken = getToken();
188
+ uni.request({
189
+ url: `${BASE}/api/formengine/${action}-${table}`,
190
+ method: 'POST',
191
+ header: {
192
+ 'Content-Type': 'application/json',
193
+ 'OsClient': OS_CLIENT,
194
+ 'authorization': requestToken ? `Bearer ${requestToken}` : '',
195
+ 'did': getDid()
196
+ },
197
+ data: { OsClient: OS_CLIENT, FormEngineKey: table, ...body },
198
+ success: (res) => {
199
+ applyResponseToken(res.header || res.headers, requestToken);
200
+ resolve(res.data || {});
201
+ },
202
+ fail: reject
203
+ });
204
+ });
205
+ }
206
+ export const formEngineGet = (t, w) => formEngineRequest('gettabledata', t, w);
207
+ export const formEngineGetOne = (t, w) => formEngineRequest('getformdata', t, w);
208
+ export const formEngineAdd = (t, d) => formEngineRequest('addformdata', t, d);
209
+ export const formEngineUpt = (t, d) => formEngineRequest('uptformdata', t, d);
210
+ export const formEngineDel = (t, d) => formEngineRequest('delformdata', t, d);
211
+ ```
212
+
213
+ ## 排错速查
214
+
215
+ | 现象 | 真实原因 |
216
+ | --- | --- |
217
+ | 404 Not Found | URL 缺 `/api/` 前缀,或表名/动作之间用 `/` 而不是 `-` |
218
+ | 405 Method Not Allowed | 用了 GET(FormEngine 全部为 POST) |
219
+ | 1001 登录身份已过期 | 没传 Token / Token 过期 / Redis 重启 |
220
+ | 1002 身份验证失败 | OsClient 不匹配 |
221
+ | `NoAuth` / `您没有权限做此操作` | Token 有效但菜单、表操作权限、表绑定角色、行级范围或敏感表策略不允许 |
222
+ | 显式传 `_SysMenuId` 后无权限 | 列表/写入使用错误菜单会严格拒绝;唯一详情在当前角色仍拥有另一个同表菜单时可恢复,不应用菜单查询范围 |
223
+ | 无 `_SysMenuId` 仍无权限 | 当前角色没有直接绑定该表的菜单授权,也没有精确表级授权 |
224
+ | 并发后提示 TokenReplaced / MissingToken | 客户端没有接收响应新 Token,或旧请求/其它标签页覆盖或清除了共享新 Token |
225
+ | Code:0 表不存在 | `FormEngineKey` 在 `diy_table` 不存在 |
226
+ | Code:0 字段不存在 | `_Where` / `_SelectFields` 写了表上没有的字段 |
227
+ | 返回 `null` 而不是 DosResult | Controller 抛了异常被吞,到后端日志看 `Microi.Core` 报错 |
228
+
229
+ ## 与服务器端 V8 的对照
230
+
231
+ | 客户端 HTTP 路由 | V8 内等价写法 |
232
+ | --- | --- |
233
+ | POST `/api/formengine/gettabledata-mall_product` | `V8.FormEngine.GetTableData('mall_product', {...})` |
234
+ | POST `/api/formengine/getformdata-mall_member` | `V8.FormEngine.GetFormData('mall_member', {...})` |
235
+ | POST `/api/formengine/uptformdata-mall_shopping_cart` | `V8.FormEngine.UptFormData('mall_shopping_cart', {...})` |
236
+
237
+ > 客户端 HTTP 调用**会**触发 `SubmitBeforeServerV8`、`SubmitAfterServerV8`、`DataFilterV8` 等服务端事件;
238
+ > 而 V8 引擎内调用 `V8.FormEngine.*` 默认**不**触发,除非显式传 `_InvokeType:'Client'`。`_InvokeType` 只影响事件语义,不授予任何客户端表权限。