@microi.net/cli 5.7.8 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) 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 +113 -112
  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 +364 -364
  19. package/skills/.microi-skills-version.json +2 -2
  20. package/skills/README.md +286 -286
  21. package/skills/ai-engine/SKILL.md +265 -265
  22. package/skills/ai-engine/agents/openai.yaml +4 -4
  23. package/skills/ai-platform-governance/SKILL.md +177 -177
  24. package/skills/ai-platform-governance/references/progressive-01-/345/212/237/350/203/275/345/274/200/345/205/263.md +190 -190
  25. package/skills/app-store/SKILL.md +396 -396
  26. package/skills/app-store/agents/openai.yaml +4 -4
  27. package/skills/business-blueprint/SKILL.md +193 -193
  28. package/skills/datasource-engine/SKILL.md +90 -90
  29. package/skills/datasource-engine/agents/openai.yaml +4 -4
  30. package/skills/dos-orm/references/api-reference.md +229 -229
  31. package/skills/email-engine/SKILL.md +78 -78
  32. package/skills/email-engine/references/v8-email.md +34 -34
  33. package/skills/job-engine/SKILL.md +172 -172
  34. package/skills/job-engine/agents/openai.yaml +4 -4
  35. package/skills/message-notification/SKILL.md +156 -156
  36. package/skills/message-notification/agents/openai.yaml +5 -5
  37. package/skills/message-notification/references/contracts.md +102 -102
  38. package/skills/microi-ai-app-auth.js +652 -652
  39. package/skills/microi-ai-application/SKILL.md +106 -106
  40. package/skills/microi-ai-application/agents/openai.yaml +4 -4
  41. package/skills/microi-ai-application/references/frontend-baseline.md +164 -164
  42. package/skills/microi-client-frontend/SKILL.md +237 -237
  43. 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
  44. 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
  45. 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
  46. package/skills/microi-codex/SKILL.md +72 -70
  47. package/skills/microi-codex-installer/SKILL.md +225 -223
  48. package/skills/microi-codex-installer/agents/openai.yaml +7 -7
  49. package/skills/microi-datasource-mapping/SKILL.md +108 -108
  50. package/skills/microi-db-schema/SKILL.md +175 -175
  51. package/skills/microi-db-schema/agents/openai.yaml +4 -4
  52. package/skills/microi-db-schema/references/core-tables.md +695 -695
  53. package/skills/microi-db-schema/references/form-component-options.md +256 -256
  54. package/skills/microi-db-schema/references/schema-overview.md +202 -202
  55. package/skills/microi-db-schema/references/schema.md +646 -646
  56. package/skills/microi-db-schema/references/table-catalog.md +1599 -1599
  57. package/skills/microi-deployment/references/deployment-matrix.md +101 -101
  58. package/skills/microi-docs-coverage/scripts/audit-doc-skill-coverage.mjs +894 -894
  59. package/skills/microi-form-engine/SKILL.md +226 -226
  60. package/skills/microi-form-engine/references/component-catalog.md +216 -216
  61. package/skills/microi-form-engine/references/data-source-events.md +124 -124
  62. package/skills/microi-form-layout/SKILL.md +205 -205
  63. 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
  64. package/skills/microi-frontend-sdk/SKILL.md +188 -188
  65. 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
  66. package/skills/microi-left-right-layout/SKILL.md +141 -141
  67. package/skills/microi-microservice/SKILL.md +323 -323
  68. package/skills/microi-microservice/references/runtime-delivery.md +278 -278
  69. package/skills/microi-mobile-app-quality/SKILL.md +181 -181
  70. 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
  71. 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
  72. package/skills/microi-solution-quotation/SKILL.md +78 -78
  73. package/skills/microi-solution-quotation/agents/openai.yaml +4 -4
  74. package/skills/microi-solution-quotation/scripts/build_solution_quote.py +296 -296
  75. package/skills/microi-sso/references/acceptance.md +49 -49
  76. package/skills/microi-sso/references/configuration-and-security.md +53 -53
  77. package/skills/microi-sso/references/inbound.md +53 -53
  78. package/skills/microi-sso/references/outbound.md +39 -39
  79. package/skills/microi-system-delivery/SKILL.md +134 -134
  80. 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
  81. 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
  82. package/skills/microi-ui/SKILL.md +174 -174
  83. 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
  84. package/skills/microi-uniapp-frontend/SKILL.md +193 -193
  85. 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
  86. 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
  87. package/skills/microi.v8.js +1921 -1921
  88. package/skills/module-engine/SKILL.md +250 -250
  89. package/skills/module-engine/references/module-config.md +204 -204
  90. package/skills/ocr-engine/SKILL.md +113 -113
  91. package/skills/ocr-engine/agents/openai.yaml +4 -4
  92. package/skills/page-engine/SKILL.md +182 -182
  93. 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
  94. 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
  95. package/skills/performance-testing/SKILL.md +221 -221
  96. package/skills/playwright-e2e/SKILL.md +197 -197
  97. 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
  98. 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
  99. package/skills/playwright-e2e/references/progressive-03-microi-helper-/346/250/241/346/235/277.md +221 -221
  100. package/skills/playwright-e2e/references/progressive-04-ci-/345/273/272/350/256/256.md +115 -115
  101. package/skills/print-engine/SKILL.md +259 -259
  102. package/skills/production-readonly-audit/SKILL.md +41 -41
  103. package/skills/report-engine/SKILL.md +71 -71
  104. package/skills/report-engine/agents/openai.yaml +4 -4
  105. package/skills/scripts/optimize-progressive-disclosure.mjs +204 -204
  106. package/skills/scripts/refresh-progressive-disclosure.mjs +64 -64
  107. package/skills/search-engine/SKILL.md +75 -75
  108. package/skills/search-engine/agents/openai.yaml +4 -4
  109. package/skills/spider-engine/SKILL.md +190 -190
  110. package/skills/system-observability/SKILL.md +238 -238
  111. package/skills/system-observability/references/memory-incident-triage.md +70 -70
  112. package/skills/translate-engine/SKILL.md +140 -140
  113. package/skills/translate-engine/agents/openai.yaml +4 -4
  114. package/skills/ui-design/SKILL.md +191 -191
  115. package/skills/ui-design/assets/templates/MCI-DESIGN.md +198 -198
  116. package/skills/ui-design/references/design-pattern-library.md +184 -184
  117. package/skills/ui-design/references/mci-design-contract.md +163 -163
  118. 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
  119. package/skills/ui-design/references/progressive-02-/345/255/227/344/275/223.md +137 -137
  120. 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
  121. 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
  122. 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
  123. 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
  124. 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
  125. 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
  126. package/skills/uniapp-mall-assets/SKILL.md +176 -176
  127. package/skills/unity-integration/SKILL.md +155 -155
  128. package/skills/unity-integration/agents/openai.yaml +4 -4
  129. package/skills/unity-integration/references/ai-app-delivery.md +103 -103
  130. package/skills/unity-integration/references/sdk-api.md +82 -82
  131. package/skills/unity-integration/references/toolbox-migration.md +66 -66
  132. package/skills/unity-integration/references/webgl-hosting.md +57 -57
  133. package/skills/v8-cache-pattern/SKILL.md +306 -306
  134. package/skills/v8-crud-api/SKILL.md +175 -175
  135. 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
  136. 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
  137. package/skills/v8-debugging/SKILL.md +284 -284
  138. package/skills/v8-explorer-tree/SKILL.md +228 -228
  139. package/skills/v8-export-import/SKILL.md +209 -209
  140. 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
  141. package/skills/v8-export-import/references/progressive-02-powerpoint-/345/257/274/345/207/272.md +202 -202
  142. 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
  143. package/skills/v8-file-upload/SKILL.md +263 -263
  144. 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
  145. 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
  146. package/skills/v8-formengine-http/SKILL.md +219 -219
  147. package/skills/v8-frontend-events/SKILL.md +178 -178
  148. package/skills/v8-frontend-events/references/bluetooth-print-api.md +135 -135
  149. package/skills/v8-frontend-events/references/bluetooth-print.md +246 -246
  150. package/skills/v8-frontend-events/references/progressive-01-/345/210/227/350/241/250/344/272/213/344/273/266.md +219 -219
  151. package/skills/v8-http-integration/SKILL.md +182 -182
  152. package/skills/v8-http-integration/references/progressive-01-get-/350/257/267/346/261/202.md +220 -220
  153. 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
  154. package/skills/v8-image-processing/SKILL.md +190 -190
  155. package/skills/v8-image-processing/agents/openai.yaml +4 -4
  156. package/skills/v8-image-processing/references/api-reference.md +623 -623
  157. package/skills/v8-menu-buttons/SKILL.md +180 -180
  158. 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
  159. 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
  160. 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
  161. package/skills/v8-mongodb/SKILL.md +192 -192
  162. package/skills/v8-mq-mqtt/SKILL.md +176 -176
  163. package/skills/v8-mq-mqtt/references/mqtt-production.md +342 -342
  164. package/skills/v8-mq-mqtt/references/progressive-01-v8-mqtt-iot-/347/211/251/350/201/224/347/275/221.md +181 -181
  165. package/skills/v8-mq-mqtt/scripts/check-mqtt-skill-coverage.mjs +203 -203
  166. package/skills/v8-saas-multi-tenant/SKILL.md +219 -219
  167. package/skills/v8-security/SKILL.md +168 -168
  168. package/skills/v8-security/references/progressive-01-2-/346/235/203/351/231/220/346/240/241/351/252/214.md +198 -198
  169. package/skills/v8-security/references/progressive-02-7-/346/227/245/345/277/227/350/256/260/345/275/225.md +158 -158
  170. package/skills/v8-sql-query/SKILL.md +302 -302
  171. package/skills/v8-table-event/SKILL.md +144 -144
  172. 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
  173. 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
  174. package/skills/v8-tcp-integration/SKILL.md +147 -147
  175. package/skills/v8-tcp-integration/agents/openai.yaml +4 -4
  176. package/skills/v8-template-engine/SKILL.md +167 -167
  177. package/skills/v8-utilities/SKILL.md +90 -90
  178. package/skills/v8-utilities/references/client-api-index.md +143 -143
  179. package/skills/v8-utilities/references/platform-http-routes.md +83 -83
  180. package/skills/v8-utilities/references/server-api-index.md +188 -188
  181. package/skills/v8-workflow/SKILL.md +243 -243
  182. 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
  183. package/skills/vision-engine/SKILL.md +159 -159
  184. package/skills/vision-engine/agents/openai.yaml +4 -4
  185. package/skills/vision-engine/references/architecture-and-acceptance.md +194 -194
  186. package/skills/workspace-conventions/SKILL.md +261 -261
  187. 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
  188. 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
  189. 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,147 +1,147 @@
1
- ---
2
- name: v8-tcp-integration
3
- description: Microi 后端 V8 TCP 原始字节集成规范。用于通过 V8.Tcp.Send/SendAsync/SendAndReceive/SendAndReceiveAsync 连接网络小票机、串口服务器、PLC 或其它 TCP 设备,处理 Byte/Base64/Hex/Text 载荷、GBK/GB18030、超时、响应、幂等与出站安全。
4
- ---
5
-
6
- > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
-
8
- # Microi V8 TCP 原始字节集成
9
-
10
- 使用后端 `V8.Tcp` 完成一次性 TCP 连接、原始字节写入和可选的有界响应读取。典型场景是 RAW/JetDirect 9100 网络小票机、串口服务器和 PLC;具体协议帧、校验码与打印业务仍由接口引擎编排。
11
-
12
- 文档维护时,只在 `microi.doc/docs/doc/v8-engine/v8-server.md` 原位更新后端 API;不要新建重复页面,也不要手工维护英文文档。改变公共契约时同步后端源码/测试、Microi.Client Monaco 定义、Microi.Agent 类型与生成知识、AI Skill 镜像。
13
-
14
- ## 先判断是否适用
15
-
16
- | 需求 | 选择 |
17
- |---|---|
18
- | 后端向设备 TCP 端口发送原始字节 | `V8.Tcp` |
19
- | HTTP/HTTPS API | `V8.Http`,不要用 TCP 重写 HTTP |
20
- | RabbitMQ/MQTT | `V8.MQ` 或 MQTT 引擎 |
21
- | 浏览器/5+App 蓝牙或 SPP 打印 | 前端 `V8.Print`,读取 `v8-frontend-events/references/bluetooth-print.md` |
22
- | 长连接、TCP 服务端监听、TLS、自定义连接池 | 当前 `V8.Tcp` 不提供;设计独立网关/Worker |
23
-
24
- 平台已经提供可复用原子能力后,打印模板、设备选择、订单状态、幂等和审计优先写在接口引擎/表单事件;不要为单个打印业务再写 C# Controller。
25
-
26
- ## API 契约
27
-
28
- | 方法 | 行为 |
29
- |---|---|
30
- | `V8.Tcp.Send({...})` | 连接、发送、关闭,返回 `DosResult` |
31
- | `await V8.Tcp.SendAsync({...})` | 当前请求内异步发送 |
32
- | `V8.Tcp.SendAndReceive({...})` | 发送后读取响应,再关闭 |
33
- | `await V8.Tcp.SendAndReceiveAsync({...})` | 当前请求内异步发送并读取响应 |
34
-
35
- 必填目标参数:
36
-
37
- - `Host`:主机名或 IP;只允许主机,不传 `tcp://` URL。
38
- - `Port`:1-65535。
39
-
40
- 发送内容必须且只能选择一组:
41
-
42
- - `Bytes`(别名 `RawBytes`、`ByteArray`):每项为 0-255 的整数。
43
- - `ByteBase64`(别名 `BytesBase64`、`Base64`)。
44
- - `Hex`:允许空格、`0x`、`-`、`:`、逗号和下划线分隔。
45
- - `Text`:按 `Encoding` 编码。默认 `utf-8`,还支持 `ascii`、`gb18030`、`gbk/gb2312`、UTF-16/UTF-32 大小端。
46
-
47
- 边界参数:
48
-
49
- | 参数 | 默认 | 范围 |
50
- |---|---:|---:|
51
- | `ConnectTimeout` | 10 秒 | 1-120 秒 |
52
- | `SendTimeout` | 10 秒 | 1-120 秒 |
53
- | `ReceiveTimeout` | 3 秒 | 1-120 秒 |
54
- | `MaxReceiveBytes` | 65536 | 1-1048576 |
55
- | `NoDelay` | `true` | 布尔值 |
56
-
57
- 单次发送最多 4 MiB。`Send` 成功数据为 `{BytesSent, RemoteEndPoint}`。收发方法另有 `BytesReceived`、`RawBytes`、`ByteBase64`、`Hex`、`ReceiveEndReason`、`Truncated`;`ReceiveEndReason` 为 `RemoteClosed`、`Timeout` 或 `MaxReceiveBytes`。
58
-
59
- ## 实现流程
60
-
61
- ### 1. 固定并授权设备目标
62
-
63
- 从 SaaS 可信配置或受行权限保护的设备表读取 `Host`、`Port`,按当前用户/门店/租户决定可用设备,再与精确白名单比较。禁止这样写:
64
-
65
- ```javascript
66
- // 错误:匿名或普通调用者可扫描后端可达内网。
67
- return V8.Tcp.Send({
68
- Host: V8.Param.Host,
69
- Port: V8.Param.Port,
70
- Hex: V8.Param.Hex
71
- });
72
- ```
73
-
74
- ### 2. 形成一个完整帧
75
-
76
- ESC/POS、Modbus TCP 或设备私有协议的命令、正文和校验码应先合成一个完整字节载荷。不要为了拼帧而打开多次连接;包含中文和控制命令时,优先在可信后端/上游把完整帧编码为 `Bytes`、`ByteBase64` 或 `Hex`。
77
-
78
- ```javascript
79
- var result = V8.Tcp.Send({
80
- Host: '192.168.1.88', // 示例;生产从可信配置读取
81
- Port: 9100,
82
- Bytes: [
83
- 27, 64, // ESC @ 初始化
84
- 77, 105, 99, 114, 111, 105, 10,
85
- 10, 10,
86
- 29, 86, 0 // GS V 0 切纸
87
- ],
88
- ConnectTimeout: 5,
89
- SendTimeout: 5
90
- });
91
- if (result.Code !== 1) return result;
92
- ```
93
-
94
- 只有纯文本时可使用打印机常见编码:
95
-
96
- ```javascript
97
- var result = await V8.Tcp.SendAsync({
98
- Host: '192.168.1.88',
99
- Port: 9100,
100
- Text: '吾码小票\n合计:12.00\n\n',
101
- Encoding: 'gb18030'
102
- });
103
- if (result.Code !== 1) return result;
104
- ```
105
-
106
- ### 3. 需要协议响应时显式收取
107
-
108
- ```javascript
109
- var result = V8.Tcp.SendAndReceive({
110
- Host: '192.168.1.20',
111
- Port: 4001,
112
- Hex: '01 03 00 00 00 02 C4 0B',
113
- ReceiveTimeout: 3,
114
- MaxReceiveBytes: 4096
115
- });
116
- if (result.Code !== 1) return result;
117
-
118
- var bytes = result.Data.RawBytes;
119
- var hex = result.Data.Hex;
120
- ```
121
-
122
- 接收超时是整段接收的总时间。已收到部分数据后超时会返回成功和已有数据,并标记 `ReceiveEndReason='Timeout'`;未收到任何字节则失败。协议必须知道响应长度或结束条件,不能把超时默认当作完整帧。
123
-
124
- ### 4. 分开判断写入、设备执行和实物结果
125
-
126
- - `Code=1` 只表示字节已写入 TCP 连接。
127
- - 设备协议回执可证明设备接受/处理到哪一步,但仍不一定证明机械动作完成。
128
- - “小票已打印”需要打印机状态、设备回执或实物/硬件验收证据。
129
-
130
- 打印不是天然幂等。不确定失败时自动重试可能重复出纸;需要可靠打印时使用业务打印单号、设备回执、状态机以及 Job/MQ/outbox,且重试策略必须识别“尚未发送”和“结果未知”。
131
-
132
- ## 安全与运行约束
133
-
134
- 1. TCP 不经过 `V8.Http` 的 SSRF 防护。容器网络策略/防火墙只放行目标设备网段和端口;匿名接口不得暴露任意目标。
135
- 2. 不把票据正文、设备口令、原始帧和响应秘密写入日志;日志只记录脱敏设备标识、业务单号、字节数、耗时和错误分类。
136
- 3. `SendAsync` 只是在当前请求内等待 I/O,不能替代后台任务。不要遗留未等待 Promise、`setTimeout` 或 `Task.Run`。
137
- 4. 每次调用都会创建并关闭连接;不能假设设备会保持会话状态。
138
- 5. Docker 内的 `localhost` 指容器自身。验收前从实际后端容器验证到设备 IP/端口的路由和出站策略。
139
- 6. 载荷、超时和响应均有硬上限;不要通过拆成无限循环规避限制。
140
-
141
- ## 修改公共能力时的同步门禁
142
-
143
- - 源码:`Microi.Server/Microi.V8Engine/Extend/Tcp/V8Tcp.cs` 与 `V8Extend.cs`。
144
- - 测试:真实 Jint 注入、Byte/Base64/Hex/Text、回环收发、超时/上限/非法参数。
145
- - 编辑器:`Microi.Client/.../v8-api-server-definitions.js` 与 `Microi.Agent/src/editor/typingsManager.ts`。
146
- - 文档与知识:官网中文后端 V8 页面、`microi.skills/README.md`、`v8-utilities` 索引、`Microi.AI/Resource` 镜像和向量资源列表。
147
- - 验收:目标测试、后端构建、精确重启与健康检查、独立 TCP 回环;真实打印机出纸必须单独报告,不能用回环测试替代。
1
+ ---
2
+ name: v8-tcp-integration
3
+ description: Microi 后端 V8 TCP 原始字节集成规范。用于通过 V8.Tcp.Send/SendAsync/SendAndReceive/SendAndReceiveAsync 连接网络小票机、串口服务器、PLC 或其它 TCP 设备,处理 Byte/Base64/Hex/Text 载荷、GBK/GB18030、超时、响应、幂等与出站安全。
4
+ ---
5
+
6
+ > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
+
8
+ # Microi V8 TCP 原始字节集成
9
+
10
+ 使用后端 `V8.Tcp` 完成一次性 TCP 连接、原始字节写入和可选的有界响应读取。典型场景是 RAW/JetDirect 9100 网络小票机、串口服务器和 PLC;具体协议帧、校验码与打印业务仍由接口引擎编排。
11
+
12
+ 文档维护时,只在 `microi.doc/docs/doc/v8-engine/v8-server.md` 原位更新后端 API;不要新建重复页面,也不要手工维护英文文档。改变公共契约时同步后端源码/测试、Microi.Client Monaco 定义、Microi.Agent 类型与生成知识、AI Skill 镜像。
13
+
14
+ ## 先判断是否适用
15
+
16
+ | 需求 | 选择 |
17
+ |---|---|
18
+ | 后端向设备 TCP 端口发送原始字节 | `V8.Tcp` |
19
+ | HTTP/HTTPS API | `V8.Http`,不要用 TCP 重写 HTTP |
20
+ | RabbitMQ/MQTT | `V8.MQ` 或 MQTT 引擎 |
21
+ | 浏览器/5+App 蓝牙或 SPP 打印 | 前端 `V8.Print`,读取 `v8-frontend-events/references/bluetooth-print.md` |
22
+ | 长连接、TCP 服务端监听、TLS、自定义连接池 | 当前 `V8.Tcp` 不提供;设计独立网关/Worker |
23
+
24
+ 平台已经提供可复用原子能力后,打印模板、设备选择、订单状态、幂等和审计优先写在接口引擎/表单事件;不要为单个打印业务再写 C# Controller。
25
+
26
+ ## API 契约
27
+
28
+ | 方法 | 行为 |
29
+ |---|---|
30
+ | `V8.Tcp.Send({...})` | 连接、发送、关闭,返回 `DosResult` |
31
+ | `await V8.Tcp.SendAsync({...})` | 当前请求内异步发送 |
32
+ | `V8.Tcp.SendAndReceive({...})` | 发送后读取响应,再关闭 |
33
+ | `await V8.Tcp.SendAndReceiveAsync({...})` | 当前请求内异步发送并读取响应 |
34
+
35
+ 必填目标参数:
36
+
37
+ - `Host`:主机名或 IP;只允许主机,不传 `tcp://` URL。
38
+ - `Port`:1-65535。
39
+
40
+ 发送内容必须且只能选择一组:
41
+
42
+ - `Bytes`(别名 `RawBytes`、`ByteArray`):每项为 0-255 的整数。
43
+ - `ByteBase64`(别名 `BytesBase64`、`Base64`)。
44
+ - `Hex`:允许空格、`0x`、`-`、`:`、逗号和下划线分隔。
45
+ - `Text`:按 `Encoding` 编码。默认 `utf-8`,还支持 `ascii`、`gb18030`、`gbk/gb2312`、UTF-16/UTF-32 大小端。
46
+
47
+ 边界参数:
48
+
49
+ | 参数 | 默认 | 范围 |
50
+ |---|---:|---:|
51
+ | `ConnectTimeout` | 10 秒 | 1-120 秒 |
52
+ | `SendTimeout` | 10 秒 | 1-120 秒 |
53
+ | `ReceiveTimeout` | 3 秒 | 1-120 秒 |
54
+ | `MaxReceiveBytes` | 65536 | 1-1048576 |
55
+ | `NoDelay` | `true` | 布尔值 |
56
+
57
+ 单次发送最多 4 MiB。`Send` 成功数据为 `{BytesSent, RemoteEndPoint}`。收发方法另有 `BytesReceived`、`RawBytes`、`ByteBase64`、`Hex`、`ReceiveEndReason`、`Truncated`;`ReceiveEndReason` 为 `RemoteClosed`、`Timeout` 或 `MaxReceiveBytes`。
58
+
59
+ ## 实现流程
60
+
61
+ ### 1. 固定并授权设备目标
62
+
63
+ 从 SaaS 可信配置或受行权限保护的设备表读取 `Host`、`Port`,按当前用户/门店/租户决定可用设备,再与精确白名单比较。禁止这样写:
64
+
65
+ ```javascript
66
+ // 错误:匿名或普通调用者可扫描后端可达内网。
67
+ return V8.Tcp.Send({
68
+ Host: V8.Param.Host,
69
+ Port: V8.Param.Port,
70
+ Hex: V8.Param.Hex
71
+ });
72
+ ```
73
+
74
+ ### 2. 形成一个完整帧
75
+
76
+ ESC/POS、Modbus TCP 或设备私有协议的命令、正文和校验码应先合成一个完整字节载荷。不要为了拼帧而打开多次连接;包含中文和控制命令时,优先在可信后端/上游把完整帧编码为 `Bytes`、`ByteBase64` 或 `Hex`。
77
+
78
+ ```javascript
79
+ var result = V8.Tcp.Send({
80
+ Host: '192.168.1.88', // 示例;生产从可信配置读取
81
+ Port: 9100,
82
+ Bytes: [
83
+ 27, 64, // ESC @ 初始化
84
+ 77, 105, 99, 114, 111, 105, 10,
85
+ 10, 10,
86
+ 29, 86, 0 // GS V 0 切纸
87
+ ],
88
+ ConnectTimeout: 5,
89
+ SendTimeout: 5
90
+ });
91
+ if (result.Code !== 1) return result;
92
+ ```
93
+
94
+ 只有纯文本时可使用打印机常见编码:
95
+
96
+ ```javascript
97
+ var result = await V8.Tcp.SendAsync({
98
+ Host: '192.168.1.88',
99
+ Port: 9100,
100
+ Text: '吾码小票\n合计:12.00\n\n',
101
+ Encoding: 'gb18030'
102
+ });
103
+ if (result.Code !== 1) return result;
104
+ ```
105
+
106
+ ### 3. 需要协议响应时显式收取
107
+
108
+ ```javascript
109
+ var result = V8.Tcp.SendAndReceive({
110
+ Host: '192.168.1.20',
111
+ Port: 4001,
112
+ Hex: '01 03 00 00 00 02 C4 0B',
113
+ ReceiveTimeout: 3,
114
+ MaxReceiveBytes: 4096
115
+ });
116
+ if (result.Code !== 1) return result;
117
+
118
+ var bytes = result.Data.RawBytes;
119
+ var hex = result.Data.Hex;
120
+ ```
121
+
122
+ 接收超时是整段接收的总时间。已收到部分数据后超时会返回成功和已有数据,并标记 `ReceiveEndReason='Timeout'`;未收到任何字节则失败。协议必须知道响应长度或结束条件,不能把超时默认当作完整帧。
123
+
124
+ ### 4. 分开判断写入、设备执行和实物结果
125
+
126
+ - `Code=1` 只表示字节已写入 TCP 连接。
127
+ - 设备协议回执可证明设备接受/处理到哪一步,但仍不一定证明机械动作完成。
128
+ - “小票已打印”需要打印机状态、设备回执或实物/硬件验收证据。
129
+
130
+ 打印不是天然幂等。不确定失败时自动重试可能重复出纸;需要可靠打印时使用业务打印单号、设备回执、状态机以及 Job/MQ/outbox,且重试策略必须识别“尚未发送”和“结果未知”。
131
+
132
+ ## 安全与运行约束
133
+
134
+ 1. TCP 不经过 `V8.Http` 的 SSRF 防护。容器网络策略/防火墙只放行目标设备网段和端口;匿名接口不得暴露任意目标。
135
+ 2. 不把票据正文、设备口令、原始帧和响应秘密写入日志;日志只记录脱敏设备标识、业务单号、字节数、耗时和错误分类。
136
+ 3. `SendAsync` 只是在当前请求内等待 I/O,不能替代后台任务。不要遗留未等待 Promise、`setTimeout` 或 `Task.Run`。
137
+ 4. 每次调用都会创建并关闭连接;不能假设设备会保持会话状态。
138
+ 5. Docker 内的 `localhost` 指容器自身。验收前从实际后端容器验证到设备 IP/端口的路由和出站策略。
139
+ 6. 载荷、超时和响应均有硬上限;不要通过拆成无限循环规避限制。
140
+
141
+ ## 修改公共能力时的同步门禁
142
+
143
+ - 源码:`Microi.Server/Microi.V8Engine/Extend/Tcp/V8Tcp.cs` 与 `V8Extend.cs`。
144
+ - 测试:真实 Jint 注入、Byte/Base64/Hex/Text、回环收发、超时/上限/非法参数。
145
+ - 编辑器:`Microi.Client/.../v8-api-server-definitions.js` 与 `Microi.Agent/src/editor/typingsManager.ts`。
146
+ - 文档与知识:官网中文后端 V8 页面、`microi.skills/README.md`、`v8-utilities` 索引、`Microi.AI/Resource` 镜像和向量资源列表。
147
+ - 验收:目标测试、后端构建、精确重启与健康检查、独立 TCP 回环;真实打印机出纸必须单独报告,不能用回环测试替代。
@@ -1,4 +1,4 @@
1
- interface:
2
- display_name: "V8 TCP 原始字节"
3
- short_description: "通过后端 V8 安全发送和接收 TCP 原始字节数据"
4
- default_prompt: "使用 $v8-tcp-integration 编写一个安全、可验证的 Microi 后端 V8 TCP 设备集成。"
1
+ interface:
2
+ display_name: "V8 TCP 原始字节"
3
+ short_description: "通过后端 V8 安全发送和接收 TCP 原始字节数据"
4
+ default_prompt: "使用 $v8-tcp-integration 编写一个安全、可验证的 Microi 后端 V8 TCP 设备集成。"
@@ -1,167 +1,167 @@
1
- ---
2
- name: v8-template-engine
3
- description: Microi V8 模板引擎指南。用于编写表格/表单模板渲染、V8.Result HTML/text 输出、行格式化、徽章、图片和自定义显示逻辑。
4
- ---
5
-
6
- > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
-
8
- # Microi V8 模板引擎(表格/表单 V8 模板)
9
-
10
- 你正在为 Microi 吾码平台编写 **表格 V8 模板引擎**、**表单 V8 模板引擎** 代码。模板引擎用于在数据渲染后自定义最终展示效果(颜色、徽章、图片、HTML),是表单引擎的高级特性。
11
-
12
- ## 核心规则
13
-
14
- - 模板引擎绑定在【表单属性】的【表格 V8 模板引擎】或【表单 V8 模板引擎】
15
- - 通过给 `V8.Result` 赋值字符串(HTML 或纯文本)来控制最终渲染结果
16
- - 在 **表格模板** 中:每行数据都会执行一次,`V8.Form` 是当前行数据
17
- - 注意:`V8.Form` 此时只能访问到【模块引擎】配置的【查询列】字段;若查询列为空则可访问全部字段
18
- - 支持 `bootstrap`、`element-ui` 样式类名
19
- - `V8.EventName` 可能为 `TableTemplateEngine` 或 `FormTemplateEngine`
20
- - 表格模板同步执行,输出优先级是 `V8.Result` → JavaScript `return` → 原字段值;表单模板异步执行并以 `V8.Result` 为输出
21
- - 模板结果通过 `v-safe-html`/DOMPurify 净化。`script`、`iframe`、`on*` 事件属性、`javascript:` 等危险内容会被剥离,禁止依赖内联点击事件
22
- - 业务文本必须 HTML 转义后再拼接;权限、校验、状态写入等业务逻辑必须放后端
23
-
24
- 模板中需要拼 HTML 时,先定义安全转义函数:
25
-
26
- ```javascript
27
- var escapeHtml = function (value) {
28
- return String(value == null ? '' : value)
29
- .replace(/&/g, '&')
30
- .replace(/</g, '&lt;')
31
- .replace(/>/g, '&gt;')
32
- .replace(/"/g, '&quot;')
33
- .replace(/'/g, '&#39;');
34
- };
35
- ```
36
-
37
- ## 状态徽章(Bootstrap 样式)
38
-
39
- ```javascript
40
- var value = V8.Form.Zhuangtai;
41
- if (V8.IsNull(value)) {
42
- V8.Result = '';
43
- } else {
44
- var classStr = 'badge-primary';
45
- if (value === '禁用') classStr = 'badge-danger';
46
- else if (value === '未通过') classStr = 'badge-warning';
47
- else if (value === '待审核') classStr = 'badge-info';
48
- else if (value === '通过') classStr = 'badge-success';
49
- V8.Result = '<span class="badge badge-pill ' + classStr + '">' + escapeHtml(value) + '</span>';
50
- }
51
- ```
52
-
53
- 可用 Bootstrap 徽章类:`badge-primary`, `badge-secondary`, `badge-success`, `badge-danger`, `badge-warning`, `badge-info`, `badge-light`, `badge-dark`
54
-
55
- ## 内联样式(颜色高亮)
56
-
57
- ```javascript
58
- // 不同业务状态显示不同字体颜色
59
- if (V8.Form.XuqiuLX === '合并') {
60
- V8.Result = '<span style="color:blue;">' + escapeHtml(V8.Form.XuqiuDDH) + '</span>';
61
- } else if (V8.Form.HebingID) {
62
- V8.Result = '<span style="color:#999;">' + escapeHtml(V8.Form.XuqiuDDH) + '</span>';
63
- } else {
64
- V8.Result = escapeHtml(V8.Form.XuqiuDDH);
65
- }
66
- ```
67
-
68
- ## 单图列渲染
69
-
70
- ```javascript
71
- var html = '';
72
- var fileServer = V8.SysConfig.FileServer;
73
- if (!V8.IsNull(V8.Form.GongsiLOGO)) {
74
- html = '<img src="' + escapeHtml(fileServer + V8.Form.GongsiLOGO) + '" '
75
- + 'alt="公司Logo" '
76
- + 'style="height:40px;width:40px;object-fit:cover;margin:5px 0;" />';
77
- }
78
- V8.Result = html;
79
- ```
80
-
81
- ## 多图列渲染(带点击放大)
82
-
83
- ```javascript
84
- var html = '';
85
- var fileServer = V8.SysConfig.FileServer;
86
- if (!V8.IsNull(V8.Form.TupianMS) && V8.Form.TupianMS.indexOf('[') !== -1) {
87
- var imgs = JSON.parse(V8.Form.TupianMS);
88
- imgs.forEach(function(item) {
89
- var url = escapeHtml(fileServer + item.Path);
90
- html += '<a href="' + url + '" target="_blank" rel="noopener noreferrer">'
91
- + '<img src="' + url + '" alt="图片" '
92
- + 'style="width:40px;height:40px;object-fit:cover;margin:5px 5px 5px 0;" />'
93
- + '</a>';
94
- });
95
- }
96
- V8.Result = html;
97
- ```
98
-
99
- ## 进度条渲染
100
-
101
- ```javascript
102
- var percent = V8.Form.Progress || 0;
103
- var color = '#67C23A';
104
- if (percent < 30) color = '#F56C6C';
105
- else if (percent < 70) color = '#E6A23C';
106
-
107
- V8.Result =
108
- '<div style="width:100%;background:#eee;border-radius:4px;height:16px;position:relative;">'
109
- + '<div style="width:' + percent + '%;background:' + color + ';height:100%;border-radius:4px;"></div>'
110
- + '<span style="position:absolute;left:50%;top:0;transform:translateX(-50%);color:#333;font-size:12px;line-height:16px;">' + percent + '%</span>'
111
- + '</div>';
112
- ```
113
-
114
- ## 多字段合并显示
115
-
116
- ```javascript
117
- // 联系人姓名 + 电话脱敏
118
- var name = V8.Form.LianxiR || '';
119
- var phone = V8.Form.LianxiPhone || '';
120
- if (phone.length === 11) phone = phone.substring(0, 3) + '****' + phone.substring(7);
121
- V8.Result = '<div><b>' + escapeHtml(name) + '</b><br/><small style="color:#999;">'
122
- + escapeHtml(phone) + '</small></div>';
123
- ```
124
-
125
- 模块引擎已有更轻量的声明式方案:`ViewSchema.Layout.List.Columns` 可用 `Field + Lines +
126
- TrailingFields` 组成多行列,`Layout.Card` 可配置移动端顶部、右侧、正文、元信息和底部字段。
127
- 仅需要多字段排版、图标、`Tone/Color/Prefix/Suffix` 时优先使用声明式配置;需要复杂条件
128
- HTML 时再给被引用的 `diy_field` 配置 `V8TmpEngineTable`。两种方式都会复用净化后的模板
129
- 结果,且所有引用字段仍必须在模块查询列或 `_SelectFields` 中。
130
-
131
- ## 条件性图标
132
-
133
- ```javascript
134
- var html = escapeHtml(V8.Form.Title || '');
135
- if (V8.Form.IsHot === 1) html += ' <i class="fas fa-fire" style="color:#F56C6C;"></i>';
136
- if (V8.Form.IsNew === 1) html += ' <span class="badge badge-danger">NEW</span>';
137
- V8.Result = html;
138
- ```
139
-
140
- ## 与字段值变更事件配合(动态计算)
141
-
142
- ```javascript
143
- // 表格模板中根据多个字段计算
144
- var price = parseFloat(V8.Form.Price) || 0;
145
- var discount = parseFloat(V8.Form.Discount) || 1;
146
- var total = (price * discount).toFixed(2);
147
- var color = total > 1000 ? '#F56C6C' : '#67C23A';
148
- V8.Result = '<span style="color:' + color + ';font-weight:bold;">¥' + total + '</span>';
149
- ```
150
-
151
- ## 常见错误
152
-
153
- ❌ 不要在模板中调用 `V8.FormEngine`(每行都查 → N+1 性能问题);需要关联数据时在查询列、接口引擎或后端 `DataFilterV8` 预取,只有 `DataFilterV8` 才提供 `V8.CacheData`
154
- ❌ 不要依赖对象/数组的隐式字符串化;`V8.Result` 建议显式输出字符串
155
- ❌ 模板中 `V8.Form` 默认只有【查询列】字段;缺字段就要去模块引擎补查询列
156
- ❌ 不要在模板里写复杂业务逻辑(应放到接口引擎或 DataFilterV8)
157
- ❌ 不要输出 `onclick/onerror`、`script/iframe` 或 `javascript:` URL;DOMPurify 会剥离这些内容
158
-
159
- ## 与 DataFilterV8 的区别
160
-
161
- | | DataFilterV8(后端) | 模板引擎(前端) |
162
- |---|---|---|
163
- | 运行端 | 服务器 | 浏览器 |
164
- | 用途 | 加工数据、脱敏、补字段 | 渲染 HTML 样式 |
165
- | 输出 | `V8.Form.字段 = ...` | `V8.Result = '<html>...</html>'` |
166
- | 字段范围 | 全部数据 | 仅查询列 |
167
- | 性能 | 每行执行(可用 `V8.CacheData`) | 浏览器渲染时执行 |
1
+ ---
2
+ name: v8-template-engine
3
+ description: Microi V8 模板引擎指南。用于编写表格/表单模板渲染、V8.Result HTML/text 输出、行格式化、徽章、图片和自定义显示逻辑。
4
+ ---
5
+
6
+ > **Codex 非阻塞自动更新:** 当前宿主为 Codex 时,吾码 CLI、Codex 插件与工作区 AI/MCP 由后台自动更新;需要诊断时读取 `../microi-codex-installer/SKILL.md`。更新失败、等待空闲或尚未重载均不得阻断当前、正在进行或新建任务。非 Codex 宿主跳过此项。
7
+
8
+ # Microi V8 模板引擎(表格/表单 V8 模板)
9
+
10
+ 你正在为 Microi 吾码平台编写 **表格 V8 模板引擎**、**表单 V8 模板引擎** 代码。模板引擎用于在数据渲染后自定义最终展示效果(颜色、徽章、图片、HTML),是表单引擎的高级特性。
11
+
12
+ ## 核心规则
13
+
14
+ - 模板引擎绑定在【表单属性】的【表格 V8 模板引擎】或【表单 V8 模板引擎】
15
+ - 通过给 `V8.Result` 赋值字符串(HTML 或纯文本)来控制最终渲染结果
16
+ - 在 **表格模板** 中:每行数据都会执行一次,`V8.Form` 是当前行数据
17
+ - 注意:`V8.Form` 此时只能访问到【模块引擎】配置的【查询列】字段;若查询列为空则可访问全部字段
18
+ - 支持 `bootstrap`、`element-ui` 样式类名
19
+ - `V8.EventName` 可能为 `TableTemplateEngine` 或 `FormTemplateEngine`
20
+ - 表格模板同步执行,输出优先级是 `V8.Result` → JavaScript `return` → 原字段值;表单模板异步执行并以 `V8.Result` 为输出
21
+ - 模板结果通过 `v-safe-html`/DOMPurify 净化。`script`、`iframe`、`on*` 事件属性、`javascript:` 等危险内容会被剥离,禁止依赖内联点击事件
22
+ - 业务文本必须 HTML 转义后再拼接;权限、校验、状态写入等业务逻辑必须放后端
23
+
24
+ 模板中需要拼 HTML 时,先定义安全转义函数:
25
+
26
+ ```javascript
27
+ var escapeHtml = function (value) {
28
+ return String(value == null ? '' : value)
29
+ .replace(/&/g, '&amp;')
30
+ .replace(/</g, '&lt;')
31
+ .replace(/>/g, '&gt;')
32
+ .replace(/"/g, '&quot;')
33
+ .replace(/'/g, '&#39;');
34
+ };
35
+ ```
36
+
37
+ ## 状态徽章(Bootstrap 样式)
38
+
39
+ ```javascript
40
+ var value = V8.Form.Zhuangtai;
41
+ if (V8.IsNull(value)) {
42
+ V8.Result = '';
43
+ } else {
44
+ var classStr = 'badge-primary';
45
+ if (value === '禁用') classStr = 'badge-danger';
46
+ else if (value === '未通过') classStr = 'badge-warning';
47
+ else if (value === '待审核') classStr = 'badge-info';
48
+ else if (value === '通过') classStr = 'badge-success';
49
+ V8.Result = '<span class="badge badge-pill ' + classStr + '">' + escapeHtml(value) + '</span>';
50
+ }
51
+ ```
52
+
53
+ 可用 Bootstrap 徽章类:`badge-primary`, `badge-secondary`, `badge-success`, `badge-danger`, `badge-warning`, `badge-info`, `badge-light`, `badge-dark`
54
+
55
+ ## 内联样式(颜色高亮)
56
+
57
+ ```javascript
58
+ // 不同业务状态显示不同字体颜色
59
+ if (V8.Form.XuqiuLX === '合并') {
60
+ V8.Result = '<span style="color:blue;">' + escapeHtml(V8.Form.XuqiuDDH) + '</span>';
61
+ } else if (V8.Form.HebingID) {
62
+ V8.Result = '<span style="color:#999;">' + escapeHtml(V8.Form.XuqiuDDH) + '</span>';
63
+ } else {
64
+ V8.Result = escapeHtml(V8.Form.XuqiuDDH);
65
+ }
66
+ ```
67
+
68
+ ## 单图列渲染
69
+
70
+ ```javascript
71
+ var html = '';
72
+ var fileServer = V8.SysConfig.FileServer;
73
+ if (!V8.IsNull(V8.Form.GongsiLOGO)) {
74
+ html = '<img src="' + escapeHtml(fileServer + V8.Form.GongsiLOGO) + '" '
75
+ + 'alt="公司Logo" '
76
+ + 'style="height:40px;width:40px;object-fit:cover;margin:5px 0;" />';
77
+ }
78
+ V8.Result = html;
79
+ ```
80
+
81
+ ## 多图列渲染(带点击放大)
82
+
83
+ ```javascript
84
+ var html = '';
85
+ var fileServer = V8.SysConfig.FileServer;
86
+ if (!V8.IsNull(V8.Form.TupianMS) && V8.Form.TupianMS.indexOf('[') !== -1) {
87
+ var imgs = JSON.parse(V8.Form.TupianMS);
88
+ imgs.forEach(function(item) {
89
+ var url = escapeHtml(fileServer + item.Path);
90
+ html += '<a href="' + url + '" target="_blank" rel="noopener noreferrer">'
91
+ + '<img src="' + url + '" alt="图片" '
92
+ + 'style="width:40px;height:40px;object-fit:cover;margin:5px 5px 5px 0;" />'
93
+ + '</a>';
94
+ });
95
+ }
96
+ V8.Result = html;
97
+ ```
98
+
99
+ ## 进度条渲染
100
+
101
+ ```javascript
102
+ var percent = V8.Form.Progress || 0;
103
+ var color = '#67C23A';
104
+ if (percent < 30) color = '#F56C6C';
105
+ else if (percent < 70) color = '#E6A23C';
106
+
107
+ V8.Result =
108
+ '<div style="width:100%;background:#eee;border-radius:4px;height:16px;position:relative;">'
109
+ + '<div style="width:' + percent + '%;background:' + color + ';height:100%;border-radius:4px;"></div>'
110
+ + '<span style="position:absolute;left:50%;top:0;transform:translateX(-50%);color:#333;font-size:12px;line-height:16px;">' + percent + '%</span>'
111
+ + '</div>';
112
+ ```
113
+
114
+ ## 多字段合并显示
115
+
116
+ ```javascript
117
+ // 联系人姓名 + 电话脱敏
118
+ var name = V8.Form.LianxiR || '';
119
+ var phone = V8.Form.LianxiPhone || '';
120
+ if (phone.length === 11) phone = phone.substring(0, 3) + '****' + phone.substring(7);
121
+ V8.Result = '<div><b>' + escapeHtml(name) + '</b><br/><small style="color:#999;">'
122
+ + escapeHtml(phone) + '</small></div>';
123
+ ```
124
+
125
+ 模块引擎已有更轻量的声明式方案:`ViewSchema.Layout.List.Columns` 可用 `Field + Lines +
126
+ TrailingFields` 组成多行列,`Layout.Card` 可配置移动端顶部、右侧、正文、元信息和底部字段。
127
+ 仅需要多字段排版、图标、`Tone/Color/Prefix/Suffix` 时优先使用声明式配置;需要复杂条件
128
+ HTML 时再给被引用的 `diy_field` 配置 `V8TmpEngineTable`。两种方式都会复用净化后的模板
129
+ 结果,且所有引用字段仍必须在模块查询列或 `_SelectFields` 中。
130
+
131
+ ## 条件性图标
132
+
133
+ ```javascript
134
+ var html = escapeHtml(V8.Form.Title || '');
135
+ if (V8.Form.IsHot === 1) html += ' <i class="fas fa-fire" style="color:#F56C6C;"></i>';
136
+ if (V8.Form.IsNew === 1) html += ' <span class="badge badge-danger">NEW</span>';
137
+ V8.Result = html;
138
+ ```
139
+
140
+ ## 与字段值变更事件配合(动态计算)
141
+
142
+ ```javascript
143
+ // 表格模板中根据多个字段计算
144
+ var price = parseFloat(V8.Form.Price) || 0;
145
+ var discount = parseFloat(V8.Form.Discount) || 1;
146
+ var total = (price * discount).toFixed(2);
147
+ var color = total > 1000 ? '#F56C6C' : '#67C23A';
148
+ V8.Result = '<span style="color:' + color + ';font-weight:bold;">¥' + total + '</span>';
149
+ ```
150
+
151
+ ## 常见错误
152
+
153
+ ❌ 不要在模板中调用 `V8.FormEngine`(每行都查 → N+1 性能问题);需要关联数据时在查询列、接口引擎或后端 `DataFilterV8` 预取,只有 `DataFilterV8` 才提供 `V8.CacheData`
154
+ ❌ 不要依赖对象/数组的隐式字符串化;`V8.Result` 建议显式输出字符串
155
+ ❌ 模板中 `V8.Form` 默认只有【查询列】字段;缺字段就要去模块引擎补查询列
156
+ ❌ 不要在模板里写复杂业务逻辑(应放到接口引擎或 DataFilterV8)
157
+ ❌ 不要输出 `onclick/onerror`、`script/iframe` 或 `javascript:` URL;DOMPurify 会剥离这些内容
158
+
159
+ ## 与 DataFilterV8 的区别
160
+
161
+ | | DataFilterV8(后端) | 模板引擎(前端) |
162
+ |---|---|---|
163
+ | 运行端 | 服务器 | 浏览器 |
164
+ | 用途 | 加工数据、脱敏、补字段 | 渲染 HTML 样式 |
165
+ | 输出 | `V8.Form.字段 = ...` | `V8.Result = '<html>...</html>'` |
166
+ | 字段范围 | 全部数据 | 仅查询列 |
167
+ | 性能 | 每行执行(可用 `V8.CacheData`) | 浏览器渲染时执行 |