weaver-e10-builder 1.5.16 → 1.6.4

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 (232) hide show
  1. package/dist/commands/auth.d.ts.map +1 -1
  2. package/dist/commands/auth.js +4 -2
  3. package/dist/commands/auth.js.map +1 -1
  4. package/dist/commands/check.d.ts.map +1 -1
  5. package/dist/commands/check.js +109 -51
  6. package/dist/commands/check.js.map +1 -1
  7. package/dist/commands/form-attachment-setting.d.ts +3 -0
  8. package/dist/commands/form-attachment-setting.d.ts.map +1 -0
  9. package/dist/commands/form-attachment-setting.js +422 -0
  10. package/dist/commands/form-attachment-setting.js.map +1 -0
  11. package/dist/commands/form-data.d.ts.map +1 -1
  12. package/dist/commands/form-data.js +49 -1
  13. package/dist/commands/form-data.js.map +1 -1
  14. package/dist/commands/form-ebuilder-scope.d.ts +21 -0
  15. package/dist/commands/form-ebuilder-scope.d.ts.map +1 -1
  16. package/dist/commands/form-ebuilder-scope.js +41 -8
  17. package/dist/commands/form-ebuilder-scope.js.map +1 -1
  18. package/dist/commands/form-field-linkage.d.ts +6 -1
  19. package/dist/commands/form-field-linkage.d.ts.map +1 -1
  20. package/dist/commands/form-field-linkage.js +138 -31
  21. package/dist/commands/form-field-linkage.js.map +1 -1
  22. package/dist/commands/form-layout-code-reviewed.d.ts +3 -0
  23. package/dist/commands/form-layout-code-reviewed.d.ts.map +1 -0
  24. package/dist/commands/form-layout-code-reviewed.js +61 -0
  25. package/dist/commands/form-layout-code-reviewed.js.map +1 -0
  26. package/dist/commands/form-layout-describe.d.ts +3 -0
  27. package/dist/commands/form-layout-describe.d.ts.map +1 -0
  28. package/dist/commands/form-layout-describe.js +58 -0
  29. package/dist/commands/form-layout-describe.js.map +1 -0
  30. package/dist/commands/form-layout-diff.d.ts +3 -0
  31. package/dist/commands/form-layout-diff.d.ts.map +1 -0
  32. package/dist/commands/form-layout-diff.js +48 -0
  33. package/dist/commands/form-layout-diff.js.map +1 -0
  34. package/dist/commands/form-layout-document.d.ts +3 -0
  35. package/dist/commands/form-layout-document.d.ts.map +1 -0
  36. package/dist/commands/form-layout-document.js +81 -0
  37. package/dist/commands/form-layout-document.js.map +1 -0
  38. package/dist/commands/form-layout-edit.d.ts +3 -0
  39. package/dist/commands/form-layout-edit.d.ts.map +1 -0
  40. package/dist/commands/form-layout-edit.js +51 -0
  41. package/dist/commands/form-layout-edit.js.map +1 -0
  42. package/dist/commands/form-layout-init-reviewed.d.ts +3 -0
  43. package/dist/commands/form-layout-init-reviewed.d.ts.map +1 -0
  44. package/dist/commands/form-layout-init-reviewed.js +78 -0
  45. package/dist/commands/form-layout-init-reviewed.js.map +1 -0
  46. package/dist/commands/form-layout-restore.d.ts.map +1 -1
  47. package/dist/commands/form-layout-restore.js +23 -0
  48. package/dist/commands/form-layout-restore.js.map +1 -1
  49. package/dist/commands/form-layout-template-catalog.d.ts +3 -0
  50. package/dist/commands/form-layout-template-catalog.d.ts.map +1 -0
  51. package/dist/commands/form-layout-template-catalog.js +45 -0
  52. package/dist/commands/form-layout-template-catalog.js.map +1 -0
  53. package/dist/commands/form.d.ts.map +1 -1
  54. package/dist/commands/form.js +80 -5
  55. package/dist/commands/form.js.map +1 -1
  56. package/dist/commands/project.d.ts.map +1 -1
  57. package/dist/commands/project.js +39 -6
  58. package/dist/commands/project.js.map +1 -1
  59. package/dist/index.js +15 -0
  60. package/dist/index.js.map +1 -1
  61. package/dist/services/actionflow/components/action_eb_add.d.ts.map +1 -1
  62. package/dist/services/actionflow/components/action_eb_add.js +12 -5
  63. package/dist/services/actionflow/components/action_eb_add.js.map +1 -1
  64. package/dist/services/actionflow/components/action_eb_add_compiler.d.ts.map +1 -1
  65. package/dist/services/actionflow/components/action_eb_add_compiler.js +5 -0
  66. package/dist/services/actionflow/components/action_eb_add_compiler.js.map +1 -1
  67. package/dist/services/actionflow/components/action_eb_delete.d.ts +6 -1
  68. package/dist/services/actionflow/components/action_eb_delete.d.ts.map +1 -1
  69. package/dist/services/actionflow/components/action_eb_delete.js +23 -5
  70. package/dist/services/actionflow/components/action_eb_delete.js.map +1 -1
  71. package/dist/services/actionflow/components/action_eb_delete_compiler.d.ts.map +1 -1
  72. package/dist/services/actionflow/components/action_eb_delete_compiler.js +22 -0
  73. package/dist/services/actionflow/components/action_eb_delete_compiler.js.map +1 -1
  74. package/dist/services/actionflow/components/action_eb_update.d.ts.map +1 -1
  75. package/dist/services/actionflow/components/action_eb_update.js +13 -4
  76. package/dist/services/actionflow/components/action_eb_update.js.map +1 -1
  77. package/dist/services/actionflow/components/action_eb_update_compiler.d.ts.map +1 -1
  78. package/dist/services/actionflow/components/action_eb_update_compiler.js +9 -2
  79. package/dist/services/actionflow/components/action_eb_update_compiler.js.map +1 -1
  80. package/dist/services/actionflow/components/date_trigger.js +2 -2
  81. package/dist/services/actionflow/components/date_trigger.js.map +1 -1
  82. package/dist/services/actionflow/components/enquiry_form.d.ts.map +1 -1
  83. package/dist/services/actionflow/components/enquiry_form.js +11 -10
  84. package/dist/services/actionflow/components/enquiry_form.js.map +1 -1
  85. package/dist/services/actionflow/components/event_button.js +1 -1
  86. package/dist/services/actionflow/components/event_button.js.map +1 -1
  87. package/dist/services/actionflow/components/form_data_builder.d.ts +29 -1
  88. package/dist/services/actionflow/components/form_data_builder.d.ts.map +1 -1
  89. package/dist/services/actionflow/components/form_data_builder.js +67 -3
  90. package/dist/services/actionflow/components/form_data_builder.js.map +1 -1
  91. package/dist/services/actionflow/components/time_batch_trigger.js +2 -2
  92. package/dist/services/actionflow/components/time_batch_trigger.js.map +1 -1
  93. package/dist/services/actionflow/form_source.d.ts +44 -1
  94. package/dist/services/actionflow/form_source.d.ts.map +1 -1
  95. package/dist/services/actionflow/form_source.js +231 -5
  96. package/dist/services/actionflow/form_source.js.map +1 -1
  97. package/dist/services/actionflow/preflight_service.d.ts +8 -0
  98. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  99. package/dist/services/actionflow/preflight_service.js +120 -14
  100. package/dist/services/actionflow/preflight_service.js.map +1 -1
  101. package/dist/services/actionflow/system_params.d.ts.map +1 -1
  102. package/dist/services/actionflow/system_params.js +4 -1
  103. package/dist/services/actionflow/system_params.js.map +1 -1
  104. package/dist/services/actionflow/trigger_common.d.ts.map +1 -1
  105. package/dist/services/actionflow/trigger_common.js +12 -3
  106. package/dist/services/actionflow/trigger_common.js.map +1 -1
  107. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  108. package/dist/services/actionflow/workflow_compiler.js +117 -40
  109. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  110. package/dist/services/form-attachment-settings.d.ts +110 -0
  111. package/dist/services/form-attachment-settings.d.ts.map +1 -0
  112. package/dist/services/form-attachment-settings.js +332 -0
  113. package/dist/services/form-attachment-settings.js.map +1 -0
  114. package/dist/services/form-attachment-upload.d.ts +30 -0
  115. package/dist/services/form-attachment-upload.d.ts.map +1 -0
  116. package/dist/services/form-attachment-upload.js +76 -0
  117. package/dist/services/form-attachment-upload.js.map +1 -0
  118. package/dist/services/form-data-openapi.d.ts +2 -0
  119. package/dist/services/form-data-openapi.d.ts.map +1 -1
  120. package/dist/services/form-data-openapi.js +1 -0
  121. package/dist/services/form-data-openapi.js.map +1 -1
  122. package/dist/services/form-layout-code-reviewed.d.ts +32 -0
  123. package/dist/services/form-layout-code-reviewed.d.ts.map +1 -0
  124. package/dist/services/form-layout-code-reviewed.js +101 -0
  125. package/dist/services/form-layout-code-reviewed.js.map +1 -0
  126. package/dist/services/form-layout-describe.d.ts +4 -0
  127. package/dist/services/form-layout-describe.d.ts.map +1 -0
  128. package/dist/services/form-layout-describe.js +107 -0
  129. package/dist/services/form-layout-describe.js.map +1 -0
  130. package/dist/services/form-layout-diff.d.ts +37 -0
  131. package/dist/services/form-layout-diff.d.ts.map +1 -0
  132. package/dist/services/form-layout-diff.js +232 -0
  133. package/dist/services/form-layout-diff.js.map +1 -0
  134. package/dist/services/form-layout-document-apply.d.ts +23 -0
  135. package/dist/services/form-layout-document-apply.d.ts.map +1 -0
  136. package/dist/services/form-layout-document-apply.js +82 -0
  137. package/dist/services/form-layout-document-apply.js.map +1 -0
  138. package/dist/services/form-layout-document.d.ts +13 -0
  139. package/dist/services/form-layout-document.d.ts.map +1 -0
  140. package/dist/services/form-layout-document.js +228 -0
  141. package/dist/services/form-layout-document.js.map +1 -0
  142. package/dist/services/form-layout-edit.d.ts +21 -0
  143. package/dist/services/form-layout-edit.d.ts.map +1 -0
  144. package/dist/services/form-layout-edit.js +103 -0
  145. package/dist/services/form-layout-edit.js.map +1 -0
  146. package/dist/services/form-layout-init-plan.d.ts +54 -0
  147. package/dist/services/form-layout-init-plan.d.ts.map +1 -0
  148. package/dist/services/form-layout-init-plan.js +211 -0
  149. package/dist/services/form-layout-init-plan.js.map +1 -0
  150. package/dist/services/form-layout-source/review.d.ts +4 -0
  151. package/dist/services/form-layout-source/review.d.ts.map +1 -0
  152. package/dist/services/form-layout-source/review.js +54 -0
  153. package/dist/services/form-layout-source/review.js.map +1 -0
  154. package/dist/services/form-layout-template-advanced.d.ts +5 -0
  155. package/dist/services/form-layout-template-advanced.d.ts.map +1 -1
  156. package/dist/services/form-layout-template-advanced.js +17 -1
  157. package/dist/services/form-layout-template-advanced.js.map +1 -1
  158. package/dist/services/form-layout-template-catalog.d.ts +13 -0
  159. package/dist/services/form-layout-template-catalog.d.ts.map +1 -0
  160. package/dist/services/form-layout-template-catalog.js +27 -0
  161. package/dist/services/form-layout-template-catalog.js.map +1 -0
  162. package/dist/services/form-layout-template-flow.d.ts +1 -1
  163. package/dist/services/form-layout-template-flow.d.ts.map +1 -1
  164. package/dist/services/form-layout-template-flow.js.map +1 -1
  165. package/dist/services/form-layout-template-verification.d.ts +34 -0
  166. package/dist/services/form-layout-template-verification.d.ts.map +1 -0
  167. package/dist/services/form-layout-template-verification.js +124 -0
  168. package/dist/services/form-layout-template-verification.js.map +1 -0
  169. package/dist/services/form-style-template.d.ts +3 -3
  170. package/dist/services/form-style-template.d.ts.map +1 -1
  171. package/dist/services/form-style-template.js +18 -13
  172. package/dist/services/form-style-template.js.map +1 -1
  173. package/package.json +1 -1
  174. package/skill-docs/SKILL.md +163 -155
  175. package/skill-docs/_catalog.md +110 -106
  176. package/skill-docs/actionflows/references/components/ebuilder/ActionEbDelete.md +60 -3
  177. package/skill-docs/actionflows/references/components/ebuilder/EventButton.md +35 -33
  178. package/skill-docs/assets/sample/api/formApi.js +689 -510
  179. package/skill-docs/assets/sample/app/config.js +4 -0
  180. package/skill-docs/assets/sample/app/fields.js +25 -0
  181. package/skill-docs/assets/sample/entry.js +24 -22
  182. package/skill-docs/assets/sample/eslint.config.cjs +1 -0
  183. package/skill-docs/assets/sample/pages/Items.js +247 -0
  184. package/skill-docs/assets/sample/styles/prototypeStyles.js +137 -0
  185. package/skill-docs/references/coding/guide-edit-backfill.md +102 -150
  186. package/skill-docs/references/coding/guide-form-crud.md +195 -172
  187. package/skill-docs/references/coding/guide-html-to-react.md +250 -0
  188. package/skill-docs/references/coding/guide-page-code.md +194 -167
  189. package/skill-docs/references/coding/guide-page-export.md +27 -18
  190. package/skill-docs/references/coding/ref-compile-rules.md +7 -7
  191. package/skill-docs/references/common/capability-boundaries.md +20 -1
  192. package/skill-docs/references/common/guide-plan-template.md +29 -3
  193. package/skill-docs/references/common/map.md +13 -8
  194. package/skill-docs/references/common/ref-cli-commands.md +31 -10
  195. package/skill-docs/references/components/display-FilePreview.md +5 -4
  196. package/skill-docs/references/form/guide-browser-definition.md +57 -13
  197. package/skill-docs/references/form/guide-create-form.md +258 -258
  198. package/skill-docs/references/form/guide-field-linkage.md +4 -1
  199. package/skill-docs/references/form/guide-form-attachment-setting.md +95 -0
  200. package/skill-docs/references/form/guide-form-data.md +22 -1
  201. package/skill-docs/references/form/layout/code-block/code-block-guide.md +153 -0
  202. package/skill-docs/references/form/layout/code-block/controls.md +60 -0
  203. package/skill-docs/references/form/layout/code-block/coverage.md +32 -0
  204. package/skill-docs/references/form/layout/code-block/details.md +57 -0
  205. package/skill-docs/references/form/layout/code-block/events-validation.md +42 -0
  206. package/skill-docs/references/form/layout/code-block/foundations-fields.md +56 -0
  207. package/skill-docs/references/form/layout/code-block/layout-css.md +116 -0
  208. package/skill-docs/references/form/layout/code-block/recipes.md +164 -0
  209. package/skill-docs/references/form/layout/code-block/troubleshooting.md +49 -0
  210. package/skill-docs/references/form/layout/code-block/ui-global.md +47 -0
  211. package/skill-docs/references/form/layout/document.md +39 -0
  212. package/skill-docs/references/form/layout/incremental.md +133 -0
  213. package/skill-docs/references/form/layout/initialization.md +39 -0
  214. package/skill-docs/references/form/layout/inspect-edit.md +76 -0
  215. package/skill-docs/references/form/layout/layout-overview.md +67 -0
  216. package/skill-docs/references/form/layout/management.md +64 -0
  217. package/skill-docs/references/form/layout/planning.md +76 -0
  218. package/skill-docs/references/form/layout/source-restoration.md +388 -0
  219. package/skill-docs/references/form/layout/template/advanced-css.md +167 -0
  220. package/skill-docs/references/form/layout/template/advanced.md +318 -0
  221. package/skill-docs/references/form/layout/template/easy.md +64 -0
  222. package/skill-docs/references/form/layout/template/flow.md +30 -0
  223. package/skill-docs/references/form/layout/template/template-guide.md +56 -0
  224. package/skill-docs/references/form/layout/workflow-layout.md +44 -0
  225. package/skill-docs/references/form/ref-form-fields.md +303 -301
  226. package/skill-docs/references/workflow/guide-workflow-node-layout.md +189 -187
  227. package/skill-docs/assets/sample/config/config.js +0 -0
  228. package/skill-docs/assets/sample/config/configLoad.js +0 -0
  229. package/skill-docs/assets/sample/config/configLoad_default.js +0 -0
  230. package/skill-docs/assets/sample/config/config_default.js +0 -0
  231. package/skill-docs/assets/sample/memo.md +0 -0
  232. package/skill-docs/assets/sample/readme.js +0 -8
@@ -1,262 +1,285 @@
1
1
  # 表单数据操作指南
2
2
 
3
- Ebuilder 项目没有后端,但可以通过读写 Ebuilder 的表单来实现数据交互。所有 CRUD 接口已实现在 `/api/formApi.js` 中。
3
+ Ebuilder 项目没有后端,页面通过读写 Ebuilder 表单完成增删改查。所有表单数据操作都走 `api/formApi.js` 里的 `formClient`,页面不要再直接调用数据集接口,也不要自己拼 `mainTable` 或转换 ID / 名称。
4
4
 
5
- > 应用已注册的表单信息及字段用 `e10-cli form read <objId> --app-id <appId> --out fields.json` 导出(机器可读 JSON),为空说明还没注册。
5
+ > 表单元数据用 `e10-cli form read <objId> --app-id <appId> --out fields.json` 导出。字段 ID 以导出结果为准,不要自己编。
6
6
 
7
7
  ---
8
8
 
9
- ## 〇、非对称设计(读写分离)
9
+ ## 一、先准备字段常量
10
10
 
11
- **这是整份指南最核心的概念,每次写表单页面之前必须理解。**
11
+ `formClient` 只认字段 ID。页面里先用短名映射,避免到处散落长数字:
12
12
 
13
- `getSimpleData` 对所有特殊类型(Select / RadioBox / CheckBox / Employee / Department / FileComponent)**统一返回 ID**(`fieldOptionId`)。好处是写入简单——直接拿 ID 原样写入,不用做任何转换。代价是展示麻烦——ID 是长数字,用户完全看不懂。
14
-
15
- ```
16
- 写入路径(简单):getSimpleData → form 直接用 ID → saveFormData/updateFormData
17
- 展示路径(复杂):getSimpleData → ID → 映射为名称 → 表格渲染
13
+ ```js
14
+ // app/fields.js
15
+ export var F = {
16
+ name: '4765111450482898127',
17
+ status: '4765111450482898155',
18
+ owner: '4765111450482898160'
19
+ };
18
20
  ```
19
21
 
20
- **不同字段类型,名称来源不同**:
22
+ `F` 的 value 必须来自 `fields.json` 的 `fieldId`,不是字段名、不是选项 ID。
21
23
 
22
- | 字段类型 | getSimpleData 返回值 | 名称来源 |
23
- |---------|---------------------|---------|
24
- | 普通文本/数字/日期 | `"名称"` / `123` / `"2026-01-01"` | 直接展示 |
25
- | Select / RadioBox / CheckBox | `"1283421826353889337"`(ID) | `getFieldOptions` 映射 `valueKey → name` |
26
- | Employee / Department | `"5140559860850691459"`(用户ID) | `getAllData` 提取 `fieldOptionName` |
27
- | FileComponent | `"fileid1,fileid2"`(文件ID串) | 上传组件的 `name` 字段 |
24
+ ---
28
25
 
29
- > **铁律:表格里永远不要直接渲染 `row[字段ID]`。** 用户看到一列长数字 = 你漏掉了名称转换。
26
+ ## 二、创建客户端
30
27
 
31
- ---
28
+ ```js
29
+ // 模块顶层调用一次
30
+ import { formClient } from '../api/formApi.js';
31
+ import { APP_ID, OBJ_ID } from '../app/config.js';
32
32
 
33
- ## 一、四个 API 的职责
33
+ var items = formClient({ objId: OBJ_ID, appId: APP_ID });
34
+ ```
34
35
 
35
- | API | 职责 |
36
- |-----|------|
37
- | `getAllData` | 做源(含 `fieldOptionName`,用于提取名称信息) |
38
- | `getSimpleData` | 做读写(纯 ID,不含名称) |
39
- | `withDisplayNames` | 做展示(ID → 名称转换) |
40
- | `getFieldOptions` | 做下拉(拿 `valueKey` + `name`) |
36
+ - `objId`:表单的 objId。
37
+ - `appId`:当前 Ebuilder 应用 ID。写操作会带 `ebbusinessid` 请求头。
38
+ - 同一个 `objId + appId` 只创建一次,字段和选项缓存会复用。
39
+ - **不要放在组件 render 里反复调用。**
41
40
 
42
41
  ---
43
42
 
44
- ## 二、核心规则:读取用 ID,展示用名称
43
+ ## 三、行数据形状
45
44
 
46
- **最容易出错的点,每次编码前务必理解:**
45
+ `list` / `get` 返回的每一行固定是:
47
46
 
48
- `getSimpleData` 对所有特殊类型(Select/RadioBox/CheckBox/Employee/Department/FileComponent)**统一返回 ID**(`fieldOptionId`),读写一致。
47
+ ```js
48
+ {
49
+ id: '数据ID',
50
+ values: { 字段ID: '写入用的值/ID' },
51
+ display: { 字段ID: '展示用名称' },
52
+ items: { 字段ID: [{ id, name }] },
53
+ details: { detail1: [...] },
54
+ raw: 平台原始行
55
+ }
56
+ ```
49
57
 
50
- > 写完代码逐条自检,90% 的 bug 都是这几个:
51
- > 1. `if (row[roomField] === '101')` — Select 字段值是 `fieldOptionId`(长数字如 `"1283421826353889337"`),永远不等于选项名称
52
- > 2. `{row[empField]}` 直接渲染 — Employee/Department 返回的是长数字 ID,人名需从 `getAllData` 提取 `fieldOptionName`
53
- > 3. 表格里直接显示 `row[fieldId]` — 用户看到一列长数字。展示用 `withDisplayNames()`
58
+ | 用途 | 用哪个 |
59
+ |---|---|
60
+ | 表单回填、保存、更新 | `values` |
61
+ | 表格、详情展示 | `display` |
62
+ | 人员 / 部门 / 附件选择器回显 | `items` |
63
+ | 明细表 | `details` |
64
+ | 平台原始报文 | `raw`(一般不用) |
54
65
 
55
- - **写入保存** → 直接用 `getSimpleData` 的返回值,所有字段都是 ID,无需转换
56
- - **表格展示** → 用 `withDisplayNames()` 把 ID 转成名称,否则用户看到的是数字
66
+ 旧的四函数(`getSimpleData` / `getAllData` / `withDisplayNames` / `getFieldOptions`)不再作为页面写法;`formClient` 已经把这些能力收进了统一入口。
57
67
 
58
68
  ---
59
69
 
60
- ## 三、读取表单数据
61
-
62
- ### 3.1 getSimpleData — 获取简单格式数据
70
+ ## 四、读取列表
63
71
 
64
72
  ```js
65
- import { getSimpleData } from '../api/formApi.js';
66
- const CONFIG = {
67
- objId: '12556432068......',
68
- userId: TEAMS.currentUser.id
69
- };
70
- const data = await getSimpleData(CONFIG.objId, CONFIG.userId);
71
- ```
73
+ var page = await items.list({ page: 1, size: 20 });
72
74
 
73
- 返回格式:
74
- ```js
75
- [
76
- {
77
- "4765111450482898127": "具体的数据内容",
78
- "4765111450482898155": "具体的数据内容",
79
- "id":"1259017552222814208" // 表单数据固有的数据ID字段,fieldId固定为"id"
80
- },
81
- {.....}
82
- ]
75
+ page.rows; // 行数组
76
+ page.total; // 总数;平台没返回时为 null
83
77
  ```
84
78
 
85
- `getSimpleData` 返回的是扁平对象,字段 ID 作为 key 直接挂载在行上,**没有 `_raw` 层**。直接用 `item[字段ID]` 访问。
86
-
87
- > 注意:Table 组件的 `onRowClick` 回调参数中会带 `_raw`(引用原始数据行),仅在编辑回显等场景通过回调参数访问,不要主动去构造 `_raw`。
88
-
89
- ### 3.2 withDisplayNames — ID → 名称转换(表格展示用)
79
+ 带条件:
90
80
 
91
- 用于在表格中把 Select/Employee/Department 等字段的 ID 转成可读名称。
92
-
93
- 推荐写法:
94
81
  ```js
95
- import { getSimpleData, withDisplayNames, getFieldOptions } from '../api/formApi.js';
96
-
97
- function TemplatePage() {
98
- const [data, setData] = useState([]);
99
- const [loading, setLoading] = useState(true);
100
-
101
- useEffect(function () {
102
- Promise.all([
103
- getSimpleData(CONFIG.objId, CONFIG.userId),
104
- // 为每个需要展示名称的 Select 字段调用 getFieldOptions
105
- getFieldOptions(F.status, OBJ_ID),
106
- ]).then(function ([rows, statusOpts]) {
107
- setData(withDisplayNames(rows, { [F.status]: statusOpts }));
108
- }).catch(function () {})
109
- .finally(function () { setLoading(false); });
110
- }, []);
111
- // ......
82
+ var page = await items.list({
83
+ page: 1,
84
+ size: 20,
85
+ filter: { [F.status]: statusOptionId } // 多个条件之间是 AND
86
+ });
112
87
  ```
113
88
 
114
- ### 3.3 getFieldOptions — 获取选项列表
115
-
116
- 动态获取 Select/RadioBox/CheckBox 字段的可选值:
89
+ 带明细:
117
90
 
118
91
  ```js
119
- import { getFieldOptions } from './api/formApi.js';
92
+ var page = await items.list({ page: 1, size: 20, withDetail: true });
93
+ page.rows[0].details; // 原始明细行,按平台 detail1/detail2 分组
120
94
  ```
121
95
 
122
- 返回结构:
123
- ```js
124
- [
125
- {
126
- "valueKey": "1263421826353889337",
127
- "name": "已入职"
128
- },{
129
- "valueKey": "1263421826353889338",
130
- "name": "已离职"
131
- }
132
- ]
133
- ```
96
+ > `filter` 的值必须是写入值(Select 用选项 ID,Employee 用人员 ID)。如果某个字段过滤不生效,先用 `items.list()` 拉一页确认该字段的 `values` 实际值,再对照平台接口确认过滤格式。
134
97
 
135
98
  ---
136
99
 
137
- ## 四、字段类型对应组件
100
+ ## 五、读一条
138
101
 
139
- `form read --out fields.json` 导出的字段列表会告诉你每个字段的类型和 ID,有一些特殊的类型你必须选用对应的组件进行输入:
102
+ ```js
103
+ var row = await items.get(dataId);
104
+ var rowWithDetail = await items.get(dataId, { withDetail: true });
105
+
106
+ if (!row) {
107
+ // 数据不存在或已被删除
108
+ }
109
+ ```
140
110
 
141
- | 字段类型 | 对应组件 |
142
- |---------|---------|
143
- | Employee | `Browser` — 人员选择框(`module="hrm" type="resource"`) |
144
- | Department | `Browser` — 部门选择框(`module="hrm" type="department"`) |
145
- | FileComponent | `Upload` — 文件上传(参考 `references/components/form-Upload.md`) |
111
+ 列表已经拿到行时,优先直接复用该行,不要为了编辑再请求一次。
146
112
 
147
113
  ---
148
114
 
149
- ## 五、数据写入
115
+ ## 六、新增、修改、删除
150
116
 
151
- ### 5.1 formData 格式
117
+ > `formClient` 写入时会先读一次 `ds/fields`,把字段 ID 转成平台 request key(自定义字段用 `config.dataKey`),再发 `v2/saveFormData` / `v2/updateFormData`。页面仍然只用字段 ID,不需要自己拼 request key。
152
118
 
153
- **一定是字段 ID 作为 key 的格式**,字段 ID 是纯数字组成的字符串,不包含任何其他符号。必须对照 `form read --out fields.json` 导出的字段来写,不要自己编造。
119
+ ### 新增
154
120
 
155
- ```
156
- {
157
- "4765111450482898127": "数据内容1",
158
- "4765111450482898155": "数据内容2"
159
- }
121
+ ```js
122
+ var newId = await items.save({
123
+ [F.name]: '测试物品',
124
+ [F.status]: statusOptionId
125
+ });
160
126
  ```
161
127
 
162
- ### 5.2 三个写接口
128
+ `save` 返回平台生成的数据 ID;没有返回时为空字符串,可重新 `list` 确认。
129
+
130
+ ### 修改
163
131
 
164
- **新增:**
165
132
  ```js
166
- export async function saveFormData(objId, formData, userId)
133
+ await items.update(row.id, {
134
+ [F.name]: '新名称'
135
+ });
167
136
  ```
168
137
 
169
- **更新(多一个 dataId 参数):**
138
+ 只传需要修改的字段。字段联动依赖完整值时,传整行 `row.values`。
139
+
140
+ ### 删除
141
+
170
142
  ```js
171
- export async function updateFormData(objId, formData, dataId, userId)
143
+ await items.remove(row.id);
172
144
  ```
173
145
 
174
- **删除:**
146
+ ### 明细表
147
+
148
+ 读取时加 `withDetail: true`:
149
+
175
150
  ```js
176
- export async function deleteFormData(objId, dataId, userId)
151
+ var page = await items.list({ page: 1, size: 20, withDetail: true });
152
+ var row = await items.get(dataId, { withDetail: true });
153
+
154
+ row.details; // 平台原始明细行,按 detail1 / detail2 分组
155
+ row.detailRows; // 已解析:detail1: [{ id, values, display, items, raw }]
177
156
  ```
178
157
 
179
- ### 5.3 调用方式
158
+ 写入:
180
159
 
181
160
  ```js
182
- if (editingId) {
183
- promise = updateFormData(OBJ_ID, formToSave, editingId, USER_ID);
184
- } else {
185
- promise = saveFormData(OBJ_ID, formToSave, USER_ID);
186
- }
161
+ await items.save(values, {
162
+ details: {
163
+ [DETAIL_SUB_FORM_ID]: [
164
+ { [D.name]: '明细一', [D.quantity]: 2 }
165
+ ]
166
+ }
167
+ });
168
+
169
+ await items.update(dataId, values, {
170
+ details: { [DETAIL_SUB_FORM_ID]: detailRows },
171
+ detailMode: 'cover' // cover=整表覆盖;不传=平台默认追加
172
+ });
187
173
  ```
188
174
 
189
- ### 5.4 写入时直接使用 form 的值(已全部为 ID)
175
+ - 明细键用 **`subFormId`**(稳定),不要硬编码 `detail1` / `detail2`;平台节点名可能随布局顺序变化。
176
+ - `formClient` 内部会按 `getTableMapping` 解析节点,并把明细字段 ID 转成 request key;页面不用自己拼。
177
+ - 编辑回显用 `row.detailRows[DETAIL_SUB_FORM_ID]` 的 `values`;`row.details` 只保留平台原始节点数据。
178
+ - 不传 `detailMode` 时平台按追加处理;编辑整表通常用 `cover`。
179
+
180
+ ---
190
181
 
191
- `getSimpleData` 对所有特殊类型(Select/Employee/Department/FileComponent)统一返回 ID。编辑保存时无需跳过任何字段,`form` 中的值可直接写入。
182
+ ## 七、字段选项
192
183
 
193
- ```js
194
- var formToSave = {};
184
+ Select / RadioBox / CheckBox 的下拉选项:
195
185
 
196
- // 所有字段统一处理,getSimpleData 已返回 ID
197
- Object.keys(form).forEach(function (key) {
198
- var val = form[key];
199
- if (val !== '' && val !== null && val !== undefined) {
200
- formToSave[key] = val;
201
- }
202
- });
186
+ ```js
187
+ var opts = await items.options(F.status);
188
+ // [{ id, valueKey, name }]
203
189
 
204
- // 用户操作选择器时用新值覆盖
205
- if (selectedPerson.length > 0) {
206
- formToSave[F.person] = selectedPerson[0].id;
207
- }
208
- if (selectedDept.length > 0) {
209
- formToSave[F.dept] = selectedDept[0].id;
210
- }
211
- if (uploadedFiles.length > 0) {
212
- formToSave[F.attachment] = uploadedFiles.map(function (f) { return f.fileid; }).join(',');
213
- }
190
+ var statusId = await items.optionId(F.status, '已完成');
191
+ var statusIds = await items.optionIds(F.status, ['待处理', '已完成']);
192
+ var nameToId = await items.optionMap(F.status);
214
193
  ```
215
194
 
195
+ - 写入用 `valueKey`(与 `id` 同值)。
196
+ - 有中文名时用 `optionId` / `optionIds`,不要在页面里自己维护「选项名 → ID」映射。
197
+ - 找不到选项会直接报错并列出可选名称,不会静默写入。
198
+ - 展示优先用行里的 `display`,不需要为了展示再拉一次选项。
199
+ - `options` / `optionMap` 按字段缓存,页面里重复调用不会重复请求。
200
+
216
201
  ---
217
202
 
218
- ## 六、三个高频编码错误
203
+ ## 八、字段类型与值
219
204
 
220
- 编写 Ebuilder 页面时,以下三个错误非常高发,生成代码前务必检查:
205
+ | 字段类型 | `values` | `display` | `items` |
206
+ |---|---|---|---|
207
+ | Text / TextArea / Number / Date | 字符串/数字 | 原值 | 无 |
208
+ | Select / RadioBox / CheckBox | 选项 ID;多选用逗号串 | 选项名称;多选用逗号分隔 | `[{id,name}]` |
209
+ | Employee / Department | 人员/部门 ID;多值逗号串 | 姓名/部门名 | `[{id,name}]` |
210
+ | FileComponent | 文件 ID 串 | 文件名 | `[{id,name}]`(`id` 即 fileid) |
211
+ | Ebuilder / Browser / RelateBrowser | 关联数据 ID | 显示名 | `[{id,name}]` |
221
212
 
222
- ### 错误 1:数据访问用错层级
213
+ **铁律:**
223
214
 
224
- `getSimpleData` 返回的每一行直接用 `item[字段ID]`,**没有 `_raw` 层**。
215
+ 1. 写入只认 `values`,不要拿 `display` 里的中文名回写。
216
+ 2. 表格里只渲染 `display`,不要直接渲染 `values`,否则用户看到长数字。
217
+ 3. 人员 / 部门 / 附件组件回显用 `items`,不要自己拆 `raw`。
218
+ 4. 多选值统一是逗号串。`formClient` 会把数组自动归一化成逗号串,但不要依赖它掩盖错误;页面状态里也直接用逗号串。
219
+ 5. **同名字段在不同表单可能不是同一种类型**。例如“拍卖范围”在登记表是组织多选(逗号 ID),在台账是文本(顿号中文名)。跨表复用常量前逐表 `form read`,不要按字段名推断。
220
+ 6. 写日期/时间不要统一一种格式;平台按字段自身的 `format` 校验,同一表单可能同时存在 `yyyy-MM-dd`、`yyyy-MM-dd HH:mm`、`yyyy-MM-dd HH:mm:ss`。
225
221
 
226
- ```js
227
- // 错误
228
- var title = item._raw[F.title];
222
+ ---
229
223
 
230
- // 正确
231
- var title = item[F.title];
232
- ```
224
+ ## 九、写完回读
233
225
 
234
- ### 错误 2:Select 字段用名称做判断
226
+ 平台有三类静默失败:选项写名字、字段类型/格式不匹配、字段有数据不允许删除。**接口 200 不等于写对**。
235
227
 
236
- `getSimpleData` 对 Select/RadioBox/CheckBox 字段返回的是**选项 ID**(`fieldOptionId`,即 `valueKey`),如 `"1283421826353889337"`,不是显示名称。
228
+ 新增后读回:
237
229
 
238
230
  ```js
239
- // 错误
240
- if (item[F.status] === '已完成') { ... } // 显示名称永远不匹配
231
+ var newId = await items.save(values);
232
+ var saved = await items.get(newId);
241
233
 
242
- // 正确
243
- if (item[F.status] === '1283421826353889337') { ... } // 用选项 ID
234
+ if (!saved) {
235
+ throw new Error('保存成功但没有读到记录');
236
+ }
237
+ if (saved.values[F.status] !== values[F.status]) {
238
+ throw new Error('状态回读不一致:写入 ' + values[F.status] + ',读回 ' + saved.values[F.status]);
239
+ }
244
240
  ```
245
241
 
246
- **表格中显示名称**请使用 `withDisplayNames()`,不要在表格列渲染时逐行查 ID。
242
+ 修改后同样用 `items.get(id)` 比对关键字段;有明细时加 `withDetail: true`,检查 `row.detailRows[DETAIL_SUB_FORM_ID]` 的行数和值。
247
243
 
248
- ### 错误 3:React state 直接修改
244
+ 页面至少要把不一致显示出来,不要只提示“保存成功”。
249
245
 
250
- 直接修改对象属性再 `setForm` 不会触发 React 重新渲染。
246
+ ---
247
+
248
+ ## 十、错误处理
249
+
250
+ `formClient` 的读写失败都会抛 `Error`,`message` 是平台返回的可读原因:
251
251
 
252
252
  ```js
253
- // 错误
254
- form[F.name] = value;
255
- setForm(form);
256
-
257
- // 正确
258
- var newForm = {};
259
- Object.keys(form).forEach(function (k) { newForm[k] = form[k]; });
260
- newForm[F.name] = value;
261
- setForm(newForm);
253
+ items.save(values).then(function () {
254
+ // 成功
255
+ }).catch(function (err) {
256
+ setError(err.message);
257
+ });
262
258
  ```
259
+
260
+ 页面不要吞掉错误;至少展示给用户或写进页面状态。
261
+
262
+ ---
263
+
264
+ ## 十一、高级项
265
+
266
+ - `save(values, { triggerAction: true })` / `update(id, values, { triggerAction: true })`:让平台执行数据动作。默认不触发;这个开关的取值要先在当前环境确认,再用于生产。
267
+ - `items.fields()`:读取字段定义,返回按 `number` 排序的 `mainFields`。一般用 `fields.js` 常量即可,动态表单才需要。
268
+ - `items.get(id, { withDetail: true })`:详情页直接按 ID 读,不用先拉整张表。
269
+
270
+ ---
271
+
272
+ ## 十二、页面自检
273
+
274
+ - [ ] `formClient` 在模块顶层创建,没有放进 render
275
+ - [ ] 字段 ID 来自 `fields.json`,没有手写短数字
276
+ - [ ] 列表只渲染 `display`,写入只用 `values`
277
+ - [ ] Select 写入用 `optionId` / `valueKey`,不是中文名
278
+ - [ ] 多选写入是逗号串,没有把数组原样发出去
279
+ - [ ] 日期/时间按字段自身格式写,没有统一套一种格式
280
+ - [ ] 人员/部门/附件回显用 `items`
281
+ - [ ] 列表带 `page/size`,没有默认 10 条就以为没数据
282
+ - [ ] 写操作有 `.catch`,错误能显示出来
283
+ - [ ] 写完用 `get` 回读并比对关键字段
284
+ - [ ] 明细用 `subFormId`,没有硬编码 `detail1`
285
+ - [ ] 明细写入前先用 `withDetail: true` 看过真实行形状