weaver-e10-builder 1.1.6 → 1.1.8

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 (193) hide show
  1. package/dist/commands/actionflow.d.ts.map +1 -1
  2. package/dist/commands/actionflow.js +93 -10
  3. package/dist/commands/actionflow.js.map +1 -1
  4. package/dist/commands/designer-common.d.ts +12 -2
  5. package/dist/commands/designer-common.d.ts.map +1 -1
  6. package/dist/commands/designer-common.js +89 -22
  7. package/dist/commands/designer-common.js.map +1 -1
  8. package/dist/commands/designer.d.ts.map +1 -1
  9. package/dist/commands/designer.js +7 -2
  10. package/dist/commands/designer.js.map +1 -1
  11. package/dist/commands/form-association-manage.js +1 -1
  12. package/dist/commands/form-association-manage.js.map +1 -1
  13. package/dist/commands/form-association.d.ts.map +1 -1
  14. package/dist/commands/form-association.js +1 -6
  15. package/dist/commands/form-association.js.map +1 -1
  16. package/dist/commands/form-field-lang.d.ts +3 -0
  17. package/dist/commands/form-field-lang.d.ts.map +1 -0
  18. package/dist/commands/form-field-lang.js +148 -0
  19. package/dist/commands/form-field-lang.js.map +1 -0
  20. package/dist/commands/form-table-view.d.ts.map +1 -1
  21. package/dist/commands/form-table-view.js +28 -9
  22. package/dist/commands/form-table-view.js.map +1 -1
  23. package/dist/commands/form.d.ts.map +1 -1
  24. package/dist/commands/form.js +10 -4
  25. package/dist/commands/form.js.map +1 -1
  26. package/dist/commands/interface.d.ts.map +1 -1
  27. package/dist/commands/interface.js +7 -3
  28. package/dist/commands/interface.js.map +1 -1
  29. package/dist/commands/matrix.d.ts.map +1 -1
  30. package/dist/commands/matrix.js +78 -16
  31. package/dist/commands/matrix.js.map +1 -1
  32. package/dist/commands/skill.d.ts.map +1 -1
  33. package/dist/commands/skill.js +4 -2
  34. package/dist/commands/skill.js.map +1 -1
  35. package/dist/commands/workflow-create-workflow.d.ts.map +1 -1
  36. package/dist/commands/workflow-create-workflow.js +20 -5
  37. package/dist/commands/workflow-create-workflow.js.map +1 -1
  38. package/dist/commands/workflow-odoc.d.ts +3 -0
  39. package/dist/commands/workflow-odoc.d.ts.map +1 -0
  40. package/dist/commands/workflow-odoc.js +288 -0
  41. package/dist/commands/workflow-odoc.js.map +1 -0
  42. package/dist/index.js +4 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/services/actionflow/build_workflow_draft.d.ts.map +1 -1
  45. package/dist/services/actionflow/build_workflow_draft.js +17 -7
  46. package/dist/services/actionflow/build_workflow_draft.js.map +1 -1
  47. package/dist/services/actionflow/command_output.d.ts +4 -0
  48. package/dist/services/actionflow/command_output.d.ts.map +1 -1
  49. package/dist/services/actionflow/command_output.js +92 -1
  50. package/dist/services/actionflow/command_output.js.map +1 -1
  51. package/dist/services/actionflow/component_registry.d.ts.map +1 -1
  52. package/dist/services/actionflow/component_registry.js +11 -2
  53. package/dist/services/actionflow/component_registry.js.map +1 -1
  54. package/dist/services/actionflow/components/action_eb_add.js +1 -1
  55. package/dist/services/actionflow/components/action_eb_add.js.map +1 -1
  56. package/dist/services/actionflow/components/action_eb_update.js +1 -1
  57. package/dist/services/actionflow/components/action_eb_update.js.map +1 -1
  58. package/dist/services/actionflow/components/dml_execute.d.ts +11 -0
  59. package/dist/services/actionflow/components/dml_execute.d.ts.map +1 -0
  60. package/dist/services/actionflow/components/dml_execute.js +172 -0
  61. package/dist/services/actionflow/components/dml_execute.js.map +1 -0
  62. package/dist/services/actionflow/components/enquiry_form.d.ts +7 -0
  63. package/dist/services/actionflow/components/enquiry_form.d.ts.map +1 -1
  64. package/dist/services/actionflow/components/enquiry_form.js +57 -7
  65. package/dist/services/actionflow/components/enquiry_form.js.map +1 -1
  66. package/dist/services/actionflow/components/http.d.ts +12 -0
  67. package/dist/services/actionflow/components/http.d.ts.map +1 -0
  68. package/dist/services/actionflow/components/http.js +216 -0
  69. package/dist/services/actionflow/components/http.js.map +1 -0
  70. package/dist/services/actionflow/components/index.d.ts.map +1 -1
  71. package/dist/services/actionflow/components/index.js +7 -0
  72. package/dist/services/actionflow/components/index.js.map +1 -1
  73. package/dist/services/actionflow/components/send_message.d.ts.map +1 -1
  74. package/dist/services/actionflow/components/send_message.js +9 -1
  75. package/dist/services/actionflow/components/send_message.js.map +1 -1
  76. package/dist/services/actionflow/context_preflight.d.ts +2 -0
  77. package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
  78. package/dist/services/actionflow/context_preflight.js +127 -16
  79. package/dist/services/actionflow/context_preflight.js.map +1 -1
  80. package/dist/services/actionflow/datasource_source.d.ts +18 -0
  81. package/dist/services/actionflow/datasource_source.d.ts.map +1 -0
  82. package/dist/services/actionflow/datasource_source.js +19 -0
  83. package/dist/services/actionflow/datasource_source.js.map +1 -0
  84. package/dist/services/actionflow/design_client.d.ts +0 -2
  85. package/dist/services/actionflow/design_client.d.ts.map +1 -1
  86. package/dist/services/actionflow/design_client.js +0 -19
  87. package/dist/services/actionflow/design_client.js.map +1 -1
  88. package/dist/services/actionflow/dynamic_resources.d.ts +69 -0
  89. package/dist/services/actionflow/dynamic_resources.d.ts.map +1 -0
  90. package/dist/services/actionflow/dynamic_resources.js +259 -0
  91. package/dist/services/actionflow/dynamic_resources.js.map +1 -0
  92. package/dist/services/actionflow/form_source.d.ts +6 -0
  93. package/dist/services/actionflow/form_source.d.ts.map +1 -1
  94. package/dist/services/actionflow/form_source.js +16 -0
  95. package/dist/services/actionflow/form_source.js.map +1 -1
  96. package/dist/services/actionflow/formula_service.d.ts +2 -0
  97. package/dist/services/actionflow/formula_service.d.ts.map +1 -1
  98. package/dist/services/actionflow/formula_service.js +126 -6
  99. package/dist/services/actionflow/formula_service.js.map +1 -1
  100. package/dist/services/actionflow/generation_service.d.ts +17 -1
  101. package/dist/services/actionflow/generation_service.d.ts.map +1 -1
  102. package/dist/services/actionflow/generation_service.js +105 -8
  103. package/dist/services/actionflow/generation_service.js.map +1 -1
  104. package/dist/services/actionflow/http_input_params.d.ts +17 -0
  105. package/dist/services/actionflow/http_input_params.d.ts.map +1 -0
  106. package/dist/services/actionflow/http_input_params.js +98 -0
  107. package/dist/services/actionflow/http_input_params.js.map +1 -0
  108. package/dist/services/actionflow/http_source.d.ts +41 -0
  109. package/dist/services/actionflow/http_source.d.ts.map +1 -0
  110. package/dist/services/actionflow/http_source.js +261 -0
  111. package/dist/services/actionflow/http_source.js.map +1 -0
  112. package/dist/services/actionflow/plan_constraints.d.ts.map +1 -1
  113. package/dist/services/actionflow/plan_constraints.js +4 -2
  114. package/dist/services/actionflow/plan_constraints.js.map +1 -1
  115. package/dist/services/actionflow/preflight_service.d.ts +8 -0
  116. package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
  117. package/dist/services/actionflow/preflight_service.js +105 -27
  118. package/dist/services/actionflow/preflight_service.js.map +1 -1
  119. package/dist/services/actionflow/readback_verifier.d.ts.map +1 -1
  120. package/dist/services/actionflow/readback_verifier.js +34 -1
  121. package/dist/services/actionflow/readback_verifier.js.map +1 -1
  122. package/dist/services/actionflow/save_workflow_draft.d.ts +1 -0
  123. package/dist/services/actionflow/save_workflow_draft.d.ts.map +1 -1
  124. package/dist/services/actionflow/save_workflow_draft.js +61 -16
  125. package/dist/services/actionflow/save_workflow_draft.js.map +1 -1
  126. package/dist/services/actionflow/step_branches.d.ts +18 -0
  127. package/dist/services/actionflow/step_branches.d.ts.map +1 -0
  128. package/dist/services/actionflow/step_branches.js +26 -0
  129. package/dist/services/actionflow/step_branches.js.map +1 -0
  130. package/dist/services/actionflow/update_service.d.ts.map +1 -1
  131. package/dist/services/actionflow/update_service.js +24 -53
  132. package/dist/services/actionflow/update_service.js.map +1 -1
  133. package/dist/services/actionflow/workflow_compiler.d.ts +1 -1
  134. package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
  135. package/dist/services/actionflow/workflow_compiler.js +47 -11
  136. package/dist/services/actionflow/workflow_compiler.js.map +1 -1
  137. package/dist/services/esb-interface/document-parser.d.ts.map +1 -1
  138. package/dist/services/esb-interface/document-parser.js +17 -1
  139. package/dist/services/esb-interface/document-parser.js.map +1 -1
  140. package/dist/services/esb-interface/importer.d.ts +4 -1
  141. package/dist/services/esb-interface/importer.d.ts.map +1 -1
  142. package/dist/services/esb-interface/importer.js +10 -4
  143. package/dist/services/esb-interface/importer.js.map +1 -1
  144. package/dist/services/esb-interface/postman-collection.d.ts +6 -0
  145. package/dist/services/esb-interface/postman-collection.d.ts.map +1 -1
  146. package/dist/services/esb-interface/postman-collection.js +12 -1
  147. package/dist/services/esb-interface/postman-collection.js.map +1 -1
  148. package/dist/services/esb-interface/types.d.ts +1 -0
  149. package/dist/services/esb-interface/types.d.ts.map +1 -1
  150. package/dist/services/form-association.d.ts +1 -0
  151. package/dist/services/form-association.d.ts.map +1 -1
  152. package/dist/services/form-association.js +28 -4
  153. package/dist/services/form-association.js.map +1 -1
  154. package/dist/services/form-table-view.d.ts +24 -4
  155. package/dist/services/form-table-view.d.ts.map +1 -1
  156. package/dist/services/form-table-view.js +144 -133
  157. package/dist/services/form-table-view.js.map +1 -1
  158. package/dist/services/rich-types.d.ts.map +1 -1
  159. package/dist/services/rich-types.js +149 -9
  160. package/dist/services/rich-types.js.map +1 -1
  161. package/dist/services/skill-provision.d.ts +9 -3
  162. package/dist/services/skill-provision.d.ts.map +1 -1
  163. package/dist/services/skill-provision.js +36 -7
  164. package/dist/services/skill-provision.js.map +1 -1
  165. package/package.json +3 -2
  166. package/skill-docs/SKILL.md +261 -252
  167. package/skill-docs/_catalog.md +66 -0
  168. package/skill-docs/actionflows/CONTEXT.md +71 -0
  169. package/skill-docs/actionflows/SKILL.md +159 -0
  170. package/skill-docs/actionflows/references/components/database/DMLExecute.md +38 -0
  171. package/skill-docs/actionflows/references/components/ebuilder/ActionEbAdd.md +2 -0
  172. package/skill-docs/actionflows/references/components/ebuilder/ActionEbUpdate.md +2 -0
  173. package/skill-docs/actionflows/references/components/ebuilder/EnquiryForm.md +2 -2
  174. package/skill-docs/actionflows/references/components/http/Http.md +77 -0
  175. package/skill-docs/actionflows/references/components/message/SendMessage.md +14 -1
  176. package/skill-docs/actionflows/references/condition_rules.md +1 -0
  177. package/skill-docs/actionflows/references/dynamic_resources.md +41 -0
  178. package/skill-docs/actionflows/references/function_rules.md +15 -13
  179. package/skill-docs/references/common/guide-plan-template.md +21 -7
  180. package/skill-docs/references/common/ref-cli-commands.md +13 -6
  181. package/skill-docs/references/esb-interface/guide-import.md +31 -0
  182. package/skill-docs/references/form/guide-create-form.md +126 -376
  183. package/skill-docs/references/form/guide-form-association.md +6 -3
  184. package/skill-docs/references/form/guide-form-layout-planning.md +68 -0
  185. package/skill-docs/references/form/guide-form-serial-mark.md +47 -0
  186. package/skill-docs/references/form/guide-form-view.md +22 -3
  187. package/skill-docs/references/form/ref-form-fields.md +147 -0
  188. package/skill-docs/references/hrm/guide-matrix.md +54 -3
  189. package/skill-docs/references/workflow/guide-workflow-action.md +2 -0
  190. package/skill-docs/references/workflow/guide-workflow-condition.md +48 -6
  191. package/skill-docs/references/workflow/guide-workflow-odoc.md +76 -0
  192. package/skill-docs/references/workflow/guide-workflow.md +467 -461
  193. package/skill-docs/references/workflow/operator-matrix.md +2 -0
@@ -1,4 +1,15 @@
1
1
  import { createHash, randomInt } from 'node:crypto';
2
+ /** 归一 --terminal(缺省 pc)。 */
3
+ export function normalizeFormTableViewTerminal(value) {
4
+ const terminal = String(value ?? 'pc').toLowerCase();
5
+ if (terminal !== 'pc' && terminal !== 'mobile')
6
+ throw new Error('--terminal 仅支持 pc / mobile');
7
+ return terminal;
8
+ }
9
+ /** 终端 → getNListConfig 的 terminalType 取值。 */
10
+ function slotOfTerminal(terminal) {
11
+ return terminal === 'pc' ? 'PC' : 'MOBILE';
12
+ }
2
13
  export const FORM_TABLE_VIEW_STYLES = {
3
14
  table: '1',
4
15
  list: '2',
@@ -201,6 +212,32 @@ export async function readTableViewConfig(client, baseUrl, appId, listId, termin
201
212
  }
202
213
  return structuredClone(response.data);
203
214
  }
215
+ /**
216
+ * 保存单端配置:`config`→PC 槽、`mConfig`→移动端槽(terminalType 写死 PC,与浏览器一致;
217
+ * 实测写 MOBILE 无效——真正决定落点的是 config / mConfig 两个字段)。
218
+ * 另一端**读出来原样回传**,因此两端互不覆盖;另一端读不到时 pcOnly 容忍、否则报错。
219
+ */
220
+ async function saveTerminalConfig(client, baseUrl, appId, listId, terminal, target, options = {}) {
221
+ const otherTerminal = terminal === 'pc' ? 'MOBILE' : 'PC';
222
+ let other = {};
223
+ let otherTerminalPreserved = true;
224
+ try {
225
+ other = await readTableViewConfig(client, baseUrl, appId, listId, otherTerminal);
226
+ }
227
+ catch (error) {
228
+ if (!options.pcOnly)
229
+ throw error;
230
+ otherTerminalPreserved = false;
231
+ }
232
+ requireSuccess(await client.post(`${baseUrl}${SAVE_CONFIG_PATH}?apid=${encode(appId)}`, {
233
+ listId,
234
+ appId,
235
+ terminalType: 'PC',
236
+ config: terminal === 'pc' ? target : other,
237
+ mConfig: terminal === 'mobile' ? target : other,
238
+ }, { ebbusinessid: appId }), 'table view config save');
239
+ return { otherTerminalPreserved };
240
+ }
204
241
  async function resolveFormId(client, baseUrl, appId, objId) {
205
242
  const response = requireSuccess(await client.get(`${baseUrl}${LIST_FORM_PATH}/${encode(appId)}?apid=${encode(appId)}`, { ebbusinessid: appId }), 'form list');
206
243
  const form = (Array.isArray(response.data) ? response.data : [])
@@ -219,8 +256,12 @@ async function resolveFormId(client, baseUrl, appId, objId) {
219
256
  * platform left empty on some on-prem environments).
220
257
  */
221
258
  async function populateListDisplayFields(client, baseUrl, appId, objId, listId, options) {
222
- const pcConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
223
- const configObjId = pcConfig.objId === undefined || pcConfig.objId === null ? objId : String(pcConfig.objId);
259
+ const terminal = normalizeFormTableViewTerminal(options.terminal);
260
+ if (terminal === 'mobile' && options.pcOnly)
261
+ throw new Error('修改移动端不能使用 --pc-only');
262
+ const terminalType = slotOfTerminal(terminal);
263
+ const targetConfig = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
264
+ const configObjId = targetConfig.objId === undefined || targetConfig.objId === null ? objId : String(targetConfig.objId);
224
265
  if (configObjId !== objId)
225
266
  throw new Error(`列表配置 objId=${configObjId} 与目标表单不一致`);
226
267
  const formId = await resolveFormId(client, baseUrl, appId, objId);
@@ -300,28 +341,13 @@ async function populateListDisplayFields(client, baseUrl, appId, objId, listId,
300
341
  });
301
342
  hiddenId.uid ??= stableUid(`ebuilder-field:${objId}:5`);
302
343
  tableFields.push(hiddenId);
303
- pcConfig.tableField = tableFields;
304
- pcConfig.tableMergeFields = [];
305
- pcConfig.personalFields = [];
306
- pcConfig.excelDisabledFieldIds ??= [];
307
- pcConfig.uaLanguage ??= 'zh_CN';
308
- let mobileConfig;
309
- try {
310
- mobileConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'MOBILE');
311
- }
312
- catch (error) {
313
- if (!options.pcOnly)
314
- throw error;
315
- mobileConfig = {};
316
- }
317
- requireSuccess(await client.post(`${baseUrl}${SAVE_CONFIG_PATH}?apid=${encode(appId)}`, {
318
- listId,
319
- appId,
320
- terminalType: 'PC',
321
- config: pcConfig,
322
- mConfig: mobileConfig,
323
- }, { ebbusinessid: appId }), 'table view config save');
324
- const verified = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
344
+ targetConfig.tableField = tableFields;
345
+ targetConfig.tableMergeFields = [];
346
+ targetConfig.personalFields = [];
347
+ targetConfig.excelDisabledFieldIds ??= [];
348
+ targetConfig.uaLanguage ??= 'zh_CN';
349
+ const { otherTerminalPreserved } = await saveTerminalConfig(client, baseUrl, appId, listId, terminal, targetConfig, options);
350
+ const verified = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
325
351
  const verifiedFields = Array.isArray(verified.tableField) ? verified.tableField : [];
326
352
  const verifiedIds = verifiedFields.map((field) => String(field.id));
327
353
  // 用实际保存的列 id 校验(DateRange 父字段已映射为 开始/结束 两个子列,selectedIds 里是父 id)
@@ -338,13 +364,15 @@ async function populateListDisplayFields(client, baseUrl, appId, objId, listId,
338
364
  // 同时填默认视图的 listFields(saveListFields 层)。CLI 之前只填 tableField(created view),
339
365
  // 默认视图 listFields 留空 → getListFields.pc=0 是 bug(见 listfields-empty-bug memory)。
340
366
  // 仅当 listFields 为空时填,不覆盖用户已配。
341
- await populateDefaultViewListFields(client, baseUrl, appId, objId, listId, formId, tableFields);
367
+ await populateDefaultViewListFields(client, baseUrl, appId, objId, listId, formId, tableFields, terminal);
342
368
  return {
343
369
  listId,
344
370
  formId,
345
371
  selectedFieldIds: visibleSavedIds,
346
372
  visibleFieldCount,
347
373
  tableFieldCount: verifiedFields.length,
374
+ terminal,
375
+ otherTerminalPreserved,
348
376
  persisted: true,
349
377
  };
350
378
  }
@@ -354,11 +382,14 @@ async function populateListDisplayFields(client, baseUrl, appId, objId, listId,
354
382
  * (ds/fields 元数据:id/text/type/compType)。saveListFields body 顶层键 listFields/mobileListFields
355
383
  * (非 pc/mobile),头必须带 ebBusinessId=appId。读回键是 data.pc[]。
356
384
  */
357
- async function populateDefaultViewListFields(client, baseUrl, appId, objId, listId, formId, tableFields) {
358
- // 先读 getListFields,pc 非空则跳过
385
+ async function populateDefaultViewListFields(client, baseUrl, appId, objId, listId, formId, tableFields, terminal = 'pc') {
386
+ // 先读 getListFields,目标终端非空则跳过(saveListFields 里 pc/mobile 同样是两个槽位)
387
+ let currentFields = {};
359
388
  try {
360
389
  const cur = await client.get(`${baseUrl}${GET_LIST_FIELDS_PATH}/${encode(listId)}?apid=${encode(appId)}&tpaid=${encode(listId)}&isVirtualForm=false&clientType=PC`, { ebbusinessid: appId });
361
- if (Array.isArray(cur?.data?.pc) && cur.data.pc.length > 0)
390
+ currentFields = cur?.data && typeof cur.data === 'object' ? cur.data : {};
391
+ const existing = currentFields[terminal];
392
+ if (Array.isArray(existing) && existing.length > 0)
362
393
  return false;
363
394
  }
364
395
  catch {
@@ -395,7 +426,17 @@ async function populateDefaultViewListFields(client, baseUrl, appId, objId, list
395
426
  conversionSet: '[]', creator, createTime: ts, deleteType: 0, fieldConfig: {},
396
427
  haveActions: false, isEditField: 1, richEditor: false, widthUnit: 'px',
397
428
  }));
398
- requireSuccess(await client.post(`${baseUrl}${SAVE_LIST_FIELDS_PATH}?apid=${encode(appId)}&tpaid=${encode(listId)}`, { list, isVirtualForm: false, listFields, mobileListFields: [], mergeColumnInfoList: [], hasMerge: 0, displayColumn: false }, { ebbusinessid: appId }), 'default view listFields save');
429
+ // 只填目标终端;另一端有配置就原样回传,避免写空把已配的一端清掉
430
+ const carryOver = (key) => (Array.isArray(currentFields[key]) ? currentFields[key] : []);
431
+ requireSuccess(await client.post(`${baseUrl}${SAVE_LIST_FIELDS_PATH}?apid=${encode(appId)}&tpaid=${encode(listId)}`, {
432
+ list,
433
+ isVirtualForm: false,
434
+ listFields: terminal === 'pc' ? listFields : carryOver('pc'),
435
+ mobileListFields: terminal === 'mobile' ? listFields : carryOver('mobile'),
436
+ mergeColumnInfoList: [],
437
+ hasMerge: 0,
438
+ displayColumn: false,
439
+ }, { ebbusinessid: appId }), 'default view listFields save');
399
440
  return true;
400
441
  }
401
442
  /**
@@ -406,6 +447,10 @@ async function populateDefaultViewListFields(client, baseUrl, appId, objId, list
406
447
  * lists are never touched, so user-configured views are safe.
407
448
  */
408
449
  export async function ensureDefaultListDisplayFields(client, baseUrl, appId, objId, options = {}) {
450
+ const terminal = normalizeFormTableViewTerminal(options.terminal);
451
+ if (terminal === 'mobile' && options.pcOnly)
452
+ throw new Error('修改移动端不能使用 --pc-only');
453
+ const terminalType = slotOfTerminal(terminal);
409
454
  const lists = await queryTableViews(client, baseUrl, appId, objId);
410
455
  let emptyListId = '';
411
456
  for (const item of lists) {
@@ -415,7 +460,7 @@ export async function ensureDefaultListDisplayFields(client, baseUrl, appId, obj
415
460
  if (!id)
416
461
  continue;
417
462
  try {
418
- const cfg = await readTableViewConfig(client, baseUrl, appId, id, 'PC');
463
+ const cfg = await readTableViewConfig(client, baseUrl, appId, id, terminalType);
419
464
  const tf = Array.isArray(cfg.tableField) ? cfg.tableField : [];
420
465
  // 台账若只有隐藏主键/系统列、无可见业务列,也视为空需补全
421
466
  // (共享表环境平台只自动建隐藏 id=5、不建业务显示列 → 台账看似非空实则无业务列)
@@ -430,7 +475,15 @@ export async function ensureDefaultListDisplayFields(client, baseUrl, appId, obj
430
475
  }
431
476
  }
432
477
  if (!emptyListId) {
433
- return { listId: '', ensured: false, visibleFieldCount: 0, tableFieldCount: 0, persisted: true };
478
+ return {
479
+ listId: '',
480
+ ensured: false,
481
+ visibleFieldCount: 0,
482
+ tableFieldCount: 0,
483
+ terminal,
484
+ otherTerminalPreserved: true,
485
+ persisted: true,
486
+ };
434
487
  }
435
488
  const result = await populateListDisplayFields(client, baseUrl, appId, objId, emptyListId, options);
436
489
  return {
@@ -438,6 +491,8 @@ export async function ensureDefaultListDisplayFields(client, baseUrl, appId, obj
438
491
  ensured: true,
439
492
  visibleFieldCount: result.visibleFieldCount,
440
493
  tableFieldCount: result.tableFieldCount,
494
+ terminal: result.terminal,
495
+ otherTerminalPreserved: result.otherTerminalPreserved,
441
496
  persisted: true,
442
497
  };
443
498
  }
@@ -470,6 +525,7 @@ export async function createAndConfigureFormTableView(client, baseUrl, appId, ob
470
525
  const result = await populateListDisplayFields(client, baseUrl, appId, objId, createdId, {
471
526
  fieldIds: options.fieldIds,
472
527
  pcOnly: options.pcOnly,
528
+ terminal: options.terminal,
473
529
  });
474
530
  const afterSave = await queryTableViews(client, baseUrl, appId, objId);
475
531
  if (!afterSave.some((item) => rowId(item) === createdId && item.name === name)) {
@@ -486,46 +542,34 @@ export async function setFormTableViewStyle(client, baseUrl, appId, objId, listI
486
542
  if (!mode) {
487
543
  throw new Error(`不支持的展示样式: ${style}。可选值: ${Object.keys(FORM_TABLE_VIEW_STYLES).join(', ')}`);
488
544
  }
545
+ const terminal = normalizeFormTableViewTerminal(options.terminal);
546
+ if (terminal === 'mobile' && options.pcOnly)
547
+ throw new Error('修改移动端不能使用 --pc-only');
548
+ const terminalType = slotOfTerminal(terminal);
489
549
  const lists = await queryTableViews(client, baseUrl, appId, objId);
490
550
  const target = lists.find((item) => rowId(item) === listId);
491
551
  if (!target)
492
552
  throw new Error(`目标表单下不存在 listId=${listId}`);
493
- const pcConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
494
- const configObjId = pcConfig.objId === undefined || pcConfig.objId === null ? objId : String(pcConfig.objId);
553
+ const targetConfig = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
554
+ const configObjId = targetConfig.objId === undefined || targetConfig.objId === null ? objId : String(targetConfig.objId);
495
555
  if (configObjId !== objId)
496
556
  throw new Error(`列表配置 objId=${configObjId} 与目标表单不一致`);
497
- const previousMode = String(pcConfig.mode ?? '');
557
+ const previousMode = String(targetConfig.mode ?? '');
498
558
  if (previousMode === mode) {
499
559
  return {
500
560
  listId,
501
561
  style,
502
562
  previousMode,
503
563
  mode,
504
- mobilePreserved: true,
564
+ terminal,
565
+ otherTerminalPreserved: true,
505
566
  alreadyConfigured: true,
506
567
  persisted: true,
507
568
  };
508
569
  }
509
- let mobileConfig;
510
- let mobilePreserved = true;
511
- try {
512
- mobileConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'MOBILE');
513
- }
514
- catch (error) {
515
- if (!options.pcOnly)
516
- throw error;
517
- mobileConfig = {};
518
- mobilePreserved = false;
519
- }
520
- pcConfig.mode = mode;
521
- requireSuccess(await client.post(`${baseUrl}${SAVE_CONFIG_PATH}?apid=${encode(appId)}`, {
522
- listId,
523
- appId,
524
- terminalType: 'PC',
525
- config: pcConfig,
526
- mConfig: mobileConfig,
527
- }, { ebbusinessid: appId }), 'table view style save');
528
- const verified = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
570
+ targetConfig.mode = mode;
571
+ const { otherTerminalPreserved } = await saveTerminalConfig(client, baseUrl, appId, listId, terminal, targetConfig, options);
572
+ const verified = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
529
573
  if (String(verified.mode ?? '') !== mode) {
530
574
  throw new Error(`展示样式保存后回读不一致: expected=${mode}, actual=${String(verified.mode ?? '')}`);
531
575
  }
@@ -538,7 +582,8 @@ export async function setFormTableViewStyle(client, baseUrl, appId, objId, listI
538
582
  style,
539
583
  previousMode,
540
584
  mode,
541
- mobilePreserved,
585
+ terminal,
586
+ otherTerminalPreserved,
542
587
  alreadyConfigured: false,
543
588
  persisted: true,
544
589
  };
@@ -548,15 +593,19 @@ export async function setFormTableViewSearchStyle(client, baseUrl, appId, objId,
548
593
  if (commonSearchType === undefined) {
549
594
  throw new Error(`不支持的常用搜索显示方式: ${style}。可选值: ${Object.keys(FORM_TABLE_VIEW_SEARCH_STYLES).join(', ')}`);
550
595
  }
596
+ const terminal = normalizeFormTableViewTerminal(options.terminal);
597
+ if (terminal === 'mobile' && options.pcOnly)
598
+ throw new Error('修改移动端不能使用 --pc-only');
599
+ const terminalType = slotOfTerminal(terminal);
551
600
  const lists = await queryTableViews(client, baseUrl, appId, objId);
552
601
  if (!lists.some((item) => rowId(item) === listId)) {
553
602
  throw new Error(`目标表单下不存在 listId=${listId}`);
554
603
  }
555
- const pcConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
556
- const configObjId = pcConfig.objId === undefined || pcConfig.objId === null ? objId : String(pcConfig.objId);
604
+ const targetConfig = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
605
+ const configObjId = targetConfig.objId === undefined || targetConfig.objId === null ? objId : String(targetConfig.objId);
557
606
  if (configObjId !== objId)
558
607
  throw new Error(`列表配置 objId=${configObjId} 与目标表单不一致`);
559
- const searchConditions = completeSearchConditions(cloneSearchConditions(pcConfig));
608
+ const searchConditions = completeSearchConditions(cloneSearchConditions(targetConfig));
560
609
  const previousType = String(searchConditions.commonSearchType ?? '');
561
610
  if (previousType === commonSearchType) {
562
611
  return {
@@ -564,32 +613,16 @@ export async function setFormTableViewSearchStyle(client, baseUrl, appId, objId,
564
613
  style,
565
614
  previousType,
566
615
  commonSearchType,
567
- mobilePreserved: true,
616
+ terminal,
617
+ otherTerminalPreserved: true,
568
618
  alreadyConfigured: true,
569
619
  persisted: true,
570
620
  };
571
621
  }
572
- let mobileConfig;
573
- let mobilePreserved = true;
574
- try {
575
- mobileConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'MOBILE');
576
- }
577
- catch (error) {
578
- if (!options.pcOnly)
579
- throw error;
580
- mobileConfig = {};
581
- mobilePreserved = false;
582
- }
583
622
  searchConditions.commonSearchType = commonSearchType;
584
- pcConfig.searchConditions = searchConditions;
585
- requireSuccess(await client.post(`${baseUrl}${SAVE_CONFIG_PATH}?apid=${encode(appId)}`, {
586
- listId,
587
- appId,
588
- terminalType: 'PC',
589
- config: pcConfig,
590
- mConfig: mobileConfig,
591
- }, { ebbusinessid: appId }), 'table view common search style save');
592
- const verified = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
623
+ targetConfig.searchConditions = searchConditions;
624
+ const { otherTerminalPreserved } = await saveTerminalConfig(client, baseUrl, appId, listId, terminal, targetConfig, options);
625
+ const verified = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
593
626
  const verifiedType = String(verified.searchConditions?.commonSearchType ?? '');
594
627
  if (verifiedType !== commonSearchType) {
595
628
  throw new Error(`常用搜索显示方式保存后回读不一致: expected=${commonSearchType}, actual=${verifiedType}`);
@@ -603,21 +636,26 @@ export async function setFormTableViewSearchStyle(client, baseUrl, appId, objId,
603
636
  style,
604
637
  previousType,
605
638
  commonSearchType,
606
- mobilePreserved,
639
+ terminal,
640
+ otherTerminalPreserved,
607
641
  alreadyConfigured: false,
608
642
  persisted: true,
609
643
  };
610
644
  }
611
645
  export async function addFormTableViewSearchField(client, baseUrl, appId, objId, listId, fieldId, options = {}) {
646
+ const terminal = normalizeFormTableViewTerminal(options.terminal);
647
+ if (terminal === 'mobile' && options.pcOnly)
648
+ throw new Error('修改移动端不能使用 --pc-only');
649
+ const terminalType = slotOfTerminal(terminal);
612
650
  const lists = await queryTableViews(client, baseUrl, appId, objId);
613
651
  if (!lists.some((item) => rowId(item) === listId)) {
614
652
  throw new Error(`目标表单下不存在 listId=${listId}`);
615
653
  }
616
- const pcConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
617
- const configObjId = pcConfig.objId === undefined || pcConfig.objId === null ? objId : String(pcConfig.objId);
654
+ const targetConfig = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
655
+ const configObjId = targetConfig.objId === undefined || targetConfig.objId === null ? objId : String(targetConfig.objId);
618
656
  if (configObjId !== objId)
619
657
  throw new Error(`列表配置 objId=${configObjId} 与目标表单不一致`);
620
- const searchConditions = completeSearchConditions(cloneSearchConditions(pcConfig));
658
+ const searchConditions = completeSearchConditions(cloneSearchConditions(targetConfig));
621
659
  const existing = searchConditions.commonFilters
622
660
  .find((field) => searchFieldId(field) === fieldId);
623
661
  if (existing) {
@@ -627,7 +665,8 @@ export async function addFormTableViewSearchField(client, baseUrl, appId, objId,
627
665
  fieldName: String(existing.text ?? existing.showName ?? existing.name ?? fieldId),
628
666
  condition: String(existing.conditionTypeValue ?? ''),
629
667
  commonFilterCount: searchConditions.commonFilters.length,
630
- mobilePreserved: true,
668
+ terminal,
669
+ otherTerminalPreserved: true,
631
670
  alreadyConfigured: true,
632
671
  persisted: true,
633
672
  };
@@ -662,27 +701,10 @@ export async function addFormTableViewSearchField(client, baseUrl, appId, objId,
662
701
  if (!availableConditions.includes(condition)) {
663
702
  throw new Error(`字段 ${fieldId} 不支持条件 ${condition};可选值: ${availableConditions.join(', ')}`);
664
703
  }
665
- let mobileConfig;
666
- let mobilePreserved = true;
667
- try {
668
- mobileConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'MOBILE');
669
- }
670
- catch (error) {
671
- if (!options.pcOnly)
672
- throw error;
673
- mobileConfig = {};
674
- mobilePreserved = false;
675
- }
676
704
  searchConditions.commonFilters.push(createCommonSearchField(fieldModel, condition, searchConditions));
677
- pcConfig.searchConditions = searchConditions;
678
- requireSuccess(await client.post(`${baseUrl}${SAVE_CONFIG_PATH}?apid=${encode(appId)}`, {
679
- listId,
680
- appId,
681
- terminalType: 'PC',
682
- config: pcConfig,
683
- mConfig: mobileConfig,
684
- }, { ebbusinessid: appId }), 'table view common search field save');
685
- const verified = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
705
+ targetConfig.searchConditions = searchConditions;
706
+ const { otherTerminalPreserved } = await saveTerminalConfig(client, baseUrl, appId, listId, terminal, targetConfig, options);
707
+ const verified = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
686
708
  const verifiedFilters = Array.isArray(verified.searchConditions?.commonFilters)
687
709
  ? verified.searchConditions.commonFilters
688
710
  : [];
@@ -700,7 +722,8 @@ export async function addFormTableViewSearchField(client, baseUrl, appId, objId,
700
722
  fieldName: String(verifiedField.text ?? verifiedField.showName ?? verifiedField.name ?? fieldId),
701
723
  condition,
702
724
  commonFilterCount: verifiedFilters.length,
703
- mobilePreserved,
725
+ terminal,
726
+ otherTerminalPreserved,
704
727
  alreadyConfigured: false,
705
728
  persisted: true,
706
729
  };
@@ -720,15 +743,19 @@ export async function configureFormTableViewSearchField(client, baseUrl, appId,
720
743
  if (options.displayName !== undefined && !options.displayName.trim()) {
721
744
  throw new Error('显示名称不能为空');
722
745
  }
746
+ const terminal = normalizeFormTableViewTerminal(options.terminal);
747
+ if (terminal === 'mobile' && options.pcOnly)
748
+ throw new Error('修改移动端不能使用 --pc-only');
749
+ const terminalType = slotOfTerminal(terminal);
723
750
  const lists = await queryTableViews(client, baseUrl, appId, objId);
724
751
  if (!lists.some((item) => rowId(item) === listId)) {
725
752
  throw new Error(`目标表单下不存在 listId=${listId}`);
726
753
  }
727
- const pcConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
728
- const configObjId = pcConfig.objId === undefined || pcConfig.objId === null ? objId : String(pcConfig.objId);
754
+ const targetConfig = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
755
+ const configObjId = targetConfig.objId === undefined || targetConfig.objId === null ? objId : String(targetConfig.objId);
729
756
  if (configObjId !== objId)
730
757
  throw new Error(`列表配置 objId=${configObjId} 与目标表单不一致`);
731
- const searchConditions = cloneSearchConditions(pcConfig);
758
+ const searchConditions = cloneSearchConditions(targetConfig);
732
759
  const before = JSON.stringify(searchConditions);
733
760
  completeSearchConditions(searchConditions);
734
761
  const field = searchConditions.commonFilters
@@ -816,7 +843,7 @@ export async function configureFormTableViewSearchField(client, baseUrl, appId,
816
843
  field.conditionTypeValue = options.condition;
817
844
  settings.conditionTypeValue = options.condition;
818
845
  }
819
- const resultFrom = (configuredField, mobilePreserved, alreadyConfigured) => {
846
+ const resultFrom = (configuredField, otherTerminalPreserved, alreadyConfigured) => {
820
847
  const configuredSettings = configuredField.listFilterDefaultSets ?? {};
821
848
  return {
822
849
  listId,
@@ -832,41 +859,25 @@ export async function configureFormTableViewSearchField(client, baseUrl, appId,
832
859
  required: Number(configuredField.required ?? 0) === 1,
833
860
  fullMatch: configuredSettings.searchContentFullMatches === true,
834
861
  condition: String(configuredField.conditionTypeValue ?? ''),
835
- mobilePreserved,
862
+ terminal,
863
+ otherTerminalPreserved,
836
864
  alreadyConfigured,
837
865
  persisted: true,
838
866
  };
839
867
  };
840
868
  if (JSON.stringify(searchConditions) === before)
841
869
  return resultFrom(field, true, true);
842
- let mobileConfig;
843
- let mobilePreserved = true;
844
- try {
845
- mobileConfig = await readTableViewConfig(client, baseUrl, appId, listId, 'MOBILE');
846
- }
847
- catch (error) {
848
- if (!options.pcOnly)
849
- throw error;
850
- mobileConfig = {};
851
- mobilePreserved = false;
852
- }
853
- pcConfig.searchConditions = searchConditions;
854
- requireSuccess(await client.post(`${baseUrl}${SAVE_CONFIG_PATH}?apid=${encode(appId)}`, {
855
- listId,
856
- appId,
857
- terminalType: 'PC',
858
- config: pcConfig,
859
- mConfig: mobileConfig,
860
- }, { ebbusinessid: appId }), 'table view common search field configure');
861
- const verified = await readTableViewConfig(client, baseUrl, appId, listId, 'PC');
870
+ targetConfig.searchConditions = searchConditions;
871
+ const { otherTerminalPreserved } = await saveTerminalConfig(client, baseUrl, appId, listId, terminal, targetConfig, options);
872
+ const verified = await readTableViewConfig(client, baseUrl, appId, listId, terminalType);
862
873
  const verifiedField = (Array.isArray(verified.searchConditions?.commonFilters)
863
874
  ? verified.searchConditions.commonFilters
864
875
  : [])
865
876
  .find((item) => searchFieldId(item) === fieldId);
866
877
  if (!verifiedField)
867
878
  throw new Error(`搜索字段配置保存后回读缺少 fieldId=${fieldId}`);
868
- const expected = resultFrom(field, mobilePreserved, false);
869
- const actual = resultFrom(verifiedField, mobilePreserved, false);
879
+ const expected = resultFrom(field, otherTerminalPreserved, false);
880
+ const actual = resultFrom(verifiedField, otherTerminalPreserved, false);
870
881
  for (const key of [
871
882
  'displayName',
872
883
  'defaultType',