weaver-e10-builder 1.5.12 → 1.5.14

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 (333) hide show
  1. package/dist/commands/actionflow.d.ts.map +1 -1
  2. package/dist/commands/actionflow.js +1 -0
  3. package/dist/commands/actionflow.js.map +1 -1
  4. package/dist/commands/designer-common.d.ts.map +1 -1
  5. package/dist/commands/designer-common.js +91 -0
  6. package/dist/commands/designer-common.js.map +1 -1
  7. package/dist/commands/designer-setters.d.ts.map +1 -1
  8. package/dist/commands/designer-setters.js +148 -47
  9. package/dist/commands/designer-setters.js.map +1 -1
  10. package/dist/commands/form-add-detail-table.d.ts.map +1 -1
  11. package/dist/commands/form-add-detail-table.js +150 -8
  12. package/dist/commands/form-add-detail-table.js.map +1 -1
  13. package/dist/commands/form-browser-definition.d.ts +14 -0
  14. package/dist/commands/form-browser-definition.d.ts.map +1 -0
  15. package/dist/commands/form-browser-definition.js +493 -0
  16. package/dist/commands/form-browser-definition.js.map +1 -0
  17. package/dist/commands/form-code.d.ts +5 -0
  18. package/dist/commands/form-code.d.ts.map +1 -0
  19. package/dist/commands/form-code.js +276 -0
  20. package/dist/commands/form-code.js.map +1 -0
  21. package/dist/commands/form-engine-linkage.d.ts +3 -0
  22. package/dist/commands/form-engine-linkage.d.ts.map +1 -0
  23. package/dist/commands/form-engine-linkage.js +199 -0
  24. package/dist/commands/form-engine-linkage.js.map +1 -0
  25. package/dist/commands/form-formula.d.ts.map +1 -1
  26. package/dist/commands/form-formula.js +11 -6
  27. package/dist/commands/form-formula.js.map +1 -1
  28. package/dist/commands/form-layout-template-advanced.d.ts +3 -0
  29. package/dist/commands/form-layout-template-advanced.d.ts.map +1 -0
  30. package/dist/commands/form-layout-template-advanced.js +115 -0
  31. package/dist/commands/form-layout-template-advanced.js.map +1 -0
  32. package/dist/commands/form-layout-template-easy.d.ts +3 -0
  33. package/dist/commands/form-layout-template-easy.d.ts.map +1 -0
  34. package/dist/commands/form-layout-template-easy.js +59 -0
  35. package/dist/commands/form-layout-template-easy.js.map +1 -0
  36. package/dist/commands/form-layout.d.ts.map +1 -1
  37. package/dist/commands/form-layout.js +77 -0
  38. package/dist/commands/form-layout.js.map +1 -1
  39. package/dist/commands/form-list-filter.js +1 -1
  40. package/dist/commands/form-list-filter.js.map +1 -1
  41. package/dist/commands/form-list-utils.d.ts +5 -0
  42. package/dist/commands/form-list-utils.d.ts.map +1 -1
  43. package/dist/commands/form-list-utils.js +23 -3
  44. package/dist/commands/form-list-utils.js.map +1 -1
  45. package/dist/commands/form-permission.d.ts.map +1 -1
  46. package/dist/commands/form-permission.js +55 -19
  47. package/dist/commands/form-permission.js.map +1 -1
  48. package/dist/commands/form-physical-table.d.ts.map +1 -1
  49. package/dist/commands/form-physical-table.js +8 -2
  50. package/dist/commands/form-physical-table.js.map +1 -1
  51. package/dist/commands/form.d.ts.map +1 -1
  52. package/dist/commands/form.js +476 -30
  53. package/dist/commands/form.js.map +1 -1
  54. package/dist/commands/menu.d.ts +68 -2
  55. package/dist/commands/menu.d.ts.map +1 -1
  56. package/dist/commands/menu.js +186 -41
  57. package/dist/commands/menu.js.map +1 -1
  58. package/dist/commands/page.d.ts.map +1 -1
  59. package/dist/commands/page.js +29 -6
  60. package/dist/commands/page.js.map +1 -1
  61. package/dist/commands/special.d.ts.map +1 -1
  62. package/dist/commands/special.js +3 -2
  63. package/dist/commands/special.js.map +1 -1
  64. package/dist/commands/wf-form.d.ts.map +1 -1
  65. package/dist/commands/wf-form.js +76 -31
  66. package/dist/commands/wf-form.js.map +1 -1
  67. package/dist/commands/workflow-auth-resp.js +2 -2
  68. package/dist/commands/workflow-auth-resp.js.map +1 -1
  69. package/dist/commands/workflow-base-settings.d.ts +3 -0
  70. package/dist/commands/workflow-base-settings.d.ts.map +1 -0
  71. package/dist/commands/workflow-base-settings.js +73 -0
  72. package/dist/commands/workflow-base-settings.js.map +1 -0
  73. package/dist/commands/workflow-condition.d.ts.map +1 -1
  74. package/dist/commands/workflow-condition.js +59 -450
  75. package/dist/commands/workflow-condition.js.map +1 -1
  76. package/dist/commands/workflow-export.d.ts +9 -0
  77. package/dist/commands/workflow-export.d.ts.map +1 -0
  78. package/dist/commands/workflow-export.js +121 -0
  79. package/dist/commands/workflow-export.js.map +1 -0
  80. package/dist/commands/workflow-node.d.ts.map +1 -1
  81. package/dist/commands/workflow-node.js +28 -53
  82. package/dist/commands/workflow-node.js.map +1 -1
  83. package/dist/commands/workflow-operator-batch.d.ts +3 -0
  84. package/dist/commands/workflow-operator-batch.d.ts.map +1 -0
  85. package/dist/commands/workflow-operator-batch.js +35 -0
  86. package/dist/commands/workflow-operator-batch.js.map +1 -0
  87. package/dist/commands/workflow-subprocess.d.ts.map +1 -1
  88. package/dist/commands/workflow-subprocess.js +21 -33
  89. package/dist/commands/workflow-subprocess.js.map +1 -1
  90. package/dist/commands/workflow.d.ts.map +1 -1
  91. package/dist/commands/workflow.js +36 -37
  92. package/dist/commands/workflow.js.map +1 -1
  93. package/dist/index.js +18 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/services/actionflow/browser_source.d.ts +9 -0
  96. package/dist/services/actionflow/browser_source.d.ts.map +1 -0
  97. package/dist/services/actionflow/browser_source.js +12 -0
  98. package/dist/services/actionflow/browser_source.js.map +1 -0
  99. package/dist/services/actionflow/components/date_trigger.js +1 -1
  100. package/dist/services/actionflow/components/date_trigger.js.map +1 -1
  101. package/dist/services/actionflow/components/document_actions.d.ts.map +1 -1
  102. package/dist/services/actionflow/components/document_actions.js +178 -25
  103. package/dist/services/actionflow/components/document_actions.js.map +1 -1
  104. package/dist/services/actionflow/components/enquiry_form.js +1 -1
  105. package/dist/services/actionflow/components/enquiry_form.js.map +1 -1
  106. package/dist/services/actionflow/components/logic_flow_set.d.ts.map +1 -1
  107. package/dist/services/actionflow/components/logic_flow_set.js +80 -8
  108. package/dist/services/actionflow/components/logic_flow_set.js.map +1 -1
  109. package/dist/services/actionflow/components/meeting_create.d.ts.map +1 -1
  110. package/dist/services/actionflow/components/meeting_create.js +1 -0
  111. package/dist/services/actionflow/components/meeting_create.js.map +1 -1
  112. package/dist/services/actionflow/components/schedule_create.d.ts.map +1 -1
  113. package/dist/services/actionflow/components/schedule_create.js +2 -0
  114. package/dist/services/actionflow/components/schedule_create.js.map +1 -1
  115. package/dist/services/actionflow/components/time_batch_trigger.js +1 -1
  116. package/dist/services/actionflow/components/time_batch_trigger.js.map +1 -1
  117. package/dist/services/actionflow/components/workflow_actions.d.ts.map +1 -1
  118. package/dist/services/actionflow/components/workflow_actions.js +6 -2
  119. package/dist/services/actionflow/components/workflow_actions.js.map +1 -1
  120. package/dist/services/actionflow/context_preflight.d.ts +5 -0
  121. package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
  122. package/dist/services/actionflow/context_preflight.js +186 -35
  123. package/dist/services/actionflow/context_preflight.js.map +1 -1
  124. package/dist/services/actionflow/filter_rules.d.ts.map +1 -1
  125. package/dist/services/actionflow/filter_rules.js +9 -8
  126. package/dist/services/actionflow/filter_rules.js.map +1 -1
  127. package/dist/services/actionflow/form_source.d.ts +2 -0
  128. package/dist/services/actionflow/form_source.d.ts.map +1 -1
  129. package/dist/services/actionflow/form_source.js +8 -0
  130. package/dist/services/actionflow/form_source.js.map +1 -1
  131. package/dist/services/actionflow/formula_service.d.ts +2 -1
  132. package/dist/services/actionflow/formula_service.d.ts.map +1 -1
  133. package/dist/services/actionflow/formula_service.js +69 -34
  134. package/dist/services/actionflow/formula_service.js.map +1 -1
  135. package/dist/services/actionflow/logicflow_source.d.ts +5 -0
  136. package/dist/services/actionflow/logicflow_source.d.ts.map +1 -0
  137. package/dist/services/actionflow/logicflow_source.js +15 -0
  138. package/dist/services/actionflow/logicflow_source.js.map +1 -0
  139. package/dist/services/actionflow/preflight_service.d.ts +15 -0
  140. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  141. package/dist/services/actionflow/preflight_service.js +561 -29
  142. package/dist/services/actionflow/preflight_service.js.map +1 -1
  143. package/dist/services/actionflow/runtime_metadata.d.ts +8 -0
  144. package/dist/services/actionflow/runtime_metadata.d.ts.map +1 -1
  145. package/dist/services/actionflow/runtime_metadata.js +25 -0
  146. package/dist/services/actionflow/runtime_metadata.js.map +1 -1
  147. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  148. package/dist/services/actionflow/workflow_compiler.js +75 -23
  149. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  150. package/dist/services/actionflow/workflow_source.d.ts +2 -0
  151. package/dist/services/actionflow/workflow_source.d.ts.map +1 -1
  152. package/dist/services/actionflow/workflow_source.js +7 -0
  153. package/dist/services/actionflow/workflow_source.js.map +1 -1
  154. package/dist/services/auth-resp-condition.d.ts +7 -3
  155. package/dist/services/auth-resp-condition.d.ts.map +1 -1
  156. package/dist/services/auth-resp-condition.js +58 -63
  157. package/dist/services/auth-resp-condition.js.map +1 -1
  158. package/dist/services/browser.d.ts +5 -0
  159. package/dist/services/browser.d.ts.map +1 -1
  160. package/dist/services/browser.js +16 -4
  161. package/dist/services/browser.js.map +1 -1
  162. package/dist/services/condition-rules.d.ts +2 -30
  163. package/dist/services/condition-rules.d.ts.map +1 -1
  164. package/dist/services/condition-rules.js +3 -219
  165. package/dist/services/condition-rules.js.map +1 -1
  166. package/dist/services/designer-dataset.d.ts +45 -0
  167. package/dist/services/designer-dataset.d.ts.map +1 -0
  168. package/dist/services/designer-dataset.js +156 -0
  169. package/dist/services/designer-dataset.js.map +1 -0
  170. package/dist/services/form-association.d.ts +7 -0
  171. package/dist/services/form-association.d.ts.map +1 -1
  172. package/dist/services/form-association.js +22 -1
  173. package/dist/services/form-association.js.map +1 -1
  174. package/dist/services/form-code.d.ts +53 -0
  175. package/dist/services/form-code.d.ts.map +1 -0
  176. package/dist/services/form-code.js +370 -0
  177. package/dist/services/form-code.js.map +1 -0
  178. package/dist/services/form-create.d.ts +20 -0
  179. package/dist/services/form-create.d.ts.map +1 -1
  180. package/dist/services/form-create.js +73 -1
  181. package/dist/services/form-create.js.map +1 -1
  182. package/dist/services/form-field-build.d.ts +1 -1
  183. package/dist/services/form-field-build.d.ts.map +1 -1
  184. package/dist/services/form-field-build.js +20 -1
  185. package/dist/services/form-field-build.js.map +1 -1
  186. package/dist/services/form-field-drop.d.ts +2 -0
  187. package/dist/services/form-field-drop.d.ts.map +1 -1
  188. package/dist/services/form-field-drop.js +2 -0
  189. package/dist/services/form-field-drop.js.map +1 -1
  190. package/dist/services/form-layout-detail-insert.d.ts +58 -0
  191. package/dist/services/form-layout-detail-insert.d.ts.map +1 -0
  192. package/dist/services/form-layout-detail-insert.js +293 -0
  193. package/dist/services/form-layout-detail-insert.js.map +1 -0
  194. package/dist/services/form-layout-insert.d.ts.map +1 -1
  195. package/dist/services/form-layout-insert.js +34 -2
  196. package/dist/services/form-layout-insert.js.map +1 -1
  197. package/dist/services/form-layout-source/compile.d.ts.map +1 -1
  198. package/dist/services/form-layout-source/compile.js +11 -4
  199. package/dist/services/form-layout-source/compile.js.map +1 -1
  200. package/dist/services/form-layout-template-advanced.d.ts +330 -0
  201. package/dist/services/form-layout-template-advanced.d.ts.map +1 -0
  202. package/dist/services/form-layout-template-advanced.js +1437 -0
  203. package/dist/services/form-layout-template-advanced.js.map +1 -0
  204. package/dist/services/form-layout-template-easy.d.ts +34 -0
  205. package/dist/services/form-layout-template-easy.d.ts.map +1 -0
  206. package/dist/services/form-layout-template-easy.js +159 -0
  207. package/dist/services/form-layout-template-easy.js.map +1 -0
  208. package/dist/services/form-layout-template-flow.d.ts +23 -0
  209. package/dist/services/form-layout-template-flow.d.ts.map +1 -0
  210. package/dist/services/form-layout-template-flow.js +99 -0
  211. package/dist/services/form-layout-template-flow.js.map +1 -0
  212. package/dist/services/form-linkage-condition.d.ts +15 -0
  213. package/dist/services/form-linkage-condition.d.ts.map +1 -1
  214. package/dist/services/form-linkage-condition.js +19 -10
  215. package/dist/services/form-linkage-condition.js.map +1 -1
  216. package/dist/services/form-permission-archive.d.ts +23 -1
  217. package/dist/services/form-permission-archive.d.ts.map +1 -1
  218. package/dist/services/form-permission-archive.js +54 -2
  219. package/dist/services/form-permission-archive.js.map +1 -1
  220. package/dist/services/form-physical-table.d.ts +10 -0
  221. package/dist/services/form-physical-table.d.ts.map +1 -1
  222. package/dist/services/form-physical-table.js +20 -0
  223. package/dist/services/form-physical-table.js.map +1 -1
  224. package/dist/services/form-sub-detail.d.ts +25 -0
  225. package/dist/services/form-sub-detail.d.ts.map +1 -1
  226. package/dist/services/form-sub-detail.js +64 -0
  227. package/dist/services/form-sub-detail.js.map +1 -1
  228. package/dist/services/form-view-linkage-functions.d.ts +19 -0
  229. package/dist/services/form-view-linkage-functions.d.ts.map +1 -0
  230. package/dist/services/form-view-linkage-functions.js +90 -0
  231. package/dist/services/form-view-linkage-functions.js.map +1 -0
  232. package/dist/services/matrix-condition.d.ts +32 -1
  233. package/dist/services/matrix-condition.d.ts.map +1 -1
  234. package/dist/services/matrix-condition.js +169 -6
  235. package/dist/services/matrix-condition.js.map +1 -1
  236. package/dist/services/menu-catalog.d.ts +24 -1
  237. package/dist/services/menu-catalog.d.ts.map +1 -1
  238. package/dist/services/menu-catalog.js +49 -2
  239. package/dist/services/menu-catalog.js.map +1 -1
  240. package/dist/services/workflow-base-settings.d.ts +117 -0
  241. package/dist/services/workflow-base-settings.d.ts.map +1 -0
  242. package/dist/services/workflow-base-settings.js +504 -0
  243. package/dist/services/workflow-base-settings.js.map +1 -0
  244. package/dist/services/workflow-condition-core.d.ts +48 -0
  245. package/dist/services/workflow-condition-core.d.ts.map +1 -0
  246. package/dist/services/workflow-condition-core.js +316 -0
  247. package/dist/services/workflow-condition-core.js.map +1 -0
  248. package/dist/services/workflow-context.d.ts +10 -0
  249. package/dist/services/workflow-context.d.ts.map +1 -0
  250. package/dist/services/workflow-context.js +15 -0
  251. package/dist/services/workflow-context.js.map +1 -0
  252. package/dist/services/workflow-export.d.ts +80 -0
  253. package/dist/services/workflow-export.d.ts.map +1 -0
  254. package/dist/services/workflow-export.js +150 -0
  255. package/dist/services/workflow-export.js.map +1 -0
  256. package/dist/services/workflow-field-permission-route.d.ts +75 -0
  257. package/dist/services/workflow-field-permission-route.d.ts.map +1 -0
  258. package/dist/services/workflow-field-permission-route.js +52 -0
  259. package/dist/services/workflow-field-permission-route.js.map +1 -0
  260. package/dist/services/workflow-field-permission.d.ts +18 -0
  261. package/dist/services/workflow-field-permission.d.ts.map +1 -0
  262. package/dist/services/workflow-field-permission.js +40 -0
  263. package/dist/services/workflow-field-permission.js.map +1 -0
  264. package/dist/services/workflow-node-layout.d.ts +11 -10
  265. package/dist/services/workflow-node-layout.d.ts.map +1 -1
  266. package/dist/services/workflow-node-layout.js +24 -62
  267. package/dist/services/workflow-node-layout.js.map +1 -1
  268. package/dist/services/workflow-operator-batch-condition.d.ts +23 -0
  269. package/dist/services/workflow-operator-batch-condition.d.ts.map +1 -0
  270. package/dist/services/workflow-operator-batch-condition.js +56 -0
  271. package/dist/services/workflow-operator-batch-condition.js.map +1 -0
  272. package/dist/services/workflow-operator.d.ts +12 -5
  273. package/dist/services/workflow-operator.d.ts.map +1 -1
  274. package/dist/services/workflow-operator.js +41 -16
  275. package/dist/services/workflow-operator.js.map +1 -1
  276. package/package.json +1 -1
  277. package/skill-docs/SKILL.md +155 -290
  278. package/skill-docs/_catalog.md +12 -3
  279. package/skill-docs/actionflows/references/components/document/GetDocumentInfo.md +17 -17
  280. package/skill-docs/actionflows/references/components/logic/LogicFlowSet.md +23 -17
  281. package/skill-docs/assets/form-template/style-templates-advanced-base-example.json +1420 -0
  282. package/skill-docs/assets/form-template/style-templates-advanced-base.css +33 -0
  283. package/skill-docs/assets/form-template/style-templates-advanced-blue-crystal-example.json +1094 -0
  284. package/skill-docs/assets/form-template/style-templates-advanced-document-example.json +1251 -0
  285. package/skill-docs/assets/form-template/style-templates-advanced-grid-example.json +39 -0
  286. package/skill-docs/assets/form-template/style-templates-advanced-page-example.json +38 -0
  287. package/skill-docs/assets/form-template/style-templates-advanced-placements-example.json +30 -0
  288. package/skill-docs/assets/form-template/style-templates-advanced-standard-example.json +53 -0
  289. package/skill-docs/assets/form-template/style-templates-advanced-structure-example.json +25 -0
  290. package/skill-docs/assets/form-template/style-templates-advanced-table-example.json +1420 -0
  291. package/skill-docs/references/code-block/guide-code-block.md +141 -0
  292. package/skill-docs/references/code-block/guide-layout-css.md +107 -0
  293. package/skill-docs/references/code-block/ref-controls.md +60 -0
  294. package/skill-docs/references/code-block/ref-coverage.md +32 -0
  295. package/skill-docs/references/code-block/ref-details.md +57 -0
  296. package/skill-docs/references/code-block/ref-events-validation.md +42 -0
  297. package/skill-docs/references/code-block/ref-foundations-fields.md +56 -0
  298. package/skill-docs/references/code-block/ref-recipes.md +164 -0
  299. package/skill-docs/references/code-block/ref-troubleshooting.md +49 -0
  300. package/skill-docs/references/code-block/ref-ui-global.md +47 -0
  301. package/skill-docs/references/coding/guide-page-code.md +2 -0
  302. package/skill-docs/references/coding/ref-compile-rules.md +2 -0
  303. package/skill-docs/references/common/capability-boundaries.md +15 -0
  304. package/skill-docs/references/common/guide-install.md +44 -0
  305. package/skill-docs/references/common/guide-plan-template.md +2 -1
  306. package/skill-docs/references/common/map.md +11 -1
  307. package/skill-docs/references/common/ref-cli-commands.md +689 -648
  308. package/skill-docs/references/ebuilder-designer/guide-designer-factory.md +8 -4
  309. package/skill-docs/references/form/form-template/style-templates-advanced-css-guide.md +167 -0
  310. package/skill-docs/references/form/form-template/style-templates-advanced.md +315 -0
  311. package/skill-docs/references/form/form-template/style-templates-easy.md +55 -0
  312. package/skill-docs/references/form/form-template/style-templates-flow.md +27 -0
  313. package/skill-docs/references/form/form-template/style-templates.md +29 -0
  314. package/skill-docs/references/form/guide-browser-definition.md +148 -0
  315. package/skill-docs/references/form/guide-create-form.md +258 -250
  316. package/skill-docs/references/form/guide-field-linkage.md +56 -14
  317. package/skill-docs/references/form/guide-form-archive-permission.md +29 -6
  318. package/skill-docs/references/form/guide-form-formula-functions.md +11 -0
  319. package/skill-docs/references/form/guide-form-layout-incremental.md +28 -0
  320. package/skill-docs/references/form/guide-form-layout-planning.md +11 -0
  321. package/skill-docs/references/form/guide-form-layout-source.md +4 -0
  322. package/skill-docs/references/form/guide-form-linkage.md +295 -269
  323. package/skill-docs/references/form/guide-form-physical-table.md +2 -0
  324. package/skill-docs/references/form/guide-form-view.md +3 -0
  325. package/skill-docs/references/form/ref-form-fields.md +301 -293
  326. package/skill-docs/references/form/ref-list-filter-date-params.md +83 -0
  327. package/skill-docs/references/menu/system-menus.md +12 -0
  328. package/skill-docs/references/workflow/condition-core-contract.md +63 -0
  329. package/skill-docs/references/workflow/guide-base-auth-share-remind.md +126 -0
  330. package/skill-docs/references/workflow/guide-workflow-condition.md +476 -447
  331. package/skill-docs/references/workflow/guide-workflow-node-layout.md +6 -0
  332. package/skill-docs/references/workflow/guide-workflow.md +29 -3
  333. package/skill-docs/references/form/style-templates.md +0 -97
@@ -1,73 +1,38 @@
1
1
  import { AuthSession } from '../core/auth.js';
2
2
  import { ApiClient } from '../core/client.js';
3
+ import { compileWorkflowCondition, persistWorkflowCondition } from '../services/workflow-condition-core.js';
4
+ import { readFileSync } from 'node:fs';
3
5
  /**
4
6
  * workflow condition — 工作流条件(add / list / get / delete)。
5
7
  * 从 workflow.ts 拆分出来的增强版:操作符矩阵、系统字段、替换语义、明细字段。
6
8
  */
7
9
  export function registerWorkflowConditionCommands(wf, program) {
8
10
  const condCmd = wf.command('condition').description('工作流条件管理(add / list / get)');
9
- // ======== Operator Matrix (from operator-matrix.md) ========
10
- const SYSTEM_FIELDS = {
11
- '流程标题': { id: '-1', family: 'String' },
12
- '发起人': { id: '-2', family: 'Browser' },
13
- '发起时间': { id: '-3', family: 'Date' },
14
- '发起人部门': { id: '-4', family: 'Browser' },
15
- '发起人分部': { id: '-5', family: 'Browser' },
16
- '发起人岗位': { id: '-6', family: 'Browser' },
17
- '发起人职级': { id: '-7', family: 'Browser' },
18
- '当前操作人': { id: '-8', family: 'Browser' },
19
- '流程超时(时)': { id: '-9', family: 'Number' },
20
- '节点通过时间(时)': { id: '-10', family: 'Number' },
21
- '紧急程度': { id: '-12', family: 'Browser' },
22
- '发起人直接上级': { id: '-13', family: 'Browser' },
23
- '当前操作人直接上级': { id: '-14', family: 'Browser' },
24
- '密级': { id: '-30', family: 'Browser' },
25
- };
26
- // Operator code → Chinese name
27
- const OP_MAP = {
28
- '大于': { code: '1', single: true, right: true },
29
- '大于等于': { code: '2', single: true, right: true },
30
- '小于': { code: '3', single: true, right: true },
31
- '小于等于': { code: '4', single: true, right: true },
32
- '等于': { code: '5', single: true, right: true },
33
- '不等于': { code: '6', single: true, right: true },
34
- '包含': { code: '9', single: true, right: false },
35
- '属于': { code: '9', single: true, right: false },
36
- '不包含': { code: '10', single: true, right: false },
37
- '不属于': { code: '10', single: true, right: false },
38
- '为空': { code: '13', single: true, right: false },
39
- '不为空': { code: '14', single: true, right: false },
40
- '包含子部门': { code: '15', single: true, right: false },
41
- '不包含子部门': { code: '16', single: true, right: false },
42
- '是': { code: '23', single: true, right: false },
43
- '否': { code: '24', single: true, right: false },
44
- '范围': { code: '', single: false, right: true }, // special: two-value range
45
- };
46
- // Family → allowed operators
47
- const FAMILY_OPS = {
48
- 'String': ['等于', '不等于', '包含', '不包含', '为空', '不为空'],
49
- 'Number': ['大于', '大于等于', '小于', '小于等于', '等于', '不等于', '为空', '不为空', '范围'],
50
- 'Date': ['大于', '大于等于', '小于', '小于等于', '等于', '不等于', '为空', '不为空', '范围'],
51
- 'Browser': ['等于', '不等于', '包含', '属于', '不包含', '不属于', '为空', '不为空', '包含子部门', '不包含子部门'],
52
- 'Bool': ['是', '否'],
53
- };
54
- // Family → param key prefix (for API payload)
55
- const FAMILY_PREFIX = {
56
- 'String': 'String',
57
- 'Number': 'Number',
58
- 'Date': 'Date',
59
- 'Browser': 'Browser',
60
- 'Bool': 'Bool',
61
- };
11
+ condCmd.command('schema').description('读取平台条件设计器契约(字段类型、操作符及浏览配置)')
12
+ .argument('<workflowId>').argument('<sourceId>').option('--source <n>', '条件场景编码', '2')
13
+ .action(async (workflowId, sourceId, o) => {
14
+ if (!/^\d+$/.test(o.source))
15
+ throw Error('source 必须为整数');
16
+ const auth = await AuthSession.fromOptions(program.opts());
17
+ if (!auth)
18
+ throw Error('无法加载认证');
19
+ const client = new ApiClient(auth);
20
+ const res = await client.post(auth.getBaseUrl() + '/api/workflow/pathdef/rule/condition/getRuleDesignCondition', { workflowId, sourceId, source: Number(o.source), needFormfield: true, readOnly: true });
21
+ if (res?.code !== 200 || res.status === false)
22
+ throw Error('读取条件契约失败');
23
+ console.log(JSON.stringify(res.data, null, 2));
24
+ });
62
25
  condCmd.command('add')
63
26
  .description('用中文简化语法添加条件(基于 operator-matrix 校验字段类型)')
64
27
  .argument('<workflowId>', '流程 ID')
65
28
  .argument('<sourceId>', '上下文出口 ID(用于解析表单)')
66
29
  .argument('<nodeId>', '来源节点 ID(用于绑定)')
67
30
  .argument('<name>', '条件名称(唯一)')
68
- .requiredOption('--rule <rules...>', '条件规则,格式: "来源:字段:操作:值[:值2]"\n'
31
+ .option('--rule <rules...>', '条件规则,格式: "来源:字段:操作:值[:值2]"\n'
69
32
  + ' 来源=system 用系统字段中文名;来源=form 可用字段ID、字段名或 dataKey(三者均可匹配)\n'
70
- + ' 例: --rule "system:流程标题:包含:测试" --rule "form:合同金额:大于:1000:小于:5000"')
33
+ + ' 例: --rule "system:流程标题:包含:测试" --rule "form:合同金额:范围:1000:5000"')
34
+ .option('--rules-json <jsonOrFile>', '结构化条件树 JSON 或 @文件')
35
+ .option('--preview', '只编译并展示条件树,不保存')
71
36
  .option('--relation <rel>', '多条规则间的关系: AND(默认) / OR', 'AND')
72
37
  .action(async (workflowId, sourceId, nodeId, name, cmdOpts) => {
73
38
  const opts = program.opts();
@@ -76,373 +41,37 @@ export function registerWorkflowConditionCommands(wf, program) {
76
41
  process.exit(1);
77
42
  const client = new ApiClient(auth);
78
43
  const baseUrl = auth.getBaseUrl();
79
- const relation = cmdOpts.relation === 'OR' ? 2 : 1;
80
- // 1. Fetch form fields (for form-type rules)
81
- let formFields = [];
82
- try {
83
- const fbRes = await client.post(`${baseUrl}/api/workflow/pathdef/common/browser/complete/conditionFieldBrowser`, { browserMultiple: false, sourceId, tab: 'formField', source: 2, workflowId, newly: 1, pageSize: 100, searchValue: '' });
84
- formFields = fbRes?.data?.data || [];
85
- }
86
- catch { /* best effort */ }
87
- // 2. Parse rules, validate, build childrens
88
- const childrens = [];
89
- const parseErrors = [];
90
- // 单条规则 → 一个叶子(或 null,出错时)。用 | 分隔的组在调用侧拆成 OR 组。
91
- async function buildLeaf(ruleStr) {
92
- let parts = ruleStr.split(':');
93
- // 明细量词:末尾 :任一 / :所有(detailOption 1=任一行 2=所有行,明细字段必填)
94
- let detailOption = '';
95
- const last = parts[parts.length - 1];
96
- if (last === '任一' || last === '所有') {
97
- detailOption = last === '所有' ? '2' : '1';
98
- parts = parts.slice(0, -1);
99
- }
100
- const source = parts[0]; // system or form
101
- const fieldRef = parts[1]; // system field name or form field ID
102
- const opName = parts[2];
103
- let family = '';
104
- let selectType = '';
105
- let systemVariable = '';
106
- let formFieldObj = null;
107
- let fieldOptions = []; // for Browser/Select/CheckBox option-value resolution
108
- if (source === 'system') {
109
- const sf = SYSTEM_FIELDS[fieldRef];
110
- if (!sf) {
111
- parseErrors.push(`未知系统字段: ${fieldRef},可选: ${Object.keys(SYSTEM_FIELDS).join(', ')}`);
112
- return null;
113
- }
114
- selectType = '3';
115
- systemVariable = sf.id;
116
- family = sf.family;
117
- }
118
- else if (source === 'form') {
119
- selectType = '4';
120
- // layoutDetail is a JSON string carrying dataKey/columnName/componentKey —
121
- // native workflow forms regenerate fieldIds on creation, so matching by id
122
- // alone fails; fall back to name / dataKey / columnName.
123
- const parseLayout = (f) => {
124
- try {
125
- return typeof f.layoutDetail === 'string' ? JSON.parse(f.layoutDetail) : (f.layoutDetail || {});
126
- }
127
- catch {
128
- return {};
129
- }
130
- };
131
- let ff = formFields.find((f) => {
132
- if (String(f.id) === fieldRef || f.name === fieldRef)
133
- return true;
134
- const ld = parseLayout(f);
135
- return ld.dataKey === fieldRef || ld.columnName === fieldRef || ld.componentKey === fieldRef;
136
- });
137
- // Select/CheckBox/RadioBox 等选项字段是懒加载:空 searchValue 不返回,
138
- // 需用字段名再搜一次才能拿到(含完整 options,供带值条件解析选项)。
139
- if (!ff) {
140
- try {
141
- const sRes = await client.post(`${baseUrl}/api/workflow/pathdef/common/browser/complete/conditionFieldBrowser`, { browserMultiple: false, sourceId, tab: 'formField', source: 2, workflowId, newly: 1, pageSize: 100, searchValue: fieldRef });
142
- const searched = sRes?.data?.data || [];
143
- ff = searched.find((f) => {
144
- if (String(f.id) === fieldRef || f.name === fieldRef)
145
- return true;
146
- const ld = parseLayout(f);
147
- return ld.dataKey === fieldRef || ld.columnName === fieldRef;
148
- }) || null;
149
- if (ff)
150
- formFields.push(ff);
151
- }
152
- catch { /* 二次搜索失败则走下面报错 */ }
153
- }
154
- if (!ff) {
155
- const avail = formFields.map((f) => {
156
- const ld = parseLayout(f);
157
- return ` ${f.id} ${f.name} [${f.fieldType}]${ld.dataKey ? ` dataKey=${ld.dataKey}` : ''}`;
158
- }).join('\n');
159
- parseErrors.push(`未找到表单字段: ${fieldRef}(在 sourceId=${sourceId} 上下文中)\n可用字段:\n${avail || ' (无)'}`);
160
- return null;
161
- }
162
- const ld = parseLayout(ff);
163
- // Send the full field object as formField[0] (matches browser payload;
164
- // layoutDetail carries options the server needs for option-value validation).
165
- formFieldObj = ff;
166
- fieldOptions = ld.options || [];
167
- // Map fieldType → family using real conditionFieldBrowser type names.
168
- // componentKey (from layoutDetail) is the authoritative type marker.
169
- // Note: CheckBox/RadioBox/Select are option-based → Browser (属于/包含某选项),
170
- // NOT Bool. Bool (是/否) only applies to a single-value Switch toggle.
171
- const ft = ff.fieldType || ld.componentKey || '';
172
- if (['DateComponent', 'DatePicker', 'DateTimePicker', 'Date'].includes(ft))
173
- family = 'Date';
174
- else if (['NumberComponent', 'Money', 'Float', 'Integer', 'Number'].includes(ft))
175
- family = 'Number';
176
- else if (['Switch', 'Bool'].includes(ft))
177
- family = 'Bool';
178
- else if (['Employee', 'Department', 'Role', 'Browser', 'BrowserButton', 'Select', 'RadioBox', 'CheckBox', 'Checkbox', 'PositionComponent', 'Location', 'Ebuilder', 'Eb', 'Flow'].includes(ft))
179
- family = 'Browser';
180
- else
181
- family = 'String';
182
- }
183
- else {
184
- parseErrors.push(`来源必须是 system 或 form: ${source}`);
185
- return null;
186
- }
187
- // Validate operator
188
- const allowed = FAMILY_OPS[family] || [];
189
- if (!allowed.includes(opName)) {
190
- parseErrors.push(`字段 "${fieldRef}" (类型=${family}) 不支持操作 "${opName}",可选: ${allowed.join(', ')}`);
191
- return null;
192
- }
193
- // Build leaf node
194
- const opInfo = OP_MAP[opName];
195
- // 系统 Browser 字段(紧急程度/密级等,selectType=3)用 SysBrowser 前缀(抓包实测)
196
- const prefix = (selectType === '3' && family === 'Browser') ? 'SysBrowser' : FAMILY_PREFIX[family];
197
- const leaf = {
198
- selectType,
199
- elementValue1Id: '', elementValue2Id: '', expressionBaseId: '', dataValueId: '',
200
- };
201
- if (selectType === '3')
202
- leaf.systemVariable = systemVariable;
203
- if (selectType === '4') {
204
- leaf.formField = [formFieldObj];
205
- // 明细字段必填 detailOption(1=任一行 默认 / 2=所有行)
206
- const isDetail = formFieldObj?.detail || (formFieldObj?.detailName && formFieldObj.detailName !== '主表');
207
- if (isDetail)
208
- leaf.detailOption = detailOption || '1';
209
- }
210
- // Single-value operators (empty/null use special codes, no value needed)
211
- if (opName === '为空' || opName === '不为空') {
212
- leaf[`${prefix}CompareOptionLeft`] = opInfo.code;
213
- }
214
- else if (opName === '范围') {
215
- // 变量模式(字段 vs 字段):来源:字段:范围:field:左字段:右字段
216
- const isVarRange = parts[3] === 'field';
217
- if (isVarRange) {
218
- const vfL = formFields.find((f) => String(f.id) === (parts[4] || '') || f.name === (parts[4] || ''));
219
- const vfR = formFields.find((f) => String(f.id) === (parts[5] || '') || f.name === (parts[5] || ''));
220
- if (!vfL || !vfR) {
221
- parseErrors.push(`范围字段未找到: 左="${parts[4]}" 右="${parts[5]}"(可用: ${formFields.map((f) => f.name).join(', ')})`);
222
- return null;
223
- }
224
- leaf[`${prefix}CompareOptionLeft`] = '1';
225
- leaf[`${prefix}ValueOptionLeft`] = '2';
226
- leaf[`${prefix}TextValueLeft2`] = [vfL];
227
- leaf[`${prefix}CompareOptionRight`] = '3';
228
- leaf[`${prefix}ValueOptionRight`] = '2';
229
- leaf[`${prefix}TextValueRight2`] = [vfR];
230
- if (family === 'Date')
231
- leaf.typeHrm = '11';
232
- }
233
- else {
234
- // Range: value and value2 are left/right boundaries(字面值)
235
- const v1 = parts[3] || '';
236
- const v2 = parts[4] || '';
237
- if (!v1 || !v2) {
238
- parseErrors.push(`范围操作需要两个值: ${ruleStr}(格式: 来源:字段:范围:左值:右值 或 来源:字段:范围:field:左字段:右字段)`);
239
- return null;
240
- }
241
- if (family === 'Number') {
242
- leaf.NumberCompareOptionLeft = '1'; // 大于
243
- leaf.NumberValueOptionLeft = '1';
244
- leaf.NumberTextValueLeft1 = Number(v1);
245
- leaf.NumberCompareOptionRight = '3'; // 小于
246
- leaf.NumberValueOptionRight = '1';
247
- leaf.NumberTextValueRight1 = Number(v2);
248
- }
249
- else if (family === 'Date') {
250
- leaf.DateCompareOptionLeft = '1';
251
- leaf.DateValueOptionLeft = '1';
252
- leaf.DateTextValueLeft1 = v1;
253
- leaf.DateCompareOptionRight = '3';
254
- leaf.DateValueOptionRight = '1';
255
- leaf.DateTextValueRight1 = v2;
256
- }
257
- }
258
- }
259
- else {
260
- // Single-bound operator
261
- const isVarSingle = parts[3] === 'field';
262
- if (isVarSingle) {
263
- // 字段 vs 字段:来源:字段:操作:field:值字段
264
- const vf = formFields.find((f) => String(f.id) === (parts[4] || '') || f.name === (parts[4] || ''));
265
- if (!vf) {
266
- parseErrors.push(`值字段未找到: "${parts[4]}"(可用: ${formFields.map((f) => f.name).join(', ')})`);
267
- return null;
268
- }
269
- leaf[`${prefix}CompareOptionLeft`] = opInfo.code;
270
- leaf[`${prefix}ValueOptionLeft`] = '2';
271
- leaf[`${prefix}TextValueLeft2`] = [vf];
272
- if (family === 'Date')
273
- leaf.typeHrm = '11';
274
- }
275
- else {
276
- const value = parts[3] || '';
277
- leaf[`${prefix}CompareOptionLeft`] = opInfo.code;
278
- if (value) {
279
- if (family === 'Browser') {
280
- // 区分:系统 Browser 字段(紧急程度等,SysBrowser 前缀 + 系统选项)、
281
- // 人员/部门字段(走 person/dept 浏览器解析成完整对象)、
282
- // Select/CheckBox/RadioBox(走 fieldOptions 选项解析)。
283
- const ft = String(formFieldObj?.fieldType || formFieldObj?.groupKey || '');
284
- const isEmployee = /employee|user/i.test(ft);
285
- const isDept = /department|dept/i.test(ft);
286
- const vals = value.split(',').map((s) => s.trim()).filter(Boolean);
287
- const resolved = [];
288
- if (selectType === '3') {
289
- // 系统 Browser 字段(紧急程度/密级等):值走系统选项 {id, content}(抓包 SysBrowserTextValueLeft1=[{id:"2",content:"紧急"}])
290
- const SYS_OPTS = {
291
- '紧急程度': { '普通': '1', '紧急': '2' },
292
- };
293
- const sysOpts = SYS_OPTS[fieldRef] || {};
294
- for (const v of vals) {
295
- const id = sysOpts[v];
296
- if (id)
297
- resolved.push({ id, content: v });
298
- else
299
- parseErrors.push(`系统字段 "${fieldRef}" 的值 "${v}" 无映射(已映射: ${Object.keys(sysOpts).join(',') || '无'})`);
300
- }
301
- if (resolved.length > 0) {
302
- leaf[`${prefix}ValueOptionLeft`] = '1';
303
- leaf[`${prefix}TextValueLeft1`] = resolved;
304
- leaf.containType = '1';
305
- }
306
- }
307
- else if (isEmployee || isDept) {
308
- // 人员/部门:值走浏览器解析成完整对象(抓包 BrowserTextValueLeft1 = 完整人员对象数组,typeHrm=1)
309
- for (const v of vals) {
310
- if (isEmployee) {
311
- const ud = await client.post(`${baseUrl}/api/hrm/common/getEmployeeByKeyWords`, {
312
- keyword: v, searchType: 1, searchCount: 1, appDetachModule: 'EM', disableAppDetach: 0, pageNo: 1, pageSize: 1,
313
- });
314
- const e = ud?.data?.userList?.[0];
315
- if (e) {
316
- resolved.push({
317
- id: e.id || '', cid: e.cid || e.companyId || '', userid: e.userid || e.userId || e.id || '',
318
- name: e.name || '', statusCode: e.statusCode || 'normal', content: e.name || '',
319
- title: `${e.name || ''}|${e.department || ''}`, contentDesc: e.name || '', department: e.department || '',
320
- avatar: e.avatar || { previewPath: '', appPreviewPath: '', name: e.name || '', userId: e.id || '' },
321
- indexType: 'R', isLeaf: true, mobile: e.mobile || e.officePhone || '', officePhone: e.officePhone || e.mobile || '',
322
- templateType: 'default', originTargetType: 'user', pid: '', richContent: e.name || '',
323
- departmentId: e.departmentId || e.departmentid || '', mainId: e.mainId || e.id || '',
324
- leaf: true, stopDepartment: false,
325
- });
326
- }
327
- else
328
- parseErrors.push(`未找到人员: ${v}`);
329
- }
330
- else {
331
- // D07: 部门解析多匹配禁止取首条(重名会选错)——精确/歧义规则在 resolveDepartment
332
- const { resolveDepartment } = await import('../services/workflow-operator.js');
333
- try {
334
- const dh = await resolveDepartment(client, baseUrl, v);
335
- resolved.push({ id: dh.id, name: dh.name, content: dh.name, title: dh.name, isLeaf: true, icon: 'Icon-department03', leaf: true, stopDepartment: false });
336
- }
337
- catch (e) {
338
- parseErrors.push(`部门解析失败: ${v}(${e.message})`);
339
- }
340
- }
341
- }
342
- if (resolved.length > 0) {
343
- leaf[`${prefix}ValueOptionLeft`] = '1';
344
- leaf[`${prefix}TextValueLeft1`] = resolved;
345
- leaf.containType = '1';
346
- if (isEmployee)
347
- leaf.typeHrm = '1';
348
- }
349
- }
350
- else {
351
- // Select/CheckBox/RadioBox: value is option label(s) or option id(s),
352
- // resolved against the field's options into [{id, content}] arrays.
353
- for (const v of vals) {
354
- const opt = fieldOptions.find((o) => o.name === v || o.selectionId === v || o.valueKey === v || o.id === v);
355
- if (opt) {
356
- // 选项对象 {id: valueKey, content: name}(抓包 BrowserTextValueLeft1 实测:id 用 valueKey,
357
- // 不是 selectionId——用雪花 selectionId 引擎查不到选项会标"(已删除)")
358
- resolved.push({ id: opt.valueKey || opt.selectionId || opt.id, content: opt.name });
359
- }
360
- else {
361
- parseErrors.push(`选项 "${v}" 不在字段 "${fieldRef}" 的选项中,可选: ${fieldOptions.map((o) => `${o.name}(${o.selectionId || o.valueKey || o.id})`).join(', ')}`);
362
- }
363
- }
364
- if (resolved.length > 0) {
365
- leaf[`${prefix}ValueOptionLeft`] = '1';
366
- leaf[`${prefix}TextValueLeft1`] = resolved;
367
- leaf.containType = '1'; // 1=任一值 2=所有值(多选场景)
368
- }
369
- }
370
- }
371
- else if (family === 'Number') {
372
- leaf[`${prefix}ValueOptionLeft`] = '1';
373
- leaf[`${prefix}TextValueLeft1`] = Number(value);
374
- }
375
- else {
376
- leaf[`${prefix}ValueOptionLeft`] = '1';
377
- leaf[`${prefix}TextValueLeft1`] = value;
378
- }
379
- }
380
- }
381
- }
382
- return leaf;
383
- }
384
- // 顶层循环:| 分隔 → OR 子组;无 | 直接叶子。子组节点 = {relation:2, childrens:[...]}(抓包实测)
385
- for (const ruleStr of cmdOpts.rule) {
386
- const subRules = ruleStr.split('|').map((s) => s.trim()).filter(Boolean);
387
- const subLeaves = [];
388
- for (const sub of subRules) {
389
- const lf = await buildLeaf(sub);
390
- if (lf)
391
- subLeaves.push(lf);
392
- }
393
- if (subLeaves.length === 1)
394
- childrens.push(subLeaves[0]);
395
- else if (subLeaves.length > 1)
396
- childrens.push({ relation: 2, childrens: subLeaves });
397
- }
398
- if (parseErrors.length > 0) {
399
- console.error('规则解析错误:');
400
- for (const e of parseErrors)
401
- console.error(` ❌ ${e}`);
402
- process.exit(1);
403
- }
404
- if (childrens.length === 0) {
405
- console.error('至少需要一条有效的 --rule');
406
- process.exit(1);
407
- }
408
- // 3. replace 语义:连线已绑条件时先删旧条件,避免 saveCondition 把新规则合并进旧条件
409
- await replaceExistingLinkCondition(client, baseUrl, workflowId, sourceId, nodeId);
410
- // 4. getConditionSet → saveCondition → bind
411
- console.error(`解析 ${childrens.length} 条规则, 关系=${cmdOpts.relation}`);
412
- let mapBaseId = '';
413
- try {
414
- const csRes = await client.post(`${baseUrl}/api/workflow/pathdef/rule/condition/getConditionSet`, { source: 2, sourceId, workflowId, conditionName: name, needFormfield: true, readOnly: false, templateTokenId: String(Date.now()) });
415
- if (csRes?.code === 200 && csRes?.data?.mapBaseId) {
416
- mapBaseId = csRes.data.mapBaseId;
417
- }
418
- }
419
- catch { /* best effort */ }
420
- if (!mapBaseId) {
421
- console.error('无法获取 mapBaseId');
422
- process.exit(1);
44
+ if (!!cmdOpts.rule?.length === !!cmdOpts.rulesJson)
45
+ throw Error('--rule 与 --rules-json 必须且只能指定一种');
46
+ const input = cmdOpts.rulesJson ? JSON.parse(cmdOpts.rulesJson.startsWith('@') ? readFileSync(cmdOpts.rulesJson.slice(1), 'utf8') : cmdOpts.rulesJson) : cmdOpts.rule;
47
+ const { relation, childrens } = await compileWorkflowCondition(client, baseUrl, { workflowId, source: 2, sourceId }, input, cmdOpts.relation);
48
+ if (cmdOpts.preview) {
49
+ console.log(JSON.stringify({ source: 2, sourceId, relation, childrens }, null, 2));
50
+ return;
423
51
  }
424
- const payload = {
425
- source: 2, sourceId, workflowId, conditionName: name,
426
- needFormfield: true, readOnly: false,
427
- mapBaseId, isEdit: false, isFromRuleListPage: true,
428
- relation,
429
- childrens,
430
- allRuleIsEmpty: false,
52
+ const readTarget = async () => {
53
+ const res = await client.get(`${baseUrl}/api/bs/workflow/pathdef/nodeLink/getWfpNodeLinkTable?workflowId=${encodeURIComponent(workflowId)}`);
54
+ if (res?.code !== 200 || res.status === false || !Array.isArray(res.data?.data))
55
+ throw Error('读取出口列表失败');
56
+ const link = res.data.data.find((r) => String(r.id) === sourceId);
57
+ if (!link || String(link.srcNodeId) !== nodeId)
58
+ throw Error('出口不属于指定流程/来源节点');
59
+ return String(link.conditionKey?.conditionKey || '');
431
60
  };
432
- const data = await client.post(`${baseUrl}/api/workflow/pathdef/rule/condition/saveCondition`, payload);
433
- if (data?.code !== 200 || !data?.status || !data?.data?.result) {
434
- console.error(`保存条件失败: ${data?.data?.msg || data?.msg || '未知错误'}`);
435
- process.exit(1);
436
- }
437
- const conditionKey = data.data.conditionKey;
438
- const conditionCn = data.data.conditionCn || '';
61
+ const previousKey = await readTarget();
62
+ const saved = await persistWorkflowCondition(client, baseUrl, { workflowId, source: 2, conditionName: name }, { relation, childrens });
63
+ const { conditionKey, conditionCn } = saved;
64
+ if (await readTarget() !== previousKey)
65
+ throw Error(`出口条件已被其他操作修改,停止绑定;新条件 ${conditionKey} 已保存`);
439
66
  // Bind to link — 必须校验结果:失败不能吞掉,否则"已保存并绑定"会误导
440
67
  let bindOk = false;
441
68
  try {
442
69
  const bindRes = await client.post(`${baseUrl}/api/bs/workflow/pathdef/nodeLink/saveLinkConditionKey`, {
443
70
  workflowId, linkId: sourceId, conditionKey, nodeId,
444
71
  });
445
- bindOk = bindRes?.code === 200 && bindRes?.status;
72
+ bindOk = bindRes?.code === 200 && bindRes?.status && bindRes?.data !== false;
73
+ if (bindOk)
74
+ bindOk = await readTarget() === conditionKey;
446
75
  }
447
76
  catch { /* 网络异常 → bindOk=false */ }
448
77
  if (!bindOk) {
@@ -450,7 +79,7 @@ export function registerWorkflowConditionCommands(wf, program) {
450
79
  console.error(` 请手动补绑: e10-cli workflow set-link-condition-key ${workflowId} ${sourceId} ${conditionKey} ${nodeId}`);
451
80
  }
452
81
  if (opts.json) {
453
- console.log(JSON.stringify({ conditionKey, conditionCn, conditionId: data.data.conditionId, mapId: data.data.mapId, bound: bindOk }, null, 2));
82
+ console.log(JSON.stringify({ conditionKey, conditionCn, conditionId: saved.conditionId, mapId: saved.mapId, bound: bindOk }, null, 2));
454
83
  }
455
84
  else if (bindOk) {
456
85
  console.log(`条件已保存并绑定: key=${conditionKey} (${conditionCn})`);
@@ -458,6 +87,8 @@ export function registerWorkflowConditionCommands(wf, program) {
458
87
  else {
459
88
  console.log(`条件已保存(未绑定): key=${conditionKey} (${conditionCn})`);
460
89
  }
90
+ if (!bindOk)
91
+ process.exitCode = 1;
461
92
  });
462
93
  /**
463
94
  * 读取一条连线(link)上绑定的条件。
@@ -495,40 +126,6 @@ export function registerWorkflowConditionCommands(wf, program) {
495
126
  const links = linkRes?.data?.data || [];
496
127
  return links.filter((l) => l.hasCondition || l?.conditionKey?.conditionKey);
497
128
  }
498
- /**
499
- * condition add 的 replace 前置:若连线(linkId)已绑条件,先删除旧条件并解绑。
500
- * 必须先删——saveCondition 在 isEdit=false 且该 conditionKey 下已有数据时,会把新
501
- * childrens 合并进旧条件(累积 bug);删到该 key 无数据后才会真正新建。无旧条件则静默返回。
502
- */
503
- async function replaceExistingLinkCondition(client, baseUrl, workflowId, linkId, nodeId) {
504
- try {
505
- const params = new URLSearchParams();
506
- params.set('workflowId', workflowId);
507
- const linkRes = await client.get(`${baseUrl}/api/bs/workflow/pathdef/nodeLink/getWfpNodeLinkTable?${params.toString()}`);
508
- const linkObj = (linkRes?.data?.data || []).find((l) => String(l.id) === String(linkId));
509
- if (!linkObj)
510
- return;
511
- const { context, records } = await loadLinkConditions(client, baseUrl, workflowId, linkObj);
512
- if (!records.length)
513
- return;
514
- const mapId = String(records[0].mapId || '');
515
- const conditionKey = String(context.conditionKey || '');
516
- if (!mapId || !conditionKey)
517
- return;
518
- await client.post(`${baseUrl}/api/workflow/pathdef/rule/condition/deleteConditions`, {
519
- source: 2, sourceId: linkId, workflowId,
520
- conditionName: linkObj?.conditionKey?.sourceName || '',
521
- linkName: linkObj?.linkName || '',
522
- needFormfield: true, readOnly: false,
523
- mapIds: mapId, conditionKey,
524
- });
525
- await client.post(`${baseUrl}/api/bs/workflow/pathdef/nodeLink/saveLinkConditionKey`, {
526
- workflowId, linkId, conditionKey: '', nodeId,
527
- }).catch(() => { });
528
- console.error(` 连线已绑条件「${records[0].conditionName || conditionKey}」,已删除旧条件后重建`);
529
- }
530
- catch { /* 前置失败不阻断主流程 */ }
531
- }
532
129
  condCmd.command('list')
533
130
  .description('列出工作流下所有连线绑定的条件规则')
534
131
  .argument('<workflowId>', '流程 ID')
@@ -579,7 +176,8 @@ export function registerWorkflowConditionCommands(wf, program) {
579
176
  .description('查看单个条件详情(含中文表达式 conditionCn)')
580
177
  .argument('<workflowId>', '流程 ID')
581
178
  .argument('<id>', '条件 ID(conditionKey / mapId / conditionId)')
582
- .action(async (workflowId, id) => {
179
+ .option('--tree', '同时回读平台保存的完整条件树')
180
+ .action(async (workflowId, id, options) => {
583
181
  const opts = program.opts();
584
182
  const auth = await AuthSession.fromOptions(opts);
585
183
  if (!auth)
@@ -601,6 +199,14 @@ export function registerWorkflowConditionCommands(wf, program) {
601
199
  process.exit(1);
602
200
  }
603
201
  const { link, context, record } = found;
202
+ let expression;
203
+ if (options.tree) {
204
+ const query = new URLSearchParams({ workflowId, source: '2', sourceId: String(link.id), conditionKey: String(context.conditionKey), mapBaseId: String(context.mapBaseId), mapId: String(record.mapId), conditionId: String(record.conditionId) });
205
+ const response = await client.get(`${baseUrl}/api/workflow/pathdef/rule/condition/getExpressionBean?${query}`);
206
+ if (response?.code !== 200 || response.status === false || !response.data)
207
+ throw Error('读取条件树失败');
208
+ expression = response.data;
209
+ }
604
210
  if (opts.json) {
605
211
  console.log(JSON.stringify({
606
212
  linkId: link.id, linkName: link.linkName,
@@ -609,6 +215,7 @@ export function registerWorkflowConditionCommands(wf, program) {
609
215
  conditionKey: context.conditionKey,
610
216
  mapId: record.mapId, conditionId: record.conditionId,
611
217
  conditionName: record.conditionName, conditionCn: record.conditionCn,
218
+ ...(options.tree ? { expression } : {}),
612
219
  }, null, 2));
613
220
  }
614
221
  else {
@@ -618,6 +225,8 @@ export function registerWorkflowConditionCommands(wf, program) {
618
225
  console.log(`mapId: ${record.mapId}`);
619
226
  console.log(`conditionId: ${record.conditionId}`);
620
227
  console.log(`中文表达式: ${record.conditionCn || '(空)'}`);
228
+ if (options.tree)
229
+ console.log(JSON.stringify(expression, null, 2));
621
230
  }
622
231
  });
623
232
  condCmd.command('delete')