weaver-e10-builder 1.2.5 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/assets/org-employee-template.xlsx +0 -0
  2. package/dist/commands/form-add-physical-field.d.ts +3 -0
  3. package/dist/commands/form-add-physical-field.d.ts.map +1 -0
  4. package/dist/commands/form-add-physical-field.js +125 -0
  5. package/dist/commands/form-add-physical-field.js.map +1 -0
  6. package/dist/commands/form-button.d.ts.map +1 -1
  7. package/dist/commands/form-button.js +28 -5
  8. package/dist/commands/form-button.js.map +1 -1
  9. package/dist/commands/form-field-linkage.d.ts.map +1 -1
  10. package/dist/commands/form-field-linkage.js +27 -6
  11. package/dist/commands/form-field-linkage.js.map +1 -1
  12. package/dist/commands/form-formula-linkage.d.ts +3 -0
  13. package/dist/commands/form-formula-linkage.d.ts.map +1 -0
  14. package/dist/commands/form-formula-linkage.js +434 -0
  15. package/dist/commands/form-formula-linkage.js.map +1 -0
  16. package/dist/commands/form-formula.d.ts.map +1 -1
  17. package/dist/commands/form-formula.js +22 -3
  18. package/dist/commands/form-formula.js.map +1 -1
  19. package/dist/commands/form-list-click.d.ts.map +1 -1
  20. package/dist/commands/form-list-click.js +2 -1
  21. package/dist/commands/form-list-click.js.map +1 -1
  22. package/dist/commands/form-list-permission.js +1 -1
  23. package/dist/commands/form-list-permission.js.map +1 -1
  24. package/dist/commands/form-native.d.ts.map +1 -1
  25. package/dist/commands/form-native.js +11 -3
  26. package/dist/commands/form-native.js.map +1 -1
  27. package/dist/commands/form-physical-table.d.ts +3 -0
  28. package/dist/commands/form-physical-table.d.ts.map +1 -0
  29. package/dist/commands/form-physical-table.js +195 -0
  30. package/dist/commands/form-physical-table.js.map +1 -0
  31. package/dist/commands/form.d.ts.map +1 -1
  32. package/dist/commands/form.js +246 -549
  33. package/dist/commands/form.js.map +1 -1
  34. package/dist/commands/matrix.d.ts.map +1 -1
  35. package/dist/commands/matrix.js +175 -36
  36. package/dist/commands/matrix.js.map +1 -1
  37. package/dist/commands/org.d.ts +10 -0
  38. package/dist/commands/org.d.ts.map +1 -0
  39. package/dist/commands/org.js +402 -0
  40. package/dist/commands/org.js.map +1 -0
  41. package/dist/commands/role.d.ts.map +1 -1
  42. package/dist/commands/role.js +106 -62
  43. package/dist/commands/role.js.map +1 -1
  44. package/dist/commands/wf-form.d.ts.map +1 -1
  45. package/dist/commands/wf-form.js +501 -26
  46. package/dist/commands/wf-form.js.map +1 -1
  47. package/dist/commands/workflow-auth-resp.d.ts.map +1 -1
  48. package/dist/commands/workflow-auth-resp.js +53 -5
  49. package/dist/commands/workflow-auth-resp.js.map +1 -1
  50. package/dist/commands/workflow-create-auth-resp.d.ts.map +1 -1
  51. package/dist/commands/workflow-create-auth-resp.js +5 -1
  52. package/dist/commands/workflow-create-auth-resp.js.map +1 -1
  53. package/dist/commands/workflow-operator-sign.js +1 -1
  54. package/dist/commands/workflow-operator-sign.js.map +1 -1
  55. package/dist/commands/workflow.d.ts.map +1 -1
  56. package/dist/commands/workflow.js +78 -9
  57. package/dist/commands/workflow.js.map +1 -1
  58. package/dist/index.js +8 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/services/action-detail.d.ts.map +1 -1
  61. package/dist/services/action-detail.js +5 -4
  62. package/dist/services/action-detail.js.map +1 -1
  63. package/dist/services/actionflow/components/action_eb_update_compiler.d.ts.map +1 -1
  64. package/dist/services/actionflow/components/action_eb_update_compiler.js +22 -7
  65. package/dist/services/actionflow/components/action_eb_update_compiler.js.map +1 -1
  66. package/dist/services/actionflow/components/approve_create.d.ts.map +1 -1
  67. package/dist/services/actionflow/components/approve_create.js +6 -3
  68. package/dist/services/actionflow/components/approve_create.js.map +1 -1
  69. package/dist/services/actionflow/components/custom_set_form.d.ts.map +1 -1
  70. package/dist/services/actionflow/components/custom_set_form.js +35 -1
  71. package/dist/services/actionflow/components/custom_set_form.js.map +1 -1
  72. package/dist/services/actionflow/components/custom_trigger.d.ts.map +1 -1
  73. package/dist/services/actionflow/components/custom_trigger.js +4 -1
  74. package/dist/services/actionflow/components/custom_trigger.js.map +1 -1
  75. package/dist/services/actionflow/components/dml_execute.d.ts.map +1 -1
  76. package/dist/services/actionflow/components/dml_execute.js +7 -3
  77. package/dist/services/actionflow/components/dml_execute.js.map +1 -1
  78. package/dist/services/actionflow/components/document_actions.d.ts.map +1 -1
  79. package/dist/services/actionflow/components/document_actions.js +7 -3
  80. package/dist/services/actionflow/components/document_actions.js.map +1 -1
  81. package/dist/services/actionflow/components/hrm_actions.d.ts.map +1 -1
  82. package/dist/services/actionflow/components/hrm_actions.js +7 -3
  83. package/dist/services/actionflow/components/hrm_actions.js.map +1 -1
  84. package/dist/services/actionflow/components/multiple_execution.d.ts.map +1 -1
  85. package/dist/services/actionflow/components/multiple_execution.js +14 -5
  86. package/dist/services/actionflow/components/multiple_execution.js.map +1 -1
  87. package/dist/services/actionflow/components/output.js +1 -1
  88. package/dist/services/actionflow/components/output.js.map +1 -1
  89. package/dist/services/actionflow/components/send_message.js +2 -2
  90. package/dist/services/actionflow/components/send_message.js.map +1 -1
  91. package/dist/services/actionflow/components/workflow_actions.d.ts.map +1 -1
  92. package/dist/services/actionflow/components/workflow_actions.js +7 -3
  93. package/dist/services/actionflow/components/workflow_actions.js.map +1 -1
  94. package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
  95. package/dist/services/actionflow/context_preflight.js +12 -2
  96. package/dist/services/actionflow/context_preflight.js.map +1 -1
  97. package/dist/services/actionflow/context_provider.d.ts.map +1 -1
  98. package/dist/services/actionflow/context_provider.js +21 -2
  99. package/dist/services/actionflow/context_provider.js.map +1 -1
  100. package/dist/services/actionflow/custom_trigger_context.d.ts +10 -0
  101. package/dist/services/actionflow/custom_trigger_context.d.ts.map +1 -0
  102. package/dist/services/actionflow/custom_trigger_context.js +46 -0
  103. package/dist/services/actionflow/custom_trigger_context.js.map +1 -0
  104. package/dist/services/actionflow/filter_rules.js +2 -2
  105. package/dist/services/actionflow/filter_rules.js.map +1 -1
  106. package/dist/services/actionflow/formula_service.d.ts +9 -1
  107. package/dist/services/actionflow/formula_service.d.ts.map +1 -1
  108. package/dist/services/actionflow/formula_service.js +59 -21
  109. package/dist/services/actionflow/formula_service.js.map +1 -1
  110. package/dist/services/actionflow/id_generator.d.ts +2 -0
  111. package/dist/services/actionflow/id_generator.d.ts.map +1 -1
  112. package/dist/services/actionflow/id_generator.js +13 -0
  113. package/dist/services/actionflow/id_generator.js.map +1 -1
  114. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  115. package/dist/services/actionflow/preflight_service.js +6 -1
  116. package/dist/services/actionflow/preflight_service.js.map +1 -1
  117. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  118. package/dist/services/actionflow/workflow_compiler.js +89 -35
  119. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  120. package/dist/services/auth-resp-condition.d.ts +35 -0
  121. package/dist/services/auth-resp-condition.d.ts.map +1 -0
  122. package/dist/services/auth-resp-condition.js +111 -0
  123. package/dist/services/auth-resp-condition.js.map +1 -0
  124. package/dist/services/condition-rules.d.ts.map +1 -1
  125. package/dist/services/condition-rules.js +4 -1
  126. package/dist/services/condition-rules.js.map +1 -1
  127. package/dist/services/esb-interface/document-parser.d.ts.map +1 -1
  128. package/dist/services/esb-interface/document-parser.js +62 -5
  129. package/dist/services/esb-interface/document-parser.js.map +1 -1
  130. package/dist/services/form-association.d.ts +19 -0
  131. package/dist/services/form-association.d.ts.map +1 -1
  132. package/dist/services/form-association.js +64 -0
  133. package/dist/services/form-association.js.map +1 -1
  134. package/dist/services/form-button-action.d.ts +7 -0
  135. package/dist/services/form-button-action.d.ts.map +1 -1
  136. package/dist/services/form-button-action.js +11 -1
  137. package/dist/services/form-button-action.js.map +1 -1
  138. package/dist/services/form-create.d.ts +4 -0
  139. package/dist/services/form-create.d.ts.map +1 -1
  140. package/dist/services/form-create.js +18 -12
  141. package/dist/services/form-create.js.map +1 -1
  142. package/dist/services/form-field-build.d.ts +71 -0
  143. package/dist/services/form-field-build.d.ts.map +1 -0
  144. package/dist/services/form-field-build.js +436 -0
  145. package/dist/services/form-field-build.js.map +1 -0
  146. package/dist/services/form-field-patch.d.ts +3 -1
  147. package/dist/services/form-field-patch.d.ts.map +1 -1
  148. package/dist/services/form-field-patch.js +23 -9
  149. package/dist/services/form-field-patch.js.map +1 -1
  150. package/dist/services/form-formula-linkage.d.ts +349 -0
  151. package/dist/services/form-formula-linkage.d.ts.map +1 -0
  152. package/dist/services/form-formula-linkage.js +546 -0
  153. package/dist/services/form-formula-linkage.js.map +1 -0
  154. package/dist/services/form-layout-insert.d.ts +84 -0
  155. package/dist/services/form-layout-insert.d.ts.map +1 -0
  156. package/dist/services/form-layout-insert.js +244 -0
  157. package/dist/services/form-layout-insert.js.map +1 -0
  158. package/dist/services/form-linkage-condition.d.ts +159 -0
  159. package/dist/services/form-linkage-condition.d.ts.map +1 -0
  160. package/dist/services/form-linkage-condition.js +307 -0
  161. package/dist/services/form-linkage-condition.js.map +1 -0
  162. package/dist/services/form-physical-table.d.ts +115 -0
  163. package/dist/services/form-physical-table.d.ts.map +1 -0
  164. package/dist/services/form-physical-table.js +153 -0
  165. package/dist/services/form-physical-table.js.map +1 -0
  166. package/dist/services/formula-detail.d.ts +98 -6
  167. package/dist/services/formula-detail.d.ts.map +1 -1
  168. package/dist/services/formula-detail.js +208 -26
  169. package/dist/services/formula-detail.js.map +1 -1
  170. package/dist/services/matrix-rows.d.ts +43 -0
  171. package/dist/services/matrix-rows.d.ts.map +1 -0
  172. package/dist/services/matrix-rows.js +104 -0
  173. package/dist/services/matrix-rows.js.map +1 -0
  174. package/dist/services/org-department.d.ts +114 -0
  175. package/dist/services/org-department.d.ts.map +1 -0
  176. package/dist/services/org-department.js +209 -0
  177. package/dist/services/org-department.js.map +1 -0
  178. package/dist/services/org-employee.d.ts +191 -0
  179. package/dist/services/org-employee.d.ts.map +1 -0
  180. package/dist/services/org-employee.js +400 -0
  181. package/dist/services/org-employee.js.map +1 -0
  182. package/dist/services/role-member.d.ts +99 -0
  183. package/dist/services/role-member.d.ts.map +1 -0
  184. package/dist/services/role-member.js +206 -0
  185. package/dist/services/role-member.js.map +1 -0
  186. package/dist/services/workflow-info.d.ts +83 -0
  187. package/dist/services/workflow-info.d.ts.map +1 -0
  188. package/dist/services/workflow-info.js +97 -0
  189. package/dist/services/workflow-info.js.map +1 -0
  190. package/dist/services/workflow-odoc-setting.d.ts +1 -1
  191. package/dist/services/workflow-odoc-setting.d.ts.map +1 -1
  192. package/dist/services/workflow-odoc-setting.js +15 -6
  193. package/dist/services/workflow-odoc-setting.js.map +1 -1
  194. package/dist/utils/column-name.d.ts +24 -0
  195. package/dist/utils/column-name.d.ts.map +1 -1
  196. package/dist/utils/column-name.js +16 -0
  197. package/dist/utils/column-name.js.map +1 -1
  198. package/ecodecmd/package.json +1 -2
  199. package/ecodecmd/src/loaddep.js +19 -9
  200. package/package.json +4 -4
  201. package/skill-docs/SKILL.md +13 -9
  202. package/skill-docs/_catalog.md +86 -81
  203. package/skill-docs/actionflows/SKILL.md +173 -170
  204. package/skill-docs/actionflows/references/components/logic/Output.md +1 -1
  205. package/skill-docs/actionflows/references/components/trigger/CustomTrigger.md +32 -0
  206. package/skill-docs/actionflows/references/components/workflow/ApproveCreate.md +1 -1
  207. package/skill-docs/references/common/guide-plan-template.md +9 -3
  208. package/skill-docs/references/common/ref-cli-commands.md +54 -23
  209. package/skill-docs/references/esb-interface/guide-import.md +4 -1
  210. package/skill-docs/references/form/guide-create-form.md +13 -0
  211. package/skill-docs/references/form/guide-field-linkage.md +2 -0
  212. package/skill-docs/references/form/guide-form-association.md +1 -1
  213. package/skill-docs/references/form/guide-form-formula-functions.md +36 -0
  214. package/skill-docs/references/form/guide-form-layout-incremental.md +75 -0
  215. package/skill-docs/references/form/guide-form-linkage.md +62 -4
  216. package/skill-docs/references/form/guide-form-physical-table.md +146 -0
  217. package/skill-docs/references/form/guide-formula-linkage.md +250 -0
  218. package/skill-docs/references/form/ref-form-fields.md +6 -0
  219. package/skill-docs/references/hrm/guide-matrix.md +79 -16
  220. package/skill-docs/references/hrm/guide-org-employee.md +124 -0
  221. package/skill-docs/references/report/cell-config-echo-guide.md +1 -1
  222. package/skill-docs/references/report/dataset-query-filter-guide.md +3 -3
  223. package/skill-docs/references/report/date-range-query-reference.md +2 -2
  224. package/skill-docs/references/report/query-condition-api-guide.md +11 -11
  225. package/skill-docs/references/report/report-designer-feature-map.md +1 -1
  226. package/skill-docs/references/report/report-permission-guide.md +2 -2
  227. package/skill-docs/references/workflow/guide-workflow-auth-resp.md +48 -22
  228. package/skill-docs/references/workflow/guide-workflow-odoc-setting.md +248 -0
  229. package/skill-docs/references/workflow/guide-workflow-odoc.md +23 -51
  230. package/skill-docs/references/workflow/guide-workflow.md +1 -1
@@ -0,0 +1,146 @@
1
+ # 多物理表(一个表单的字段分散到多张物理表)
2
+
3
+ 设计器里「表单 → 字段管理」有三个页签:**主表 | 明细表 | 其他**。本文说的是**「其他」** —— 同一个表单的字段分散在多张**物理表**上。
4
+
5
+ ## 什么时候用
6
+
7
+ **字段数过多时的容量兜底**(单表字段超过 100 个左右)。正常表单用不到,属于偶尔一用的结构级能力。业务上要「一行对多行」请用**明细表**,那是另一回事(见 `guide-form-sub-detail.md`)。
8
+
9
+ ## ⚠ 和「明细表」是两根轴,别混
10
+
11
+ | | 明细表 | **物理表(本文)** |
12
+ |---|---|---|
13
+ | 建表命令 | `form add-detail-table` | **`form add-physical-table`** |
14
+ | 加字段命令 | `form add-field --sub-form-id` | **`form add-physical-field`** |
15
+ | 建表端点 | `saveSubForm` | **`saveFormTable`** |
16
+ | 标志 | `isSubForm: true` | **`isSubForm: false`** |
17
+ | `tableType` | `MAIN` | **`SUBSIDIARY`** |
18
+ | 布局里 | `DetailTable` 组件 | 无(不自动进布局,见下) |
19
+ | 语义 | 一对多业务建模 | 一个表单自己的字段拆到多张表 |
20
+
21
+ ## 命令
22
+
23
+ ```shell
24
+ # 1) 列出表单的全部物理表(含主表)—— 忘掉 formTableId 时就用它
25
+ e10-cli form physical-table list <objId> <appId>
26
+
27
+ # 2) 建一张附属物理表 —— 输出 formTableId,后面都要用它
28
+ e10-cli form add-physical-table <objId> <appId> \
29
+ --name 物理表A \
30
+ --table-name uf_ryxxb_6_1
31
+
32
+ # 3) 往那张表里加字段(任意类型,能力同 form add-field)
33
+ e10-cli form add-physical-field <objId> <appId> <formTableId> <字段名> <类型> [标题] [选项]
34
+
35
+ # 4) 改名
36
+ e10-cli form rename-physical-table <objId> <appId> <formTableId> \
37
+ --name 新名字 --table-name uf_ryxxb_6_1
38
+
39
+ # 5) 删除(可一次删多张;表里的字段一并删除,不可逆)
40
+ e10-cli form delete-physical-table <objId> <appId> <formTableId...>
41
+ ```
42
+
43
+ `add-physical-field` 的选项与 `form add-field` 同名同义(`--precision` / `--format` / `--default` / `--data-key` / `--column-name` / `--multiple` / `--option-template` / `--browser-type` / `--sform-id` …)—— 两者**共用同一份字段构造器**,所以字段形状是同一套,不存在「这个命令能建那个命令不能建」的差异。
44
+
45
+ | 参数 | 说明 |
46
+ |---|---|
47
+ | `--name <名>` | 物理表**显示名**,设计器里那排 chip 上的字 |
48
+ | `--table-name <名>` | **数据库表名**(如 `uf_ryxxb_6_1`)。⚠ 平台的建议命名规则未抓到报文,**必填**;改名时也要原样回传 |
49
+
50
+ ## 表 id 从哪来
51
+
52
+ 建表输出里就带着:
53
+
54
+ ```
55
+ 物理表已建: 物理表A formTableId=1323895867900731392 tableName=uf_ryxxb_6_1
56
+ ```
57
+
58
+ 事后想找回,用 `form physical-table list`(走 `getFormAGroupList`,就是设计器那排 chip 的数据源):
59
+
60
+ ```
61
+ $ e10-cli form physical-table list 1323898521989193728 1323897873591762945
62
+ 表单 1323898521989193728 共 3 张物理表:
63
+ 多物理表测试表单 [主表] formTableId=1323898521989193731 库表=uf_dwlbcsbd_5766 字段2
64
+ 表1 [附属] formTableId=1323898595055067136 库表=uf_dwlbcs_t1 字段3
65
+ 表2 [附属] formTableId=1323898612300947456 库表=uf_dwlbcs_t2 字段3
66
+ ```
67
+
68
+ ⚠ 注意这只列**物理表**。`form detail-table list`(走 `querySubForms`)是另一回事,只列**明细表**。
69
+
70
+ 字段**归属**也随时可读:`form read <objId> --app-id <appId>` 每个字段后面会带 `· 物理表: 表1`。
71
+
72
+ > 读 `getFormAGroupList` 时别碰那条记录里的 `id` 键 —— 它是 **formId**,`formTableId` 才是表 id。这个子系统里 `id` 反复是这个陷阱。
73
+
74
+ ## ⚠ `add-physical-field` **不碰布局**
75
+
76
+ 字段建在这张物理表上,但**不会自动进表单布局**——它是否需要在布局里出现、怎么放,尚未抓到报文。别默认它已经挂在表单上了;要不要进布局请在设计器里确认。
77
+
78
+ (`form add-field` 会做布局插入,是因为它落在主表/明细表这些**本来就在布局里**的落点上。)
79
+
80
+ ## 报文契约
81
+
82
+ ### 建表 / 改名 —— 同一个端点,带不带 `id` 决定是哪种
83
+
84
+ ```
85
+ POST /api/ebuilder/form/form/field/manage/saveFormTable?apid=<appId>
86
+ header ebbusinessid: <formId>
87
+ ```
88
+
89
+ ```json
90
+ {"module":"ebuilderform",
91
+ "formTable":{"id":"<表id:改名时带,新建时不带>",
92
+ "name":"物理表A",
93
+ "tableName":"uf_ryxxb_6_1",
94
+ "tableType":"SUBSIDIARY",
95
+ "form":{"id":"<formId>"},
96
+ "otherProperties":"{}"},
97
+ "customParam":{"appId":"...","objId":"..."}}
98
+ ```
99
+
100
+ 响应:`{"code":200,"status":true,"data":{"formTableId":"..."}}` —— 新表的 id 在 `data.formTableId`。
101
+
102
+ ### 加字段 —— **不是**批量端点
103
+
104
+ ```
105
+ POST /api/ebuilder/form/form/field/manage/saveFormFieldNew
106
+ body {"formId":...,"module":"ebuilderform","jsonObj":"{... 带 \"formTableId\":\"<表id>\" ...}"}
107
+ ```
108
+
109
+ 字段落点由 **jsonObj 里的 `formTableId`** 决定。这条与「建表时连字段一起建」的 `batch/save/formField` + `formTableList` **不是同一条路**。
110
+
111
+ ### 删表
112
+
113
+ ```
114
+ POST /api/ebuilder/form/form/field/manage/deleteFormTable?apid=<appId>
115
+ body {"module":"ebuilderform","formId":"<formId>","ids":["<表id>"],"customParam":{...}}
116
+ ```
117
+
118
+ ### 列表(`form physical-table list`)
119
+
120
+ ```
121
+ POST /api/ebuilder/form/form/field/manage/getFormAGroupList?apid=<appId>
122
+ body {"module":"ebuilderform","formId":"<formId>","customParam":{...}}
123
+ ```
124
+
125
+ 响应 `data.formList[]` 每条:`name`(显示名)/ `tableName` / `tableType`(`MAIN` | `SUBSIDIARY`)/ `formTableId` / `systemTable` / `dataCount`;
126
+ 另外 `data.groupList[]` 是字段分组。**主表也在 `formList` 里**(`tableType: MAIN`)。
127
+
128
+ ⚠ 记录里的 `id` 键是 **formId**,不是表 id。
129
+
130
+ ## 踩过的两条坑(都别再走)
131
+
132
+ **1. 不能把已有字段搬到另一张表。** 试过把字段的 `formTableId` 改成新表再整份写回,平台明确拒绝:
133
+
134
+ ```
135
+ 【备注】此字段不属于当前物理表,不能更改位置
136
+ ```
137
+
138
+ 所以**别指望「字段超 100 之后把老字段挪走」**——至少这条路径不行。能做的只有:**一开始就把新字段建到新表上**。这也解释了设计器的真实用法:先建附属表,后续新增的字段直接落在它上面。
139
+
140
+ **2. 平台会对形状不认的字段回 `200` 但静默不落库。** 在 `batch/save/formField` 那条路上,`DateTime` / `Percent` / `Attachment` / `Browser` 四种就是这样——接口回成功,字段根本没建出来。所以 `add-physical-field` **每次写完都回读确认**,「接口回 200」不等于「建上了」。带配置的类型(如 Select 的选项)建完再用对应命令补。
141
+
142
+ ## 注意事项
143
+
144
+ 1. **删除不可逆**,表里的字段一并删除。执行前先确认表 id。
145
+ 2. **`--table-name` 必填**。设计器用的是 `uf_<表单名拼音>_<n>_<m>` 这类命名,但规则没抓到报文,CLI 不替你猜 —— 重名/非法由平台报错(`此表的数据库表名称与数据库现有表存在冲突`)。
146
+ 3. **建完的空表照样存在**于「其他」页签里;要清掉用 `delete-physical-table`。
@@ -0,0 +1,250 @@
1
+ # 函数联动(本表字段间的公式赋值)指南
2
+
3
+ ## 概述
4
+
5
+ 函数联动:在**本表单内部**,当某个字段变化(或表单载入)时,用一张**公式**算出结果,赋值给本表的另一个字段。
6
+
7
+ 例:`数量` 或 `单价` 变化时 → `销售金额 = 数量 × 单价`。
8
+
9
+ 设计器里的位置是字段属性面板的「函数联动」,要配四件事:**在哪生效**(当前表单 / 某个布局)、**什么时候触发**(事件)、**谁触发**(触发字段)、**赋值给谁 + 怎么算**(目标字段 + 函数体)。
10
+
11
+ > **不跨表。** 要查另一张表把值带回来,那是 `form field-linkage`(跨表带出),见 `guide-field-linkage.md`。
12
+
13
+ ## 四套联动对比
14
+
15
+ | | 属性联动(显隐) | 关联表带出 | **字段联动(跨表带出)** | **函数联动(本表赋值)** |
16
+ |---|---|---|---|---|
17
+ | 命令 | `form linkage add` | `form relate` | `form field-linkage add` | `form formula-linkage add` |
18
+ | 取值靠 | — | HRM 源 | ESB 动作流(查另一张表) | **一张公式** |
19
+ | `linkageType` | (另一套存储) | — | `template` | `excel` |
20
+ | 做的事 | 改字段显示属性 | 换 Employee/Department→带 HRM 属性 | 查任意表→带出字段赋值 | **本表字段→算→赋给本表字段** |
21
+ | 跨表 | 否 | 否 | **是** | 否 |
22
+
23
+ 四者可以叠加:同一个字段既可以有显隐联动,也可以被函数联动赋值。
24
+
25
+ ## 赋值式:公式长什么样
26
+
27
+ 落库的 `expressSql` 是一条**赋值式**,左边是目标字段、右边是函数体:
28
+
29
+ ```
30
+ {主表.销售金额}=VALUE({主表.数量})*VALUE({主表.单价})
31
+ ```
32
+
33
+ CLI 的 `--expression` **只给右边**就行,左边的 `{主表.<目标>}=` 会自动拼上。
34
+
35
+ 从设计器里整段复制也行 —— 如果表达式里已经有赋值式,CLI 会校验它的左侧与 `--target` 是否指向同一字段:一致就沿用,不一致就**报错中止**(不会偷偷改目标)。
36
+
37
+ > ⚠ **一个等号是赋值,两个等号才是比较 —— 两个层次别写反。**
38
+ > - **顶层**那个 `=` 是「赋给谁」:`{主表.销售金额}=…`。**一个等号**。
39
+ > - **函数体内部**做判断要用 `==`:`IF({主表.状态}=="已完成", 1, 0)`。**两个等号**。
40
+ >
41
+ > 函数体里写成单个 `=` 不报错,只是按赋值语义走、算出来不对。另:**函数名必须大写**(自定义 JS 脚本函数除外)、**跨表粘贴的公式要把 `{主表.X}`/`{明细表.X}` 逐个换成本表字段**、**选项型控件要比就得引用选项本身**(`{主表.性别}=={主表.性别.男}`,写成 `=='男'` 恒不成立)—— 合看 `guide-form-formula-functions.md` 的「写公式前先记住这几条」。
42
+
43
+ ### 字段引用的两种写法
44
+
45
+ | 写法 | 场景 |
46
+ |---|---|
47
+ | `{主表.字段名}` / `{明细表名.字段名}` | 平台存储格式,整段复制来的就是这种 |
48
+ | `[字段名]` / `[表名.字段名]` | 设计器编辑器里的显示格式 |
49
+
50
+ 两种都收,保存前统一归一化成花括号再下发(原样发方括号会静默失效,见 `guide-form-formula-functions.md`)。
51
+
52
+ **函数体里不要出现裸方括号** —— 解析器把任何 `[...]` 都当字段引用,`SUBSTR("a[1]",…)` 这种会被当成找不到的字段。
53
+
54
+ ## 模块字段(系统字段)
55
+
56
+ `{主表.主表数据id}`、`{主表.当前日期}`、`{主表.操作者部门}` 这类是**系统模块字段**,可以出现在公式右边,也能当触发字段,但**不能作为赋值目标**。
57
+
58
+ 原因很直白:平台在公式的 `extendParam.unSupportTargets` 里把这 21 个字段列成了「不可赋值」,而 CLI 就用这份清单做判据 —— 传了模块字段当 `--target` 会当场报错,不会建出一条平台不认的规则。
59
+
60
+ 两种写法都能用:
61
+
62
+ ```
63
+ {主表.主表数据id} ← 裸标签,平台存储格式
64
+ [formDataId] ← 语义键,等价;归一化后仍写成裸标签
65
+ ```
66
+
67
+ `form formula-linkage columns` 会把两桶分开列:业务字段(可作目标)+ 系统模块字段(不可作目标)。
68
+
69
+ ## CLI 命令
70
+
71
+ ```bash
72
+ # 看有哪些事件可选(值改变时 / 载入时 / 创建数据时 …)
73
+ e10-cli form formula-linkage events <appId> <objId>
74
+
75
+ # 看有哪些字段可用(业务字段 / 系统模块字段分两桶)
76
+ e10-cli form formula-linkage columns <appId> <objId>
77
+ e10-cli form formula-linkage columns <appId> <objId> --keyword 金额
78
+
79
+ # 列出/回读(read 带公式表达式与参数)
80
+ e10-cli form formula-linkage list <appId> <objId>
81
+ e10-cli form formula-linkage read <appId> <objId> <linkageId>
82
+
83
+ # 新增
84
+ e10-cli form formula-linkage add <appId> <objId> \
85
+ --event changeField \
86
+ --trigger 数量 --trigger 单价 \
87
+ --target 销售金额 \
88
+ --expression "VALUE({主表.数量})*VALUE({主表.单价})"
89
+
90
+ # 改(只传要改的;--event/--trigger 不传就沿用现有的)
91
+ e10-cli form formula-linkage update <appId> <objId> <linkageId> --trigger 产品类别
92
+ e10-cli form formula-linkage update <appId> <objId> <linkageId> --state off
93
+ e10-cli form formula-linkage update <appId> <objId> <linkageId> --name "重算金额"
94
+
95
+ # 删除(批量)
96
+ e10-cli form formula-linkage delete <appId> <objId> <linkageId...>
97
+ ```
98
+
99
+ ### add 的参数
100
+
101
+ | 参数 | 说明 |
102
+ |---|---|
103
+ | `--target <字段>` | **赋值目标**,被写入的字段。只能是业务字段 |
104
+ | `--expression <函数体>` | 公式右侧。含引号/换行时可用 `@文件路径` |
105
+ | `--event <事件>` | 触发事件,默认 `changeField`(值改变时)。可传 `type` 或中文名 |
106
+ | `--trigger <字段...>` | 触发字段,可多个。字段级事件必填;表单级事件(如「载入时」)不用给 |
107
+ | `--effect <维度>` | 生效维度:`form`(默认,当前表单)/ `formLayout`(表单布局) |
108
+ | `--name <名>` | 联动名。默认 `<公式名> - 公式_<时间戳>` |
109
+ | `--formula-name <名>` | 公式名,默认取表单名 |
110
+ | `--formula-id <id>` | 复用/更新已有公式,不新建 |
111
+
112
+ ### 生效维度(`--effect`)
113
+
114
+ | 维度 | `--effect` | 生效范围 |
115
+ |---|---|---|
116
+ | 当前表单(默认) | 不传 或 `form` | 该表单的**所有布局**,以及所有关联了该表单的工作流 |
117
+ | 表单布局 | `formLayout` | **只对选定的那一个布局** |
118
+
119
+ ```bash
120
+ # 只在这个布局上生效
121
+ e10-cli form formula-linkage add <appId> <objId> --effect formLayout \
122
+ --event changeField --trigger 数量 --target 销售金额 \
123
+ --expression "VALUE({主表.数量})"
124
+ ```
125
+
126
+ > ⚠ 布局 id 取的是 `getFormLayout` 返回的 **`multipleLayoutId`**,不是 `formLayout.id` —— 同一张表上这两个值相邻但不同(如 `…375` / `…376`),**发错不报错,只是指向另一个布局**,回读时生效范围会是个空白。CLI 走的是与显隐联动同一套解析(`resolveEffect`),不用手填 id。
127
+
128
+ ### 触发事件
129
+
130
+ | 分组 | 事件 | type | 要触发字段 |
131
+ |---|---|---|---|
132
+ | 字段 | 值改变时 / 获取输入焦点时 / 失去输入焦点时 / 鼠标单击时 / 鼠标双击时 | `changeField` / `onfocus` / `onblur` / `onclick` / `ondbclick` | 要 |
133
+ | 表单 | 载入时 / 载入时(可编辑) / 载入时(新建) / 创建数据时 / 窗口滚动时 | `onLoadForm` / `onLoadFormEdit` / `onLoadFormCreate` / `createData` / `onscroll` | 不要 |
134
+
135
+ ## 示例
136
+
137
+ ### 金额 = 数量 × 单价(两个触发字段)
138
+
139
+ ```bash
140
+ e10-cli form formula-linkage add <appId> <objId> \
141
+ --event changeField --trigger 数量 --trigger 单价 \
142
+ --target 销售金额 \
143
+ --expression "VALUE({主表.数量})*VALUE({主表.单价})"
144
+ ```
145
+
146
+ ### 编号 = 数据ID + 订单号(引用系统模块字段)
147
+
148
+ ```bash
149
+ e10-cli form formula-linkage add <appId> <objId> \
150
+ --event onLoadFormCreate \
151
+ --target 订单编号 \
152
+ --expression 'CONCAT({主表.主表数据id},{主表.订单编号})'
153
+ ```
154
+
155
+ ### 载入时赋当前日期(表单级事件,不给 --trigger)
156
+
157
+ ```bash
158
+ e10-cli form formula-linkage add <appId> <objId> \
159
+ --event onLoadForm --target 登记日期 --expression '{主表.当前日期}'
160
+ ```
161
+
162
+ ## 注意事项
163
+
164
+ > 公式**语言本身**的硬规则(函数名必须大写 / 比较用 `==` / 赋值用 `=` / 跨表粘贴要换字段变量)在 `guide-form-formula-functions.md` 的「写公式前先记住这四条」,写表达式前先过一遍 —— 这几条写错**不报错**,只是算不对。
165
+
166
+ 1. **目标只能是业务字段**。系统模块字段(`主表数据id`/`当前日期`/`操作者部门` 等 21 个)不能作 `--target`,但可以出现在公式右边、也可以当触发字段。
167
+ 2. **一个触发字段一条触发动作**。`--trigger` 传多个时,平台侧是 N 条动作记录,不是一条里挂 N 个字段 —— CLI 已按这个形状下发。
168
+ 3. **触发字段与目标不能搞反**。`--trigger` 是「谁变了」,`--target` 是「谁被写」。写反了规则会反向生效,回读时表达式左边能看到真实目标。
169
+ 4. **字段名有歧义会报错**,不会默认取第一条。两张明细表里各有一个「编号」时,写 `编号` 会列出两个候选,改用字段 id 或 `明细表名.编号`。
170
+ 5. **业务字段与模块字段同名时**(如业务字段叫「标题」、模块字段 `name` 的标签也叫「标题」),按裸标签写会报歧义,用字段 id 或完整列名 `主表.标题` 区分。
171
+ 6. **生效范围两种**:缺省「当前表单」(所有布局 + 所有关联该表单的工作流),`--effect formLayout` 则只对某个布局生效。布局 id 由 CLI 现查(见上「生效维度」)。`update` 不传 `--effect` 会沿用现有维度。
172
+ 7. **改了公式不会同步 `inFields`/`outFields`**。平台的数据源上带这两组字段(公式用到的来源字段 / 被赋值的字段),它们反映的是**建这条联动时**的公式;后来改公式它们不跟着变。这不影响运行,但别拿它当「当前公式用了哪些字段」的依据 —— 用 `form formula-linkage read` 看表达式。
173
+ 8. **`form field-linkage` 看不见这类联动**。两者 `linkageType` 不同(`excel` vs `template`),各查各的。`form field-linkage list` 末尾会提示「另有 N 条函数联动」;`form field-linkage delete` 传函数联动的 id 会直接报错指路,不会静默删 0 条。
174
+
175
+ ## 流程表单上的函数联动(`wf-form formula-linkage`)
176
+
177
+ 流程表单也支持函数联动,是**同一能力的另一条路由**。命令面与 eb 表逐字对齐,只有位置参数和多出来的选项不同:
178
+
179
+ ```bash
180
+ wf-form formula-linkage list <formId> --workflow-id <id>
181
+ wf-form formula-linkage read <formId> --workflow-id <id> <linkageId>
182
+ wf-form formula-linkage events <formId> --workflow-id <id>
183
+ wf-form formula-linkage columns<formId> --workflow-id <id>
184
+ wf-form formula-linkage add <formId> --workflow-id <id> --target <字段> --expression <函数体> [...]
185
+ wf-form formula-linkage update <formId> --workflow-id <id> <linkageId> [...]
186
+ wf-form formula-linkage delete <formId> --workflow-id <id> <linkageIds...>
187
+ ```
188
+
189
+ `--workflow-id` 一个旗标管两件事:**`refId`**(这条联动挂在流程上)+「当前工作流 / 选择节点」两个维度的取值来源。不给就按 `formId` 兜底(查不到时先补上它)。流程 ID 用 `workflow search --name <流程名>` 拿。
190
+
191
+ ### 两条路由的差异
192
+
193
+ | | eb 表 `form formula-linkage` | **流程表单 `wf-form formula-linkage`** |
194
+ |---|---|---|
195
+ | 位置参数 | `<appId> <objId>` | **`<formId>`** + `--workflow-id` |
196
+ | 联动端点 | `/api/ebuilder/form/form/linkage` | `/api/ebuilder/flow/form/linkage`(**不带 `?apid=`**) |
197
+ | `module` | `ebuilderform` | **`ebuildercard`** |
198
+ | 定位入参 | `customParam: {appId, objId}` | **顶层 `refId` = workflowId**;`customParam: {scene:'workflow'}` |
199
+ | 公式参数里的 `appId` | 有 | **没有这个键** |
200
+ | 不可作赋值目标的系统字段 | 21 项 | **30 项**(模块字段桶是 32 —— 差的两个见下) |
201
+ | 触发事件 | 10 个(字段组 5 + 表单组 5) | **17 个**(多一组「流程」事件) |
202
+ | 生效维度 | 当前表单 / 表单布局 | 当前表单 / 表单布局 / **当前工作流 / 选择节点** |
203
+
204
+ ### 多出来的「流程」触发事件
205
+
206
+ 除了字段组的 5 个与表单组的 5 个,流程表单还多 7 个流程级事件(都不需要 `--trigger`):
207
+
208
+ ```
209
+ EVENT_SUBMIT_OR_AGREE 提交/批准时 EVENT_REJECT 退回时
210
+ EVENT_FORWARD 转发时 EVENT_TURNTODO 转办时
211
+ EVENT_SAVE_DATA 保存时 EVENT_REMARKADVICE 意见征询时
212
+ EVENT_CIRCULATE 传阅时
213
+ ```
214
+
215
+ ### 生效维度的四种取值
216
+
217
+ ```bash
218
+ --effect form # 默认。当前表单
219
+ --effect formLayout # 表单布局(--layout-id 可指定,不传取默认布局)
220
+ --effect workFlow # 当前工作流,必须给 --workflow-id
221
+ --effect includeNode # 选择节点,必须给 --workflow-id 与 --node
222
+ ```
223
+
224
+ 「选择节点」的 `--node` 可以给节点 id 或节点名。「当前工作流」的选项名是 `流程名【V活动版本号】`,版本号取活动版本 —— 与设计器发出的形状一致。
225
+
226
+ ### 系统字段里有两个**可以**当赋值目标
227
+
228
+ 流程表单的模块字段桶有 32 项,但平台标「不可赋值」的只有 30 项,差的是:
229
+
230
+ ```
231
+ REQ_REQUEST_NAME 流程标题
232
+ REQUEST_LEVEL 紧急程度
233
+ ```
234
+
235
+ 这两个**可以**作 `--target`。`columns` 命令会按「可作 / 不可作赋值目标」分桶列出,别拿「是不是系统字段」去判断。
236
+
237
+ ### 流程表单这条路由读不出字段时
238
+
239
+ `wf-form` 的多数命令靠 `getFormLayout` + `getConfig` 读字段,但**部分流程表单上 `getFormLayout` 会直接 500**(`Form.isPhysicalTable()` 上 NPE)。函数联动**不受影响** —— 它的字段清单直接取 `findFormDrivingColumns`(这条路由自己给的),没走 `getConfig`。所以 `wf-form read` 读不出来的表单,`wf-form formula-linkage columns` 照样能列出字段。
240
+
241
+ ## 常见报错
242
+
243
+ | 报错 | 原因 | 怎么办 |
244
+ |---|---|---|
245
+ | 系统模块字段「X」不能作为赋值目标 | `--target` 写了模块字段 | 换成业务字段;模块字段只能出现在公式右边 |
246
+ | 「X」在…上匹配到 N 个字段 | 字段名有歧义 | 用字段 id(`form formula-linkage columns` 里)
247
+ | 表达式里写的是一个赋值式,它的左侧是「A」,与 --target「B」不一致 | 粘贴的赋值式目标与 `--target` 不符 | 改 `--target`,或只给右侧函数体 |
248
+ | 事件「载入时」不需要触发字段 | 表单级事件给了 `--trigger` | 去掉 `--trigger`(CLI 会忽略并提示) |
249
+ | 事件「值改变时」需要指定触发字段 | 字段级事件没给 `--trigger` | 补 `--trigger` |
250
+ | 平台回读的表达式与提交不一致 | 归一化猜错了写法 | 以平台为准;把 `read` 的结果记下来反馈 |
@@ -8,6 +8,8 @@
8
8
  {
9
9
  "componentKey": "Text",
10
10
  "fieldName": "项目名称",
11
+ "dataKey": "xmmc",
12
+ "columnName": "xmmc",
11
13
  "required": true,
12
14
  "readOnly": false,
13
15
  "hidden": false,
@@ -21,6 +23,7 @@
21
23
  | --- | --- |
22
24
  | `componentKey` | 字段类型标识 |
23
25
  | `fieldName` | 字段名称 |
26
+ | `dataKey` / `columnName` | 字段编码 / 数据库列名。**两者是两个独立的东西**,可分别指定;都不写则同为字段名拼音首字母,只写 `dataKey` 时列名跟随。建后由 `add-field --data-key/--column-name`、`edit-field --column-name` 调整 |
24
27
  | `required` / `readOnly` / `hidden` | 必填、只读、隐藏 |
25
28
  | `singleRow` | 独占一行 |
26
29
  | `group` | 所属分组 |
@@ -73,8 +76,11 @@
73
76
  | --- | --- | --- |
74
77
  | 人员选择 | `Employee` | `multiple` |
75
78
  | 部门选择 | `Department` | `multiple` |
79
+ | 分部选择 | `SubCompany` | `multiple`(默认单选);平台读回的组件名为 `Subcompany` |
76
80
  | 共享人 | `Sharer` | 共享范围设置 |
77
81
 
82
+ 创建“分部选择”字段使用原生组织类型 `SubCompany`,例如 `form add-field <objId> <appId> 所属分部 SubCompany`;多选时加 `--multiple`。它与“关联浏览”中选择分部数据源是两种字段配置。
83
+
78
84
  ### 关联类型
79
85
 
80
86
  以下为原生关联对象码表。需求明确指向这些业务对象时,直接使用对应类型。
@@ -1,4 +1,4 @@
1
- # HRM 条件矩阵指南
1
+ # HRM 矩阵指南(条件矩阵 / 部门矩阵 / 分部矩阵)
2
2
 
3
3
  > 矩阵 = 「条件维度(行)→ 值维度(列)」的映射查询表。例如:部门 + 费用类型 → 审批人。用于流程中的矩阵对应操作者类型。
4
4
 
@@ -10,9 +10,9 @@
10
10
  |------|------|
11
11
  | `e10-cli matrix create <name>` | 新建矩阵。`--type 0=分部/1=部门/2=自定义` `--desc` `--org-id` |
12
12
  | `e10-cli matrix update <id>` | 更新矩阵。`--name` `--desc` `--type` |
13
- | `e10-cli matrix list` | 查询矩阵列表。`--name` `--enable-status` `--org-id` |
13
+ | `e10-cli matrix list` | 查询矩阵列表。`--name` `--enable-status` `--org-id`。非 JSON 输出会标出「行随组织同步 / 行手工维护」「字段只读」 |
14
14
  | `e10-cli matrix config <id>` | 查看矩阵配置(条件字段 + 值字段) |
15
- | `e10-cli matrix config-edit <id>` | 编辑配置。`--condition` `--value` 或 `--config` 一次性提交 |
15
+ | `e10-cli matrix config-edit <id>` | 编辑配置。`--value`(配合可选 `--condition`)或 `--config` 一次性提交。**`--condition` 可省略**,省略则沿用现有条件列 |
16
16
  | `e10-cli matrix enable <id>` | 启用矩阵 |
17
17
  | `e10-cli matrix disable <id>` | 停用矩阵 |
18
18
  | `e10-cli matrix delete <ids...>` | 删除矩阵。**矩阵里有数据行时平台会拒绝删除**(报"存在不能删除的矩阵"且不指出是哪个)——先 `matrix data delete <id> <rowIds...>` 清空数据行再删;批量删除时只要有**一条**不可删,整批都失败 |
@@ -22,7 +22,7 @@
22
22
  | 命令 | 说明 |
23
23
  |------|------|
24
24
  | `e10-cli matrix data list <matrixId>` | 分页查询矩阵数据行。`--condition` `--value` 过滤 |
25
- | `e10-cli matrix data save <matrixId> --rows @file` | 保存数据行(新增/修改)。简写: `[{"字段configId":["实体ID"]}]` |
25
+ | `e10-cli matrix data save <matrixId> --rows @file` | 保存数据行(新增/修改)。简写: `[{rowId?, "字段configId":["实体ID"]}]` —— 带 `rowId` 为改该行,不带为新增 |
26
26
  | `e10-cli matrix data delete <matrixId> <ids...>` | 删除数据行 |
27
27
  | `e10-cli matrix data template <matrixId>` | 下载导入模板(Excel) |
28
28
  | `e10-cli matrix data import <matrixId> <file>` | 从 Excel 导入。`--mode add/cover` |
@@ -59,22 +59,75 @@ e10-cli workflow set-operator <wf> <nodeId> --type matrix \
59
59
  --matrix-rule "<条件configId>:1:1:1"
60
60
  ```
61
61
 
62
+ 部门矩阵少一步 —— 条件列是平台建矩阵时自动给的,只配值列:
63
+
64
+ ```bash
65
+ # 1. 建(--sync-depart = 界面上那个「从组织架构中同步部门」;行随组织同步,不可增删)
66
+ e10-cli matrix create "部门负责人" --type 1 --sync-depart --desc "部门→负责人"
67
+
68
+ # 2. 只配值列,--condition 省略(CLI 会沿用平台建好的「部门」条件列)
69
+ e10-cli matrix config-edit <matrixId> \
70
+ --value '[{"type":"resource","name":"部门负责人","singleType":0}]'
71
+
72
+ # 3. 看行 —— 同步型矩阵的行是组织架构带来的,行 id 就是部门 id
73
+ e10-cli matrix data list <matrixId>
74
+
75
+ # 4. 给某一行填值(带 rowId 才是改那一行,不带就是新增一行)
76
+ echo '[{"rowId":"<部门id>","<值configId>":["<人员ID>"]}]' > rows.json
77
+ e10-cli matrix data save <matrixId> --rows @rows.json
78
+ ```
79
+
62
80
  ---
63
81
 
64
- ## 系统矩阵 vs 自定义矩阵
82
+ ## 行从哪来、字段能不能改:看 `syncType` 和 `permList`
65
83
 
66
- `matrix list --json` 每条记录带三个标记位,决定这个矩阵能改什么:
84
+ `matrix list --json` 每条记录带几个标记位。**不要拿 `sysType` 当判据** —— 它只说明是不是平台内置的,不决定能力:
67
85
 
68
86
  | 字段 | 取值 | 含义 |
69
87
  |---|---|---|
70
88
  | `type` | `0` / `1` / `2` | `0`=分部矩阵、`1`=部门矩阵、`2`=自定义矩阵 |
71
- | `sysType` | `1` / `0` | `1`=系统矩阵(平台内置的组织维度矩阵),`0`=非系统 |
72
- | `syncType` | `1` / `0` | `1`=数据行随系统组织同步,`0`=手工维护 |
89
+ | `syncType` | `1` / `0` | **行从哪来**。`1`=数据行随组织架构同步(**行不可增删,行 id 就是部门/分部 id**);`0`=行手工维护(行 id 是平台发号的雪花) |
90
+ | `permList` | 数组 | **含 `FIELD` 才能改字段配置**;不含就是字段只读(平台内置矩阵是这种) |
91
+ | `sysType` | `1` / `0` | 是否平台内置。只影响名字语义,**不影响能做什么** |
92
+
93
+ `matrix list` 的非 JSON 输出会直接把这两条标出来:`行随组织同步 / 行手工维护`、`字段只读`。
73
94
 
74
- - **系统矩阵**(`sysType=1`,即 type 0/1 的分部/部门矩阵):条件列由平台内置的组织维度决定(分部 / 部门),建好后不自行增删条件列;`syncType=1` 时数据行随系统组织同步,不需要 `matrix data save` 手工填(典型:`部门矩阵` —— 条件列=部门、值列为空、描述"同步系统部门信息")。
75
- - **自定义矩阵**(`sysType=0`,`type=2`):条件列与值列都自由配置,数据行手工维护,可带 `belongOrgId` 归属机构。
95
+ 同一租户里四个矩阵的对照,四个象限都出现过:
96
+
97
+ | 矩阵 | type | sysType | syncType | permList 有 `FIELD` | 结果 |
98
+ |---|---|---|---|---|---|
99
+ | 平台内置的部门矩阵 | 1 | 1 | 1 | 否 | 行随组织同步、字段只读 |
100
+ | 部门负责人矩阵 | 1 | 0 | 0 | 是 | 行手工维护、字段可改 |
101
+ | 自建并勾了「同步部门」 | 1 | 0 | 1 | 是 | 行随组织同步、字段可改 |
102
+ | 自建未勾同步 | 1 | 0 | 0 | 是 | 行手工维护、字段可改 |
103
+
104
+ > **`type` 与 `syncType` 互相独立**:`type=1` 的部门矩阵既可以是同步的、也可以是手工维护的;创建时用 `--sync-depart` / `--sync-subcompany` 决定,事后也能用 `matrix update --sync-depart` 改。
105
+ >
106
+ > 不管哪种,**在流程里的用法完全一样**(都是 `workflow set-operator --type matrix`)。
76
107
 
77
- > 两者**在流程里的用法完全一样**(都是 `workflow set-operator --type matrix`),差别只在"条件列从哪来 / 数据谁来填"。
108
+ ## 部门矩阵 / 分部矩阵:条件列是平台给的
109
+
110
+ 建部门矩阵(`matrix create <name> --type 1 --sync-depart`)时,平台会**自动把条件列建好**:
111
+
112
+ ```json
113
+ "conditionConfigList": [
114
+ { "id": "<矩阵id + 1>", "name": "部门", "type": "department", "singleType": 1 }
115
+ ],
116
+ "valueConfigList": [] ← 这才是你要配的
117
+ ```
118
+
119
+ 所以配列时**只给值列就行**,`--condition` 省略掉:
120
+
121
+ ```bash
122
+ e10-cli matrix config-edit <matrixId> \
123
+ --value '[{"type":"resource","name":"部门负责人","singleType":0}]'
124
+ ```
125
+
126
+ CLI 会把现有条件列原样带上(会打印一行 `ℹ 未指定条件列,已沿用现有的: 部门`)。
127
+
128
+ > **别手写条件列。** 写一个不带 `id` 的 `{"type":"department","name":"部门"}` 进去,CLI 会当成新列去 `addField` 取号,结果矩阵里多出一条一模一样的「部门」列。
129
+ >
130
+ > 可用类型用 `GET /api/bs/hrm/matrix2/config/typeList?id=<matrixId>&matrixType=<0|1|2>` 查:部门矩阵返回 `conditionTypeList:[department]` / `valueTypeList:[resource]`。
78
131
 
79
132
  **所属机构与分权**:矩阵强制校验"所属机构",而落到哪个字段由**分权状态**决定——分权开启时平台读 `belong_org_id`(归属机构),关闭时读 `targetId`。CLI 建矩阵前会自动查 `check-detach` 判断并选对字段,分权租户还会直接用返回的当前机构兜底,所以 `matrix create` 通常不用手写机构;只有"非分权租户"或"归属机构与目标机构必须不同"时才需要 `--org-id` / `--target-id`。
80
133
 
@@ -130,25 +183,35 @@ e10-cli matrix config <matrixId>
130
183
  {
131
184
  "id": "<矩阵ID>",
132
185
  "conditionConfigList": [
133
- { "type": "department", "name": "显示名", "sort": 1 }
186
+ { "id": "<现有条件列id>", "type": "department", "name": "显示名", "sort": 1 }
134
187
  ],
135
188
  "valueConfigList": [
136
- { "type": "resource", "name": "显示名", "singleType": 1, "sort": 1 }
189
+ { "id": "<现有值列id>", "type": "resource", "name": "显示名", "singleType": 1, "sort": 1 },
190
+ { "type": "resource", "name": "新加的列", "singleType": 0, "sort": 2 }
137
191
  ],
138
192
  "conditionDelList": [],
139
193
  "valueDelList": []
140
194
  }
141
195
  ```
142
196
 
143
- > `singleType`: 0=多选, 1=单选。条件字段不传,值字段必传。
197
+ - `singleType`: 0=多选, 1=单选。值字段必传,条件字段可省(省了沿用现有的)。条件列在平台上**本身是必填的**,空着下发会被拒(「请至少维护一个条件字段」)。
198
+ - **已有的列要带 `id`**(从 `matrix config` 拿);不带 `id` 的会被当成新列去 `addField` 取号,**等于多建一列**。不带 id 但与现有列重名时 CLI 会告警。
199
+ - **列 id 必须属于该矩阵**。传了别的矩阵的列 id,平台只回一句「系统内部错误」(NPE),CLI 会抢先报错并点名是哪一列。
200
+ - ⚠ **保存是「按 id 合并」,不是整表替换**:没传的列**不会**被删(删列要走 `--value-del`)。所以「加一列」只传那一列就够了,不必把现有列全列一遍。
201
+ - 保存后回读比对提交的列(在不在、名字对不对),平台回 200 但没按提交落库会直接报错。
144
202
 
145
203
  ## data save 简写格式
146
204
 
147
205
  ```json
148
206
  [
149
- {"<条件configId>": ["<实体ID>"], "<值configId>": ["<实体ID>"]}
207
+ {"<条件configId>": ["<实体ID>"], "<值configId>": ["<实体ID>"]},
208
+ {"rowId": "<行id>", "<值configId>": ["<实体ID>"]}
150
209
  ]
151
210
  ```
152
211
 
153
- CLI 自动查 config 判断 `conditionAble` 标记并展开为完整格式。
212
+ - 不带 `rowId` = 新增一行;带 `rowId`(或写作 `id`)= 改那一行。行 id 用 `matrix data list <matrixId>` 拿。
213
+ - **改行只给要改的列就行**:平台是整行覆盖,CLI 会先读回该行、把没给的列补上再发。
214
+ - 键不是该矩阵的列时直接报错并列出可用列,不会静默发出去。
215
+
216
+ CLI 自动查 config 判断 `conditionAble` 标记并展开为完整格式;改过的行保存后会回读比对,平台回 200 但没按提交落库会直接报错。
154
217