weaver-e10-builder 1.5.12 → 1.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/actionflow.d.ts.map +1 -1
- package/dist/commands/actionflow.js +1 -0
- package/dist/commands/actionflow.js.map +1 -1
- package/dist/commands/designer-common.d.ts.map +1 -1
- package/dist/commands/designer-common.js +91 -0
- package/dist/commands/designer-common.js.map +1 -1
- package/dist/commands/designer-setters.d.ts.map +1 -1
- package/dist/commands/designer-setters.js +148 -47
- package/dist/commands/designer-setters.js.map +1 -1
- package/dist/commands/form-add-detail-table.d.ts.map +1 -1
- package/dist/commands/form-add-detail-table.js +150 -8
- package/dist/commands/form-add-detail-table.js.map +1 -1
- package/dist/commands/form-browser-definition.d.ts +14 -0
- package/dist/commands/form-browser-definition.d.ts.map +1 -0
- package/dist/commands/form-browser-definition.js +493 -0
- package/dist/commands/form-browser-definition.js.map +1 -0
- package/dist/commands/form-code.d.ts +5 -0
- package/dist/commands/form-code.d.ts.map +1 -0
- package/dist/commands/form-code.js +276 -0
- package/dist/commands/form-code.js.map +1 -0
- package/dist/commands/form-engine-linkage.d.ts +3 -0
- package/dist/commands/form-engine-linkage.d.ts.map +1 -0
- package/dist/commands/form-engine-linkage.js +199 -0
- package/dist/commands/form-engine-linkage.js.map +1 -0
- package/dist/commands/form-formula.d.ts.map +1 -1
- package/dist/commands/form-formula.js +11 -6
- package/dist/commands/form-formula.js.map +1 -1
- package/dist/commands/form-layout-template-advanced.d.ts +3 -0
- package/dist/commands/form-layout-template-advanced.d.ts.map +1 -0
- package/dist/commands/form-layout-template-advanced.js +115 -0
- package/dist/commands/form-layout-template-advanced.js.map +1 -0
- package/dist/commands/form-layout-template-easy.d.ts +3 -0
- package/dist/commands/form-layout-template-easy.d.ts.map +1 -0
- package/dist/commands/form-layout-template-easy.js +59 -0
- package/dist/commands/form-layout-template-easy.js.map +1 -0
- package/dist/commands/form-layout.d.ts.map +1 -1
- package/dist/commands/form-layout.js +77 -0
- package/dist/commands/form-layout.js.map +1 -1
- package/dist/commands/form-list-filter.js +1 -1
- package/dist/commands/form-list-filter.js.map +1 -1
- package/dist/commands/form-list-utils.d.ts +5 -0
- package/dist/commands/form-list-utils.d.ts.map +1 -1
- package/dist/commands/form-list-utils.js +23 -3
- package/dist/commands/form-list-utils.js.map +1 -1
- package/dist/commands/form-permission.d.ts.map +1 -1
- package/dist/commands/form-permission.js +55 -19
- package/dist/commands/form-permission.js.map +1 -1
- package/dist/commands/form-physical-table.d.ts.map +1 -1
- package/dist/commands/form-physical-table.js +8 -2
- package/dist/commands/form-physical-table.js.map +1 -1
- package/dist/commands/form.d.ts.map +1 -1
- package/dist/commands/form.js +476 -30
- package/dist/commands/form.js.map +1 -1
- package/dist/commands/menu.d.ts +68 -2
- package/dist/commands/menu.d.ts.map +1 -1
- package/dist/commands/menu.js +186 -41
- package/dist/commands/menu.js.map +1 -1
- package/dist/commands/page.d.ts.map +1 -1
- package/dist/commands/page.js +29 -6
- package/dist/commands/page.js.map +1 -1
- package/dist/commands/special.d.ts.map +1 -1
- package/dist/commands/special.js +3 -2
- package/dist/commands/special.js.map +1 -1
- package/dist/commands/wf-form.d.ts.map +1 -1
- package/dist/commands/wf-form.js +76 -31
- package/dist/commands/wf-form.js.map +1 -1
- package/dist/commands/workflow-auth-resp.js +2 -2
- package/dist/commands/workflow-auth-resp.js.map +1 -1
- package/dist/commands/workflow-base-settings.d.ts +3 -0
- package/dist/commands/workflow-base-settings.d.ts.map +1 -0
- package/dist/commands/workflow-base-settings.js +73 -0
- package/dist/commands/workflow-base-settings.js.map +1 -0
- package/dist/commands/workflow-condition.d.ts.map +1 -1
- package/dist/commands/workflow-condition.js +59 -450
- package/dist/commands/workflow-condition.js.map +1 -1
- package/dist/commands/workflow-export.d.ts +9 -0
- package/dist/commands/workflow-export.d.ts.map +1 -0
- package/dist/commands/workflow-export.js +121 -0
- package/dist/commands/workflow-export.js.map +1 -0
- package/dist/commands/workflow-node.d.ts.map +1 -1
- package/dist/commands/workflow-node.js +28 -53
- package/dist/commands/workflow-node.js.map +1 -1
- package/dist/commands/workflow-operator-batch.d.ts +3 -0
- package/dist/commands/workflow-operator-batch.d.ts.map +1 -0
- package/dist/commands/workflow-operator-batch.js +35 -0
- package/dist/commands/workflow-operator-batch.js.map +1 -0
- package/dist/commands/workflow-subprocess.d.ts.map +1 -1
- package/dist/commands/workflow-subprocess.js +21 -33
- package/dist/commands/workflow-subprocess.js.map +1 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +36 -37
- package/dist/commands/workflow.js.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/services/actionflow/browser_source.d.ts +9 -0
- package/dist/services/actionflow/browser_source.d.ts.map +1 -0
- package/dist/services/actionflow/browser_source.js +12 -0
- package/dist/services/actionflow/browser_source.js.map +1 -0
- package/dist/services/actionflow/components/date_trigger.js +1 -1
- package/dist/services/actionflow/components/date_trigger.js.map +1 -1
- package/dist/services/actionflow/components/document_actions.d.ts.map +1 -1
- package/dist/services/actionflow/components/document_actions.js +178 -25
- package/dist/services/actionflow/components/document_actions.js.map +1 -1
- package/dist/services/actionflow/components/enquiry_form.js +1 -1
- package/dist/services/actionflow/components/enquiry_form.js.map +1 -1
- package/dist/services/actionflow/components/logic_flow_set.d.ts.map +1 -1
- package/dist/services/actionflow/components/logic_flow_set.js +80 -8
- package/dist/services/actionflow/components/logic_flow_set.js.map +1 -1
- package/dist/services/actionflow/components/meeting_create.d.ts.map +1 -1
- package/dist/services/actionflow/components/meeting_create.js +1 -0
- package/dist/services/actionflow/components/meeting_create.js.map +1 -1
- package/dist/services/actionflow/components/schedule_create.d.ts.map +1 -1
- package/dist/services/actionflow/components/schedule_create.js +2 -0
- package/dist/services/actionflow/components/schedule_create.js.map +1 -1
- package/dist/services/actionflow/components/time_batch_trigger.js +1 -1
- package/dist/services/actionflow/components/time_batch_trigger.js.map +1 -1
- package/dist/services/actionflow/components/workflow_actions.d.ts.map +1 -1
- package/dist/services/actionflow/components/workflow_actions.js +6 -2
- package/dist/services/actionflow/components/workflow_actions.js.map +1 -1
- package/dist/services/actionflow/context_preflight.d.ts +5 -0
- package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
- package/dist/services/actionflow/context_preflight.js +186 -35
- package/dist/services/actionflow/context_preflight.js.map +1 -1
- package/dist/services/actionflow/filter_rules.d.ts.map +1 -1
- package/dist/services/actionflow/filter_rules.js +9 -8
- package/dist/services/actionflow/filter_rules.js.map +1 -1
- package/dist/services/actionflow/form_source.d.ts +2 -0
- package/dist/services/actionflow/form_source.d.ts.map +1 -1
- package/dist/services/actionflow/form_source.js +8 -0
- package/dist/services/actionflow/form_source.js.map +1 -1
- package/dist/services/actionflow/formula_service.d.ts +2 -1
- package/dist/services/actionflow/formula_service.d.ts.map +1 -1
- package/dist/services/actionflow/formula_service.js +69 -34
- package/dist/services/actionflow/formula_service.js.map +1 -1
- package/dist/services/actionflow/logicflow_source.d.ts +5 -0
- package/dist/services/actionflow/logicflow_source.d.ts.map +1 -0
- package/dist/services/actionflow/logicflow_source.js +15 -0
- package/dist/services/actionflow/logicflow_source.js.map +1 -0
- package/dist/services/actionflow/preflight_service.d.ts +15 -0
- package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
- package/dist/services/actionflow/preflight_service.js +561 -29
- package/dist/services/actionflow/preflight_service.js.map +1 -1
- package/dist/services/actionflow/runtime_metadata.d.ts +8 -0
- package/dist/services/actionflow/runtime_metadata.d.ts.map +1 -1
- package/dist/services/actionflow/runtime_metadata.js +25 -0
- package/dist/services/actionflow/runtime_metadata.js.map +1 -1
- package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
- package/dist/services/actionflow/workflow_compiler.js +75 -23
- package/dist/services/actionflow/workflow_compiler.js.map +1 -1
- package/dist/services/actionflow/workflow_source.d.ts +2 -0
- package/dist/services/actionflow/workflow_source.d.ts.map +1 -1
- package/dist/services/actionflow/workflow_source.js +7 -0
- package/dist/services/actionflow/workflow_source.js.map +1 -1
- package/dist/services/auth-resp-condition.d.ts +7 -3
- package/dist/services/auth-resp-condition.d.ts.map +1 -1
- package/dist/services/auth-resp-condition.js +58 -63
- package/dist/services/auth-resp-condition.js.map +1 -1
- package/dist/services/browser.d.ts +5 -0
- package/dist/services/browser.d.ts.map +1 -1
- package/dist/services/browser.js +16 -4
- package/dist/services/browser.js.map +1 -1
- package/dist/services/condition-rules.d.ts +2 -30
- package/dist/services/condition-rules.d.ts.map +1 -1
- package/dist/services/condition-rules.js +3 -219
- package/dist/services/condition-rules.js.map +1 -1
- package/dist/services/designer-dataset.d.ts +45 -0
- package/dist/services/designer-dataset.d.ts.map +1 -0
- package/dist/services/designer-dataset.js +156 -0
- package/dist/services/designer-dataset.js.map +1 -0
- package/dist/services/form-association.d.ts +7 -0
- package/dist/services/form-association.d.ts.map +1 -1
- package/dist/services/form-association.js +22 -1
- package/dist/services/form-association.js.map +1 -1
- package/dist/services/form-code.d.ts +53 -0
- package/dist/services/form-code.d.ts.map +1 -0
- package/dist/services/form-code.js +370 -0
- package/dist/services/form-code.js.map +1 -0
- package/dist/services/form-create.d.ts +20 -0
- package/dist/services/form-create.d.ts.map +1 -1
- package/dist/services/form-create.js +73 -1
- package/dist/services/form-create.js.map +1 -1
- package/dist/services/form-field-build.d.ts +1 -1
- package/dist/services/form-field-build.d.ts.map +1 -1
- package/dist/services/form-field-build.js +20 -1
- package/dist/services/form-field-build.js.map +1 -1
- package/dist/services/form-field-drop.d.ts +2 -0
- package/dist/services/form-field-drop.d.ts.map +1 -1
- package/dist/services/form-field-drop.js +2 -0
- package/dist/services/form-field-drop.js.map +1 -1
- package/dist/services/form-layout-detail-insert.d.ts +58 -0
- package/dist/services/form-layout-detail-insert.d.ts.map +1 -0
- package/dist/services/form-layout-detail-insert.js +293 -0
- package/dist/services/form-layout-detail-insert.js.map +1 -0
- package/dist/services/form-layout-insert.d.ts.map +1 -1
- package/dist/services/form-layout-insert.js +34 -2
- package/dist/services/form-layout-insert.js.map +1 -1
- package/dist/services/form-layout-source/compile.d.ts.map +1 -1
- package/dist/services/form-layout-source/compile.js +11 -4
- package/dist/services/form-layout-source/compile.js.map +1 -1
- package/dist/services/form-layout-template-advanced.d.ts +330 -0
- package/dist/services/form-layout-template-advanced.d.ts.map +1 -0
- package/dist/services/form-layout-template-advanced.js +1437 -0
- package/dist/services/form-layout-template-advanced.js.map +1 -0
- package/dist/services/form-layout-template-easy.d.ts +34 -0
- package/dist/services/form-layout-template-easy.d.ts.map +1 -0
- package/dist/services/form-layout-template-easy.js +159 -0
- package/dist/services/form-layout-template-easy.js.map +1 -0
- package/dist/services/form-layout-template-flow.d.ts +23 -0
- package/dist/services/form-layout-template-flow.d.ts.map +1 -0
- package/dist/services/form-layout-template-flow.js +99 -0
- package/dist/services/form-layout-template-flow.js.map +1 -0
- package/dist/services/form-linkage-condition.d.ts +15 -0
- package/dist/services/form-linkage-condition.d.ts.map +1 -1
- package/dist/services/form-linkage-condition.js +19 -10
- package/dist/services/form-linkage-condition.js.map +1 -1
- package/dist/services/form-permission-archive.d.ts +23 -1
- package/dist/services/form-permission-archive.d.ts.map +1 -1
- package/dist/services/form-permission-archive.js +54 -2
- package/dist/services/form-permission-archive.js.map +1 -1
- package/dist/services/form-physical-table.d.ts +10 -0
- package/dist/services/form-physical-table.d.ts.map +1 -1
- package/dist/services/form-physical-table.js +20 -0
- package/dist/services/form-physical-table.js.map +1 -1
- package/dist/services/form-sub-detail.d.ts +25 -0
- package/dist/services/form-sub-detail.d.ts.map +1 -1
- package/dist/services/form-sub-detail.js +64 -0
- package/dist/services/form-sub-detail.js.map +1 -1
- package/dist/services/form-view-linkage-functions.d.ts +19 -0
- package/dist/services/form-view-linkage-functions.d.ts.map +1 -0
- package/dist/services/form-view-linkage-functions.js +90 -0
- package/dist/services/form-view-linkage-functions.js.map +1 -0
- package/dist/services/matrix-condition.d.ts +32 -1
- package/dist/services/matrix-condition.d.ts.map +1 -1
- package/dist/services/matrix-condition.js +169 -6
- package/dist/services/matrix-condition.js.map +1 -1
- package/dist/services/menu-catalog.d.ts +24 -1
- package/dist/services/menu-catalog.d.ts.map +1 -1
- package/dist/services/menu-catalog.js +49 -2
- package/dist/services/menu-catalog.js.map +1 -1
- package/dist/services/workflow-base-settings.d.ts +117 -0
- package/dist/services/workflow-base-settings.d.ts.map +1 -0
- package/dist/services/workflow-base-settings.js +504 -0
- package/dist/services/workflow-base-settings.js.map +1 -0
- package/dist/services/workflow-condition-core.d.ts +48 -0
- package/dist/services/workflow-condition-core.d.ts.map +1 -0
- package/dist/services/workflow-condition-core.js +316 -0
- package/dist/services/workflow-condition-core.js.map +1 -0
- package/dist/services/workflow-context.d.ts +10 -0
- package/dist/services/workflow-context.d.ts.map +1 -0
- package/dist/services/workflow-context.js +15 -0
- package/dist/services/workflow-context.js.map +1 -0
- package/dist/services/workflow-export.d.ts +80 -0
- package/dist/services/workflow-export.d.ts.map +1 -0
- package/dist/services/workflow-export.js +150 -0
- package/dist/services/workflow-export.js.map +1 -0
- package/dist/services/workflow-field-permission-route.d.ts +75 -0
- package/dist/services/workflow-field-permission-route.d.ts.map +1 -0
- package/dist/services/workflow-field-permission-route.js +52 -0
- package/dist/services/workflow-field-permission-route.js.map +1 -0
- package/dist/services/workflow-field-permission.d.ts +18 -0
- package/dist/services/workflow-field-permission.d.ts.map +1 -0
- package/dist/services/workflow-field-permission.js +40 -0
- package/dist/services/workflow-field-permission.js.map +1 -0
- package/dist/services/workflow-node-layout.d.ts +11 -10
- package/dist/services/workflow-node-layout.d.ts.map +1 -1
- package/dist/services/workflow-node-layout.js +24 -62
- package/dist/services/workflow-node-layout.js.map +1 -1
- package/dist/services/workflow-operator-batch-condition.d.ts +23 -0
- package/dist/services/workflow-operator-batch-condition.d.ts.map +1 -0
- package/dist/services/workflow-operator-batch-condition.js +56 -0
- package/dist/services/workflow-operator-batch-condition.js.map +1 -0
- package/dist/services/workflow-operator.d.ts +12 -5
- package/dist/services/workflow-operator.d.ts.map +1 -1
- package/dist/services/workflow-operator.js +41 -16
- package/dist/services/workflow-operator.js.map +1 -1
- package/package.json +1 -1
- package/skill-docs/SKILL.md +155 -290
- package/skill-docs/_catalog.md +12 -3
- package/skill-docs/actionflows/references/components/document/GetDocumentInfo.md +17 -17
- package/skill-docs/actionflows/references/components/logic/LogicFlowSet.md +23 -17
- package/skill-docs/assets/form-template/style-templates-advanced-base-example.json +1420 -0
- package/skill-docs/assets/form-template/style-templates-advanced-base.css +33 -0
- package/skill-docs/assets/form-template/style-templates-advanced-blue-crystal-example.json +1094 -0
- package/skill-docs/assets/form-template/style-templates-advanced-document-example.json +1251 -0
- package/skill-docs/assets/form-template/style-templates-advanced-grid-example.json +39 -0
- package/skill-docs/assets/form-template/style-templates-advanced-page-example.json +38 -0
- package/skill-docs/assets/form-template/style-templates-advanced-placements-example.json +30 -0
- package/skill-docs/assets/form-template/style-templates-advanced-standard-example.json +53 -0
- package/skill-docs/assets/form-template/style-templates-advanced-structure-example.json +25 -0
- package/skill-docs/assets/form-template/style-templates-advanced-table-example.json +1420 -0
- package/skill-docs/references/code-block/guide-code-block.md +141 -0
- package/skill-docs/references/code-block/guide-layout-css.md +107 -0
- package/skill-docs/references/code-block/ref-controls.md +60 -0
- package/skill-docs/references/code-block/ref-coverage.md +32 -0
- package/skill-docs/references/code-block/ref-details.md +57 -0
- package/skill-docs/references/code-block/ref-events-validation.md +42 -0
- package/skill-docs/references/code-block/ref-foundations-fields.md +56 -0
- package/skill-docs/references/code-block/ref-recipes.md +164 -0
- package/skill-docs/references/code-block/ref-troubleshooting.md +49 -0
- package/skill-docs/references/code-block/ref-ui-global.md +47 -0
- package/skill-docs/references/coding/guide-page-code.md +2 -0
- package/skill-docs/references/coding/ref-compile-rules.md +2 -0
- package/skill-docs/references/common/capability-boundaries.md +15 -0
- package/skill-docs/references/common/guide-install.md +44 -0
- package/skill-docs/references/common/guide-plan-template.md +2 -1
- package/skill-docs/references/common/map.md +11 -1
- package/skill-docs/references/common/ref-cli-commands.md +689 -648
- package/skill-docs/references/ebuilder-designer/guide-designer-factory.md +8 -4
- package/skill-docs/references/form/form-template/style-templates-advanced-css-guide.md +167 -0
- package/skill-docs/references/form/form-template/style-templates-advanced.md +315 -0
- package/skill-docs/references/form/form-template/style-templates-easy.md +55 -0
- package/skill-docs/references/form/form-template/style-templates-flow.md +27 -0
- package/skill-docs/references/form/form-template/style-templates.md +29 -0
- package/skill-docs/references/form/guide-browser-definition.md +148 -0
- package/skill-docs/references/form/guide-create-form.md +258 -250
- package/skill-docs/references/form/guide-field-linkage.md +56 -14
- package/skill-docs/references/form/guide-form-archive-permission.md +29 -6
- package/skill-docs/references/form/guide-form-formula-functions.md +11 -0
- package/skill-docs/references/form/guide-form-layout-incremental.md +28 -0
- package/skill-docs/references/form/guide-form-layout-planning.md +11 -0
- package/skill-docs/references/form/guide-form-layout-source.md +4 -0
- package/skill-docs/references/form/guide-form-linkage.md +295 -269
- package/skill-docs/references/form/guide-form-physical-table.md +2 -0
- package/skill-docs/references/form/guide-form-view.md +3 -0
- package/skill-docs/references/form/ref-form-fields.md +301 -293
- package/skill-docs/references/form/ref-list-filter-date-params.md +83 -0
- package/skill-docs/references/menu/system-menus.md +12 -0
- package/skill-docs/references/workflow/condition-core-contract.md +63 -0
- package/skill-docs/references/workflow/guide-base-auth-share-remind.md +126 -0
- package/skill-docs/references/workflow/guide-workflow-condition.md +476 -447
- package/skill-docs/references/workflow/guide-workflow-node-layout.md +6 -0
- package/skill-docs/references/workflow/guide-workflow.md +29 -3
- package/skill-docs/references/form/style-templates.md +0 -97
package/dist/commands/form.js
CHANGED
|
@@ -3,8 +3,9 @@ import { AuthSession } from '../core/auth.js';
|
|
|
3
3
|
import { ApiClient } from '../core/client.js';
|
|
4
4
|
import { parseLayoutJson } from '../services/form-layout-source/json.js';
|
|
5
5
|
import { toColumnName, toTableName, resolveFieldKeys } from '../utils/column-name.js';
|
|
6
|
-
import { createCustomPhysicalForm, applyInitialFieldsToNewForm, placeholderFromFormat, reapplyGroupLayout, queryFormStorageSetting } from '../services/form-create.js';
|
|
6
|
+
import { createCustomPhysicalForm, applyInitialFieldsToNewForm, collectDetailEBuilderFields, defaultSwitchOptions, placeholderFromFormat, reapplyGroupLayout, queryFormStorageSetting } from '../services/form-create.js';
|
|
7
7
|
import { getRichType, richIdUnits, BROWSER_KINDS } from '../services/rich-types.js';
|
|
8
|
+
import { BROWSER_BEAN_SEARCH, browserBeanRows, resolveBrowserByName } from '../services/browser.js';
|
|
8
9
|
import { dropFieldComponents, prepareLayoutForSave } from '../services/form-field-drop.js';
|
|
9
10
|
import { describeEditBaseFailure, resolveEditBase as resolveEditBasePure } from '../services/form-edit-base.js';
|
|
10
11
|
import { applyFieldPatches, platformFieldShape } from '../services/form-field-patch.js';
|
|
@@ -22,6 +23,7 @@ import { resolveFormRecord, resolveFormId, appendThirdPartyForms, resolveObjIdBy
|
|
|
22
23
|
import { FIELD_TYPE_CHOICES, canonComponentKey, assertFieldType, normalizeFieldDef } from '../services/form-field-validate.js';
|
|
23
24
|
import { listFormTables, readFieldRecords, mapFieldsToTables } from '../services/form-physical-table.js';
|
|
24
25
|
import { buildFormulaParameters, defaultReturnType } from '../services/formula-detail.js';
|
|
26
|
+
import { assertViewLinkageFormulaFunctions, loadViewLinkageFunctions } from '../services/form-view-linkage-functions.js';
|
|
25
27
|
import { registerOptionTemplateCommand } from './form-option-template.js';
|
|
26
28
|
import { registerFormObjMetaCommands } from './form-obj-meta.js';
|
|
27
29
|
import { prepareSourceLayoutInputs, restoreSourceLayoutAfterCreate } from '../services/form-layout-source/creation.js';
|
|
@@ -310,6 +312,19 @@ export function registerFormCommands(program) {
|
|
|
310
312
|
}
|
|
311
313
|
}
|
|
312
314
|
});
|
|
315
|
+
form.command('browser-source')
|
|
316
|
+
.description('检索当前环境可用的关联浏览数据源(含自定义浏览框)')
|
|
317
|
+
.option('--keyword <name>', '按名称关键词检索', '')
|
|
318
|
+
.action(async (o) => {
|
|
319
|
+
const auth = await AuthSession.fromOptions(program.opts());
|
|
320
|
+
if (!auth)
|
|
321
|
+
throw new Error('无法加载认证');
|
|
322
|
+
const client = new ApiClient(auth);
|
|
323
|
+
const res = await client.get(`${auth.getBaseUrl()}${BROWSER_BEAN_SEARCH}?searchValue=${encodeURIComponent(o.keyword)}`);
|
|
324
|
+
if (res?.code !== 200 || res?.status === false)
|
|
325
|
+
throw new Error(res?.msg || '浏览数据源检索失败');
|
|
326
|
+
console.log(JSON.stringify(browserBeanRows(res).map((b) => ({ id: b.id, name: b.name, module: b.module, type: b.type })), null, 2));
|
|
327
|
+
});
|
|
313
328
|
form.command('create')
|
|
314
329
|
.description('创建表单')
|
|
315
330
|
.argument('<appId>', '应用 ID')
|
|
@@ -571,6 +586,8 @@ export function registerFormCommands(program) {
|
|
|
571
586
|
let objId = '';
|
|
572
587
|
let formId = '';
|
|
573
588
|
let fieldGroups = [];
|
|
589
|
+
/** 明细表定义 → 建出来的 subFormId(明细 EBuilder 关联绑定要用)。 */
|
|
590
|
+
let detailTables = [];
|
|
574
591
|
try {
|
|
575
592
|
const result = await createCustomPhysicalForm(client, baseUrl, appId, name, requestedTableName, false, layoutType);
|
|
576
593
|
objId = result.objId;
|
|
@@ -586,6 +603,7 @@ export function registerFormCommands(program) {
|
|
|
586
603
|
// services/form-create.ts 的 applyInitialFieldsToNewForm,「专项建表」共用同一条链。
|
|
587
604
|
const fieldResult = await applyInitialFieldsToNewForm(client, baseUrl, appId, objId, formId, fieldDefs, { tenantKey: auth.tenantKey, layoutType, systemOverrides });
|
|
588
605
|
fieldGroups = fieldResult.fieldGroups;
|
|
606
|
+
detailTables = fieldResult.detailTables || [];
|
|
589
607
|
}
|
|
590
608
|
catch (e) {
|
|
591
609
|
console.error(`创建失败: ${e.message}`);
|
|
@@ -637,15 +655,22 @@ export function registerFormCommands(program) {
|
|
|
637
655
|
// Step 2: EBuilder fields need follow-up binding to target forms.
|
|
638
656
|
// 无 sformId 的 EBuilder 会被建成裸关联字段(isAddForRelation=false,无目标表),
|
|
639
657
|
// 这是"关联ebuilder不对"的常见来源,明确警告避免静默。
|
|
640
|
-
|
|
658
|
+
// 明细表里的 EBuilder 子字段也要绑定 —— 它们不在 fieldDefs 顶层,必须从 DetailTable.formFields 里取。
|
|
659
|
+
// 只靠下面的顶层循环,明细 EBuilder 会建成`isAddForRelation=false`、没有 sformId/formName 的裸字段。
|
|
660
|
+
const detailEbDefs = collectDetailEBuilderFields(fieldDefs);
|
|
661
|
+
const ebNoTarget = [
|
|
662
|
+
...fieldDefs.filter(f => f.componentKey === 'EBuilder' && !f.sformId),
|
|
663
|
+
...detailEbDefs.filter((f) => !f.sformId).map((f) => ({ ...f, fieldName: `${f.detailName}.${f.fieldName}` })),
|
|
664
|
+
];
|
|
641
665
|
if (ebNoTarget.length > 0) {
|
|
642
666
|
console.error(` ⚠ ${ebNoTarget.length} 个 EBuilder 字段缺少 sformId,将建成无关联裸字段:`);
|
|
643
667
|
for (const f of ebNoTarget)
|
|
644
668
|
console.error(` - ${f.fieldName}(需在 fields.json 指定 sformId=<目标表单objId> 与 dataTitle=<显示字段>)`);
|
|
645
669
|
}
|
|
646
670
|
const ebFields = fieldDefs.filter(f => f.componentKey === 'EBuilder' && f.sformId);
|
|
647
|
-
|
|
648
|
-
|
|
671
|
+
const detailEbFields = detailEbDefs.filter((f) => f.sformId);
|
|
672
|
+
if (ebFields.length > 0 || detailEbFields.length > 0) {
|
|
673
|
+
console.error(` 绑定 ${ebFields.length + detailEbFields.length} 个 EBuilder 关联字段...`);
|
|
649
674
|
// Resolve target form names and field IDs from sformId
|
|
650
675
|
const formList = await client.get(`${baseUrl}/api/bs/ebuilder/form/obj/getList/${appId}?apid=${appId}`, { ebbusinessid: appId });
|
|
651
676
|
const allForms = formList?.data || [];
|
|
@@ -807,6 +832,81 @@ export function registerFormCommands(program) {
|
|
|
807
832
|
console.error(` 关联失败: ${ef.fieldName} — ${updateRes?.msg || '未知错误'}`);
|
|
808
833
|
}
|
|
809
834
|
}
|
|
835
|
+
// 明细表子字段:创建时不在主表字段记录里,按 subFormId 单独读回再补关联。
|
|
836
|
+
// 用 getFormField 的完整记录做底保存 —— 只发少数字段会把 subFormId / formTableId 等冲掉。
|
|
837
|
+
if (detailEbFields.length > 0) {
|
|
838
|
+
const subFormIdByDetail = new Map(detailTables.map((dt) => [String(dt.definition?.fieldName ?? ''), String(dt.subFormId ?? '')]));
|
|
839
|
+
const childRowsCache = new Map();
|
|
840
|
+
const childRowsOf = async (subFormId) => {
|
|
841
|
+
if (!childRowsCache.has(subFormId)) {
|
|
842
|
+
const r = await client.post(`${baseUrl}/api/ebuilder/form/form/field/manage/getFormFieldPage?apid=${appId}`, {
|
|
843
|
+
pageNo: 1, pageSize: 500, module: 'ebuilderform',
|
|
844
|
+
customParam: { appId, objId },
|
|
845
|
+
formFieldSearchEntity: { isDelete: 0, status: 'enable', formId: resolvedFormId, subFormId },
|
|
846
|
+
}, { ebbusinessid: resolvedFormId });
|
|
847
|
+
childRowsCache.set(subFormId, r?.data?.pageDatas?.result || r?.data?.data?.records || r?.data?.data || []);
|
|
848
|
+
}
|
|
849
|
+
return childRowsCache.get(subFormId);
|
|
850
|
+
};
|
|
851
|
+
for (const ef of detailEbFields) {
|
|
852
|
+
const subFormId = subFormIdByDetail.get(String(ef.detailName)) || '';
|
|
853
|
+
if (!subFormId) {
|
|
854
|
+
console.error(` 警告: 找不到明细表「${ef.detailName}」的 subFormId,跳过 ${ef.fieldName}`);
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
const rows = await childRowsOf(subFormId);
|
|
858
|
+
const hits = rows.filter((r) => String(r.title ?? r.fieldName ?? '') === String(ef.fieldName));
|
|
859
|
+
if (hits.length !== 1) {
|
|
860
|
+
console.error(` 警告: 明细表「${ef.detailName}」里${hits.length ? '有多个' : '找不到'}「${ef.fieldName}」,无法绑定,跳过`);
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
const child = hits[0];
|
|
864
|
+
const gf = await client.post(`${baseUrl}/api/ebuilder/form/form/field/manage/getFormField`, { module: 'ebuilderform', formTableField: { formField: { id: child.fieldId, form: { id: resolvedFormId } } } }, { ebbusinessid: resolvedFormId });
|
|
865
|
+
const full = gf?.data || child;
|
|
866
|
+
let targetBizFields = [];
|
|
867
|
+
try {
|
|
868
|
+
const tfd = await client.post(`${baseUrl}/api/ebuilder/form/dataset/v1/getFields`, {
|
|
869
|
+
objId: ef.sformId, userid: auth.userId, tenantKey: auth.tenantKey,
|
|
870
|
+
});
|
|
871
|
+
targetBizFields = (tfd?.data?.mainFields || [])
|
|
872
|
+
.filter((f) => /^\d+$/.test(String(f.fieldId)))
|
|
873
|
+
.map((f) => ({ id: String(f.fieldId), name: String(f.fieldName || f.title || '') }))
|
|
874
|
+
.slice(0, 5);
|
|
875
|
+
}
|
|
876
|
+
catch { /* 目标表查询失败则显示列留空 */ }
|
|
877
|
+
const jsonObj = {
|
|
878
|
+
...full,
|
|
879
|
+
formId: resolvedFormId,
|
|
880
|
+
sformId: ef.sformId,
|
|
881
|
+
formName: ef.formName || formNameById.get(ef.sformId || '') || ef.sformId || '',
|
|
882
|
+
dataTitle: await resolveDataTitle(ef.sformId || '', ef.dataTitle || 'name'),
|
|
883
|
+
appId,
|
|
884
|
+
isAddForRelation: true,
|
|
885
|
+
displayType: 'line',
|
|
886
|
+
viewDataDetail: true,
|
|
887
|
+
quickAddParams: [],
|
|
888
|
+
relateViewData: [],
|
|
889
|
+
relateField: null,
|
|
890
|
+
virtualForm: false,
|
|
891
|
+
virtualTable: false,
|
|
892
|
+
type: 'EBuilder',
|
|
893
|
+
componentKey: 'Ebuilder',
|
|
894
|
+
isSingle: ef.multiple ? false : true,
|
|
895
|
+
ffDisplayColumns: Array.isArray(ef.displayColumns) && ef.displayColumns.length
|
|
896
|
+
? ef.displayColumns
|
|
897
|
+
.map((name) => targetBizFields.find((f) => f.name === name))
|
|
898
|
+
.filter((f) => !!f)
|
|
899
|
+
: targetBizFields,
|
|
900
|
+
};
|
|
901
|
+
const res = await client.post(`${baseUrl}/api/ebuilder/form/form/field/manage/saveFormFieldNew?apid=${appId}`, { formId: resolvedFormId, module: 'ebuilderform', customParam: { appId, objId }, jsonObj: JSON.stringify(jsonObj) }, { ebbusinessid: resolvedFormId });
|
|
902
|
+
if (res?.code === 200 && res?.status) {
|
|
903
|
+
console.error(` 已关联: ${ef.detailName}.${ef.fieldName} → ${ef.sformId}`);
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
console.error(` 关联失败: ${ef.detailName}.${ef.fieldName} — ${res?.msg || '未知错误'}`);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
810
910
|
}
|
|
811
911
|
// Step 2a: Select 绑定选项预设模板(fields.json optionTemplate 属性)。
|
|
812
912
|
// 建表时字段已建成裸 Select(无选项),此处补 templateId/templateName/publicTemplate:false/options:[]。
|
|
@@ -1768,13 +1868,121 @@ export function registerFormCommands(program) {
|
|
|
1768
1868
|
}
|
|
1769
1869
|
});
|
|
1770
1870
|
const linkageCmd = form.command('linkage').description('表单字段显隐联动管理');
|
|
1871
|
+
const linkageBase = '/api/ebuilder/form/form/setting/viewlinkage';
|
|
1872
|
+
async function readLinkage(client, baseUrl, appId, objId, formId, id) {
|
|
1873
|
+
const res = await client.get(`${baseUrl}${linkageBase}/id?${new URLSearchParams({ id, formId, module: 'ebuilderform', apid: appId })}`);
|
|
1874
|
+
if (res?.code !== 200 || !res?.status || !res?.data || String(res.data.id) !== id) {
|
|
1875
|
+
throw new Error(`读取显示属性联动 ${id} 失败: ${res?.msg || '未找到规则'}`);
|
|
1876
|
+
}
|
|
1877
|
+
if (String(res.data.formId) !== formId)
|
|
1878
|
+
throw new Error(`规则 ${id} 不属于表单 ${objId}`);
|
|
1879
|
+
return res.data;
|
|
1880
|
+
}
|
|
1881
|
+
async function readLinkageLayoutTargets(client, baseUrl, appId, objId, formId) {
|
|
1882
|
+
const res = await client.post(`${baseUrl}/api/ebuilder/form/common/browser/complete/form_dataDrivenColumn?apid=${appId}`, {
|
|
1883
|
+
browserMultiple: true, formId, module: 'ebuilderform', groupId: 'layoutComponent',
|
|
1884
|
+
makeComplexField: true, openTab: false, scenarioType: 'VIEW_LINKAGE_TARGET',
|
|
1885
|
+
notComponentKeyList: ['DividingLine', 'ColumnPanel', 'MultiTypeField', 'WPSEditor'],
|
|
1886
|
+
needI18n: true, newly: 1, searchValue: '', customParam: { appId, objId },
|
|
1887
|
+
});
|
|
1888
|
+
if (res?.code !== 200 || !res?.status || !Array.isArray(res?.data?.data)) {
|
|
1889
|
+
throw new Error(`查询布局组件失败: ${res?.msg || '未返回组件列表'}`);
|
|
1890
|
+
}
|
|
1891
|
+
return res.data.data;
|
|
1892
|
+
}
|
|
1893
|
+
async function resolveLayoutActions(client, baseUrl, appId, objId, formId, actions) {
|
|
1894
|
+
if (!actions.some((action) => action.linkageObj === 'layout'))
|
|
1895
|
+
return actions;
|
|
1896
|
+
const targets = await readLinkageLayoutTargets(client, baseUrl, appId, objId, formId);
|
|
1897
|
+
return actions.map((action) => action.linkageObj !== 'layout' ? action : {
|
|
1898
|
+
...action,
|
|
1899
|
+
fields: action.fields.map((field) => {
|
|
1900
|
+
const target = targets.find((item) => String(item.id) === String(field.id));
|
|
1901
|
+
if (!target)
|
|
1902
|
+
throw new Error(`布局组件 ${field.id} 不在当前表单的可选列表中`);
|
|
1903
|
+
return target;
|
|
1904
|
+
}),
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
function checkLinkageActions(actions) {
|
|
1908
|
+
if (!Array.isArray(actions) || actions.length === 0)
|
|
1909
|
+
throw new Error('至少配置一项联动变更对象 actions[]');
|
|
1910
|
+
const props = {
|
|
1911
|
+
field: ['hide', 'show', 'edit', 'readonly', 'required', 'hideLine', 'hideRow'],
|
|
1912
|
+
option: ['hide', 'disabled'],
|
|
1913
|
+
detail: ['hide', 'show', 'edit', 'readonly', 'hideLine', 'hideRow'],
|
|
1914
|
+
layout: ['hide', 'show', 'hideLine'],
|
|
1915
|
+
};
|
|
1916
|
+
for (const action of actions) {
|
|
1917
|
+
const obj = action.linkageObj || 'field';
|
|
1918
|
+
if (!props[obj])
|
|
1919
|
+
throw new Error(`联动对象 ${obj} 暂无已确认的保存结构;支持 field / option / detail / layout`);
|
|
1920
|
+
if (!props[obj].includes(action.prop))
|
|
1921
|
+
throw new Error(`${obj} 不支持效果 ${action.prop};可用 ${props[obj].join('/')}`);
|
|
1922
|
+
if (!Array.isArray(action.fields) || !action.fields.length)
|
|
1923
|
+
throw new Error(`${obj} 效果需指定 fields[]`);
|
|
1924
|
+
if (obj === 'layout' && action.fields.some((field) => !field.id)) {
|
|
1925
|
+
throw new Error('布局组件目标需在 fields[] 中提供可选列表返回的 id');
|
|
1926
|
+
}
|
|
1927
|
+
if (obj === 'option' && (!Array.isArray(action.options) || !action.options.length)) {
|
|
1928
|
+
throw new Error('选项目标需指定 options[](fieldId、optionId、optionName)');
|
|
1929
|
+
}
|
|
1930
|
+
for (const option of action.options || []) {
|
|
1931
|
+
if (!option.fieldId || !option.optionId || !option.optionName) {
|
|
1932
|
+
throw new Error('options[] 每项需包含 fieldId、optionId、optionName');
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
}
|
|
1937
|
+
async function resolveLinkageFormula(client, baseUrl, appId, objId, formId, config) {
|
|
1938
|
+
if (config.formulaId) {
|
|
1939
|
+
if (!config.formulaName)
|
|
1940
|
+
throw new Error('引用已有公式需同时提供 formulaName');
|
|
1941
|
+
const detail = await client.post(`${baseUrl}/api/excel/formula/detail`, { formulaId: config.formulaId });
|
|
1942
|
+
const existing = detail?.resultJson?.data;
|
|
1943
|
+
if (!detail?.resultJson?.excute || !existing?.expressSql)
|
|
1944
|
+
throw new Error('无法读取已有公式表达式,已停止绑定显示属性联动');
|
|
1945
|
+
if (String(existing.returnType || '').toLowerCase() !== 'boolean')
|
|
1946
|
+
throw new Error('显示属性联动引用的已有公式必须返回 Boolean');
|
|
1947
|
+
assertViewLinkageFormulaFunctions(String(existing.expressSql), await loadViewLinkageFunctions(client, baseUrl));
|
|
1948
|
+
return { id: String(config.formulaId), name: String(config.formulaName) };
|
|
1949
|
+
}
|
|
1950
|
+
if (!config.formula)
|
|
1951
|
+
return undefined;
|
|
1952
|
+
const expression = String(config.formula).trim();
|
|
1953
|
+
assertViewLinkageFormulaFunctions(expression, await loadViewLinkageFunctions(client, baseUrl));
|
|
1954
|
+
const parsed = await buildFormulaParameters(client, baseUrl, objId, appId, formId, expression);
|
|
1955
|
+
if (parsed.errors.length)
|
|
1956
|
+
throw new Error(`公式引用无效: ${parsed.errors.join('; ')}`);
|
|
1957
|
+
for (const warning of parsed.warnings)
|
|
1958
|
+
console.error(` ⚠ ${warning}`);
|
|
1959
|
+
const name = String(config.formulaName || `显示属性联动公式_${Date.now()}`);
|
|
1960
|
+
const res = await client.post(`${baseUrl}/api/excel/formula/save`, {
|
|
1961
|
+
expressSql: parsed.normalizedExpression, name, parameters: parsed.parameters,
|
|
1962
|
+
returnType: 'Boolean', validateType: 'normal', referenceType: 'check',
|
|
1963
|
+
extendParam: JSON.stringify({ isFormViewLinkage: true }), formulaId: null,
|
|
1964
|
+
dataSources: [], formulaType: 'normal', mainDataSource: [null],
|
|
1965
|
+
tempVariableList: [], nameAuto: false, module: 'ebuilderform', multiFuncSepType: 1,
|
|
1966
|
+
});
|
|
1967
|
+
if (res?.returnInfo?.state === 'VERIFY_REQUIRED' || res?.securityCheckResult === false) {
|
|
1968
|
+
throw new Error('公式保存需要二次验证,联动规则尚未保存;请完成平台验证后再试');
|
|
1969
|
+
}
|
|
1970
|
+
if (!res?.resultJson?.excute || !res?.resultJson?.id || res?.resultJson?.returnType !== 'Boolean') {
|
|
1971
|
+
throw new Error(`布尔公式保存失败: ${res?.resultJson?.error || res?.msg || '未返回有效 Boolean 公式'}`);
|
|
1972
|
+
}
|
|
1973
|
+
console.error(` 布尔公式已保存: ${res.resultJson.id}(若后续联动保存失败,请用 formulaId/formulaName 复用)`);
|
|
1974
|
+
return { id: String(res.resultJson.id), name };
|
|
1975
|
+
}
|
|
1771
1976
|
linkageCmd.command('add')
|
|
1772
1977
|
.description('添加字段显隐联动规则')
|
|
1773
1978
|
.argument('<appId>', '应用 ID')
|
|
1774
1979
|
.argument('<objId>', '表单 objId')
|
|
1775
1980
|
.argument('<name>', '联动规则名称')
|
|
1776
1981
|
.requiredOption('--config <json>', '联动配置 JSON(@文件路径),格式见文档')
|
|
1982
|
+
.option('--disabled', '新建时停用(默认启用)')
|
|
1777
1983
|
.action(async (appId, objId, name, cmdOpts) => {
|
|
1984
|
+
if (name.length > 200)
|
|
1985
|
+
throw new Error('联动名称不能超过 200 字');
|
|
1778
1986
|
const opts = program.opts();
|
|
1779
1987
|
const auth = await AuthSession.fromOptions(opts);
|
|
1780
1988
|
if (!auth)
|
|
@@ -1790,23 +1998,15 @@ export function registerFormCommands(program) {
|
|
|
1790
1998
|
console.error(e.message);
|
|
1791
1999
|
process.exit(1);
|
|
1792
2000
|
}
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
if (missingProps.length > 0) {
|
|
1803
|
-
console.error(`联动 action 缺少 prop(联动效果类型必填)`);
|
|
1804
|
-
}
|
|
1805
|
-
if (invalidProps.length > 0) {
|
|
1806
|
-
console.error(`联动 prop 不支持: ${[...new Set(invalidProps)].join(', ')}`);
|
|
1807
|
-
console.error(` 平台支持: ${SUPPORTED_PROPS.join(', ')}`);
|
|
1808
|
-
}
|
|
1809
|
-
process.exit(1);
|
|
2001
|
+
checkLinkageActions(config.actions || []);
|
|
2002
|
+
if (config.conditions !== undefined && (config.formula || config.formulaId)) {
|
|
2003
|
+
throw new Error('简易条件 conditions 与函数条件 formula/formulaId 不能同时指定');
|
|
2004
|
+
}
|
|
2005
|
+
if (!config.formula && !config.formulaId && !Array.isArray(config.conditions)) {
|
|
2006
|
+
throw new Error('请提供 conditions[] 或 Boolean 公式');
|
|
2007
|
+
}
|
|
2008
|
+
if (Array.isArray(config.conditions) && config.conditions.length === 0) {
|
|
2009
|
+
throw new Error('简易条件 conditions[] 至少包含一项');
|
|
1810
2010
|
}
|
|
1811
2011
|
// Get formId from appId
|
|
1812
2012
|
const formInfo = await resolveFormRecord(client, baseUrl, appId, objId);
|
|
@@ -1820,27 +2020,231 @@ export function registerFormCommands(program) {
|
|
|
1820
2020
|
// 不看设计器实际报文就想不到的约束。
|
|
1821
2021
|
const formName = formInfo?.formName || formInfo?.objName || '表单';
|
|
1822
2022
|
const effect = await resolveEffect(client, baseUrl, formId, formName, config.effect);
|
|
2023
|
+
const formula = await resolveLinkageFormula(client, baseUrl, appId, objId, formId, config);
|
|
2024
|
+
const actions = await resolveLayoutActions(client, baseUrl, appId, objId, formId, config.actions || []);
|
|
1823
2025
|
const { payload, warnings } = buildLinkageAddPayload({
|
|
1824
2026
|
appId, objId, formId, formName, name,
|
|
1825
2027
|
conditions: config.conditions || [],
|
|
1826
2028
|
detailType: config.detailType,
|
|
1827
|
-
actions
|
|
1828
|
-
effect,
|
|
2029
|
+
actions,
|
|
2030
|
+
effect, formula, enableState: cmdOpts.disabled ? '0' : '1',
|
|
1829
2031
|
});
|
|
1830
2032
|
for (const w of warnings)
|
|
1831
2033
|
console.error(` ⚠ ${w}`);
|
|
1832
2034
|
const data = await addLinkage(client, baseUrl, appId, formId, payload);
|
|
1833
2035
|
if (data?.code === 200 && data?.status) {
|
|
1834
|
-
|
|
2036
|
+
// add 的 data 在部分环境是成功标记 1,并非规则 ID;从列表按名称回查唯一记录。
|
|
2037
|
+
const listed = await client.post(`${baseUrl}${linkageBase}/queryByPages?apid=${appId}`, {
|
|
2038
|
+
formId, module: 'ebuilderform', linkageTypeList: ['template', 'sql'],
|
|
2039
|
+
customParam: { appId, objId }, pageNo: 1, pageSize: 50,
|
|
2040
|
+
}, { ebbusinessid: appId });
|
|
2041
|
+
const matches = listed?.code === 200 && listed?.status
|
|
2042
|
+
? (listed?.data?.result || []).filter((item) => item.linkageName === name) : [];
|
|
2043
|
+
const linkageId = matches.length === 1 ? String(matches[0].id) : '';
|
|
1835
2044
|
console.log(opts.json
|
|
1836
2045
|
? JSON.stringify({ success: true, linkageId, name })
|
|
1837
|
-
: `联动规则已添加: ${name}` + (linkageId ? ` (id: ${linkageId})` : ''));
|
|
2046
|
+
: `联动规则已添加: ${name}` + (linkageId ? ` (id: ${linkageId})` : ';请用 linkage list 核对 ID'));
|
|
1838
2047
|
}
|
|
1839
2048
|
else {
|
|
1840
2049
|
console.error(`添加失败: ${data?.msg || '未知错误'}`);
|
|
1841
2050
|
process.exit(1);
|
|
1842
2051
|
}
|
|
1843
2052
|
});
|
|
2053
|
+
linkageCmd.command('get')
|
|
2054
|
+
.description('读取单条显示属性联动规则详情')
|
|
2055
|
+
.argument('<appId>').argument('<objId>').argument('<id>')
|
|
2056
|
+
.action(async (appId, objId, id) => {
|
|
2057
|
+
try {
|
|
2058
|
+
const opts = program.opts();
|
|
2059
|
+
const auth = await AuthSession.fromOptions(opts);
|
|
2060
|
+
if (!auth)
|
|
2061
|
+
throw new Error('无法加载认证');
|
|
2062
|
+
const client = new ApiClient(auth);
|
|
2063
|
+
const form = await resolveFormRecord(client, auth.getBaseUrl(), appId, objId);
|
|
2064
|
+
const formId = String(form?.formId || '');
|
|
2065
|
+
if (!formId)
|
|
2066
|
+
throw new Error('无法获取 formId');
|
|
2067
|
+
const record = await readLinkage(client, auth.getBaseUrl(), appId, objId, formId, id);
|
|
2068
|
+
console.log(opts.json ? JSON.stringify(record, null, 2)
|
|
2069
|
+
: `${record.linkageName} (${id}) ${record.enableState === '1' ? '启用' : '停用'};条件=${record.condition?.conditionType || '未知'};目标=${(record.linkageDetails || []).length} 项`);
|
|
2070
|
+
}
|
|
2071
|
+
catch (e) {
|
|
2072
|
+
console.error(`读取显示属性联动失败: ${e.message}`);
|
|
2073
|
+
process.exitCode = 1;
|
|
2074
|
+
}
|
|
2075
|
+
});
|
|
2076
|
+
linkageCmd.command('layout-targets')
|
|
2077
|
+
.description('查询当前表单可作为显示属性联动目标的布局组件')
|
|
2078
|
+
.argument('<appId>').argument('<objId>')
|
|
2079
|
+
.action(async (appId, objId) => {
|
|
2080
|
+
try {
|
|
2081
|
+
const auth = await AuthSession.fromOptions(program.opts());
|
|
2082
|
+
if (!auth)
|
|
2083
|
+
throw new Error('无法加载认证');
|
|
2084
|
+
const client = new ApiClient(auth);
|
|
2085
|
+
const baseUrl = auth.getBaseUrl();
|
|
2086
|
+
const form = await resolveFormRecord(client, baseUrl, appId, objId);
|
|
2087
|
+
const formId = String(form?.formId || '');
|
|
2088
|
+
if (!formId)
|
|
2089
|
+
throw new Error('无法获取 formId');
|
|
2090
|
+
const targets = await readLinkageLayoutTargets(client, baseUrl, appId, objId, formId);
|
|
2091
|
+
console.log(JSON.stringify(targets, null, 2));
|
|
2092
|
+
}
|
|
2093
|
+
catch (e) {
|
|
2094
|
+
console.error(`查询布局联动目标失败: ${e.message}`);
|
|
2095
|
+
process.exitCode = 1;
|
|
2096
|
+
}
|
|
2097
|
+
});
|
|
2098
|
+
linkageCmd.command('state')
|
|
2099
|
+
.description('启用或停用显示属性联动规则')
|
|
2100
|
+
.argument('<appId>').argument('<objId>').argument('<id>')
|
|
2101
|
+
.requiredOption('--set <on|off>', 'on=启用,off=停用')
|
|
2102
|
+
.action(async (appId, objId, id, cmdOpts) => {
|
|
2103
|
+
try {
|
|
2104
|
+
const state = cmdOpts.set === 'on' ? '1' : cmdOpts.set === 'off' ? '0' : '';
|
|
2105
|
+
if (!state)
|
|
2106
|
+
throw new Error('--set 只能为 on 或 off');
|
|
2107
|
+
const auth = await AuthSession.fromOptions(program.opts());
|
|
2108
|
+
if (!auth)
|
|
2109
|
+
throw new Error('无法加载认证');
|
|
2110
|
+
const client = new ApiClient(auth);
|
|
2111
|
+
const baseUrl = auth.getBaseUrl();
|
|
2112
|
+
const form = await resolveFormRecord(client, baseUrl, appId, objId);
|
|
2113
|
+
const formId = String(form?.formId || '');
|
|
2114
|
+
if (!formId)
|
|
2115
|
+
throw new Error('无法获取 formId');
|
|
2116
|
+
await readLinkage(client, baseUrl, appId, objId, formId, id);
|
|
2117
|
+
const res = await client.post(`${baseUrl}${linkageBase}/updateEnableStateByEntity?apid=${appId}`, { formId, id, enableState: state, customParam: { appId, objId } }, { ebbusinessid: formId });
|
|
2118
|
+
if (res?.code !== 200 || !res?.status)
|
|
2119
|
+
throw new Error(res?.msg || '保存失败');
|
|
2120
|
+
const saved = await readLinkage(client, baseUrl, appId, objId, formId, id);
|
|
2121
|
+
if (String(saved.enableState) !== state)
|
|
2122
|
+
throw new Error('启停状态保存后读回不一致');
|
|
2123
|
+
console.log(`显示属性联动已${state === '1' ? '启用' : '停用'}: ${saved.linkageName} (${id})`);
|
|
2124
|
+
}
|
|
2125
|
+
catch (e) {
|
|
2126
|
+
console.error(`切换显示属性联动失败: ${e.message}`);
|
|
2127
|
+
process.exitCode = 1;
|
|
2128
|
+
}
|
|
2129
|
+
});
|
|
2130
|
+
linkageCmd.command('update')
|
|
2131
|
+
.description('读取并修改已有显示属性联动;未指定内容保持原样')
|
|
2132
|
+
.argument('<appId>').argument('<objId>').argument('<id>')
|
|
2133
|
+
.option('--name <text>', '新名称')
|
|
2134
|
+
.option('--config <json>', '需替换的条件、目标或生效范围 JSON(@文件或内联)')
|
|
2135
|
+
.action(async (appId, objId, id, cmdOpts) => {
|
|
2136
|
+
try {
|
|
2137
|
+
if (!cmdOpts.name && !cmdOpts.config)
|
|
2138
|
+
throw new Error('至少提供 --name 或 --config');
|
|
2139
|
+
if (cmdOpts.name && cmdOpts.name.length > 200)
|
|
2140
|
+
throw new Error('联动名称不能超过 200 字');
|
|
2141
|
+
const auth = await AuthSession.fromOptions(program.opts());
|
|
2142
|
+
if (!auth)
|
|
2143
|
+
throw new Error('无法加载认证');
|
|
2144
|
+
const client = new ApiClient(auth);
|
|
2145
|
+
const baseUrl = auth.getBaseUrl();
|
|
2146
|
+
const form = await resolveFormRecord(client, baseUrl, appId, objId);
|
|
2147
|
+
const formId = String(form?.formId || '');
|
|
2148
|
+
if (!formId)
|
|
2149
|
+
throw new Error('无法获取 formId');
|
|
2150
|
+
const old = await readLinkage(client, baseUrl, appId, objId, formId, id);
|
|
2151
|
+
// 详情响应还含展示/统计字段;更新接口只接收设计器提交的规则主体。
|
|
2152
|
+
const payload = JSON.parse(JSON.stringify({
|
|
2153
|
+
fdEffect: old.fdEffect, condition: old.condition, linkageDetails: old.linkageDetails,
|
|
2154
|
+
module: 'ebuilderform', formId, refId: formId, id,
|
|
2155
|
+
enableState: old.enableState, linkageName: old.linkageName,
|
|
2156
|
+
customParam: { appId, objId },
|
|
2157
|
+
}));
|
|
2158
|
+
const config = cmdOpts.config ? readLinkageConfig(cmdOpts.config) : {};
|
|
2159
|
+
if (config.actions !== undefined)
|
|
2160
|
+
checkLinkageActions(config.actions);
|
|
2161
|
+
if (config.conditions !== undefined && (config.formula || config.formulaId)) {
|
|
2162
|
+
throw new Error('简易条件 conditions 与函数条件 formula/formulaId 不能同时指定');
|
|
2163
|
+
}
|
|
2164
|
+
if (config.conditions !== undefined && (!Array.isArray(config.conditions) || config.conditions.length === 0)) {
|
|
2165
|
+
throw new Error('简易条件 conditions[] 至少包含一项');
|
|
2166
|
+
}
|
|
2167
|
+
const formula = config.formula || config.formulaId
|
|
2168
|
+
? await resolveLinkageFormula(client, baseUrl, appId, objId, formId, config) : undefined;
|
|
2169
|
+
const actions = config.actions === undefined ? []
|
|
2170
|
+
: await resolveLayoutActions(client, baseUrl, appId, objId, formId, config.actions);
|
|
2171
|
+
const generated = buildLinkageAddPayload({
|
|
2172
|
+
appId, objId, formId, formName: String(form?.formName || form?.objName || '表单'),
|
|
2173
|
+
name: cmdOpts.name || old.linkageName, conditions: config.conditions || [],
|
|
2174
|
+
actions, detailType: config.detailType, formula,
|
|
2175
|
+
});
|
|
2176
|
+
for (const warning of generated.warnings)
|
|
2177
|
+
console.error(` ⚠ ${warning}`);
|
|
2178
|
+
if (cmdOpts.name)
|
|
2179
|
+
payload.linkageName = cmdOpts.name;
|
|
2180
|
+
if (config.effect !== undefined)
|
|
2181
|
+
payload.fdEffect = await resolveEffect(client, baseUrl, formId, String(form?.formName || form?.objName || '表单'), config.effect).then((effect) => ({
|
|
2182
|
+
...generated.payload.fdEffect, effectType: effect.effectType, effectName: effect.effectName,
|
|
2183
|
+
optionList: [{ effectValue: effect.effectValue, effectName: effect.optionName || effect.effectName }],
|
|
2184
|
+
}));
|
|
2185
|
+
if (config.conditions !== undefined || formula) {
|
|
2186
|
+
payload.condition = { ...old.condition, ...generated.payload.condition };
|
|
2187
|
+
}
|
|
2188
|
+
else if (config.detailType !== undefined) {
|
|
2189
|
+
payload.condition.detailType = config.detailType;
|
|
2190
|
+
}
|
|
2191
|
+
if (config.actions !== undefined)
|
|
2192
|
+
payload.linkageDetails = generated.payload.linkageDetails;
|
|
2193
|
+
payload.id = id;
|
|
2194
|
+
payload.formId = formId;
|
|
2195
|
+
payload.refId = formId;
|
|
2196
|
+
payload.module = 'ebuilderform';
|
|
2197
|
+
payload.customParam = { appId, objId };
|
|
2198
|
+
const res = await client.post(`${baseUrl}${linkageBase}/update?apid=${appId}`, payload, { ebbusinessid: formId });
|
|
2199
|
+
if (res?.code !== 200 || !res?.status)
|
|
2200
|
+
throw new Error(res?.msg || '保存失败');
|
|
2201
|
+
const saved = await readLinkage(client, baseUrl, appId, objId, formId, id);
|
|
2202
|
+
if (cmdOpts.name && saved.linkageName !== cmdOpts.name)
|
|
2203
|
+
throw new Error('规则名称保存后读回不一致');
|
|
2204
|
+
if (formula && String(saved.condition?.formulaId || '') !== formula.id)
|
|
2205
|
+
throw new Error('函数条件保存后读回不一致');
|
|
2206
|
+
if (config.detailType && saved.condition?.detailType !== config.detailType)
|
|
2207
|
+
throw new Error('条件关系保存后读回不一致');
|
|
2208
|
+
if (config.actions && (saved.linkageDetails || []).length !== config.actions.length)
|
|
2209
|
+
throw new Error('变更对象数量保存后读回不一致');
|
|
2210
|
+
console.log(`显示属性联动已修改: ${saved.linkageName} (${id})`);
|
|
2211
|
+
}
|
|
2212
|
+
catch (e) {
|
|
2213
|
+
console.error(`修改显示属性联动失败: ${e.message}`);
|
|
2214
|
+
process.exitCode = 1;
|
|
2215
|
+
}
|
|
2216
|
+
});
|
|
2217
|
+
linkageCmd.command('delete')
|
|
2218
|
+
.description('删除当前表单的一条显示属性联动规则')
|
|
2219
|
+
.argument('<appId>').argument('<objId>').argument('<id>')
|
|
2220
|
+
.action(async (appId, objId, id) => {
|
|
2221
|
+
try {
|
|
2222
|
+
const auth = await AuthSession.fromOptions(program.opts());
|
|
2223
|
+
if (!auth)
|
|
2224
|
+
throw new Error('无法加载认证');
|
|
2225
|
+
const client = new ApiClient(auth);
|
|
2226
|
+
const baseUrl = auth.getBaseUrl();
|
|
2227
|
+
const form = await resolveFormRecord(client, baseUrl, appId, objId);
|
|
2228
|
+
const formId = String(form?.formId || '');
|
|
2229
|
+
if (!formId)
|
|
2230
|
+
throw new Error('无法获取 formId');
|
|
2231
|
+
await readLinkage(client, baseUrl, appId, objId, formId, id);
|
|
2232
|
+
const query = new URLSearchParams({ ids: id, formId, module: 'ebuilderform', apid: appId });
|
|
2233
|
+
const res = await client.get(`${baseUrl}${linkageBase}/deleteByIds?${query}`);
|
|
2234
|
+
if (res?.code !== 200 || !res?.status || res?.data === 0)
|
|
2235
|
+
throw new Error(res?.msg || '删除失败');
|
|
2236
|
+
const check = await client.get(`${baseUrl}${linkageBase}/id?${new URLSearchParams({ id, formId, module: 'ebuilderform', apid: appId })}`);
|
|
2237
|
+
if (check?.code === 200 && check?.status && String(check?.data?.id || '') === id
|
|
2238
|
+
&& check.data.deleteType !== '1' && check.data.deleteType !== 1 && check.data.deleteType !== true) {
|
|
2239
|
+
throw new Error(`规则 ${id} 删除后仍可读到,请核查`);
|
|
2240
|
+
}
|
|
2241
|
+
console.log(`显示属性联动规则已删除: ${id}`);
|
|
2242
|
+
}
|
|
2243
|
+
catch (e) {
|
|
2244
|
+
console.error(`删除显示属性联动失败: ${e.message}`);
|
|
2245
|
+
process.exitCode = 1;
|
|
2246
|
+
}
|
|
2247
|
+
});
|
|
1844
2248
|
linkageCmd.command('list')
|
|
1845
2249
|
.description('查看显隐联动规则列表(回读条件/动作/启用状态)')
|
|
1846
2250
|
.argument('<appId>', '应用 ID')
|
|
@@ -1865,19 +2269,31 @@ export function registerFormCommands(program) {
|
|
|
1865
2269
|
formId, module: 'ebuilderform', linkageTypeList: ['template', 'sql'],
|
|
1866
2270
|
customParam: { appId, objId }, pageNo: 1, pageSize: 50,
|
|
1867
2271
|
};
|
|
1868
|
-
if (cmdOpts.keyword)
|
|
1869
|
-
body.keyword = cmdOpts.keyword;
|
|
1870
2272
|
const res = await client.post(`${baseUrl}/api/ebuilder/form/form/setting/viewlinkage/queryByPages?apid=${appId}`, body, { ebbusinessid: appId });
|
|
1871
2273
|
if (res?.code !== 200 || !res?.status) {
|
|
1872
2274
|
console.error(`查询失败: ${res?.msg || '未知错误'}`);
|
|
1873
2275
|
process.exit(1);
|
|
1874
2276
|
}
|
|
1875
|
-
|
|
2277
|
+
// 该接口的 keyword 不是字符串 DTO,直接传文本会触发反序列化错误;按名称在读回结果中过滤。
|
|
2278
|
+
let list = res?.data?.result || [];
|
|
2279
|
+
if (cmdOpts.keyword) {
|
|
2280
|
+
const total = Number(res?.data?.totalCount || list.length);
|
|
2281
|
+
for (let pageNo = 2; pageNo <= Math.ceil(total / body.pageSize); pageNo++) {
|
|
2282
|
+
const page = await client.post(`${baseUrl}${linkageBase}/queryByPages?apid=${appId}`, { ...body, pageNo }, { ebbusinessid: appId });
|
|
2283
|
+
if (page?.code !== 200 || !page?.status) {
|
|
2284
|
+
console.error(`第 ${pageNo} 页查询失败: ${page?.msg || '未知错误'}`);
|
|
2285
|
+
process.exitCode = 1;
|
|
2286
|
+
return;
|
|
2287
|
+
}
|
|
2288
|
+
list = list.concat(page?.data?.result || []);
|
|
2289
|
+
}
|
|
2290
|
+
list = list.filter((item) => String(item.linkageName || '').includes(cmdOpts.keyword));
|
|
2291
|
+
}
|
|
1876
2292
|
if (opts.json) {
|
|
1877
2293
|
console.log(JSON.stringify(list, null, 2));
|
|
1878
2294
|
}
|
|
1879
2295
|
else {
|
|
1880
|
-
console.log(`共 ${res?.data?.totalCount ?? list.length} 条联动规则:`);
|
|
2296
|
+
console.log(`共 ${cmdOpts.keyword ? list.length : (res?.data?.totalCount ?? list.length)} 条联动规则:`);
|
|
1881
2297
|
for (const x of list) {
|
|
1882
2298
|
const en = x.enableState === '1' ? '启用' : '停用';
|
|
1883
2299
|
console.log(` [${x.id}] ${x.linkageName} (${en})`);
|
|
@@ -2051,6 +2467,7 @@ export function registerFormCommands(program) {
|
|
|
2051
2467
|
.option('--data-title <field>', '目标表单的显示字段名(仅 EBuilder;缺省 name=目标表含"名称"的字段,无则第一个业务字段)')
|
|
2052
2468
|
.option('--form-name <name>', '目标表单名称(仅 EBuilder 类型,可选)')
|
|
2053
2469
|
.option('--browser-type <type>', `通用浏览类型:${BROWSER_KINDS.join('、')}`)
|
|
2470
|
+
.option('--browser-name <name>', '按名称精确指定浏览数据源(含自定义浏览框);优先于 --browser-type')
|
|
2054
2471
|
.option('--browser-form-source <source>', '表单浏览数据源:business 或 ebuilder(仅 --browser-type form)')
|
|
2055
2472
|
.option('--format <fmt>', '日期精度格式(Date/DateTime/DateRange),如 yyyy-MM-dd、yyyy-MM-dd HH:mm')
|
|
2056
2473
|
.option('--min-field <field>', 'Date/DateTime 日期限制:最早不得早于该字段(字段名,min.dateField)')
|
|
@@ -2105,6 +2522,12 @@ export function registerFormCommands(program) {
|
|
|
2105
2522
|
const endId = genIds[2] || '';
|
|
2106
2523
|
const labelFieldId = genIds[idCount] || String(Date.now());
|
|
2107
2524
|
const cmdOpts = cmdOptsRaw || {};
|
|
2525
|
+
if (cmdOpts.browserName) {
|
|
2526
|
+
if (fieldType !== 'Browser' && fieldType !== 'RelateBrowser') {
|
|
2527
|
+
throw new Error('--browser-name 仅适用于 Browser/RelateBrowser 字段');
|
|
2528
|
+
}
|
|
2529
|
+
cmdOpts.browserType = await resolveBrowserByName(client, baseUrl, cmdOpts.browserName, { ebbusinessid: formId });
|
|
2530
|
+
}
|
|
2108
2531
|
const sformId = cmdOpts.sformId || '';
|
|
2109
2532
|
const dataTitle = cmdOpts.dataTitle || '';
|
|
2110
2533
|
const formName = cmdOpts.formName || '';
|
|
@@ -2191,7 +2614,7 @@ export function registerFormCommands(program) {
|
|
|
2191
2614
|
console.error(' 本表还没有这个类型,改用平台给的字段模板合成组件...');
|
|
2192
2615
|
placed = await insertFieldIntoLayout(client, baseUrl, formId, { ...insertArgs, fieldTypeTemplate: tpl });
|
|
2193
2616
|
}
|
|
2194
|
-
console.error(` 布局已更新: excel[${placed.row},${placed.col}](增量插入,未重建)`);
|
|
2617
|
+
console.error(` 布局已更新: ${placed.row ? `excel[${placed.row},${placed.col}]` : 'FLOW'}(增量插入,未重建)`);
|
|
2195
2618
|
// 网格补格这类「改成功了但不干净」的情况要让人看见,不能闷掉。
|
|
2196
2619
|
for (const w of placed.warnings)
|
|
2197
2620
|
console.error(` ⚠ ${w}`);
|
|
@@ -2285,6 +2708,29 @@ export function registerFormCommands(program) {
|
|
|
2285
2708
|
console.error(` 布局更新失败: ${e.message}`);
|
|
2286
2709
|
}
|
|
2287
2710
|
}
|
|
2711
|
+
// 开关:布局写入会把字段 options 冲回空(模板 comp 里没有选项),
|
|
2712
|
+
// 必须在布局之后按完整记录补一次 开启=1 / 关闭=0。
|
|
2713
|
+
if (fieldType === 'Switch') {
|
|
2714
|
+
try {
|
|
2715
|
+
const gf = await client.post(`${baseUrl}/api/ebuilder/form/form/field/manage/getFormField`, { module: 'ebuilderform', formTableField: { formField: { id: fieldId, form: { id: formId } } } }, { ebbusinessid: formId });
|
|
2716
|
+
const full = gf?.data || {};
|
|
2717
|
+
if (full.fieldId) {
|
|
2718
|
+
const ogen = await client.post(`${baseUrl}/api/form/local/generatorIds?size=2&apid=${appId}`, {});
|
|
2719
|
+
const optionIds = (ogen?.data?.generatorIds || []).map(String);
|
|
2720
|
+
const ores = await client.post(`${baseUrl}/api/ebuilder/form/form/field/manage/saveFormFieldNew?apid=${appId}`, {
|
|
2721
|
+
formId, module: 'ebuilderform', customParam: { appId, objId },
|
|
2722
|
+
jsonObj: JSON.stringify({ ...full, options: defaultSwitchOptions(fieldId, optionIds) }),
|
|
2723
|
+
}, { ebbusinessid: formId });
|
|
2724
|
+
if (ores?.code === 200 && ores?.status)
|
|
2725
|
+
console.error(' 开关默认选项已配置: 开启=1 / 关闭=0');
|
|
2726
|
+
else
|
|
2727
|
+
console.error(` ⚠ 开关默认选项未确认保存: ${ores?.msg || '未知错误'}`);
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
catch (e) {
|
|
2731
|
+
console.error(` ⚠ 开关默认选项配置失败: ${e.message}`);
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2288
2734
|
}
|
|
2289
2735
|
else {
|
|
2290
2736
|
console.error(`添加失败: ${data?.msg || JSON.stringify(data) || '未知错误'}`);
|