weaver-e10-builder 1.0.10-beta → 1.0.12-beta

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 (254) hide show
  1. package/dist/commands/actionflow.d.ts.map +1 -1
  2. package/dist/commands/actionflow.js +10 -6
  3. package/dist/commands/actionflow.js.map +1 -1
  4. package/dist/commands/auth.d.ts.map +1 -1
  5. package/dist/commands/auth.js +13 -0
  6. package/dist/commands/auth.js.map +1 -1
  7. package/dist/commands/form-layout-init.d.ts.map +1 -1
  8. package/dist/commands/form-layout-init.js +7 -1
  9. package/dist/commands/form-layout-init.js.map +1 -1
  10. package/dist/commands/form-list-permission.d.ts.map +1 -1
  11. package/dist/commands/form-list-permission.js +130 -15
  12. package/dist/commands/form-list-permission.js.map +1 -1
  13. package/dist/commands/form-nlist.d.ts +22 -0
  14. package/dist/commands/form-nlist.d.ts.map +1 -0
  15. package/dist/commands/form-nlist.js +179 -0
  16. package/dist/commands/form-nlist.js.map +1 -0
  17. package/dist/commands/form-serial-mark.d.ts +0 -15
  18. package/dist/commands/form-serial-mark.d.ts.map +1 -1
  19. package/dist/commands/form-serial-mark.js +604 -137
  20. package/dist/commands/form-serial-mark.js.map +1 -1
  21. package/dist/commands/form.d.ts.map +1 -1
  22. package/dist/commands/form.js +145 -16
  23. package/dist/commands/form.js.map +1 -1
  24. package/dist/commands/skill.d.ts +3 -0
  25. package/dist/commands/skill.d.ts.map +1 -0
  26. package/dist/commands/skill.js +112 -0
  27. package/dist/commands/skill.js.map +1 -0
  28. package/dist/commands/wf-form.d.ts +18 -0
  29. package/dist/commands/wf-form.d.ts.map +1 -1
  30. package/dist/commands/wf-form.js +156 -181
  31. package/dist/commands/wf-form.js.map +1 -1
  32. package/dist/commands/workflow-condition.d.ts.map +1 -1
  33. package/dist/commands/workflow-condition.js +3 -1
  34. package/dist/commands/workflow-condition.js.map +1 -1
  35. package/dist/commands/workflow-create-workflow.d.ts.map +1 -1
  36. package/dist/commands/workflow-create-workflow.js +14 -0
  37. package/dist/commands/workflow-create-workflow.js.map +1 -1
  38. package/dist/commands/workflow-node-validate.d.ts.map +1 -1
  39. package/dist/commands/workflow-node-validate.js +16 -2
  40. package/dist/commands/workflow-node-validate.js.map +1 -1
  41. package/dist/commands/workflow-numbering.d.ts.map +1 -1
  42. package/dist/commands/workflow-numbering.js +18 -2
  43. package/dist/commands/workflow-numbering.js.map +1 -1
  44. package/dist/commands/workflow.d.ts.map +1 -1
  45. package/dist/commands/workflow.js +58 -42
  46. package/dist/commands/workflow.js.map +1 -1
  47. package/dist/index.js +4 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/services/actionflow/build_workflow_draft.d.ts.map +1 -1
  50. package/dist/services/actionflow/build_workflow_draft.js +23 -2
  51. package/dist/services/actionflow/build_workflow_draft.js.map +1 -1
  52. package/dist/services/actionflow/command_output.d.ts +6 -0
  53. package/dist/services/actionflow/command_output.d.ts.map +1 -0
  54. package/dist/services/actionflow/command_output.js +91 -0
  55. package/dist/services/actionflow/command_output.js.map +1 -0
  56. package/dist/services/actionflow/components/action_eb_add.d.ts.map +1 -1
  57. package/dist/services/actionflow/components/action_eb_add.js +5 -4
  58. package/dist/services/actionflow/components/action_eb_add.js.map +1 -1
  59. package/dist/services/actionflow/components/action_eb_delete.js +1 -1
  60. package/dist/services/actionflow/components/action_eb_delete.js.map +1 -1
  61. package/dist/services/actionflow/components/action_eb_update.js +4 -4
  62. package/dist/services/actionflow/components/action_eb_update.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 +4 -1
  65. package/dist/services/actionflow/components/action_eb_update_compiler.js.map +1 -1
  66. package/dist/services/actionflow/components/approve_create.js +1 -1
  67. package/dist/services/actionflow/components/approve_create.js.map +1 -1
  68. package/dist/services/actionflow/components/approve_trigger.d.ts.map +1 -1
  69. package/dist/services/actionflow/components/approve_trigger.js +48 -16
  70. package/dist/services/actionflow/components/approve_trigger.js.map +1 -1
  71. package/dist/services/actionflow/components/date_trigger.js +3 -3
  72. package/dist/services/actionflow/components/date_trigger.js.map +1 -1
  73. package/dist/services/actionflow/components/enquiry_form.d.ts.map +1 -1
  74. package/dist/services/actionflow/components/enquiry_form.js +15 -8
  75. package/dist/services/actionflow/components/enquiry_form.js.map +1 -1
  76. package/dist/services/actionflow/enrich_approve_trigger.d.ts.map +1 -1
  77. package/dist/services/actionflow/enrich_approve_trigger.js +47 -17
  78. package/dist/services/actionflow/enrich_approve_trigger.js.map +1 -1
  79. package/dist/services/actionflow/formula_service.d.ts.map +1 -1
  80. package/dist/services/actionflow/formula_service.js +71 -3
  81. package/dist/services/actionflow/formula_service.js.map +1 -1
  82. package/dist/services/actionflow/functions_catalog.d.ts +26 -0
  83. package/dist/services/actionflow/functions_catalog.d.ts.map +1 -0
  84. package/dist/services/actionflow/functions_catalog.js +8986 -0
  85. package/dist/services/actionflow/functions_catalog.js.map +1 -0
  86. package/dist/services/actionflow/functions_source.d.ts +7 -0
  87. package/dist/services/actionflow/functions_source.d.ts.map +1 -0
  88. package/dist/services/actionflow/functions_source.js +50 -0
  89. package/dist/services/actionflow/functions_source.js.map +1 -0
  90. package/dist/services/actionflow/generation_service.d.ts +8 -0
  91. package/dist/services/actionflow/generation_service.d.ts.map +1 -1
  92. package/dist/services/actionflow/generation_service.js +60 -2
  93. package/dist/services/actionflow/generation_service.js.map +1 -1
  94. package/dist/services/actionflow/preflight_service.d.ts +6 -0
  95. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  96. package/dist/services/actionflow/preflight_service.js +69 -0
  97. package/dist/services/actionflow/preflight_service.js.map +1 -1
  98. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  99. package/dist/services/actionflow/workflow_compiler.js +102 -85
  100. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  101. package/dist/services/actionflow/workflow_source.d.ts +2 -0
  102. package/dist/services/actionflow/workflow_source.d.ts.map +1 -1
  103. package/dist/services/actionflow/workflow_source.js +8 -0
  104. package/dist/services/actionflow/workflow_source.js.map +1 -1
  105. package/dist/services/condition-rules.d.ts.map +1 -1
  106. package/dist/services/condition-rules.js +3 -1
  107. package/dist/services/condition-rules.js.map +1 -1
  108. package/dist/services/form-create.d.ts.map +1 -1
  109. package/dist/services/form-create.js +4 -1
  110. package/dist/services/form-create.js.map +1 -1
  111. package/dist/services/form-nlist.d.ts +42 -0
  112. package/dist/services/form-nlist.d.ts.map +1 -0
  113. package/dist/services/form-nlist.js +332 -0
  114. package/dist/services/form-nlist.js.map +1 -0
  115. package/dist/services/skill-provision.d.ts +18 -0
  116. package/dist/services/skill-provision.d.ts.map +1 -0
  117. package/dist/services/skill-provision.js +86 -0
  118. package/dist/services/skill-provision.js.map +1 -0
  119. package/dist/services/workflow-initiator.js +3 -3
  120. package/dist/services/workflow-initiator.js.map +1 -1
  121. package/dist/services/workflow-operator.d.ts +3 -1
  122. package/dist/services/workflow-operator.d.ts.map +1 -1
  123. package/dist/services/workflow-operator.js +5 -4
  124. package/dist/services/workflow-operator.js.map +1 -1
  125. package/package.json +4 -2
  126. package/skill-docs/SKILL.md +348 -0
  127. package/skill-docs/actionflows/references/components/calendar/MeetingCreate.md +17 -0
  128. package/skill-docs/actionflows/references/components/calendar/ScheduleCreate.md +17 -0
  129. package/skill-docs/actionflows/references/components/document/AttachmentCopy.md +17 -0
  130. package/skill-docs/actionflows/references/components/document/AttachmentMove.md +17 -0
  131. package/skill-docs/actionflows/references/components/document/DocumentCopy.md +17 -0
  132. package/skill-docs/actionflows/references/components/document/DocumentDelete.md +17 -0
  133. package/skill-docs/actionflows/references/components/document/DocumentEdit.md +17 -0
  134. package/skill-docs/actionflows/references/components/document/DocumentMove.md +17 -0
  135. package/skill-docs/actionflows/references/components/document/DocumentPermissionChange.md +17 -0
  136. package/skill-docs/actionflows/references/components/document/DocumentRenewal.md +17 -0
  137. package/skill-docs/actionflows/references/components/document/DocumentRevert.md +17 -0
  138. package/skill-docs/actionflows/references/components/document/DocumentSave.md +17 -0
  139. package/skill-docs/actionflows/references/components/document/DocumentSubscription.md +17 -0
  140. package/skill-docs/actionflows/references/components/document/DocumentSubscriptionApprove.md +17 -0
  141. package/skill-docs/actionflows/references/components/document/DocumentSubscriptionSendBack.md +17 -0
  142. package/skill-docs/actionflows/references/components/document/DocumentSubscriptionWithdraw.md +17 -0
  143. package/skill-docs/actionflows/references/components/document/FileFolderSave.md +17 -0
  144. package/skill-docs/actionflows/references/components/document/GetAttachmentInfo.md +17 -0
  145. package/skill-docs/actionflows/references/components/document/GetDocumentInfo.md +17 -0
  146. package/skill-docs/actionflows/references/components/document/ModifyDocumentStatus.md +17 -0
  147. package/skill-docs/actionflows/references/components/document/ReplaceAttachment.md +17 -0
  148. package/skill-docs/actionflows/references/components/document/UpdatePrintNum.md +17 -0
  149. package/skill-docs/actionflows/references/components/ebuilder/ActionEbAdd.md +39 -0
  150. package/skill-docs/actionflows/references/components/ebuilder/ActionEbDelete.md +21 -0
  151. package/skill-docs/actionflows/references/components/ebuilder/ActionEbRecover.md +17 -0
  152. package/skill-docs/actionflows/references/components/ebuilder/ActionEbSaveVersion.md +17 -0
  153. package/skill-docs/actionflows/references/components/ebuilder/ActionEbUpdate.md +21 -0
  154. package/skill-docs/actionflows/references/components/ebuilder/DateTrigger.md +17 -0
  155. package/skill-docs/actionflows/references/components/ebuilder/EbGetDataById.md +17 -0
  156. package/skill-docs/actionflows/references/components/ebuilder/EnquiryForm.md +75 -0
  157. package/skill-docs/actionflows/references/components/ebuilder/EventFormData.md +17 -0
  158. package/skill-docs/actionflows/references/components/ebuilder/TimeBatchTrigger.md +17 -0
  159. package/skill-docs/actionflows/references/components/logic/Condition.md +23 -0
  160. package/skill-docs/actionflows/references/components/logic/LogicFlowSet.md +17 -0
  161. package/skill-docs/actionflows/references/components/logic/MultipleExecution.md +38 -0
  162. package/skill-docs/actionflows/references/components/logic/Output.md +17 -0
  163. package/skill-docs/actionflows/references/components/message/SendMessage.md +17 -0
  164. package/skill-docs/actionflows/references/components/personnel/AlterPersonStatus.md +30 -0
  165. package/skill-docs/actionflows/references/components/personnel/HrmEmployeeUpdate.md +32 -0
  166. package/skill-docs/actionflows/references/components/personnel/PersonnelOnboarding.md +34 -0
  167. package/skill-docs/actionflows/references/components/trigger/SimpleScheduler.md +17 -0
  168. package/skill-docs/actionflows/references/components/workflow/ApproveAddSign.md +17 -0
  169. package/skill-docs/actionflows/references/components/workflow/ApproveAgreeRejectApply.md +17 -0
  170. package/skill-docs/actionflows/references/components/workflow/ApproveCommit.md +17 -0
  171. package/skill-docs/actionflows/references/components/workflow/ApproveCompletelyDelete.md +17 -0
  172. package/skill-docs/actionflows/references/components/workflow/ApproveConsulTurnTodo.md +17 -0
  173. package/skill-docs/actionflows/references/components/workflow/ApproveCreate.md +17 -0
  174. package/skill-docs/actionflows/references/components/workflow/ApproveDelete.md +17 -0
  175. package/skill-docs/actionflows/references/components/workflow/ApproveDoCirculate.md +17 -0
  176. package/skill-docs/actionflows/references/components/workflow/ApproveDoForward.md +17 -0
  177. package/skill-docs/actionflows/references/components/workflow/ApproveDoTurnTodo.md +17 -0
  178. package/skill-docs/actionflows/references/components/workflow/ApproveEntrust.md +17 -0
  179. package/skill-docs/actionflows/references/components/workflow/ApproveIntervention.md +17 -0
  180. package/skill-docs/actionflows/references/components/workflow/ApproveMandatoryArchiving.md +17 -0
  181. package/skill-docs/actionflows/references/components/workflow/ApproveManualCC.md +17 -0
  182. package/skill-docs/actionflows/references/components/workflow/ApproveRefuseRejectApply.md +17 -0
  183. package/skill-docs/actionflows/references/components/workflow/ApproveRejectApply.md +17 -0
  184. package/skill-docs/actionflows/references/components/workflow/ApproveSave.md +17 -0
  185. package/skill-docs/actionflows/references/components/workflow/ApproveSendBack.md +17 -0
  186. package/skill-docs/actionflows/references/components/workflow/ApproveShareEntry.md +17 -0
  187. package/skill-docs/actionflows/references/components/workflow/ApproveTrigger.md +49 -0
  188. package/skill-docs/actionflows/references/components/workflow/ApproveWithdraw.md +17 -0
  189. package/skill-docs/actionflows/references/components/workflow/WorkFlowDocEmpowerment.md +17 -0
  190. package/skill-docs/actionflows/references/components/workflow/WorkflowToDoc.md +17 -0
  191. package/skill-docs/actionflows/references/condition_rules.md +97 -0
  192. package/skill-docs/actionflows/references/examples/enquiry-form-batch-insert-scene2.json +1046 -0
  193. package/skill-docs/actionflows/references/function_rules.md +13 -0
  194. package/skill-docs/actionflows/references/trigger_runtime_notes.md +51 -0
  195. package/skill-docs/assets/sample/.claude/settings.local.json +8 -0
  196. package/skill-docs/assets/sample/api/formApi.js +510 -0
  197. package/skill-docs/assets/sample/config/config.js +0 -0
  198. package/skill-docs/assets/sample/config/configLoad.js +0 -0
  199. package/skill-docs/assets/sample/config/configLoad_default.js +0 -0
  200. package/skill-docs/assets/sample/config/config_default.js +0 -0
  201. package/skill-docs/assets/sample/entry.js +22 -0
  202. package/skill-docs/assets/sample/eslint.config.cjs +48 -0
  203. package/skill-docs/assets/sample/memo.md +0 -0
  204. package/skill-docs/assets/sample/readme.js +8 -0
  205. package/skill-docs/references/auth/guide-auth.md +88 -0
  206. package/skill-docs/references/coding/guide-edit-backfill.md +189 -0
  207. package/skill-docs/references/coding/guide-form-crud.md +262 -0
  208. package/skill-docs/references/coding/guide-page-code.md +224 -0
  209. package/skill-docs/references/coding/guide-page-export.md +119 -0
  210. package/skill-docs/references/coding/ref-compile-rules.md +106 -0
  211. package/skill-docs/references/common/ref-cli-commands.md +286 -0
  212. package/skill-docs/references/components/@weapp-Button.md +104 -0
  213. package/skill-docs/references/components/base-Badge.md +100 -0
  214. package/skill-docs/references/components/base-Dialog.md +358 -0
  215. package/skill-docs/references/components/base-Empty.md +58 -0
  216. package/skill-docs/references/components/base-Tag.md +112 -0
  217. package/skill-docs/references/components/display-Alert.md +64 -0
  218. package/skill-docs/references/components/display-Avatar.md +150 -0
  219. package/skill-docs/references/components/display-Calendar.md +263 -0
  220. package/skill-docs/references/components/display-Carousel.md +115 -0
  221. package/skill-docs/references/components/display-Collapse.md +299 -0
  222. package/skill-docs/references/components/display-FilePreview.md +49 -0
  223. package/skill-docs/references/components/display-Icon.md +66 -0
  224. package/skill-docs/references/components/display-List.md +320 -0
  225. package/skill-docs/references/components/display-Pagination.md +41 -0
  226. package/skill-docs/references/components/display-Spin.md +34 -0
  227. package/skill-docs/references/components/display-Steps.md +89 -0
  228. package/skill-docs/references/components/display-Table.md +160 -0
  229. package/skill-docs/references/components/display-Title.md +117 -0
  230. package/skill-docs/references/components/form-Checkbox.md +161 -0
  231. package/skill-docs/references/components/form-DepartmentBrowser-api.md +52 -0
  232. package/skill-docs/references/components/form-EmployeeBrowser-api.md +51 -0
  233. package/skill-docs/references/components/form-EmployeeBrowser.md +51 -0
  234. package/skill-docs/references/components/form-Input.md +123 -0
  235. package/skill-docs/references/components/form-Radio.md +145 -0
  236. package/skill-docs/references/components/form-Select.md +191 -0
  237. package/skill-docs/references/components/form-Switch.md +46 -0
  238. package/skill-docs/references/components/form-Upload.md +53 -0
  239. package/skill-docs/references/components/generic-Echarts.md +102 -0
  240. package/skill-docs/references/form/guide-create-form.md +407 -0
  241. package/skill-docs/references/form/guide-ebuilder-filter.md +73 -0
  242. package/skill-docs/references/form/guide-ebuilder-scope.md +82 -0
  243. package/skill-docs/references/form/guide-form-data.md +48 -0
  244. package/skill-docs/references/form/guide-form-formula-functions.md +297 -0
  245. package/skill-docs/references/form/guide-form-linkage.md +185 -0
  246. package/skill-docs/references/form/guide-form-view-permission.md +38 -0
  247. package/skill-docs/references/form/guide-form-view.md +267 -0
  248. package/skill-docs/references/form/style-templates.md +44 -0
  249. package/skill-docs/references/hrm/guide-matrix.md +103 -0
  250. package/skill-docs/references/menu/system-menus.md +63 -0
  251. package/skill-docs/references/workflow/guide-workflow-action.md +168 -0
  252. package/skill-docs/references/workflow/guide-workflow-condition.md +405 -0
  253. package/skill-docs/references/workflow/guide-workflow.md +388 -0
  254. package/skill-docs/references/workflow/operator-matrix.md +74 -0
@@ -1,31 +1,340 @@
1
+ import { readFileSync } from 'node:fs';
1
2
  import { AuthSession } from '../core/auth.js';
2
3
  import { ApiClient } from '../core/client.js';
3
4
  /**
4
- * form serial-mark — 复杂编号(markField 年份编号,如 XM-2026-001)。
5
+ * form serial-mark — 复杂编号(markField)命令组。
5
6
  *
6
- * 依据 scaffold-apis/ebuilder-form/ebuilder-form-codingrule.md(权威流程):
7
- * 1) GET mark/markSet/getEbMarkTargetId?apid → targetId(后续接口的 workflowId/targetId)
8
- * 2) GET workflow/pathdef/mark/markSet/getMarkSetForm?workflowId → data.data.numberingRules(默认规则 ID)
9
- * 3) POST workflow/pathdef/mark/markSet/saveSingleMarkDef(numberingRules=上一步)→ data.markDefId(真实编码定义 ID)
10
- * 4) POST mark/markSet/saveOrUpdate?apid(id:"" 新增绑定)→ 绑定字段
11
- * 5) GET workflow/pathdef/mark/markField/getMarkFieldEditTable?markDefId&workflowId → 当前编号组成(默认年+流水)
12
- * 6) 按需修改组成(去年/改流水位数/加固定内容 FIX_CONTEXT)→ POST .../markField/saveMarkField
13
- * 解除编号:POST mark/markSet/updateEbMarkDeleteType(multipart,ids=<绑定记录id>)
7
+ * 平台编号由若干"段"按 position 顺序拼接,段类型:
8
+ * FIX_CONTEXT(固定内容) / DATE_YEAR(年) / SERIAL_NUMBER(流水号) /
9
+ * FORM_FIELD(表单字段值) / SYSTEM_FIELD(系统字段:创建人/创建人所属部门) / DATE(日期)
14
10
  *
15
- * 关键:markDefId 必须来自 saveSingleMarkDef 返回(不能用 generatorIds 自造);编号组成要基于
16
- * getMarkFieldEditTable 返回的原始对象归一化后修改(seqAlone 数组→标量、带 id),不能精简字段。
11
+ * 段对象必须来自 getMarkFieldAddData 预生成(含 id/newData/markExtend),不能自造。
12
+ * markDefId 必须来自 saveSingleMarkDef(不能用 generatorIds,幂等返回 numberingRules)。
13
+ * seqAlone 读是数组、写要数字(["DATE_YEAR"]→1),不能原样回写读回值。
14
+ * saveMarkField 是 upsert-by-id + delDefIds 删多余,不传 delDefIds 会累积段。
15
+ *
16
+ * 依据 scaffold-apis/ebuilder-form/ebuilder-form-codingrule.md + 浏览器抓包 monitor_1788252252375。
17
+ *
18
+ * 命令组:
19
+ * read 查看编号配置(绑定/组成/代字)
20
+ * set 基础编号(前缀+年+分隔符+流水,含 --year-format/--no-zero)
21
+ * add-segment 追加段(field/system/date/fixed,可任意 position)
22
+ * short-name 代字/简称(list/set,选项字段值用简称)
23
+ * fields 查可绑定为编号目标的字段
24
+ * clear 解除编号
17
25
  */
26
+ const EB_MARK = '/api/bs/ebuilder/form/mark/markSet';
27
+ const WF_MARK = '/api/bs/ebuilder/form/workflow/pathdef/mark';
28
+ // ─── 共用辅助 ───────────────────────────────────────────────
29
+ /** getEbMarkTargetId → targetId(后续接口当 workflowId 用) */
30
+ async function getTargetId(client, baseUrl, appId) {
31
+ const res = await client.get(`${baseUrl}${EB_MARK}/getEbMarkTargetId?apid=${appId}`);
32
+ const id = String(res?.data || '');
33
+ if (!id)
34
+ throw new Error(`获取编码目标失败: ${res?.msg || '未知错误'}`);
35
+ return id;
36
+ }
37
+ /** getMarkSetForm → numberingRules(默认规则ID,等同 markDefId) */
38
+ async function getNumberingRules(client, baseUrl, targetId) {
39
+ const res = await client.get(`${baseUrl}${WF_MARK}/markSet/getMarkSetForm?workflowId=${targetId}`);
40
+ const rules = String(res?.data?.data?.numberingRules || '');
41
+ if (!rules)
42
+ throw new Error(`获取默认编号规则失败: ${res?.msg || '未知错误'}`);
43
+ return rules;
44
+ }
45
+ /** saveSingleMarkDef → markDefId(真实编码定义ID,幂等返回 numberingRules) */
46
+ async function saveMarkDef(client, baseUrl, targetId) {
47
+ const numberingRules = await getNumberingRules(client, baseUrl, targetId);
48
+ const res = await client.post(`${baseUrl}${WF_MARK}/markSet/saveSingleMarkDef`, {
49
+ isUse: 1, contentChange: 0, markTriggerType: '1', numberingRules,
50
+ isFirstSet: false, isMultiMark: '0', reGenerate: 0, workflowSeqalone: 1,
51
+ disableInput: '0', workflowId: targetId,
52
+ });
53
+ const markDefId = String(res?.data?.markDefId || '');
54
+ if (!markDefId)
55
+ throw new Error(`创建编码定义失败: ${res?.msg || '未知错误'}`);
56
+ return markDefId;
57
+ }
58
+ /** getEbMarkSetList → 该表单所有编号绑定 */
59
+ async function getBindings(client, baseUrl, objId, appId) {
60
+ const res = await client.get(`${baseUrl}${EB_MARK}/getEbMarkSetList?objId=${objId}&apid=${appId}&sourceType=BACK`);
61
+ return res?.data?.markSetList || [];
62
+ }
63
+ /** 清除某字段的全部旧绑定(防累积),返回清除条数 */
64
+ async function clearFieldBindings(client, baseUrl, objId, appId, fieldId) {
65
+ const existing = (await getBindings(client, baseUrl, objId, appId))
66
+ .filter((x) => String(x.markFieldId) === String(fieldId));
67
+ for (const x of existing) {
68
+ const f = new URLSearchParams();
69
+ f.set('ids', String(x.id));
70
+ await client.postForm(`${baseUrl}${EB_MARK}/updateEbMarkDeleteType?apid=${appId}&objId=${objId}`, f.toString());
71
+ }
72
+ return existing.length;
73
+ }
74
+ /** 绑定字段到编号(id:"" 新建,或传已有 bindingId 更新) */
75
+ async function bindField(client, baseUrl, appId, objId, fieldId, targetId, bindingId = '') {
76
+ const res = await client.post(`${baseUrl}${EB_MARK}/saveOrUpdate?apid=${appId}&objId=${objId}`, {
77
+ markFieldId: fieldId, objId, id: bindingId, targetId,
78
+ codeEmptyUpdate: 0, enableReservedCode: 0, enableCustomChange: 0, remarks: '',
79
+ });
80
+ if (res?.code !== 200 || !res?.status)
81
+ throw new Error(`绑定字段失败: ${res?.msg || '未知错误'}`);
82
+ }
83
+ /** getMarkFieldEditTable → 当前编号组成段 */
84
+ async function getEditTable(client, baseUrl, markDefId, targetId) {
85
+ const res = await client.get(`${baseUrl}${WF_MARK}/markField/getMarkFieldEditTable?markDefId=${markDefId}&workflowId=${targetId}`);
86
+ return res?.data?.data || [];
87
+ }
88
+ /** 归一化段:seqAlone 数组→数字、补 workflowId/markDefId */
89
+ function normSeg(seg, targetId, markDefId) {
90
+ const s2 = { ...seg };
91
+ if (Array.isArray(s2.seqAlone))
92
+ s2.seqAlone = s2.seqAlone.length ? 1 : 0;
93
+ const sa = String(s2.seqAlone);
94
+ if (sa === '1' || sa === 'true')
95
+ s2.seqAlone = 1;
96
+ else if (s2.seqAlone === undefined || sa === '' || sa === 'false' || sa === '0' || sa === '[]')
97
+ s2.seqAlone = 0;
98
+ s2.workflowId = targetId;
99
+ s2.markDefId = markDefId;
100
+ return s2;
101
+ }
102
+ /** getMarkFieldAddData → 取预生成段对象(data[0]) */
103
+ async function getAddData(client, baseUrl, params, targetId) {
104
+ const qs = new URLSearchParams({
105
+ sub: '-2', other: '0', year: '-2', yearFormat: '0', yearMonthDay: '-2',
106
+ dep: '-2', otherType: '0', parentSub: '-2', hourMinSec: '-2', month: '-2',
107
+ hourMin: '-2', day: '-2', user: '-2', customRelateobjvalue: '',
108
+ variableCategory: '100', ...params, workflowId: targetId,
109
+ }).toString();
110
+ const res = await client.get(`${baseUrl}${WF_MARK}/markField/getMarkFieldAddData?${qs}`);
111
+ const arr = res?.data || [];
112
+ if (!arr.length)
113
+ throw new Error(`取编号段对象失败: ${res?.msg || '返回空'}`);
114
+ const seg = arr[0];
115
+ seg.workflowId = targetId;
116
+ seg.markDefId = '';
117
+ return seg;
118
+ }
119
+ /** 取固定内容段(FIX_CONTEXT) */
120
+ async function getFixSeg(client, baseUrl, baseFieldId, targetId, markDefId, value) {
121
+ const seg = await getAddData(client, baseUrl, {
122
+ showTypeItem: 'fixContent', relateType: 'dep', baseType: baseFieldId,
123
+ dateType: 'yearMonthDay', selectType: '0', systemField: '0',
124
+ }, targetId);
125
+ seg.relateObjValue = value;
126
+ seg.markDefId = markDefId;
127
+ return seg;
128
+ }
129
+ /** 取表单字段段(FORM_FIELD):baseType=取值字段 fieldId,返回段 markExtend=103(代字) */
130
+ async function getFieldSeg(client, baseUrl, fieldId, targetId, markDefId) {
131
+ const seg = await getAddData(client, baseUrl, {
132
+ showTypeItem: 'baseType', relateType: 'dep', baseType: fieldId,
133
+ dateType: 'yearMonthDay', selectType: '0', systemField: '0',
134
+ }, targetId);
135
+ seg.markDefId = markDefId;
136
+ return seg;
137
+ }
138
+ /** 取系统字段段(SYSTEM_FIELD):systemField 0=创建人 1=创建人所属部门(markExtend=101 部门代字) */
139
+ async function getSystemSeg(client, baseUrl, baseFieldId, targetId, markDefId, systemField) {
140
+ const seg = await getAddData(client, baseUrl, {
141
+ showTypeItem: 'systemField', relateType: 'dep', baseType: baseFieldId,
142
+ dateType: 'yearMonthDay', selectType: '0', systemField,
143
+ }, targetId);
144
+ seg.markDefId = markDefId;
145
+ return seg;
146
+ }
147
+ /** 取字段的编号上下文:优先用已绑定 markDef(持久化 targetId),无则按 createNew 决定是否新建。
148
+ * 注意:getEbMarkTargetId 每次返回新 targetId,故已有绑定时必须用绑定记录里的 targetId,
149
+ * 否则 saveSingleMarkDef 会建新 markDef,旧 markDef 上的段/代字数据被孤立。 */
150
+ async function getMarkContext(client, baseUrl, appId, objId, fieldId, createNew) {
151
+ const bindings = (await getBindings(client, baseUrl, objId, appId))
152
+ .filter((b) => String(b.markFieldId) === String(fieldId));
153
+ if (bindings.length) {
154
+ const b = bindings[0];
155
+ const targetId = String(b.targetId);
156
+ let markDefId = '';
157
+ try {
158
+ markDefId = await getNumberingRules(client, baseUrl, targetId);
159
+ }
160
+ catch { /* markSet 未初始化 */ }
161
+ return { targetId, markDefId, bindingId: String(b.id) };
162
+ }
163
+ if (!createNew)
164
+ return null;
165
+ const targetId = await getTargetId(client, baseUrl, appId);
166
+ const markDefId = await saveMarkDef(client, baseUrl, targetId);
167
+ await bindField(client, baseUrl, appId, objId, fieldId, targetId, '');
168
+ return { targetId, markDefId, bindingId: '' };
169
+ }
170
+ /** saveMarkField → 保存编号组成(upsert + delDefIds 删多余) */
171
+ async function saveSegments(client, baseUrl, targetId, markDefId, markFields, delDefIds = []) {
172
+ const res = await client.post(`${baseUrl}${WF_MARK}/markField/saveMarkField`, {
173
+ markFields, delDefIds, workflowId: targetId, markDefId,
174
+ });
175
+ if (res?.code !== 200 || !res?.status)
176
+ throw new Error(`保存编号组成失败: ${res?.msg || '未知错误'}`);
177
+ }
178
+ /** 查某 FORM_FIELD 段对应字段的代字列表 */
179
+ async function getShortNames(client, baseUrl, markDefId, targetId, fieldId) {
180
+ const res = await client.post(`${baseUrl}${WF_MARK}/shortNameSetting/getShortNameSettingEditTable`, {
181
+ current: 1, pageSize: 100, markDefId, workflowId: targetId, fieldId,
182
+ });
183
+ return res?.data?.data || [];
184
+ }
185
+ /** 保存代字 */
186
+ async function saveShortNames(client, baseUrl, list) {
187
+ const res = await client.post(`${baseUrl}${WF_MARK}/shortNameSetting/saveShortNameSetting`, { shortNameSettingList: list });
188
+ if (res?.code !== 200 || !res?.status)
189
+ throw new Error(`保存代字失败: ${res?.msg || '未知错误'}`);
190
+ }
191
+ /** 段类型 → 中文 */
192
+ const SEG_TYPE_LABEL = {
193
+ FIX_CONTEXT: '固定内容', DATE_YEAR: '年', SERIAL_NUMBER: '流水号位数',
194
+ FORM_FIELD: '表单字段', SYSTEM_FIELD: '系统字段', DATE_MONTH: '月', DATE_DAY: '日',
195
+ DATE: '日期',
196
+ };
197
+ /** 把段声明({type,...})映射为平台段对象。year/serial 复用 raw 默认段(带 id),
198
+ * 其余类型走 getMarkFieldAddData 预生成。 */
199
+ async function buildSegment(def, client, baseUrl, boundFieldId, targetId, markDefId, rawByType) {
200
+ const alone = def.alone ? 1 : 0;
201
+ switch (def.type) {
202
+ case 'fixed':
203
+ if (def.value === undefined)
204
+ throw new Error('fixed 段需要 value');
205
+ return await getFixSeg(client, baseUrl, boundFieldId, targetId, markDefId, String(def.value));
206
+ case 'year': {
207
+ const raw = rawByType('DATE_YEAR');
208
+ if (!raw)
209
+ throw new Error('无默认年份段(markDef 未初始化)');
210
+ const seg = normSeg(raw, targetId, markDefId);
211
+ seg.markExtend = def.format === 'two' ? '1' : '0'; // 0=四位(2026) 1=两位(26)
212
+ // alone:true → 按年份单独流水(DATE_YEAR seqAlone=1,流水号每年重新计数)
213
+ seg.seqAlone = def.alone === false ? 0 : 1;
214
+ return seg;
215
+ }
216
+ case 'serial': {
217
+ const raw = rawByType('SERIAL_NUMBER');
218
+ if (!raw)
219
+ throw new Error('无默认流水段(markDef 未初始化)');
220
+ const seg = normSeg(raw, targetId, markDefId);
221
+ seg.relateObjValue = Number(def.digits) || 4;
222
+ seg.seqAlone = def.zero === false ? 0 : 1; // 补零 0001
223
+ return seg;
224
+ }
225
+ case 'field': {
226
+ if (!def.fieldId)
227
+ throw new Error('field 段需要 fieldId');
228
+ const seg = await getFieldSeg(client, baseUrl, String(def.fieldId), targetId, markDefId);
229
+ seg.seqAlone = alone;
230
+ return seg;
231
+ }
232
+ case 'system': {
233
+ const sf = def.systemField === 'creator-dept' ? '1' : '0'; // 0=创建人 1=创建人所属部门
234
+ const seg = await getSystemSeg(client, baseUrl, boundFieldId, targetId, markDefId, sf);
235
+ seg.seqAlone = alone;
236
+ return seg;
237
+ }
238
+ case 'date': {
239
+ const src = def.source === 'current' ? '-2' : (def.source || '-2');
240
+ const seg = await getAddData(client, baseUrl, {
241
+ showTypeItem: 'dateType', relateType: 'dep', baseType: boundFieldId,
242
+ dateType: 'yearMonthDay', yearMonthDay: src, selectType: '0', systemField: '0',
243
+ }, targetId);
244
+ seg.markDefId = markDefId;
245
+ seg.seqAlone = alone;
246
+ return seg;
247
+ }
248
+ default:
249
+ throw new Error(`不支持的段类型: ${def.type}(fixed/year/serial/field/system/date)`);
250
+ }
251
+ }
252
+ /** 段声明 → 可读描述 */
253
+ function segDesc(def) {
254
+ switch (def.type) {
255
+ case 'fixed': return `固定(${def.value})`;
256
+ case 'year': return `年(${def.format || 'four'})`;
257
+ case 'serial': return `${def.digits || 4}位流水${def.zero === false ? '(不补零)' : ''}`;
258
+ case 'field': return `字段(${def.fieldId})`;
259
+ case 'system': return def.systemField === 'creator-dept' ? '创建人部门' : '创建人';
260
+ case 'date': return `日期(${def.format || 'yyyyMMdd'})`;
261
+ default: return def.type;
262
+ }
263
+ }
264
+ // ─── 命令组注册 ─────────────────────────────────────────────
18
265
  export function registerFormSerialMarkCommands(form, program) {
19
- form.command('serial-mark')
20
- .description('配置/解除复杂编号(markField:固定内容+年份+流水号,支持 XM-2026-001 年份编号)')
266
+ const sm = form.command('serial-mark')
267
+ .description('复杂编号(markField:固定内容+年份+流水+表单字段+系统字段+代字)');
268
+ // ─── read ───────────────────────────────────────────────
269
+ sm.command('read')
270
+ .description('查看编号配置(绑定字段 + 组成段 + 代字)')
271
+ .argument('<objId>', '表单 objId')
272
+ .argument('<appId>', '应用 ID')
273
+ .action(async (objId, appId) => {
274
+ const opts = program.opts();
275
+ const auth = await AuthSession.fromOptions(opts);
276
+ if (!auth)
277
+ process.exit(1);
278
+ const client = new ApiClient(auth);
279
+ const baseUrl = auth.getBaseUrl();
280
+ const bindings = await getBindings(client, baseUrl, objId, appId);
281
+ if (!bindings.length) {
282
+ console.log('未配置编号');
283
+ return;
284
+ }
285
+ const out = [];
286
+ for (const b of bindings) {
287
+ const fieldId = String(b.markFieldId);
288
+ const targetId = String(b.targetId);
289
+ const showName = b.showName || '';
290
+ let markDefId = '';
291
+ try {
292
+ markDefId = await getNumberingRules(client, baseUrl, targetId);
293
+ }
294
+ catch { /* markSet 未初始化 */ }
295
+ const segs = markDefId ? await getEditTable(client, baseUrl, markDefId, targetId) : [];
296
+ const segList = segs
297
+ .sort((a, b) => (a.position ?? 0) - (b.position ?? 0))
298
+ .map((s) => ({
299
+ type: s.markFieldType, label: SEG_TYPE_LABEL[s.markFieldType] || s.markFieldType,
300
+ value: s.relateObjValue ?? '', markExtend: s.markExtend ?? '', seqAlone: s.seqAlone,
301
+ }));
302
+ // 对 FORM_FIELD 段补代字
303
+ for (const seg of segList) {
304
+ if (seg.type === 'FORM_FIELD' && markDefId) {
305
+ try {
306
+ const names = await getShortNames(client, baseUrl, markDefId, targetId, String(seg.value));
307
+ seg.shortNames = names.filter((n) => n.abbr).map((n) => `${n.showName}=${n.abbr}`);
308
+ }
309
+ catch { /* 无代字 */ }
310
+ }
311
+ }
312
+ out.push({ fieldId, showName, targetId, markDefId, segments: segList });
313
+ }
314
+ if (opts.json) {
315
+ console.log(JSON.stringify(out, null, 2));
316
+ }
317
+ else {
318
+ for (const b of out) {
319
+ console.log(`字段 ${b.fieldId} (${b.showName || '?'}) targetId=${b.targetId} markDefId=${b.markDefId}`);
320
+ for (const s of b.segments) {
321
+ const ext = s.markExtend ? ` 代字(${s.markExtend})` : '';
322
+ const sa = s.seqAlone;
323
+ const isAlone = sa === 1 || sa === '1' || (Array.isArray(sa) && sa.length > 0);
324
+ const alone = isAlone ? ' [单独流水]' : '';
325
+ const sn = s.shortNames?.length ? ` 代字映射: ${s.shortNames.join(', ')}` : '';
326
+ console.log(` ${s.label}: ${s.value}${ext}${alone}${sn}`);
327
+ }
328
+ }
329
+ }
330
+ });
331
+ // ─── set(配置编号:--segments 多段组合,唯一正典方式)─────────────
332
+ sm.command('set')
333
+ .description('配置编号规则。--segments <json> 多段组合(数组顺序即编号拼接顺序,支持任意规则直接组合),重跑全量替换')
21
334
  .argument('<objId>', '表单 objId')
22
335
  .argument('<appId>', '应用 ID')
23
336
  .argument('<fieldId>', '要生成编号的字段 ID')
24
- .option('--prefix <text>', '固定内容前缀,如 "XM-"(FIX_CONTEXT)')
25
- .option('--year', '带年份段(DATE_YEAR)。缺省不带年份(仅 前缀+流水)')
26
- .option('--serial <n>', '流水号位数(SERIAL_NUMBER,如 4=0001)', '4')
27
- .option('--sep <text>', '年→流水之间的分隔符(独立 FIX_CONTEXT 段,默认 "-")', '-')
28
- .option('--clear', '解除该字段的编号')
337
+ .requiredOption('--segments <json>', '编号段配置 JSON(@文件 或 内联数组),按顺序决定段顺序。段类型: fixed/year/serial/field/system/date')
29
338
  .action(async (objId, appId, fieldId, cmdOpts) => {
30
339
  const opts = program.opts();
31
340
  const auth = await AuthSession.fromOptions(opts);
@@ -33,135 +342,293 @@ export function registerFormSerialMarkCommands(form, program) {
33
342
  process.exit(1);
34
343
  const client = new ApiClient(auth);
35
344
  const baseUrl = auth.getBaseUrl();
36
- const MARK_API = `${baseUrl}/api/bs/ebuilder/form/mark/markSet`;
37
- const MARK_WF_API = `${baseUrl}/api/bs/ebuilder/form/workflow/pathdef/mark/markSet`;
38
- const MARK_FIELD_API = `${baseUrl}/api/bs/ebuilder/form/workflow/pathdef/mark/markField`;
39
- // 1. targetId
40
- const tRes = await client.get(`${MARK_API}/getEbMarkTargetId?apid=${appId}`);
41
- const targetId = String(tRes?.data || '');
42
- if (!targetId) {
43
- console.error(`获取编码目标失败: ${tRes?.msg || '未知错误'}`);
44
- process.exit(1);
45
- }
46
- // --clear:查绑定记录 id → 解除
47
- if (cmdOpts.clear) {
48
- let bindingId = '';
49
- try {
50
- const q = await client.get(`${MARK_API}/getEbMarkSetList?objId=${objId}&apid=${appId}&sourceType=BACK`);
51
- const s = (q?.data?.markSetList || []).find((x) => String(x.markFieldId) === String(fieldId));
52
- bindingId = String(s?.id || '');
345
+ let segStr = cmdOpts.segments;
346
+ if (segStr.startsWith('@'))
347
+ segStr = readFileSync(segStr.slice(1), 'utf-8');
348
+ let segDefs;
349
+ try {
350
+ segDefs = JSON.parse(segStr);
351
+ }
352
+ catch {
353
+ console.error('--segments JSON 解析失败');
354
+ process.exit(1);
355
+ }
356
+ if (!Array.isArray(segDefs) || !segDefs.length) {
357
+ console.error('--segments 必须是非空数组');
358
+ process.exit(1);
359
+ }
360
+ // 复用已有 markDef(保代字/绑定),无则新建并绑定
361
+ const ctx = await getMarkContext(client, baseUrl, appId, objId, fieldId, true);
362
+ if (!ctx) {
363
+ console.error('无法获取编号上下文');
364
+ process.exit(1);
365
+ }
366
+ const { targetId, markDefId } = ctx;
367
+ // 读现有段(复用 year/serial 的 id,其余旧段 id 进 delDefIds)
368
+ const raw = markDefId ? await getEditTable(client, baseUrl, markDefId, targetId) : [];
369
+ const rawByType = (t) => raw.find((x) => x.markFieldType === t);
370
+ const final = [];
371
+ const shortNameBatches = [];
372
+ for (const def of segDefs) {
373
+ final.push(await buildSegment(def, client, baseUrl, fieldId, targetId, markDefId, rawByType));
374
+ if (def.type === 'field' && def.fieldId && def.shortName) {
375
+ shortNameBatches.push({ fieldId: String(def.fieldId), map: def.shortName });
376
+ }
377
+ }
378
+ final.forEach((s, i) => { s.position = i; });
379
+ // delDefIds:现有段不在 final(按 id)的全部删除(全量替换,防累积)
380
+ const finalIds = new Set(final.filter((s) => s.id).map((s) => String(s.id)));
381
+ const delDefIds = raw.filter((s) => s.id && !finalIds.has(String(s.id))).map((s) => String(s.id));
382
+ await saveSegments(client, baseUrl, targetId, markDefId, final, delDefIds);
383
+ // inline 代字(field 段带 shortName)
384
+ for (const sn of shortNameBatches) {
385
+ const existing = await getShortNames(client, baseUrl, markDefId, targetId, sn.fieldId);
386
+ const byName = new Map(existing.map((n) => [String(n.showName), n]));
387
+ const list = [];
388
+ let idx = 0;
389
+ for (const [showName, abbr] of Object.entries(sn.map)) {
390
+ const old = byName.get(showName);
391
+ list.push({ showName, markDefId, abbr, fieldValue: old?.fieldValue || '', fieldId: sn.fieldId, id: old?.id ?? idx++ });
53
392
  }
54
- catch { /* 查询失败则无从清除 */ }
55
- if (!bindingId) {
56
- console.error('未找到该字段的编号绑定,无需解除');
393
+ await saveShortNames(client, baseUrl, list);
394
+ }
395
+ const desc = segDefs.map(segDesc).join(' + ');
396
+ console.log(opts.json
397
+ ? JSON.stringify({ success: true, targetId, markDefId, fieldId, segments: final.length, shortNames: shortNameBatches.length })
398
+ : `编号已配置(${final.length}段): ${desc} → 绑定字段 ${fieldId}`);
399
+ });
400
+ // ─── add-segment(追加段)─────────────────────────────────
401
+ sm.command('add-segment')
402
+ .description('给编号追加段。--type field/system/date/fixed;保留已有段,新段默认追加到末尾')
403
+ .argument('<objId>', '表单 objId')
404
+ .argument('<appId>', '应用 ID')
405
+ .argument('<fieldId>', '已绑定编号的字段 ID')
406
+ .requiredOption('--type <type>', '段类型: field(表单字段) / system(系统字段) / date(日期) / fixed(固定内容)')
407
+ .option('--field-id <id>', '取值字段 ID(type=field 时必填;type=date 且 --source 为字段时用)')
408
+ .option('--system-field <which>', '系统字段: creator(创建人) / creator-dept(创建人所属部门)。type=system 时必填')
409
+ .option('--value <text>', '固定内容值(type=fixed 时必填)')
410
+ .option('--date-format <fmt>', '日期格式: yyyy / yyyyMM / yyyyMMdd(type=date 时,缺省 yyyyMMdd)', 'yyyyMMdd')
411
+ .option('--source <src>', '日期来源: current(当前日期,缺省) / <字段ID>(type=date 时)', 'current')
412
+ .option('--alone', '该段机构单独流水(seqAlone=1)')
413
+ .option('--position <n>', '插入位置(0 起,缺省追加末尾)')
414
+ .action(async (objId, appId, fieldId, cmdOpts) => {
415
+ const opts = program.opts();
416
+ const auth = await AuthSession.fromOptions(opts);
417
+ if (!auth)
418
+ process.exit(1);
419
+ const client = new ApiClient(auth);
420
+ const baseUrl = auth.getBaseUrl();
421
+ // 取编号上下文:已有绑定用旧 markDef(保住段/代字),无则新建
422
+ const ctx = await getMarkContext(client, baseUrl, appId, objId, fieldId, true);
423
+ if (!ctx) {
424
+ console.error('无法获取编号上下文');
425
+ process.exit(1);
426
+ }
427
+ const { targetId, markDefId } = ctx;
428
+ // 取现有段(复用 id,防累积)
429
+ const existing = markDefId ? await getEditTable(client, baseUrl, markDefId, targetId) : [];
430
+ let newSeg;
431
+ if (cmdOpts.type === 'field') {
432
+ if (!cmdOpts.fieldId) {
433
+ console.error('type=field 需要 --field-id');
57
434
  process.exit(1);
58
435
  }
59
- const form = new URLSearchParams();
60
- form.set('ids', bindingId);
61
- const delRes = await client.postForm(`${MARK_API}/updateEbMarkDeleteType?apid=${appId}&objId=${objId}`, form.toString());
62
- if (delRes?.code === 200 && delRes?.status)
63
- console.log(`已解除字段 ${fieldId} 的编号绑定`);
64
- else {
65
- console.error(`解除失败: ${delRes?.msg || '未知错误'}`);
436
+ newSeg = await getFieldSeg(client, baseUrl, cmdOpts.fieldId, targetId, markDefId);
437
+ }
438
+ else if (cmdOpts.type === 'system') {
439
+ const sf = cmdOpts.systemField === 'creator-dept' ? '1' : '0';
440
+ newSeg = await getSystemSeg(client, baseUrl, fieldId, targetId, markDefId, sf);
441
+ }
442
+ else if (cmdOpts.type === 'date') {
443
+ const src = cmdOpts.source === 'current' ? '-2' : (cmdOpts.source || '-2');
444
+ newSeg = await getAddData(client, baseUrl, {
445
+ showTypeItem: 'dateType', relateType: 'dep', baseType: fieldId,
446
+ dateType: 'yearMonthDay', yearMonthDay: src, selectType: '0', systemField: '0',
447
+ }, targetId);
448
+ newSeg.markDefId = markDefId;
449
+ }
450
+ else if (cmdOpts.type === 'fixed') {
451
+ if (cmdOpts.value === undefined) {
452
+ console.error('type=fixed 需要 --value');
66
453
  process.exit(1);
67
454
  }
68
- return;
455
+ newSeg = await getFixSeg(client, baseUrl, fieldId, targetId, markDefId, cmdOpts.value);
69
456
  }
70
- // 2. 默认规则 ID(getMarkSetForm → numberingRules)
71
- const gsf = await client.get(`${MARK_WF_API}/getMarkSetForm?workflowId=${targetId}`);
72
- const numberingRules = String(gsf?.data?.data?.numberingRules || '');
73
- if (!numberingRules) {
74
- console.error(`获取默认编号规则失败: ${gsf?.msg || '未知错误'}`);
457
+ else {
458
+ console.error(`不支持的 type: ${cmdOpts.type}(field/system/date/fixed)`);
75
459
  process.exit(1);
76
460
  }
77
- // 2.5 清除该字段已有编号绑定(防累积:重跑时旧绑定残留带年份,与新绑定冲突 → "KH-20260001")
461
+ // seqAlone
462
+ newSeg.seqAlone = cmdOpts.alone ? 1 : 0;
463
+ // 合并:现有段(归一化,保留 id)+ 新段
464
+ const merged = existing.map((s) => normSeg(s, targetId, markDefId));
465
+ merged.push(newSeg);
466
+ // position:指定位置插入,否则末尾
467
+ const pos = cmdOpts.position !== undefined ? parseInt(cmdOpts.position, 10) : merged.length - 1;
468
+ // 先把新段放最后,再按 position 重排(简单做法:移到指定下标)
469
+ const idx = merged.length - 1;
470
+ if (pos >= 0 && pos < idx) {
471
+ const [item] = merged.splice(idx, 1);
472
+ merged.splice(pos, 0, item);
473
+ }
474
+ merged.forEach((s, i) => { s.position = i; });
475
+ await saveSegments(client, baseUrl, targetId, markDefId, merged, []);
476
+ // 回读验证
477
+ const after = await getEditTable(client, baseUrl, markDefId, targetId);
478
+ console.log(opts.json
479
+ ? JSON.stringify({ success: true, targetId, markDefId, fieldId, segments: after.length })
480
+ : `已追加 ${cmdOpts.type} 段 → 编号现有 ${after.length} 段`);
481
+ });
482
+ // ─── short-name(代字/简称)──────────────────────────────
483
+ const sn = sm.command('short-name').description('代字/简称设置(选项字段值用简称拼进编号)');
484
+ sn.command('list')
485
+ .description('查看某字段各选项的代字')
486
+ .argument('<objId>', '表单 objId')
487
+ .argument('<appId>', '应用 ID')
488
+ .argument('<fieldId>', '选项字段 ID(FORM_FIELD 段的取值字段)')
489
+ .action(async (objId, appId, fieldId) => {
490
+ const opts = program.opts();
491
+ const auth = await AuthSession.fromOptions(opts);
492
+ if (!auth)
493
+ process.exit(1);
494
+ const client = new ApiClient(auth);
495
+ const baseUrl = auth.getBaseUrl();
496
+ // 代字属于编号绑定字段的 markDef,fieldId 是被引用的 Select 字段(非绑定字段)。
497
+ // 从表单任意绑定取 targetId/markDefId,再用 fieldId 查代字。
498
+ const bindings = await getBindings(client, baseUrl, objId, appId);
499
+ if (!bindings.length) {
500
+ console.error('该表单未配置编号,无法查代字');
501
+ process.exit(1);
502
+ }
503
+ const targetId = String(bindings[0].targetId);
504
+ let markDefId = '';
78
505
  try {
79
- const q = await client.get(`${MARK_API}/getEbMarkSetList?objId=${objId}&apid=${appId}&sourceType=BACK`);
80
- const existing = (q?.data?.markSetList || []).filter((x) => String(x.markFieldId) === String(fieldId));
81
- for (const x of existing) {
82
- const f = new URLSearchParams();
83
- f.set('ids', String(x.id));
84
- await client.postForm(`${MARK_API}/updateEbMarkDeleteType?apid=${appId}&objId=${objId}`, f.toString());
85
- }
86
- if (existing.length)
87
- console.error(` 已清除 ${existing.length} 个旧编号绑定`);
88
- }
89
- catch { /* 清除失败不阻断 */ }
90
- // 3. 创建编码定义 → 真实 markDefId
91
- const smd = await client.post(`${MARK_WF_API}/saveSingleMarkDef`, {
92
- isUse: 1, contentChange: 0, markTriggerType: '1', numberingRules,
93
- isFirstSet: true, isMultiMark: '0', reGenerate: 0, workflowSeqalone: 1,
94
- disableInput: '0', workflowId: targetId,
95
- });
96
- const markDefId = String(smd?.data?.markDefId || '');
506
+ markDefId = await getNumberingRules(client, baseUrl, targetId);
507
+ }
508
+ catch { /* */ }
97
509
  if (!markDefId) {
98
- console.error(`创建编码定义失败: ${smd?.msg || '未知错误'}`);
99
- process.exit(1);
100
- }
101
- // 4. 绑定到字段(新建 id:"")
102
- const bindRes = await client.post(`${MARK_API}/saveOrUpdate?apid=${appId}&objId=${objId}`, {
103
- markFieldId: fieldId, objId, id: '', targetId,
104
- codeEmptyUpdate: 0, enableReservedCode: 0, enableCustomChange: 0, remarks: '',
105
- });
106
- if (bindRes?.code !== 200 || !bindRes?.status) {
107
- console.error(`绑定字段失败: ${bindRes?.msg || '未知错误'}`);
108
- process.exit(1);
109
- }
110
- // 5. 读当前编号组成(默认 年+流水)
111
- const et = await client.get(`${MARK_FIELD_API}/getMarkFieldEditTable?markDefId=${markDefId}&workflowId=${targetId}`);
112
- const raw = et?.data?.data || [];
113
- // 6. 归一化 raw 段(seqAlone 数组→标量;保留 id/workflowId/markDefId),按 前缀→年→流水 顺序重排
114
- const norm = (seg) => {
115
- const s2 = { ...seg };
116
- if (Array.isArray(s2.seqAlone))
117
- s2.seqAlone = s2.seqAlone.length ? '1' : '0';
118
- if (String(s2.seqAlone) === '1' || String(s2.seqAlone) === 'true')
119
- s2.seqAlone = 1;
120
- s2.workflowId = targetId;
121
- s2.markDefId = markDefId;
122
- return s2;
123
- };
124
- const byType = (type) => raw.find((x) => x.markFieldType === type);
125
- const getFixCfg = async () => {
126
- const addFix = await client.get(`${MARK_FIELD_API}/getMarkFieldAddData?showTypeItem=fixContent&relateType=dep&baseType=${fieldId}&workflowId=${targetId}&variableCategory=100&dateType=yearMonthDay&selectType=0&systemField=0`);
127
- return (addFix?.data || [])[0] || {};
128
- };
129
- const final = [];
130
- if (cmdOpts.prefix)
131
- final.push({ ...await getFixCfg(), relateObjValue: cmdOpts.prefix, workflowId: targetId, markDefId });
132
- if (cmdOpts.year && byType('DATE_YEAR'))
133
- final.push(norm(byType('DATE_YEAR')));
134
- if (cmdOpts.year && byType('SERIAL_NUMBER') && cmdOpts.sep) {
135
- // 年→流水之间的分隔符是独立 FIX_CONTEXT 段(对齐浏览器:HTMC-2026-0001 的 "-")
136
- final.push({ ...await getFixCfg(), relateObjValue: cmdOpts.sep, workflowId: targetId, markDefId });
137
- }
138
- if (byType('SERIAL_NUMBER')) {
139
- const serialSeg = norm(byType('SERIAL_NUMBER'));
140
- serialSeg.relateObjValue = parseInt(cmdOpts.serial || '4', 10) || 4; // 流水位数
141
- serialSeg.seqAlone = 1; // 对齐浏览器配置:序列独立 → 补零 0001
142
- final.push(serialSeg);
143
- }
144
- final.forEach((seg, i) => { seg.position = i; });
145
- // 不在 final 中的默认段(如未指定 --year 时的 DATE_YEAR)必须显式删除,
146
- // 否则 saveMarkField 保留默认组成 → 年份残留,显示成 "2026KH-0001" 而非 "KH-0001"
147
- const finalTypes = new Set(final.map((s) => s.markFieldType));
148
- const delDefIds = raw
149
- .filter((s) => s.id && !finalTypes.has(s.markFieldType))
150
- .map((s) => String(s.id));
151
- // 7. 保存编号组成
152
- const saveRes = await client.post(`${MARK_FIELD_API}/saveMarkField`, {
153
- markFields: final, markDefId, delDefIds, workflowId: targetId,
154
- });
155
- if (saveRes?.code !== 200 || !saveRes?.status) {
156
- console.error(`保存编号组成失败: ${saveRes?.msg || '未知错误'}`);
157
- process.exit(1);
158
- }
159
- // 注:被编码字段平台自动设为只读(无需 CLI 处理)
160
- const parts = [cmdOpts.prefix, cmdOpts.year ? '年份' : '', `${cmdOpts.serial}位流水`].filter(Boolean);
161
- const msg = opts.json
162
- ? JSON.stringify({ success: true, targetId, markDefId, fieldId })
163
- : `编号已配置: ${parts.join('+')} → 绑定字段 ${fieldId}`;
164
- console.log(msg);
510
+ console.error('无法获取编号定义 markDefId');
511
+ process.exit(1);
512
+ }
513
+ const list = await getShortNames(client, baseUrl, markDefId, targetId, fieldId);
514
+ if (opts.json) {
515
+ console.log(JSON.stringify(list, null, 2));
516
+ }
517
+ else {
518
+ console.log(`共 ${list.length} 个选项:`);
519
+ for (const n of list)
520
+ console.log(` ${n.showName} 代字: ${n.abbr || '(未设)'}`);
521
+ }
522
+ });
523
+ sn.command('set')
524
+ .description('批量设置代字。--map 为 JSON 映射(选项名→代字),如 @map.json 或 {"研发":"YF"}')
525
+ .argument('<objId>', '表单 objId')
526
+ .argument('<appId>', '应用 ID')
527
+ .argument('<fieldId>', '选项字段 ID')
528
+ .requiredOption('--map <json>', '代字映射 JSON({"研发":"YF","实施":"SS"})或 @文件')
529
+ .action(async (objId, appId, fieldId, cmdOpts) => {
530
+ const opts = program.opts();
531
+ const auth = await AuthSession.fromOptions(opts);
532
+ if (!auth)
533
+ process.exit(1);
534
+ const client = new ApiClient(auth);
535
+ const baseUrl = auth.getBaseUrl();
536
+ // 解析映射
537
+ let mapStr = cmdOpts.map;
538
+ if (mapStr.startsWith('@'))
539
+ mapStr = readFileSync(mapStr.slice(1), 'utf-8');
540
+ const map = JSON.parse(mapStr);
541
+ // 从表单绑定取 markDefId(代字挂在编号绑定的 markDef 上,fieldId 是被引用 Select 字段)
542
+ const bindings = await getBindings(client, baseUrl, objId, appId);
543
+ if (!bindings.length) {
544
+ console.error('该表单未配置编号,无法设代字');
545
+ process.exit(1);
546
+ }
547
+ const targetId = String(bindings[0].targetId);
548
+ let markDefId = '';
549
+ try {
550
+ markDefId = await getNumberingRules(client, baseUrl, targetId);
551
+ }
552
+ catch { /* */ }
553
+ if (!markDefId) {
554
+ console.error('无法获取编号定义 markDefId');
555
+ process.exit(1);
556
+ }
557
+ const existing = await getShortNames(client, baseUrl, markDefId, targetId, fieldId);
558
+ // 现有项 id 映射(更新用真实 id,新增用 0/1/2 递增)
559
+ const byName = new Map(existing.map((n) => [String(n.showName), n]));
560
+ const list = [];
561
+ let newIdx = 0;
562
+ for (const [showName, abbr] of Object.entries(map)) {
563
+ const old = byName.get(showName);
564
+ list.push({
565
+ showName, markDefId, abbr,
566
+ fieldValue: old?.fieldValue || '',
567
+ fieldId,
568
+ id: old?.id ?? newIdx++,
569
+ });
570
+ }
571
+ await saveShortNames(client, baseUrl, list);
572
+ console.log(opts.json
573
+ ? JSON.stringify({ success: true, set: list.length })
574
+ : `已设置 ${list.length} 个代字: ${list.map((n) => `${n.showName}=${n.abbr}`).join(', ')}`);
575
+ });
576
+ // ─── fields(查可绑定字段)────────────────────────────────
577
+ sm.command('fields')
578
+ .description('查可作为编号目标的字段列表')
579
+ .argument('<objId>', '表单 objId')
580
+ .argument('<appId>', '应用 ID')
581
+ .option('--target-field <fieldId>', '参考字段 ID(可选,过滤可绑定字段)')
582
+ .action(async (objId, appId, cmdOpts) => {
583
+ const opts = program.opts();
584
+ const auth = await AuthSession.fromOptions(opts);
585
+ if (!auth)
586
+ process.exit(1);
587
+ const client = new ApiClient(auth);
588
+ const baseUrl = auth.getBaseUrl();
589
+ const params = new URLSearchParams({ objId, apid: appId });
590
+ params.set('targetMarkField', cmdOpts.targetField || '-2');
591
+ if (cmdOpts.targetField) {
592
+ params.set('objId', objId);
593
+ }
594
+ const res = await client.get(`${baseUrl}${EB_MARK}/getEbMarkFields?${params.toString()}`);
595
+ const fields = res?.data || [];
596
+ if (opts.json) {
597
+ console.log(JSON.stringify(fields, null, 2));
598
+ }
599
+ else {
600
+ console.log(`共 ${fields.length} 个可绑定字段:`);
601
+ for (const f of fields)
602
+ console.log(` ${f.id} ${f.showName} (${f.componentKey || f.type})`);
603
+ }
604
+ });
605
+ // ─── clear(解除编号)─────────────────────────────────────
606
+ sm.command('clear')
607
+ .description('解除该字段的编号绑定')
608
+ .argument('<objId>', '表单 objId')
609
+ .argument('<appId>', '应用 ID')
610
+ .argument('<fieldId>', '要解除的字段 ID')
611
+ .action(async (objId, appId, fieldId) => {
612
+ const opts = program.opts();
613
+ const auth = await AuthSession.fromOptions(opts);
614
+ if (!auth)
615
+ process.exit(1);
616
+ const client = new ApiClient(auth);
617
+ const baseUrl = auth.getBaseUrl();
618
+ const existing = (await getBindings(client, baseUrl, objId, appId))
619
+ .filter((x) => String(x.markFieldId) === String(fieldId));
620
+ if (!existing.length) {
621
+ console.error('未找到该字段的编号绑定,无需解除');
622
+ process.exit(1);
623
+ }
624
+ for (const x of existing) {
625
+ const f = new URLSearchParams();
626
+ f.set('ids', String(x.id));
627
+ await client.postForm(`${baseUrl}${EB_MARK}/updateEbMarkDeleteType?apid=${appId}&objId=${objId}`, f.toString());
628
+ }
629
+ console.log(opts.json
630
+ ? JSON.stringify({ success: true, fieldId, cleared: existing.length })
631
+ : `已解除字段 ${fieldId} 的编号绑定(${existing.length} 条)`);
165
632
  });
166
633
  }
167
634
  //# sourceMappingURL=form-serial-mark.js.map