weaver-e10-builder 1.5.6 → 1.5.9

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 (194) hide show
  1. package/dist/commands/actionflow.d.ts.map +1 -1
  2. package/dist/commands/actionflow.js +6 -0
  3. package/dist/commands/actionflow.js.map +1 -1
  4. package/dist/commands/app.d.ts.map +1 -1
  5. package/dist/commands/app.js +259 -0
  6. package/dist/commands/app.js.map +1 -1
  7. package/dist/commands/form-add-detail-table.d.ts.map +1 -1
  8. package/dist/commands/form-add-detail-table.js +13 -2
  9. package/dist/commands/form-add-detail-table.js.map +1 -1
  10. package/dist/commands/form-button.d.ts.map +1 -1
  11. package/dist/commands/form-button.js +6 -4
  12. package/dist/commands/form-button.js.map +1 -1
  13. package/dist/commands/form-formula-linkage.d.ts.map +1 -1
  14. package/dist/commands/form-formula-linkage.js +4 -4
  15. package/dist/commands/form-formula-linkage.js.map +1 -1
  16. package/dist/commands/form-list-filter.d.ts +3 -0
  17. package/dist/commands/form-list-filter.d.ts.map +1 -1
  18. package/dist/commands/form-list-filter.js +88 -24
  19. package/dist/commands/form-list-filter.js.map +1 -1
  20. package/dist/commands/form-list-search-group.d.ts.map +1 -1
  21. package/dist/commands/form-list-search-group.js +54 -64
  22. package/dist/commands/form-list-search-group.js.map +1 -1
  23. package/dist/commands/form-list-stats.d.ts.map +1 -1
  24. package/dist/commands/form-list-stats.js +29 -4
  25. package/dist/commands/form-list-stats.js.map +1 -1
  26. package/dist/commands/form-list-utils.d.ts +46 -1
  27. package/dist/commands/form-list-utils.d.ts.map +1 -1
  28. package/dist/commands/form-list-utils.js +140 -47
  29. package/dist/commands/form-list-utils.js.map +1 -1
  30. package/dist/commands/form-list.d.ts.map +1 -1
  31. package/dist/commands/form-list.js +141 -71
  32. package/dist/commands/form-list.js.map +1 -1
  33. package/dist/commands/form-message.d.ts +3 -0
  34. package/dist/commands/form-message.d.ts.map +1 -0
  35. package/dist/commands/form-message.js +341 -0
  36. package/dist/commands/form-message.js.map +1 -0
  37. package/dist/commands/form-view.d.ts.map +1 -1
  38. package/dist/commands/form-view.js +31 -4
  39. package/dist/commands/form-view.js.map +1 -1
  40. package/dist/commands/form.js +1 -1
  41. package/dist/commands/form.js.map +1 -1
  42. package/dist/commands/matrix.d.ts.map +1 -1
  43. package/dist/commands/matrix.js +80 -42
  44. package/dist/commands/matrix.js.map +1 -1
  45. package/dist/commands/org.d.ts.map +1 -1
  46. package/dist/commands/org.js +61 -0
  47. package/dist/commands/org.js.map +1 -1
  48. package/dist/commands/role.d.ts.map +1 -1
  49. package/dist/commands/role.js +69 -9
  50. package/dist/commands/role.js.map +1 -1
  51. package/dist/commands/wf-form.d.ts.map +1 -1
  52. package/dist/commands/wf-form.js +5 -5
  53. package/dist/commands/wf-form.js.map +1 -1
  54. package/dist/commands/workflow-node-validate.d.ts.map +1 -1
  55. package/dist/commands/workflow-node-validate.js +159 -15
  56. package/dist/commands/workflow-node-validate.js.map +1 -1
  57. package/dist/core/crypto.d.ts +19 -0
  58. package/dist/core/crypto.d.ts.map +1 -1
  59. package/dist/core/crypto.js +70 -35
  60. package/dist/core/crypto.js.map +1 -1
  61. package/dist/index.js +2 -0
  62. package/dist/index.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 +3 -1
  65. package/dist/services/actionflow/components/action_eb_update_compiler.js.map +1 -1
  66. package/dist/services/actionflow/components/custom_trigger.d.ts.map +1 -1
  67. package/dist/services/actionflow/components/custom_trigger.js +2 -0
  68. package/dist/services/actionflow/components/custom_trigger.js.map +1 -1
  69. package/dist/services/actionflow/components/event_button.d.ts.map +1 -1
  70. package/dist/services/actionflow/components/event_button.js +2 -0
  71. package/dist/services/actionflow/components/event_button.js.map +1 -1
  72. package/dist/services/actionflow/components/event_form_data.d.ts.map +1 -1
  73. package/dist/services/actionflow/components/event_form_data.js +2 -0
  74. package/dist/services/actionflow/components/event_form_data.js.map +1 -1
  75. package/dist/services/actionflow/components/form_data_builder.d.ts +23 -0
  76. package/dist/services/actionflow/components/form_data_builder.d.ts.map +1 -0
  77. package/dist/services/actionflow/components/form_data_builder.js +106 -0
  78. package/dist/services/actionflow/components/form_data_builder.js.map +1 -0
  79. package/dist/services/actionflow/components/hrm_actions.d.ts +1 -0
  80. package/dist/services/actionflow/components/hrm_actions.d.ts.map +1 -1
  81. package/dist/services/actionflow/components/hrm_actions.js +136 -44
  82. package/dist/services/actionflow/components/hrm_actions.js.map +1 -1
  83. package/dist/services/actionflow/components/inner_mq_listener.d.ts.map +1 -1
  84. package/dist/services/actionflow/components/inner_mq_listener.js +2 -0
  85. package/dist/services/actionflow/components/inner_mq_listener.js.map +1 -1
  86. package/dist/services/actionflow/components/webhook_trigger.d.ts.map +1 -1
  87. package/dist/services/actionflow/components/webhook_trigger.js +6 -5
  88. package/dist/services/actionflow/components/webhook_trigger.js.map +1 -1
  89. package/dist/services/actionflow/components/workflow_actions.d.ts.map +1 -1
  90. package/dist/services/actionflow/components/workflow_actions.js +6 -3
  91. package/dist/services/actionflow/components/workflow_actions.js.map +1 -1
  92. package/dist/services/actionflow/context_preflight.d.ts +3 -3
  93. package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
  94. package/dist/services/actionflow/context_preflight.js +45 -24
  95. package/dist/services/actionflow/context_preflight.js.map +1 -1
  96. package/dist/services/actionflow/context_provider.d.ts +7 -0
  97. package/dist/services/actionflow/context_provider.d.ts.map +1 -1
  98. package/dist/services/actionflow/context_provider.js +13 -1
  99. package/dist/services/actionflow/context_provider.js.map +1 -1
  100. package/dist/services/actionflow/formula_service.d.ts +16 -1
  101. package/dist/services/actionflow/formula_service.d.ts.map +1 -1
  102. package/dist/services/actionflow/formula_service.js +414 -63
  103. package/dist/services/actionflow/formula_service.js.map +1 -1
  104. package/dist/services/actionflow/hrm_source.d.ts +2 -0
  105. package/dist/services/actionflow/hrm_source.d.ts.map +1 -1
  106. package/dist/services/actionflow/hrm_source.js +4 -0
  107. package/dist/services/actionflow/hrm_source.js.map +1 -1
  108. package/dist/services/actionflow/param_group_dto.d.ts.map +1 -1
  109. package/dist/services/actionflow/param_group_dto.js +17 -3
  110. package/dist/services/actionflow/param_group_dto.js.map +1 -1
  111. package/dist/services/actionflow/param_type.d.ts +14 -0
  112. package/dist/services/actionflow/param_type.d.ts.map +1 -0
  113. package/dist/services/actionflow/param_type.js +69 -0
  114. package/dist/services/actionflow/param_type.js.map +1 -0
  115. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  116. package/dist/services/actionflow/preflight_service.js +121 -41
  117. package/dist/services/actionflow/preflight_service.js.map +1 -1
  118. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  119. package/dist/services/actionflow/workflow_compiler.js +83 -50
  120. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  121. package/dist/services/app-publish.d.ts +227 -0
  122. package/dist/services/app-publish.d.ts.map +1 -0
  123. package/dist/services/app-publish.js +403 -0
  124. package/dist/services/app-publish.js.map +1 -0
  125. package/dist/services/form-button-position.d.ts.map +1 -1
  126. package/dist/services/form-button-position.js +7 -1
  127. package/dist/services/form-button-position.js.map +1 -1
  128. package/dist/services/form-field-drop.d.ts.map +1 -1
  129. package/dist/services/form-field-drop.js +7 -0
  130. package/dist/services/form-field-drop.js.map +1 -1
  131. package/dist/services/form-formula-linkage.d.ts +24 -3
  132. package/dist/services/form-formula-linkage.d.ts.map +1 -1
  133. package/dist/services/form-formula-linkage.js +24 -5
  134. package/dist/services/form-formula-linkage.js.map +1 -1
  135. package/dist/services/form-layout-insert.js +1 -1
  136. package/dist/services/form-layout-insert.js.map +1 -1
  137. package/dist/services/form-list-search-group.d.ts +89 -0
  138. package/dist/services/form-list-search-group.d.ts.map +1 -0
  139. package/dist/services/form-list-search-group.js +260 -0
  140. package/dist/services/form-list-search-group.js.map +1 -0
  141. package/dist/services/form-list-search.d.ts +110 -0
  142. package/dist/services/form-list-search.d.ts.map +1 -0
  143. package/dist/services/form-list-search.js +231 -0
  144. package/dist/services/form-list-search.js.map +1 -0
  145. package/dist/services/form-list-stats.d.ts +21 -1
  146. package/dist/services/form-list-stats.d.ts.map +1 -1
  147. package/dist/services/form-list-stats.js +86 -12
  148. package/dist/services/form-list-stats.js.map +1 -1
  149. package/dist/services/form-message.d.ts +273 -0
  150. package/dist/services/form-message.d.ts.map +1 -0
  151. package/dist/services/form-message.js +575 -0
  152. package/dist/services/form-message.js.map +1 -0
  153. package/dist/services/form-sub-detail.d.ts.map +1 -1
  154. package/dist/services/form-sub-detail.js +5 -1
  155. package/dist/services/form-sub-detail.js.map +1 -1
  156. package/dist/services/form-view.d.ts +34 -2
  157. package/dist/services/form-view.d.ts.map +1 -1
  158. package/dist/services/form-view.js +74 -8
  159. package/dist/services/form-view.js.map +1 -1
  160. package/dist/services/matrix-fields.d.ts +42 -0
  161. package/dist/services/matrix-fields.d.ts.map +1 -0
  162. package/dist/services/matrix-fields.js +102 -0
  163. package/dist/services/matrix-fields.js.map +1 -0
  164. package/dist/services/org-browser.d.ts +60 -0
  165. package/dist/services/org-browser.d.ts.map +1 -0
  166. package/dist/services/org-browser.js +62 -0
  167. package/dist/services/org-browser.js.map +1 -0
  168. package/dist/services/quick-date-range.d.ts +22 -0
  169. package/dist/services/quick-date-range.d.ts.map +1 -0
  170. package/dist/services/quick-date-range.js +134 -0
  171. package/dist/services/quick-date-range.js.map +1 -0
  172. package/dist/services/role-member.d.ts +73 -2
  173. package/dist/services/role-member.d.ts.map +1 -1
  174. package/dist/services/role-member.js +141 -9
  175. package/dist/services/role-member.js.map +1 -1
  176. package/package.json +1 -1
  177. package/skill-docs/SKILL.md +20 -21
  178. package/skill-docs/_catalog.md +90 -86
  179. package/skill-docs/actionflows/SKILL.md +2 -1
  180. package/skill-docs/actionflows/references/components/message/InnerMQSend.md +6 -0
  181. package/skill-docs/actionflows/references/components/personnel/HrmEmployeeUpdate.md +3 -1
  182. package/skill-docs/actionflows/references/components/personnel/PersonnelAlterType.md +38 -0
  183. package/skill-docs/actionflows/references/components/personnel/PersonnelOnboarding.md +36 -34
  184. package/skill-docs/actionflows/references/components/trigger/WebHookTrigger.md +4 -2
  185. package/skill-docs/references/app/guide-app-publish.md +92 -0
  186. package/skill-docs/references/common/guide-plan-template.md +150 -246
  187. package/skill-docs/references/common/map.md +153 -0
  188. package/skill-docs/references/common/ref-cli-commands.md +28 -8
  189. package/skill-docs/references/form/guide-form-message.md +57 -0
  190. package/skill-docs/references/form/guide-form-view.md +7 -2
  191. package/skill-docs/references/form/guide-formula-linkage.md +1 -1
  192. package/skill-docs/references/form/guide-list-stats.md +55 -2
  193. package/skill-docs/references/hrm/guide-matrix.md +30 -2
  194. package/skill-docs/references/workflow/guide-workflow.md +20 -2
@@ -29,11 +29,25 @@ const VALUE_TYPE_ALIASES = {
29
29
  };
30
30
  const WEBHOOK_CONTEXT_TABLES = new Set(['Params', 'Header', 'Body']);
31
31
  const SERVERLESS_CONTEXT_TABLES = new Set(['Request', 'Response']);
32
+ const DESIGNER_FORM_CONTEXT_ROOTS = new Set(['FormData', 'ApprovalData', 'SelectParams', 'CycleParams']);
33
+ function isComponentContextRoot(root) {
34
+ const value = String(root || '').trim();
35
+ return Boolean(value) && !DESIGNER_FORM_CONTEXT_ROOTS.has(value);
36
+ }
37
+ function parameterContextRoot(paramKey, componentType) {
38
+ const head = String(paramKey || '').split('.')[0];
39
+ if (componentType === 'WebHookTrigger' && WEBHOOK_CONTEXT_TABLES.has(head))
40
+ return head;
41
+ if (componentType === 'ServerlessAction' && SERVERLESS_CONTEXT_TABLES.has(head))
42
+ return head;
43
+ return '';
44
+ }
32
45
  function isParameterContext(componentType, paramKey, tableKey = '') {
33
46
  if (componentType === 'WebHookTrigger' || componentType === 'ServerlessAction')
34
47
  return true;
35
48
  const head = String(paramKey).split('.')[0];
36
- return WEBHOOK_CONTEXT_TABLES.has(String(tableKey)) || WEBHOOK_CONTEXT_TABLES.has(head)
49
+ return isComponentContextRoot(tableKey)
50
+ || WEBHOOK_CONTEXT_TABLES.has(String(tableKey)) || WEBHOOK_CONTEXT_TABLES.has(head)
37
51
  || SERVERLESS_CONTEXT_TABLES.has(String(tableKey)) || SERVERLESS_CONTEXT_TABLES.has(head);
38
52
  }
39
53
  /** 触发器上下文根节点。自定义触发的参数由 SelectParams 提供,不是普通表单数据。 */
@@ -45,7 +59,11 @@ export function contextRootForComponent(componentType) {
45
59
  : 'FormData';
46
60
  }
47
61
  export function contextTableNameForRoot(root) {
48
- return root === 'ApprovalData' ? '流程数据' : root === 'SelectParams' ? '选择参数' : '表单数据';
62
+ return root === 'ApprovalData' ? '流程数据'
63
+ : root === 'SelectParams' ? '选择参数'
64
+ : root === 'CycleParams' ? '循环参数'
65
+ : root && isComponentContextRoot(root) ? root
66
+ : '表单数据';
49
67
  }
50
68
  /**
51
69
  * 自定义触发的来源 key 只保存业务路径,不能把公式根节点混进 paramKey。
@@ -144,6 +162,204 @@ export function resolveSourceFieldLabel(paramKey, meta, fallback = '') {
144
162
  }
145
163
  return String(fallback || paramKey);
146
164
  }
165
+ /**
166
+ * 查找动态赋值上下文中的原始字段对象。
167
+ *
168
+ * 表单设置组件的“依据值下级”不能用 paramKey 的最后一段代替字段 key:
169
+ * 前端 set-formdata 会用子节点的 paramName 作为 level=1 的选项 id,
170
+ * 而字段 id 只用于 frontId/节点定位。这里优先按完整 paramKey 查找,
171
+ * 不命中时再按字段 paramKey 做一次兼容匹配。
172
+ */
173
+ function resolveContextFieldMeta(paramKey, meta) {
174
+ const key = String(paramKey || '').trim();
175
+ if (!key || !meta || typeof meta !== 'object')
176
+ return {};
177
+ const workflowId = String(meta._workflow_id || meta._event_form_id || '');
178
+ if (workflowId) {
179
+ const exact = getWorkflowContextFieldsByKey()[workflowId]?.[key];
180
+ if (exact && typeof exact === 'object')
181
+ return exact;
182
+ const fields = getWorkflowContextFields()[workflowId] || {};
183
+ const hit = Object.values(fields).find((field) => field && String(field.paramKey || '') === key);
184
+ if (hit && typeof hit === 'object')
185
+ return hit;
186
+ }
187
+ const customKey = key.replace(/^(?:FormData|ApprovalData|SelectParams)\./, '');
188
+ const tableToken = customKey.includes('[]')
189
+ ? customKey.slice(0, customKey.indexOf('[]')).split('.').filter(Boolean).pop() || ''
190
+ : '';
191
+ const fieldToken = customKey.includes('[]')
192
+ ? customKey.slice(customKey.indexOf('[]') + 2).split('.').filter(Boolean).pop() || ''
193
+ : customKey.split('.').filter(Boolean).pop() || '';
194
+ if (tableToken && fieldToken) {
195
+ const table = customTriggerTables(meta).find((candidate) => candidate && [
196
+ candidate.id, candidate.formId, candidate.paramName, candidate.paramKey,
197
+ candidate.key, candidate.showName, candidate.name,
198
+ ].some((value) => String(value ?? '').trim() === tableToken));
199
+ const field = table?.fields?.find((candidate) => candidate && [
200
+ candidate.id, candidate.paramName, candidate.key, candidate.fieldKey,
201
+ candidate.showName, candidate.name,
202
+ ].some((value) => String(value ?? '').trim() === fieldToken));
203
+ if (field && typeof field === 'object')
204
+ return field;
205
+ }
206
+ return {};
207
+ }
208
+ /**
209
+ * 依据值下级的业务 key:对齐 set-formdata/transSubBasisParamkey。
210
+ * level=1 使用子字段 paramName,而不是字段 id;没有实时元数据时保留
211
+ * 旧的 paramKey 尾段作为兼容兜底。
212
+ */
213
+ function resolveFormSettingSubKey(paramKey, meta) {
214
+ const key = String(paramKey || '').trim();
215
+ const field = resolveContextFieldMeta(key, meta);
216
+ const configured = String(field.paramName || field.key || field.fieldKey || '').trim();
217
+ if (configured)
218
+ return configured;
219
+ const tail = key.includes('.') ? key.slice(key.lastIndexOf('.') + 1) : key;
220
+ return tail.replace(/\[\]$/, '');
221
+ }
222
+ /**
223
+ * ParamMappingBean 的下级 key 与 EsbFormDataDto 不同:前端
224
+ * transSubBasisParamkey 会先去掉依据值的 paramKey,且参数设置不去掉
225
+ * 下级路径中的 [];表单设置则保留 level=1 的 paramName,并对更深层级
226
+ * 去掉数组标记。这里只消费 API 回填的 basisParamKey/字段 paramKey。
227
+ */
228
+ function resolveBasisSubKey(paramKey, basisParamKey, basisType, meta, resolved) {
229
+ const kind = String(basisType || '').toLowerCase();
230
+ const root = resolvedContextRoot(resolved, String(resolved.componentType || meta?._context_component_type || ''), '');
231
+ const selected = protocolParamKey(String(paramKey || ''), root, String(resolved.componentType || meta?._context_component_type || ''));
232
+ const basis = protocolParamKey(String(basisParamKey || ''), root, String(resolved.componentType || meta?._context_component_type || ''));
233
+ if (!basis || selected === basis)
234
+ return 'esbAssignSelf';
235
+ const relative = selected.startsWith(`${basis}.`) ? selected.slice(basis.length + 1) : selected;
236
+ if (kind.includes('param'))
237
+ return relative;
238
+ const field = resolveContextFieldMeta(paramKey, meta);
239
+ const firstLevel = String(field.paramName || field.key || '').trim();
240
+ if (firstLevel && !relative.includes('.'))
241
+ return firstLevel.replace(/\[\]$/, '');
242
+ return relative.replace(/\[\]/g, '');
243
+ }
244
+ /**
245
+ * 将预检阶段由 getComponentContext 回填的字段身份投影到公式编译上下文。
246
+ * 这里不创建字段身份,只搬运 API 返回的字段/分组元数据;没有 resolved
247
+ * 元数据时,调用方仍可保留旧的直编兼容行为,但真实生成流程会在预检阶段
248
+ * 先因 unresolved context 被拦截。
249
+ */
250
+ export function contextMetaForReference(meta, reference, componentType = '') {
251
+ const resolved = reference?._resolvedContext && typeof reference._resolvedContext === 'object'
252
+ ? reference._resolvedContext : {};
253
+ const type = String(resolved.componentType || componentType || meta?._context_component_type || meta?._upstream_component_type || '');
254
+ const projected = {
255
+ ...(meta || {}),
256
+ ...(type ? { _context_component_type: type } : {}),
257
+ };
258
+ const copy = (key, target = key) => {
259
+ if (resolved[key] !== undefined && resolved[key] !== null && String(resolved[key]) !== '')
260
+ projected[target] = String(resolved[key]);
261
+ };
262
+ copy('tablePrimaryKey', '_context_table_primary_key');
263
+ copy('tableName', '_context_table_name');
264
+ copy('tableKey', '_context_table_key');
265
+ copy('paramKey', '_context_original_param_key');
266
+ copy('parentName', '_context_original_parent_name');
267
+ copy('multKey', '_context_mult_key');
268
+ copy('multName', '_context_mult_name');
269
+ copy('effectiveMultKey', '_context_effective_mult_key');
270
+ copy('effectiveMultName', '_context_effective_mult_name');
271
+ copy('allParentName', '_context_all_parent_name');
272
+ if (resolved.isMultCom !== undefined)
273
+ projected._context_is_mult_com = Boolean(resolved.isMultCom);
274
+ if (resolved.parentComId !== undefined && resolved.parentComId !== null)
275
+ projected._context_parent_com_id = String(resolved.parentComId);
276
+ // getComponentContext 返回的 paramKey 是分组内业务路径,例如
277
+ // `detailOne[].detailText`;`Body.detailOne[].detailText` 只是 CLI 用于
278
+ // 定位上下文分组的完整引用。不能把分组根写回 ParamBean/FormulaBean
279
+ // 的 config.paramKey,否则前端会把 Body 当成字段路径的一部分。
280
+ const selectedRaw = String(reference?.paramKey || reference?.key || resolved.paramKey || '');
281
+ const selectedRoot = String(resolved.tablePrimaryKey
282
+ || projected._context_table_primary_key
283
+ || parameterContextRoot(selectedRaw, type));
284
+ projected._context_selected_param_key = ((type === 'WebHookTrigger' || type === 'ServerlessAction')
285
+ || isComponentContextRoot(selectedRoot))
286
+ ? protocolParamKey(selectedRaw, selectedRoot, type)
287
+ : normalizeContextParamKey(selectedRaw, type);
288
+ return projected;
289
+ }
290
+ export function resolvedContextRoot(resolved, componentType, fallback = '') {
291
+ const supplied = String(resolved.tablePrimaryKey || '').trim();
292
+ if (supplied)
293
+ return supplied;
294
+ if (componentType === 'WebHookTrigger') {
295
+ const key = String(resolved.tableKey || '').trim();
296
+ if (WEBHOOK_CONTEXT_TABLES.has(key))
297
+ return key;
298
+ }
299
+ if (componentType === 'ServerlessAction') {
300
+ const key = String(resolved.tableKey || '').trim();
301
+ if (SERVERLESS_CONTEXT_TABLES.has(key))
302
+ return key;
303
+ }
304
+ return fallback || contextRootForComponent(componentType);
305
+ }
306
+ export function protocolParamKey(paramKey, root, componentType) {
307
+ const raw = String(paramKey || '');
308
+ if ((componentType === 'WebHookTrigger' && WEBHOOK_CONTEXT_TABLES.has(root))
309
+ || (componentType === 'ServerlessAction' && SERVERLESS_CONTEXT_TABLES.has(root))
310
+ || isComponentContextRoot(root)) {
311
+ return raw.startsWith(`${root}.`) ? raw.slice(root.length + 1) : raw;
312
+ }
313
+ return raw.replace(/^(?:FormData|ApprovalData|SelectParams)\./, '');
314
+ }
315
+ function customTriggerTables(meta) {
316
+ return meta && Array.isArray(meta._custom_trigger_data?.tableList)
317
+ ? meta._custom_trigger_data.tableList.filter((item) => item && typeof item === 'object')
318
+ : [];
319
+ }
320
+ function customTriggerTableLabel(table, fallback = '') {
321
+ return String(table?.showName || table?.name || table?.paramName || table?.key || fallback);
322
+ }
323
+ /**
324
+ * 生成表单设置 basisValue 的展示路径。
325
+ * parentName 是设计器展示路径,不是运行时根节点;因此 CustomTrigger
326
+ * 不能把 SelectParams 当成 parentName,而要从 tableList 还原“主表.明细表”。
327
+ */
328
+ export function resolveFormSettingBasisParentName(paramKey, fallbackLabel, meta = null) {
329
+ const key = String(paramKey || '').replace(/^(?:FormData|ApprovalData|SelectParams)\./, '').trim();
330
+ const componentType = String(meta?._context_component_type || meta?._upstream_component_type || '');
331
+ if (componentType === 'CustomTrigger') {
332
+ const tables = customTriggerTables(meta);
333
+ const pathBeforeArray = key.includes('[]') ? key.slice(0, key.indexOf('[]')) : key;
334
+ const tableToken = pathBeforeArray.split('.').filter(Boolean).pop() || '';
335
+ const same = (value, token) => String(value ?? '').trim() === token;
336
+ const details = tables.filter((item) => !(item.isMain === true || item.isMain === 1 || String(item.isMain) === '1'))
337
+ .sort((left, right) => Number(left.orderNum ?? left.order ?? 0) - Number(right.orderNum ?? right.order ?? 0));
338
+ const numbered = /^detail(\d+)$/i.exec(tableToken);
339
+ const table = tables.find((item) => item
340
+ && [item.id, item.formId, item.paramName, item.paramKey, item.key, item.showName, item.name]
341
+ .some((value) => same(value, tableToken)))
342
+ || (numbered ? details[Number(numbered[1]) - 1] : undefined)
343
+ || (tables.length === 1 ? tables[0] : undefined);
344
+ if (table) {
345
+ const detailLabel = customTriggerTableLabel(table, String(fallbackLabel || tableToken));
346
+ const isMain = table.isMain === true || table.isMain === 1 || String(table.isMain) === '1';
347
+ if (isMain)
348
+ return detailLabel;
349
+ const main = tables.find((item) => item.isMain === true || item.isMain === 1 || String(item.isMain) === '1');
350
+ const mainLabel = customTriggerTableLabel(main);
351
+ return mainLabel ? `${mainLabel}.${detailLabel}[]` : `${detailLabel}[]`;
352
+ }
353
+ }
354
+ const field = resolveContextFieldMeta(`${key}`, meta);
355
+ const metadataParent = String(field.parentName || field.newParentName || '')
356
+ .replace(/^(?:FormData|ApprovalData|SelectParams)\./, '').trim();
357
+ if (metadataParent && !/^(?:FormData|ApprovalData|SelectParams)\.?$/.test(metadataParent))
358
+ return metadataParent;
359
+ const prefix = String(meta?._upstream_workflow_name || meta?._upstream_form_name || '').trim();
360
+ const label = String(fallbackLabel || key);
361
+ return prefix ? `${prefix}.${label}[]` : `${label}[]`;
362
+ }
147
363
  const SYSTEM_ALIASES = {
148
364
  id: '数据ID', name: '标题', creator: '创建者', create_time: '创建时间',
149
365
  update_time: '最后更新时间', updater: '最后更新人', data_status: '数据状态',
@@ -667,7 +883,7 @@ export function buildPersonFormula(personRef, meta, appId = '', forSendMessage =
667
883
  const personSourceMeta = personRef._resolvedContext?.componentType === 'CustomTrigger'
668
884
  ? { ...(meta || {}), _context_component_type: 'CustomTrigger' }
669
885
  : meta;
670
- child = assignFlatContextDirect(pk, disp, src, appId, ft, full, personSourceMeta, personRef._resolvedContext?.fieldId);
886
+ child = assignFlatContextDirect(pk, disp, src, appId, ft, full, personSourceMeta, personRef._resolvedContext?.fieldId || personRef.frontId || personRef.fieldId);
671
887
  }
672
888
  else {
673
889
  child = formulaSystemVar('{userid}');
@@ -861,7 +1077,14 @@ function buildNamedFunctionBean(ref, fieldId, fieldType, meta, appId, defaultSou
861
1077
  };
862
1078
  }
863
1079
  }
864
- return buildAssignBean(normalizedChild && typeof normalizedChild === 'object' ? { ...normalizedChild, _formulaArgument: true } : normalizedChild, fieldId, resolved.fieldType || formulaType, meta, appId, defaultSourceId);
1080
+ const argumentFieldType = [
1081
+ resolved.fieldType,
1082
+ child?.fieldType,
1083
+ child?.valueType,
1084
+ formulaType,
1085
+ ].map((value) => String(value || '').trim())
1086
+ .find((value) => value && !/^(?:unknown|none|null|undefined)$/i.test(value)) || formulaType;
1087
+ return buildAssignBean(normalizedChild && typeof normalizedChild === 'object' ? { ...normalizedChild, _formulaArgument: true } : normalizedChild, fieldId, argumentFieldType, meta, appId, defaultSourceId);
865
1088
  });
866
1089
  return formulaFunction(entry.id, entry.name, childs, formulaType, entry.excelFunc, entry.category || entry.resultType, entry.detail, appId, entry.paramSize);
867
1090
  }
@@ -989,26 +1212,39 @@ export function buildAssignBean(raw, fieldId, fieldType, meta, appId, defaultSou
989
1212
  }
990
1213
  const wfId = String(meta._workflow_id || '');
991
1214
  const resolvedKey = resolveParamKey(wfId, String(key));
992
- const sourceFieldType = resolveSourceFieldType(resolvedKey, meta) || String(src.fieldType || src.valueType || 'string');
993
1215
  const resolved = src && typeof src._resolvedContext === 'object' ? src._resolvedContext : {};
1216
+ const resolvedFieldTypeCandidate = [
1217
+ resolved.fieldType,
1218
+ resolved.rawField?.paramType,
1219
+ resolved.rawField?.componentKey,
1220
+ src.fieldType,
1221
+ src.valueType,
1222
+ fieldType,
1223
+ ].map((value) => String(value || '').trim())
1224
+ .find((value) => value && !/^(?:unknown|none|null|undefined)$/i.test(value)) || '';
1225
+ const resolvedFieldType = String(resolvedFieldTypeCandidate);
1226
+ const sourceFieldType = resolvedFieldType || resolveSourceFieldType(resolvedKey, meta) || 'string';
994
1227
  // 批量新增的普通字段映射与函数参数使用不同的前端协议:前者是 type=10/sub,
995
1228
  // 而函数里的明细字段必须是带索引子节点的 type=3 上下文引用。
996
1229
  if (resolvedKey.includes('[].')) {
997
1230
  const detailLabel = String(src?.detailLabel || src?.parentName || '');
998
1231
  const workflowName = String(meta._upstream_workflow_name || '');
999
1232
  if (src?._formulaArgument) {
1233
+ const basisParamKey = String(src?.basisParamKey || src?.basisValue?.paramKey || '').trim();
1234
+ const basisType = String(src?.basisType || src?.config?.basisType || '');
1235
+ if (basisParamKey) {
1236
+ return assignBasisFormulaArgument(resolvedKey, String(label), String(sourceId), appId, String(sourceFieldType || fieldType || 'string'), basisParamKey, basisType || 'formSetting', contextMetaForReference(meta, src, sourceComponent), resolved);
1237
+ }
1000
1238
  // 查询结果是一层数组(formId[].fieldId),不能套用流程明细的
1001
1239
  // workflowId.detailId[].fieldId 解析器。
1002
1240
  if (/^[^\.\[]+\[\]\.[^\.\[]+$/.test(resolvedKey)) {
1003
1241
  return formulaIndexedQueryResultArgument(resolvedKey, String(label), String(sourceId), appId, String(sourceFieldType || fieldType || 'string'), detailLabel || '表单数据');
1004
1242
  }
1005
- return formulaIndexedWorkflowDetailArgument(resolvedKey, String(label), String(sourceId), appId, String(sourceFieldType || fieldType || 'string'), detailLabel, sourceComponent === 'CustomTrigger'
1006
- ? { ...(meta || {}), _context_component_type: sourceComponent, _upstream_component_type: sourceComponent }
1007
- : meta, sourceComponent === 'CustomTrigger'
1243
+ return formulaIndexedWorkflowDetailArgument(resolvedKey, String(label), String(sourceId), appId, String(sourceFieldType || fieldType || 'string'), detailLabel, contextMetaForReference(meta, src, sourceComponent), sourceComponent === 'CustomTrigger'
1008
1244
  ? String(resolved.fieldId || resolveCustomTriggerFormulaFrontId(resolvedKey, resolved, meta))
1009
- : src?._resolvedContext?.fieldId);
1245
+ : src?._resolvedContext?.fieldId, resolved);
1010
1246
  }
1011
- const child = assignFlatEsbChild(resolvedKey, String(label), String(sourceId), appId, String(sourceFieldType || fieldType || 'string'), undefined, detailLabel, workflowName, sourceComponent);
1247
+ const child = assignFlatEsbChild(resolvedKey, String(label), String(sourceId), appId, String(sourceFieldType || fieldType || 'string'), undefined, detailLabel, workflowName, sourceComponent, contextMetaForReference(meta, src, sourceComponent), resolved, String(src?.basisParamKey || src?.basisValue?.paramKey || ''), String(src?.basisType || src?.config?.basisType || 'formSetting'));
1012
1248
  attachEsbAssign(child, meta, String(sourceId));
1013
1249
  return child;
1014
1250
  }
@@ -1344,18 +1580,18 @@ export function assignFlatContextDirect(paramKey, fieldLabel, sourceId, appId, f
1344
1580
  const componentType = String(meta?._context_component_type || meta?._upstream_component_type || '');
1345
1581
  const contextRoot = String(meta?._context_table_primary_key || contextRootForComponent(componentType));
1346
1582
  const parameterContext = isParameterContext(componentType, requestedPkey, contextRoot);
1347
- const parameterTable = WEBHOOK_CONTEXT_TABLES.has(contextRoot)
1583
+ const parameterTable = parameterContext
1348
1584
  ? contextRoot
1349
1585
  : WEBHOOK_CONTEXT_TABLES.has(requestedPkey.split('.')[0])
1350
1586
  ? requestedPkey.split('.')[0]
1351
- : componentType === 'ServerlessAction' && SERVERLESS_CONTEXT_TABLES.has(contextRoot)
1352
- ? contextRoot
1353
- : SERVERLESS_CONTEXT_TABLES.has(requestedPkey.split('.')[0])
1354
- ? requestedPkey.split('.')[0]
1355
- : componentType === 'ServerlessAction' ? 'Response' : 'Body';
1587
+ : SERVERLESS_CONTEXT_TABLES.has(requestedPkey.split('.')[0])
1588
+ ? requestedPkey.split('.')[0]
1589
+ : componentType === 'ServerlessAction' ? 'Response' : 'Body';
1590
+ const apiParamKey = String(meta?._context_original_param_key || '').trim();
1356
1591
  const pkey = parameterContext
1357
- ? ((WEBHOOK_CONTEXT_TABLES.has(requestedPkey.split('.')[0]) || SERVERLESS_CONTEXT_TABLES.has(requestedPkey.split('.')[0]))
1358
- ? requestedPkey : `${parameterTable}.${requestedPkey}`)
1592
+ ? (apiParamKey
1593
+ ? protocolParamKey(apiParamKey, parameterTable, componentType)
1594
+ : protocolParamKey(requestedPkey, parameterTable, componentType))
1359
1595
  : requestedPkey.replace(/^(?:FormData|ApprovalData|SelectParams)\./, '');
1360
1596
  const multPath = resolveFrontendMultPath(pkey, parentName || `表单数据.${fieldLabel}`, meta);
1361
1597
  const currentPkey = multPath.paramKey;
@@ -1407,11 +1643,14 @@ export function assignFlatContextDirect(paramKey, fieldLabel, sourceId, appId, f
1407
1643
  const valuePrefix = parameterContext ? '' : `${prefix}.`;
1408
1644
  const tableName = String(meta?._context_table_name || (parameterContext ? parameterTable : contextTableNameForRoot(prefix)));
1409
1645
  const sourceComponent = resolvedSourceComponent;
1410
- const valueParamKey = parameterContext ? currentPkey : addContextTableKey(currentPkey, meta);
1411
- const allValueParamKey = parameterContext ? multPath.allParamKey : addContextTableKey(multPath.allParamKey, meta);
1412
- const fieldInfoParamKey = String(meta?._context_original_param_key || pkey);
1646
+ const valueParamKey = parameterContext ? `${parameterTable}.${currentPkey}` : addContextTableKey(currentPkey, meta);
1647
+ const allValueParamKey = parameterContext ? `${parameterTable}.${multPath.allParamKey}` : addContextTableKey(multPath.allParamKey, meta);
1648
+ const fieldInfoParamKey = parameterContext
1649
+ ? protocolParamKey(String(meta?._context_original_param_key || pkey), parameterTable, componentType)
1650
+ : String(meta?._context_original_param_key || pkey);
1413
1651
  const result = {
1414
1652
  formulaType: fieldType, name: String(fieldLabel), businessId: appId || '', id: fid,
1653
+ paramType: fieldType,
1415
1654
  source: src, type: '3', value: `${valuePrefix}${valueParamKey}`,
1416
1655
  frontId, paramKey: currentPkey, parentName: pname, childs: [],
1417
1656
  config: {
@@ -1438,48 +1677,138 @@ function directContextMeta(meta, sourceComponent, sourceRef) {
1438
1677
  const resolved = sourceRef?._resolvedContext && typeof sourceRef._resolvedContext === 'object'
1439
1678
  ? sourceRef._resolvedContext : {};
1440
1679
  return {
1441
- ...(meta || {}),
1680
+ ...contextMetaForReference(meta, sourceRef, sourceComponent),
1442
1681
  _context_component_type: sourceComponent,
1443
1682
  ...(['WebHookTrigger', 'ServerlessAction'].includes(sourceComponent) ? {
1444
- _context_table_primary_key: String(resolved.tablePrimaryKey || resolved.tableKey || ''),
1445
- _context_table_name: String(resolved.tableName || ''),
1683
+ _context_table_primary_key: String(resolved.tablePrimaryKey || resolved.tableKey || meta?._context_table_primary_key || ''),
1684
+ _context_table_name: String(resolved.tableName || meta?._context_table_name || ''),
1446
1685
  } : {}),
1447
1686
  };
1448
1687
  }
1449
- function assignFlatEsbChild(paramKey, fieldLabel, sourceId, appId, fieldType = 'string', detailParamKey = '', detailLabel = '', workflowName = '', componentType = 'ApproveTrigger') {
1688
+ function assignFlatEsbChild(paramKey, fieldLabel, sourceId, appId, fieldType = 'string', detailParamKey = '', detailLabel = '', workflowName = '', componentType = 'ApproveTrigger', meta = null, resolvedContext = null, basisParamKey = '', basisType = 'formSetting') {
1450
1689
  const fid = genSfId();
1451
1690
  const src = String(sourceId) || '0';
1452
- const contextRoot = contextRootForComponent(componentType);
1453
- const tableName = contextTableNameForRoot(contextRoot);
1454
- const tailPart = paramKey.includes('.') ? paramKey.slice(paramKey.lastIndexOf('.') + 1) : paramKey;
1455
- const subId = tailPart.replace(/\[\]$/, '');
1456
- const detailPk = detailParamKey || (paramKey.includes('[]') ? paramKey.slice(0, paramKey.indexOf('[]')) + '[]' : '');
1691
+ const resolved = resolvedContext && typeof resolvedContext === 'object' ? resolvedContext : {};
1692
+ const sourceComponent = String(resolved.componentType || componentType || 'ApproveTrigger');
1693
+ // EsbFormDataDto/CustSetFormDto 的依据值下级协议使用表单设置根;
1694
+ // 只有 API 已回填 tablePrimaryKey 时才采用来源组件的实际参数根。
1695
+ const contextRoot = resolvedContextRoot(resolved, sourceComponent, sourceComponent === 'CustomTrigger'
1696
+ ? 'SelectParams'
1697
+ : parameterContextRoot(paramKey, sourceComponent) || 'FormData');
1698
+ const sourceMeta = contextMetaForReference(meta, { paramKey, _resolvedContext: resolved }, sourceComponent);
1699
+ const rawField = resolved.rawField && typeof resolved.rawField === 'object' ? resolved.rawField : {};
1700
+ const rawDetailPk = detailParamKey || basisParamKey || (paramKey.includes('[]') ? paramKey.slice(0, paramKey.indexOf('[]')) + '[]' : '');
1701
+ const subId = basisParamKey
1702
+ ? resolveBasisSubKey(paramKey, basisParamKey, basisType, sourceMeta, resolved)
1703
+ : String(rawField.paramName || rawField.key || resolveFormSettingSubKey(paramKey, sourceMeta));
1704
+ const detailPk = protocolParamKey(rawDetailPk, contextRoot, sourceComponent);
1457
1705
  const detailVal = `${contextRoot}.${detailPk}`;
1458
- const parentName = workflowName ? `${workflowName}.${fieldLabel}[]` : `${fieldLabel}[]`;
1706
+ const resolvedParentName = String(resolved.parentName || '').trim();
1707
+ const basisParentName = resolvedParentName.includes('[]')
1708
+ ? resolvedParentName.slice(0, resolvedParentName.indexOf('[]') + 2)
1709
+ : '';
1710
+ const parentName = basisParentName || resolveFormSettingBasisParentName(detailPk, detailLabel || fieldLabel, sourceMeta);
1711
+ const basisPathMeta = { ...sourceMeta, _context_original_parent_name: parentName };
1712
+ const path = resolveFrontendMultPath(detailPk, parentName, basisPathMeta);
1459
1713
  const subName = workflowName ? `${workflowName}.${fieldLabel}` : String(fieldLabel);
1460
- const allName = workflowName && detailLabel ? `${workflowName}.${detailLabel}[]` : parentName;
1714
+ const allName = path.allParentName || (workflowName && detailLabel ? `${workflowName}.${detailLabel}[]` : parentName);
1715
+ const currentParamKey = path.paramKey.startsWith(`${contextRoot}.`)
1716
+ ? path.paramKey
1717
+ : `${contextRoot}.${path.paramKey}`;
1718
+ const allParamKey = path.allParamKey.startsWith(`${contextRoot}.`)
1719
+ ? path.allParamKey
1720
+ : `${contextRoot}.${path.allParamKey}`;
1721
+ const apiParamKey = String(resolved.paramKey
1722
+ || sourceMeta._context_original_param_key
1723
+ || protocolParamKey(paramKey, contextRoot, sourceComponent));
1461
1724
  return {
1462
1725
  id: fid, name: String(fieldLabel), value: subId, type: '10', fieldType, formulaType: fieldType,
1726
+ paramType: fieldType,
1463
1727
  applicationId: appId || '',
1464
1728
  config: {
1465
- paramKey: String(paramKey), basisType: 'formSetting', switchType: 'sub', level: 1,
1729
+ paramKey: apiParamKey, basisType: String(basisType || 'formSetting'), switchType: 'sub', level: 1,
1466
1730
  id: subId, source: src, formulaVersion: 'V1', value: detailVal,
1467
1731
  config: {
1468
- paramKey: detailPk, isMultCom: false, comType: componentType, switchType: 'assign', parentComId: 0,
1732
+ paramKey: path.paramKey, isMultCom: Boolean(resolved.isMultCom), comType: sourceComponent, switchType: 'assign', parentComId: 0,
1469
1733
  fieldInfo: { paramKey: detailPk, tablePrimaryKey: contextRoot },
1470
- tableName, paramType: fieldType, parentName, multName: '', multKey: '',
1734
+ tableName: String(resolved.tableName || contextTableNameForRoot(contextRoot)), paramType: fieldType,
1735
+ parentName: path.parentName || parentName, multName: path.multName, multKey: path.multKey,
1471
1736
  multTypeObj: {
1472
- allName, currentName: subName,
1473
- currentParamKey: paramKey.startsWith(`${contextRoot}.`) ? String(paramKey) : `${contextRoot}.${paramKey}`,
1474
- allParamKey: detailVal,
1737
+ allName, currentName: path.parentName || subName,
1738
+ currentParamKey, allParamKey,
1475
1739
  },
1476
- comId: src, newParentName: parentName,
1740
+ comId: src, newParentName: path.allParentName || parentName,
1477
1741
  },
1478
1742
  originValue: subId, content: String(fieldLabel),
1479
1743
  },
1480
1744
  childs: [], parentId: '0',
1481
1745
  };
1482
1746
  }
1747
+ /**
1748
+ * 函数参数中的表单设置依据值下级。
1749
+ *
1750
+ * set-formdata/common assignment 的 Basis.onClick 会把这类引用保存为
1751
+ * type=10,并把 value 写成 detailBasis.<detailTable>.<field>;它不是函数
1752
+ * 编辑器为普通上下文字段生成的 type=3 + 第 0 行索引节点。
1753
+ */
1754
+ function assignBasisFormulaArgument(paramKey, fieldLabel, sourceId, appId, fieldType, basisParamKey, basisType, meta, resolvedContext = {}) {
1755
+ const fid = genSfId();
1756
+ const sourceComponent = String(resolvedContext.componentType || meta?._context_component_type || meta?._upstream_component_type || 'ApproveTrigger');
1757
+ const contextRoot = resolvedContextRoot(resolvedContext, sourceComponent, sourceComponent === 'CustomTrigger'
1758
+ ? 'SelectParams'
1759
+ : parameterContextRoot(paramKey, sourceComponent) || 'FormData');
1760
+ const selectedParamKey = protocolParamKey(String(paramKey), contextRoot, sourceComponent);
1761
+ const selectedBasisKey = protocolParamKey(String(basisParamKey), contextRoot, sourceComponent);
1762
+ const relative = selectedParamKey.startsWith(`${selectedBasisKey}.`)
1763
+ ? selectedParamKey.slice(selectedBasisKey.length + 1)
1764
+ : selectedParamKey;
1765
+ const basisToken = selectedBasisKey
1766
+ .split('.')
1767
+ .filter(Boolean)
1768
+ .pop()
1769
+ ?.replace(/\[\]$/, '') || '';
1770
+ const baseType = String(resolvedContext.baseType
1771
+ || (selectedBasisKey.includes('[]') ? 'detailBasis' : 'mainBasis'));
1772
+ const basisValue = `${baseType}.${basisToken}.${relative.replace(/\[\]/g, '')}`;
1773
+ const parentName = String(resolvedContext.parentName
1774
+ || meta?._context_original_parent_name
1775
+ || fieldLabel);
1776
+ const fieldId = String(resolvedContext.fieldId
1777
+ || resolvedContext.rawField?.id
1778
+ || resolvedContext.rawField?.paramId
1779
+ || '');
1780
+ const multKey = String(resolvedContext.multKey || meta?._context_mult_key || '');
1781
+ const comId = String(resolvedContext.comId || meta?._context_com_id || sourceId || '0');
1782
+ return {
1783
+ id: fid,
1784
+ name: String(fieldLabel),
1785
+ value: basisValue,
1786
+ type: '10',
1787
+ fieldType,
1788
+ formulaType: fieldType,
1789
+ paramType: fieldType,
1790
+ applicationId: appId || '',
1791
+ frontId: fieldId ? normalizeNumericFrontId(fieldId, '依据值下级 FormulaBean.frontId') : undefined,
1792
+ config: {
1793
+ basisType: String(basisType || 'formSetting'),
1794
+ paramKey: selectedParamKey,
1795
+ paramType: fieldType,
1796
+ parentName,
1797
+ source: String(sourceId || '0'),
1798
+ frontId: fieldId || undefined,
1799
+ value: contextRoot,
1800
+ config: { multKey, comId, paramType: fieldType },
1801
+ fieldInfo: {
1802
+ paramKey: selectedParamKey,
1803
+ tablePrimaryKey: contextRoot,
1804
+ baseType,
1805
+ },
1806
+ formulaVersion: 'V1',
1807
+ },
1808
+ childs: [],
1809
+ parentId: '0',
1810
+ };
1811
+ }
1483
1812
  /**
1484
1813
  * 函数中的流程明细字段引用。
1485
1814
  *
@@ -1487,24 +1816,39 @@ function assignFlatEsbChild(paramKey, fieldLabel, sourceId, appId, fieldType = '
1487
1816
  * 选中“明细[0].字段”后保存的真实结构是 type=3:value 的 [] 被一个 type=1
1488
1817
  * 索引子节点 position 替换。缺少这个索引节点时,设计器只会把字段名渲染成红字。
1489
1818
  */
1490
- function formulaIndexedWorkflowDetailArgument(paramKey, fieldLabel, sourceId, appId, fieldType = 'string', detailLabel = '', meta = {}, resolvedFrontId = '') {
1819
+ function formulaIndexedWorkflowDetailArgument(paramKey, fieldLabel, sourceId, appId, fieldType = 'string', detailLabel = '', meta = {}, resolvedFrontId = '', resolvedContext = {}) {
1491
1820
  const fid = genSfId();
1492
- const match = String(paramKey).match(/^([^\.]+)\.([^\.\[]+)\[\]\.([^\.\[]+)$/);
1493
- if (!match)
1821
+ const sourceComponent = String(resolvedContext.componentType || meta?._context_component_type || meta?._upstream_component_type || 'ApproveTrigger');
1822
+ const parameterRoot = (sourceComponent === 'WebHookTrigger' || sourceComponent === 'ServerlessAction')
1823
+ ? String(resolvedContext.tablePrimaryKey || resolvedContext.tableKey || meta?._context_table_primary_key || parameterContextRoot(paramKey, sourceComponent) || '')
1824
+ : '';
1825
+ const normalizedParamKey = parameterRoot
1826
+ ? protocolParamKey(String(paramKey), parameterRoot, sourceComponent)
1827
+ : String(paramKey).replace(/^(?:FormData|ApprovalData|SelectParams)\./, '');
1828
+ const workflowDetailMatch = normalizedParamKey.match(/^([^\.]+)\.([^\.\[]+)\[\]\.([^\.\[]+)$/);
1829
+ const parameterDetailMatch = normalizedParamKey.match(/^([^\.\[]+)\[\]\.([^\.\[]+)$/);
1830
+ if (!workflowDetailMatch && !parameterDetailMatch)
1494
1831
  throw new Error(`[formula] 明细函数参数 paramKey 不合法: ${paramKey}`);
1495
- const [, workflowId, detailId, detailFieldId] = match;
1496
- const detailName = String(getWorkflowDetailNames()[workflowId]?.[detailId] || detailLabel || detailId);
1832
+ const workflowId = workflowDetailMatch?.[1] || parameterDetailMatch?.[1] || '';
1833
+ const detailId = workflowDetailMatch?.[2] || '';
1834
+ const detailFieldId = workflowDetailMatch?.[3] || parameterDetailMatch?.[2] || '';
1835
+ const detailName = parameterDetailMatch
1836
+ ? String(resolvedContext.parentName || detailLabel || workflowId).split('[]')[0]
1837
+ : String(getWorkflowDetailNames()[workflowId]?.[detailId] || detailLabel || detailId);
1497
1838
  const workflowName = String(meta?._upstream_workflow_name || '');
1498
- const sourceComponent = String(meta?._context_component_type || meta?._upstream_component_type || 'ApproveTrigger');
1499
- const parentName = alignContextParentName(paramKey, `${workflowName ? `${workflowName}.` : ''}${detailName}[].${fieldLabel}`, fieldLabel, meta, { componentType: sourceComponent });
1839
+ const parentName = alignContextParentName(normalizedParamKey, resolvedContext.parentName
1840
+ || meta?._context_original_parent_name
1841
+ || `${workflowName ? `${workflowName}.` : ''}${detailName}[].${fieldLabel}`, fieldLabel, meta, { componentType: sourceComponent });
1500
1842
  const index = formulaFixed('0', 'string');
1501
1843
  index.name = '0';
1502
1844
  index.position = genSfId();
1503
1845
  index.parentId = fid;
1504
- const contextRoot = contextRootForComponent(sourceComponent);
1505
- const tableName = contextTableNameForRoot(contextRoot);
1506
- const contextValue = `${contextRoot}.${workflowId}.${detailId}[${index.position}].${detailFieldId}`;
1507
- const allParamKey = `${contextRoot}.${paramKey}`;
1846
+ const contextRoot = parameterRoot || contextRootForComponent(sourceComponent);
1847
+ const tableName = parameterRoot
1848
+ ? String(resolvedContext.tableName || meta?._context_table_name || contextRoot)
1849
+ : contextTableNameForRoot(contextRoot);
1850
+ const contextValue = `${contextRoot}.${normalizedParamKey.replace('[]', `[${index.position}]`)}`;
1851
+ const allParamKey = `${contextRoot}.${normalizedParamKey}`;
1508
1852
  return {
1509
1853
  formulaType: fieldType,
1510
1854
  name: String(fieldLabel),
@@ -1515,18 +1859,18 @@ function formulaIndexedWorkflowDetailArgument(paramKey, fieldLabel, sourceId, ap
1515
1859
  applicationId: appId || '',
1516
1860
  value: contextValue,
1517
1861
  frontId: normalizeNumericFrontId(sourceComponent === 'CustomTrigger' ? resolvedFrontId : (resolvedFrontId || detailFieldId), '流程明细 FormulaBean.frontId'),
1518
- paramKey: String(paramKey),
1862
+ paramKey: normalizedParamKey,
1519
1863
  parentName,
1520
1864
  childs: [index],
1521
1865
  config: {
1522
- paramKey: String(paramKey),
1866
+ paramKey: normalizedParamKey,
1523
1867
  isMultCom: false,
1524
1868
  comType: sourceComponent,
1525
1869
  switchType: 'assign',
1526
1870
  parentComId: 0,
1527
1871
  parentName,
1528
1872
  formulaVersion: 'V1',
1529
- fieldInfo: { paramKey: String(paramKey), tablePrimaryKey: contextRoot },
1873
+ fieldInfo: { paramKey: normalizedParamKey, tablePrimaryKey: contextRoot },
1530
1874
  tableName,
1531
1875
  paramType: fieldType,
1532
1876
  multName: '',
@@ -1625,7 +1969,7 @@ export function attachEsbAssign(bean, meta, fallbackSource = '') {
1625
1969
  esbWid = String(Date.now()).slice(0, 13);
1626
1970
  bean.esbAssign = { wId: esbWid, textarea: false, withoutDftNum: true };
1627
1971
  }
1628
- export function buildSettingEntry(fieldId, assignment, fieldType = 'Text', meta = {}, appId = '', defaultSourceId = '', operate = 'OPERATE_EQUAL', componentType = '', detailMode = false, assignmentMode = '') {
1972
+ export function buildSettingEntry(fieldId, assignment, fieldType = 'Text', meta = {}, appId = '', defaultSourceId = '', operate = 'OPERATE_EQUAL', componentType = '', detailMode = false, assignmentMode = '', preserveTextarea = false) {
1629
1973
  if (!meta || typeof meta !== 'object')
1630
1974
  meta = {};
1631
1975
  const rawValue = assignment && typeof assignment === 'object' ? (assignment.value ?? assignment) : assignment;
@@ -1682,7 +2026,7 @@ export function buildSettingEntry(fieldId, assignment, fieldType = 'Text', meta
1682
2026
  if (realDtl)
1683
2027
  detailLabel = realDtl;
1684
2028
  const workflowName = String(meta._upstream_workflow_name || '');
1685
- flat = assignFlatEsbChild(pkeyFull, subLabel, String(src), appId, ft, undefined, detailLabel, workflowName, sourceComponent);
2029
+ flat = assignFlatEsbChild(pkeyFull, subLabel, String(src), appId, ft, undefined, detailLabel, workflowName, sourceComponent, contextMetaForReference(meta, ref, sourceComponent), ref?._resolvedContext || {}, String(ref?.basisParamKey || ref?.basisValue?.paramKey || ''), String(ref?.basisType || ref?.config?.basisType || 'formSetting'));
1686
2030
  switchT = 'sub';
1687
2031
  attachEsbAssign(flat, meta, String(src));
1688
2032
  return {
@@ -1696,8 +2040,8 @@ export function buildSettingEntry(fieldId, assignment, fieldType = 'Text', meta
1696
2040
  else if (assignmentMode === 'direct' && operate === 'OPERATE_EQUAL') {
1697
2041
  const workflowId = String(meta._workflow_id || '');
1698
2042
  const paramKeyFull = resolveParamKey(workflowId, String(key));
1699
- const directMeta = directContextMeta(meta, sourceComponent, src);
1700
- flat = assignFlatContextDirect(paramKeyFull, String(label || key), String(src), appId, 'string', String(meta._upstream_workflow_name || ''), directMeta, ref?._resolvedContext?.fieldId);
2043
+ const directMeta = directContextMeta(meta, sourceComponent, ref);
2044
+ flat = assignFlatContextDirect(paramKeyFull, String(label || key), String(src), appId, ft, String(meta._upstream_workflow_name || ''), directMeta, ref?._resolvedContext?.fieldId || ref?.frontId || ref?.fieldId);
1701
2045
  switchT = 'assign';
1702
2046
  }
1703
2047
  else if (assignmentMode === 'nested' && operate === 'OPERATE_EQUAL') {
@@ -1743,8 +2087,8 @@ export function buildSettingEntry(fieldId, assignment, fieldType = 'Text', meta
1743
2087
  directParent = `${formName}.${label || pkey}`;
1744
2088
  else
1745
2089
  directParent = `表单数据.${label || key}`;
1746
- const directMeta = directContextMeta(meta, sourceComponent, src);
1747
- flat = assignFlatContextDirect(pkey, String(label || key), String(src), appId, ft, directParent, directMeta, ref?._resolvedContext?.fieldId);
2090
+ const directMeta = directContextMeta(meta, sourceComponent, ref);
2091
+ flat = assignFlatContextDirect(pkey, String(label || key), String(src), appId, ft, directParent, directMeta, ref?._resolvedContext?.fieldId || ref?.frontId || ref?.fieldId);
1748
2092
  switchT = 'assign';
1749
2093
  }
1750
2094
  else {
@@ -1763,14 +2107,15 @@ export function buildSettingEntry(fieldId, assignment, fieldType = 'Text', meta
1763
2107
  if (!srcName)
1764
2108
  srcName = String(meta._upstream_form_name || '');
1765
2109
  const directParent = srcName ? `${srcName}.${label || key}` : `表单数据.${label || key}`;
1766
- const directMeta = directContextMeta(meta, sourceComponent, src);
1767
- flat = assignFlatContextDirect(pkey, String(label || key), String(src), appId, ft, directParent, directMeta, ref?._resolvedContext?.fieldId);
2110
+ const directMeta = directContextMeta(meta, sourceComponent, ref);
2111
+ flat = assignFlatContextDirect(pkey, String(label || key), String(src), appId, ft, directParent, directMeta, ref?._resolvedContext?.fieldId || ref?.frontId || ref?.fieldId);
1768
2112
  switchT = 'assign';
1769
2113
  }
1770
2114
  }
1771
2115
  else if (kind === 'system_variable') {
1772
2116
  const key = ref && typeof ref === 'object' ? (ref.key ?? '{userid}') : '{userid}';
1773
- flat = assignFlatSystemVar(String(key), appId, ft);
2117
+ const systemVar = assignFlatSystemVar(String(key), appId, ft);
2118
+ flat = preserveTextarea ? formulaContainerString([systemVar], '', appId) : systemVar;
1774
2119
  switchT = 'assign';
1775
2120
  }
1776
2121
  else if (kind === 'fixed') {
@@ -1809,7 +2154,13 @@ export function buildSettingEntry(fieldId, assignment, fieldType = 'Text', meta
1809
2154
  switchT = 'fixvalue';
1810
2155
  }
1811
2156
  else if (kind === 'constant' || kind === 'variable' || kind === 'transform' || kind === 'formula' || kind === 'function' || kind === 'query_result') {
1812
- const bean = unwrapDynamicTextarea(buildAssignBean(assignment, fieldId, fieldType, meta, appId, defaultSourceId), `字段 ${fieldId} 的动态赋值`);
2157
+ const builtBean = buildAssignBean(assignment, fieldId, fieldType, meta, appId, defaultSourceId);
2158
+ // HRM 表单组件的前端 ActionEbDlg 会把文本类动态赋值保存为
2159
+ // textarea(type=8) + 一个子 FormulaBean;普通 e-builder 动作仍使用
2160
+ // 展平后的 FormulaBean,避免改变其他组件的既有协议。
2161
+ const bean = preserveTextarea
2162
+ ? (builtBean?.type === '8' ? builtBean : formulaContainerString([builtBean], '', appId))
2163
+ : unwrapDynamicTextarea(builtBean, `字段 ${fieldId} 的动态赋值`);
1813
2164
  const flatId = bean.id || assignId;
1814
2165
  flat = Object.fromEntries(Object.entries(bean).filter(([k]) => !['configObject', 'childs', 'parentId', 'sortWeight', 'position'].includes(k)));
1815
2166
  if (bean.childs)