weaver-e10-builder 1.2.2 → 1.2.5
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/README.md +8 -19
- package/dist/commands/actionflow.d.ts.map +1 -1
- package/dist/commands/actionflow.js +14 -1
- package/dist/commands/actionflow.js.map +1 -1
- package/dist/commands/designer-css.d.ts +15 -0
- package/dist/commands/designer-css.d.ts.map +1 -0
- package/dist/commands/designer-css.js +205 -0
- package/dist/commands/designer-css.js.map +1 -0
- package/dist/commands/form-add-detail-table.d.ts.map +1 -1
- package/dist/commands/form-add-detail-table.js +127 -7
- package/dist/commands/form-add-detail-table.js.map +1 -1
- package/dist/commands/form-ebuilder-columns.d.ts +7 -0
- package/dist/commands/form-ebuilder-columns.d.ts.map +1 -1
- package/dist/commands/form-ebuilder-columns.js +2 -24
- package/dist/commands/form-ebuilder-columns.js.map +1 -1
- package/dist/commands/form-field-lang.d.ts.map +1 -1
- package/dist/commands/form-field-lang.js +4 -39
- package/dist/commands/form-field-lang.js.map +1 -1
- package/dist/commands/form-formula.d.ts.map +1 -1
- package/dist/commands/form-formula.js +35 -11
- package/dist/commands/form-formula.js.map +1 -1
- package/dist/commands/form-layout-init.d.ts.map +1 -1
- package/dist/commands/form-layout-init.js +15 -10
- package/dist/commands/form-layout-init.js.map +1 -1
- package/dist/commands/form-layout.js +24 -21
- package/dist/commands/form-layout.js.map +1 -1
- package/dist/commands/form-native.d.ts.map +1 -1
- package/dist/commands/form-native.js +181 -0
- package/dist/commands/form-native.js.map +1 -1
- package/dist/commands/form-nlist.d.ts +1 -1
- package/dist/commands/form-nlist.d.ts.map +1 -1
- package/dist/commands/form-nlist.js +5 -3
- package/dist/commands/form-nlist.js.map +1 -1
- package/dist/commands/form-validate.d.ts.map +1 -1
- package/dist/commands/form-validate.js +11 -3
- package/dist/commands/form-validate.js.map +1 -1
- package/dist/commands/form.d.ts.map +1 -1
- package/dist/commands/form.js +168 -90
- package/dist/commands/form.js.map +1 -1
- package/dist/commands/menu.d.ts.map +1 -1
- package/dist/commands/menu.js +170 -23
- package/dist/commands/menu.js.map +1 -1
- package/dist/commands/wf-form.d.ts +1 -0
- package/dist/commands/wf-form.d.ts.map +1 -1
- package/dist/commands/wf-form.js +44 -13
- package/dist/commands/wf-form.js.map +1 -1
- package/dist/commands/workflow-auth-resp.d.ts.map +1 -1
- package/dist/commands/workflow-auth-resp.js +69 -8
- package/dist/commands/workflow-auth-resp.js.map +1 -1
- package/dist/commands/workflow-node-assign-flow.d.ts +3 -0
- package/dist/commands/workflow-node-assign-flow.d.ts.map +1 -0
- package/dist/commands/workflow-node-assign-flow.js +341 -0
- package/dist/commands/workflow-node-assign-flow.js.map +1 -0
- package/dist/commands/workflow-node.d.ts +2 -0
- package/dist/commands/workflow-node.d.ts.map +1 -1
- package/dist/commands/workflow-node.js +219 -48
- package/dist/commands/workflow-node.js.map +1 -1
- package/dist/commands/workflow-odoc.d.ts.map +1 -1
- package/dist/commands/workflow-odoc.js +56 -56
- package/dist/commands/workflow-odoc.js.map +1 -1
- package/dist/commands/workflow-setting.d.ts.map +1 -1
- package/dist/commands/workflow-setting.js +77 -1
- package/dist/commands/workflow-setting.js.map +1 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +36 -80
- package/dist/commands/workflow.js.map +1 -1
- package/dist/core/auth.js +1 -1
- package/dist/core/client.d.ts +14 -0
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +28 -12
- package/dist/core/client.js.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/services/actionflow/command_output.d.ts +7 -0
- package/dist/services/actionflow/command_output.d.ts.map +1 -1
- package/dist/services/actionflow/command_output.js +46 -0
- package/dist/services/actionflow/command_output.js.map +1 -1
- package/dist/services/actionflow/components/action_eb_add.d.ts.map +1 -1
- package/dist/services/actionflow/components/action_eb_add.js +14 -4
- package/dist/services/actionflow/components/action_eb_add.js.map +1 -1
- package/dist/services/actionflow/components/action_eb_add_compiler.d.ts.map +1 -1
- package/dist/services/actionflow/components/action_eb_add_compiler.js +29 -0
- package/dist/services/actionflow/components/action_eb_add_compiler.js.map +1 -1
- package/dist/services/actionflow/components/action_eb_update.d.ts.map +1 -1
- package/dist/services/actionflow/components/action_eb_update.js +23 -8
- package/dist/services/actionflow/components/action_eb_update.js.map +1 -1
- package/dist/services/actionflow/components/action_eb_update_compiler.d.ts.map +1 -1
- package/dist/services/actionflow/components/action_eb_update_compiler.js +239 -6
- package/dist/services/actionflow/components/action_eb_update_compiler.js.map +1 -1
- package/dist/services/actionflow/components/assign_var.d.ts +12 -0
- package/dist/services/actionflow/components/assign_var.d.ts.map +1 -0
- package/dist/services/actionflow/components/assign_var.js +133 -0
- package/dist/services/actionflow/components/assign_var.js.map +1 -0
- package/dist/services/actionflow/components/custom_set_form.d.ts +10 -0
- package/dist/services/actionflow/components/custom_set_form.d.ts.map +1 -0
- package/dist/services/actionflow/components/custom_set_form.js +65 -0
- package/dist/services/actionflow/components/custom_set_form.js.map +1 -0
- package/dist/services/actionflow/components/custom_trigger.d.ts +2 -2
- package/dist/services/actionflow/components/custom_trigger.d.ts.map +1 -1
- package/dist/services/actionflow/components/custom_trigger.js +7 -10
- package/dist/services/actionflow/components/custom_trigger.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/index.d.ts.map +1 -1
- package/dist/services/actionflow/components/index.js +9 -0
- package/dist/services/actionflow/components/index.js.map +1 -1
- package/dist/services/actionflow/components/output.d.ts.map +1 -1
- package/dist/services/actionflow/components/output.js +6 -1
- package/dist/services/actionflow/components/output.js.map +1 -1
- package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
- package/dist/services/actionflow/context_preflight.js +13 -6
- package/dist/services/actionflow/context_preflight.js.map +1 -1
- package/dist/services/actionflow/context_provider.d.ts.map +1 -1
- package/dist/services/actionflow/context_provider.js +3 -2
- package/dist/services/actionflow/context_provider.js.map +1 -1
- package/dist/services/actionflow/dynamic_resources.d.ts +7 -1
- package/dist/services/actionflow/dynamic_resources.d.ts.map +1 -1
- package/dist/services/actionflow/dynamic_resources.js +65 -8
- package/dist/services/actionflow/dynamic_resources.js.map +1 -1
- package/dist/services/actionflow/ebuilder_source.d.ts +19 -0
- package/dist/services/actionflow/ebuilder_source.d.ts.map +1 -0
- package/dist/services/actionflow/ebuilder_source.js +78 -0
- package/dist/services/actionflow/ebuilder_source.js.map +1 -0
- package/dist/services/actionflow/form_source.d.ts +76 -0
- package/dist/services/actionflow/form_source.d.ts.map +1 -1
- package/dist/services/actionflow/form_source.js +195 -1
- package/dist/services/actionflow/form_source.js.map +1 -1
- package/dist/services/actionflow/formula_service.d.ts +4 -1
- package/dist/services/actionflow/formula_service.d.ts.map +1 -1
- package/dist/services/actionflow/formula_service.js +97 -23
- package/dist/services/actionflow/formula_service.js.map +1 -1
- package/dist/services/actionflow/preflight_service.d.ts +6 -0
- package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
- package/dist/services/actionflow/preflight_service.js +211 -3
- package/dist/services/actionflow/preflight_service.js.map +1 -1
- package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
- package/dist/services/actionflow/workflow_compiler.js +83 -15
- package/dist/services/actionflow/workflow_compiler.js.map +1 -1
- package/dist/services/designer-css.d.ts +89 -0
- package/dist/services/designer-css.d.ts.map +1 -0
- package/dist/services/designer-css.js +163 -0
- package/dist/services/designer-css.js.map +1 -0
- package/dist/services/dom-structure.d.ts +42 -0
- package/dist/services/dom-structure.d.ts.map +1 -0
- package/dist/services/dom-structure.js +251 -0
- package/dist/services/dom-structure.js.map +1 -0
- package/dist/services/form-create.d.ts +2 -1
- package/dist/services/form-create.d.ts.map +1 -1
- package/dist/services/form-create.js.map +1 -1
- package/dist/services/form-ebuilder-columns.d.ts +50 -0
- package/dist/services/form-ebuilder-columns.d.ts.map +1 -0
- package/dist/services/form-ebuilder-columns.js +68 -0
- package/dist/services/form-ebuilder-columns.js.map +1 -0
- package/dist/services/form-field-drop.d.ts +30 -1
- package/dist/services/form-field-drop.d.ts.map +1 -1
- package/dist/services/form-field-drop.js +60 -0
- package/dist/services/form-field-drop.js.map +1 -1
- package/dist/services/form-field-patch.d.ts +69 -0
- package/dist/services/form-field-patch.d.ts.map +1 -0
- package/dist/services/form-field-patch.js +117 -0
- package/dist/services/form-field-patch.js.map +1 -0
- package/dist/services/form-i18n-label.d.ts +48 -0
- package/dist/services/form-i18n-label.d.ts.map +1 -0
- package/dist/services/form-i18n-label.js +91 -0
- package/dist/services/form-i18n-label.js.map +1 -0
- package/dist/services/form-nlist.d.ts +1 -0
- package/dist/services/form-nlist.d.ts.map +1 -1
- package/dist/services/form-nlist.js +32 -5
- package/dist/services/form-nlist.js.map +1 -1
- package/dist/services/form-style-template.d.ts +6 -2
- package/dist/services/form-style-template.d.ts.map +1 -1
- package/dist/services/form-style-template.js +8 -4
- package/dist/services/form-style-template.js.map +1 -1
- package/dist/services/form-sub-detail.d.ts +51 -3
- package/dist/services/form-sub-detail.d.ts.map +1 -1
- package/dist/services/form-sub-detail.js +183 -20
- package/dist/services/form-sub-detail.js.map +1 -1
- package/dist/services/formula-detail.d.ts +68 -5
- package/dist/services/formula-detail.d.ts.map +1 -1
- package/dist/services/formula-detail.js +110 -44
- package/dist/services/formula-detail.js.map +1 -1
- package/dist/services/menu-catalog.d.ts +84 -0
- package/dist/services/menu-catalog.d.ts.map +1 -0
- package/dist/services/menu-catalog.js +183 -0
- package/dist/services/menu-catalog.js.map +1 -0
- package/dist/services/rich-text.d.ts +33 -0
- package/dist/services/rich-text.d.ts.map +1 -0
- package/dist/services/rich-text.js +134 -0
- package/dist/services/rich-text.js.map +1 -0
- package/dist/services/workflow-add-step.d.ts +45 -0
- package/dist/services/workflow-add-step.d.ts.map +1 -0
- package/dist/services/workflow-add-step.js +122 -0
- package/dist/services/workflow-add-step.js.map +1 -0
- package/dist/services/workflow-assign-flow.d.ts +109 -0
- package/dist/services/workflow-assign-flow.d.ts.map +1 -0
- package/dist/services/workflow-assign-flow.js +306 -0
- package/dist/services/workflow-assign-flow.js.map +1 -0
- package/dist/services/workflow-drawback.d.ts +19 -0
- package/dist/services/workflow-drawback.d.ts.map +1 -0
- package/dist/services/workflow-drawback.js +59 -0
- package/dist/services/workflow-drawback.js.map +1 -0
- package/dist/services/workflow-links.d.ts +51 -0
- package/dist/services/workflow-links.d.ts.map +1 -0
- package/dist/services/workflow-links.js +162 -0
- package/dist/services/workflow-links.js.map +1 -0
- package/dist/services/workflow-node-layout.d.ts +45 -4
- package/dist/services/workflow-node-layout.d.ts.map +1 -1
- package/dist/services/workflow-node-layout.js +142 -41
- package/dist/services/workflow-node-layout.js.map +1 -1
- package/dist/services/workflow-node-menu.d.ts +57 -0
- package/dist/services/workflow-node-menu.d.ts.map +1 -0
- package/dist/services/workflow-node-menu.js +144 -0
- package/dist/services/workflow-node-menu.js.map +1 -0
- package/dist/services/workflow-odoc-setting.d.ts +43 -0
- package/dist/services/workflow-odoc-setting.d.ts.map +1 -0
- package/dist/services/workflow-odoc-setting.js +100 -0
- package/dist/services/workflow-odoc-setting.js.map +1 -0
- package/dist/services/workflow-tab-config.d.ts +54 -0
- package/dist/services/workflow-tab-config.d.ts.map +1 -0
- package/dist/services/workflow-tab-config.js +137 -0
- package/dist/services/workflow-tab-config.js.map +1 -0
- package/dist/types.d.ts +5 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/skill-docs/SKILL.md +8 -7
- package/skill-docs/_catalog.md +81 -77
- package/skill-docs/actionflows/SKILL.md +170 -167
- package/skill-docs/actionflows/references/components/ebuilder/ActionEbAdd.md +39 -2
- package/skill-docs/actionflows/references/components/ebuilder/ActionEbUpdate.md +42 -0
- package/skill-docs/actionflows/references/components/ebuilder/EventButton.md +33 -33
- package/skill-docs/actionflows/references/components/logic/Output.md +2 -0
- package/skill-docs/actionflows/references/components/trigger/CustomTrigger.md +16 -11
- package/skill-docs/assets/dom-structure/Bar.json +341 -0
- package/skill-docs/assets/dom-structure/BarStack.json +341 -0
- package/skill-docs/assets/dom-structure/Bubble.json +323 -0
- package/skill-docs/assets/dom-structure/Calendar.json +515 -0
- package/skill-docs/assets/dom-structure/Circular.json +337 -0
- package/skill-docs/assets/dom-structure/CollapsePanel.json +289 -0
- package/skill-docs/assets/dom-structure/Comment.json +617 -0
- package/skill-docs/assets/dom-structure/CountDown.json +755 -0
- package/skill-docs/assets/dom-structure/DigitalPanel.json +191 -0
- package/skill-docs/assets/dom-structure/EbButton.json +387 -0
- package/skill-docs/assets/dom-structure/FastCreate.json +242 -0
- package/skill-docs/assets/dom-structure/Gauge.json +282 -0
- package/skill-docs/assets/dom-structure/HBar.json +336 -0
- package/skill-docs/assets/dom-structure/HBarStack.json +337 -0
- package/skill-docs/assets/dom-structure/Line.json +341 -0
- package/skill-docs/assets/dom-structure/NList.json +712 -0
- package/skill-docs/assets/dom-structure/NavBar.json +274 -0
- package/skill-docs/assets/dom-structure/NavPanel.json +390 -0
- package/skill-docs/assets/dom-structure/NewTab.json +606 -0
- package/skill-docs/assets/dom-structure/Nightingale.json +336 -0
- package/skill-docs/assets/dom-structure/PageHeader.json +205 -0
- package/skill-docs/assets/dom-structure/Picture.json +209 -0
- package/skill-docs/assets/dom-structure/Pie.json +338 -0
- package/skill-docs/assets/dom-structure/ProgressChart.json +299 -0
- package/skill-docs/assets/dom-structure/SearchGlobal.json +628 -0
- package/skill-docs/assets/dom-structure/Slide.json +489 -0
- package/skill-docs/assets/dom-structure/Treemap.json +324 -0
- package/skill-docs/references/common/guide-plan-template.md +254 -251
- package/skill-docs/references/common/ref-cli-commands.md +537 -519
- package/skill-docs/references/ebuilder-designer/guide-designer-components.md +12 -1
- package/skill-docs/references/ebuilder-designer/guide-designer-css.md +127 -0
- package/skill-docs/references/ebuilder-designer/guide-designer.md +6 -5
- package/skill-docs/references/form/guide-create-form.md +233 -232
- package/skill-docs/references/form/guide-form-formula-functions.md +11 -1
- package/skill-docs/references/form/guide-form-layout-planning.md +1 -1
- package/skill-docs/references/form/guide-form-linkage.md +28 -2
- package/skill-docs/references/form/guide-form-sub-detail.md +82 -0
- package/skill-docs/references/form/guide-list-custom-text.md +52 -0
- package/skill-docs/references/menu/system-menus.md +12 -0
- package/skill-docs/references/workflow/guide-workflow-auth-resp.md +198 -190
- package/skill-docs/references/workflow/guide-workflow-odoc.md +22 -2
- package/skill-docs/references/workflow/guide-workflow.md +25 -3
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 应用菜单目录:把 `allMenus` 的原始返回**递归展开**成可查询的节点表,并构造改名的写报文。
|
|
3
|
+
*
|
|
4
|
+
* 两件事非做不可,都是踩过的坑:
|
|
5
|
+
*
|
|
6
|
+
* 1. **菜单是棵树,不是一层。** `allMenus` 返回的每条记录带 `children`(实测嵌套到三层,
|
|
7
|
+
* 如「设置 → 个人设置 → 个人菜单设置」)。只映射顶层数组会把嵌套菜单全丢掉 ——
|
|
8
|
+
* 调用方据此断言「这个应用没有这个菜单」,是**没取到 ≠ 不存在**的那类假否定。
|
|
9
|
+
*
|
|
10
|
+
* 2. **改名不能把读回来的那条记录原样写回去。** 读侧是扁平记录,写侧读的是**嵌套的
|
|
11
|
+
* `page: {pageId, pageName, pageType, …}`** 对象;直接回写会把菜单写坏
|
|
12
|
+
* (实测 LINK → EMPTY、pageId 清空、menuType 归零)。必须重建 `page`。
|
|
13
|
+
* `menuUrl` 同理:记录里有就原样带,没有就**整个省略** —— 拿 pageId 顶替会把菜单写脏,
|
|
14
|
+
* 而服务端只在它为空时才肯写这个键。
|
|
15
|
+
*/
|
|
16
|
+
/** 读侧派生 / 只读键:回写会造成干扰(与 fields/表单一侧的只读键同理)。 */
|
|
17
|
+
export declare const MENU_READONLY_KEYS: readonly ["children", "createTime", "updateTime", "creator", "tenantKey", "deleteType"];
|
|
18
|
+
/**
|
|
19
|
+
* 改名后**必须原样不变**的字段。任一不等即视为写坏 —— 这正是「扁平记录直接回写」
|
|
20
|
+
* 那次事故的形状(pageType 被改成 EMPTY、menuType 归零)。
|
|
21
|
+
*/
|
|
22
|
+
export declare const MENU_GUARD_KEYS: readonly ["pageType", "pageId", "menuUrl", "menuType", "linkType", "openMode", "showType", "showOrder", "pid", "type", "sysMenuId", "tabs", "pageExtend", "filterCondition"];
|
|
23
|
+
export interface MenuNode {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
pageType: string;
|
|
27
|
+
pageId: string;
|
|
28
|
+
menuUrl: string;
|
|
29
|
+
menuType: string;
|
|
30
|
+
sysMenuId: string;
|
|
31
|
+
parentId: string;
|
|
32
|
+
depth: number;
|
|
33
|
+
raw: Record<string, any>;
|
|
34
|
+
}
|
|
35
|
+
export type MenuBucket = 'ebAppMenus' | 'cusAppMenus';
|
|
36
|
+
export declare function menuNameOf(raw: Record<string, any>): string;
|
|
37
|
+
/**
|
|
38
|
+
* 递归展开菜单树。`depth` 从 0 起,`parentId` 取记录自带的 pid/parentId,
|
|
39
|
+
* 缺失时回落到所在层的父节点 id。
|
|
40
|
+
*/
|
|
41
|
+
export declare function flattenMenus(nodes: any[], depth?: number, parentId?: string): MenuNode[];
|
|
42
|
+
/**
|
|
43
|
+
* 选桶。两桶装的是同一批菜单的两种形状(`ebAppMenus` 用 `content`/`pid`,
|
|
44
|
+
* `cusAppMenus` 用 `menuName`/`parentId`),**不能合并**(会翻倍)。
|
|
45
|
+
* 优先 `ebAppMenus` —— 它的键集就是写报文(`savePublishMenu` 的 navigation)的形状。
|
|
46
|
+
*/
|
|
47
|
+
export declare function pickMenuBucket(data: any): {
|
|
48
|
+
nodes: MenuNode[];
|
|
49
|
+
bucket: MenuBucket;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* 按 id 或名称找菜单。id 精确命中优先;否则返回**所有**同名节点
|
|
53
|
+
* (真实数据里同一个应用存在两条「合同门户页面」—— 调用方必须据此报歧义,不能擅自挑一条)。
|
|
54
|
+
*/
|
|
55
|
+
export declare function findMenus(nodes: MenuNode[], query: string): MenuNode[];
|
|
56
|
+
/** 按名称模糊找候选(用于「找不到」时给提示)。 */
|
|
57
|
+
export declare function similarMenus(nodes: MenuNode[], query: string, limit?: number): MenuNode[];
|
|
58
|
+
/**
|
|
59
|
+
* 平台系统项(回收站 / 设置 / 个人设置 …)。这些菜单由平台维护、指向内置页面,
|
|
60
|
+
* 改名没有语义,调用方应拒绝。
|
|
61
|
+
*/
|
|
62
|
+
export declare function isSystemMenu(node: MenuNode): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* 构造改名的写报文:以读回的记录为底,只动名字,再**补上写侧要的嵌套 `page`**。
|
|
65
|
+
*
|
|
66
|
+
* 关键取舍:
|
|
67
|
+
* - 读侧派生键一律摘掉(`children` 等),它们不是 navigation 的一部分。
|
|
68
|
+
* - `page` 必须重建:记录里没有这个键,而写侧认它。缺了就是「LINK 变 EMPTY」那次事故。
|
|
69
|
+
* - `menuUrl` **只在记录里本来就有非空值时**带上;没有就整个省略。服务端只在它为空时才写它,
|
|
70
|
+
* 拿 pageId 顶替会把菜单写脏。
|
|
71
|
+
* - `filterCondition` / `tabs` / `pageExtend` 等一律沿用记录原值,不重造 ——
|
|
72
|
+
* 改名不该顺手改掉别人的筛选条件。
|
|
73
|
+
*/
|
|
74
|
+
export declare function buildRenameNavigation(node: MenuNode, newName: string, appId: string): Record<string, any>;
|
|
75
|
+
/**
|
|
76
|
+
* 比对改名前后,返回**名字之外**发生变化的守卫字段。
|
|
77
|
+
* 返回空数组才算改名干净;非空即调用方应硬失败并点名。
|
|
78
|
+
*/
|
|
79
|
+
export declare function diffMenuGuard(before: MenuNode, after: MenuNode): string[];
|
|
80
|
+
/** 把节点表按层级渲染成缩进行(对齐 `role` 命令的树形打印)。 */
|
|
81
|
+
export declare function renderMenuTree(nodes: MenuNode[]): string[];
|
|
82
|
+
/** 嵌套(非顶层)节点数。 */
|
|
83
|
+
export declare function nestedCount(nodes: MenuNode[]): number;
|
|
84
|
+
//# sourceMappingURL=menu-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu-catalog.d.ts","sourceRoot":"","sources":["../../src/services/menu-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,yFAOrB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,eAAe,8KAGlB,CAAC;AAEX,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,aAAa,CAAC;AAWtD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAE3D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,KAAK,SAAI,EAAE,QAAQ,SAAM,GAAG,QAAQ,EAAE,CAsBhF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,GAAG,GAAG;IAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAMnF;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAMtE;AAED,6BAA6B;AAC7B,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,QAAQ,EAAE,CAOrF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAEpD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA2BzG;AAOD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,GAAG,MAAM,EAAE,CAQzE;AAED,wCAAwC;AACxC,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,EAAE,CAE1D;AAED,kBAAkB;AAClB,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 应用菜单目录:把 `allMenus` 的原始返回**递归展开**成可查询的节点表,并构造改名的写报文。
|
|
3
|
+
*
|
|
4
|
+
* 两件事非做不可,都是踩过的坑:
|
|
5
|
+
*
|
|
6
|
+
* 1. **菜单是棵树,不是一层。** `allMenus` 返回的每条记录带 `children`(实测嵌套到三层,
|
|
7
|
+
* 如「设置 → 个人设置 → 个人菜单设置」)。只映射顶层数组会把嵌套菜单全丢掉 ——
|
|
8
|
+
* 调用方据此断言「这个应用没有这个菜单」,是**没取到 ≠ 不存在**的那类假否定。
|
|
9
|
+
*
|
|
10
|
+
* 2. **改名不能把读回来的那条记录原样写回去。** 读侧是扁平记录,写侧读的是**嵌套的
|
|
11
|
+
* `page: {pageId, pageName, pageType, …}`** 对象;直接回写会把菜单写坏
|
|
12
|
+
* (实测 LINK → EMPTY、pageId 清空、menuType 归零)。必须重建 `page`。
|
|
13
|
+
* `menuUrl` 同理:记录里有就原样带,没有就**整个省略** —— 拿 pageId 顶替会把菜单写脏,
|
|
14
|
+
* 而服务端只在它为空时才肯写这个键。
|
|
15
|
+
*/
|
|
16
|
+
/** 两个桶的字段名不同,取值时两组都要认。 */
|
|
17
|
+
const NAME_KEYS = ['content', 'menuName', 'showName', 'alias', 'nameAlias', 'realName'];
|
|
18
|
+
const PARENT_KEYS = ['pid', 'parentId'];
|
|
19
|
+
/** 读侧派生 / 只读键:回写会造成干扰(与 fields/表单一侧的只读键同理)。 */
|
|
20
|
+
export const MENU_READONLY_KEYS = [
|
|
21
|
+
'children',
|
|
22
|
+
'createTime',
|
|
23
|
+
'updateTime',
|
|
24
|
+
'creator',
|
|
25
|
+
'tenantKey',
|
|
26
|
+
'deleteType',
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* 改名后**必须原样不变**的字段。任一不等即视为写坏 —— 这正是「扁平记录直接回写」
|
|
30
|
+
* 那次事故的形状(pageType 被改成 EMPTY、menuType 归零)。
|
|
31
|
+
*/
|
|
32
|
+
export const MENU_GUARD_KEYS = [
|
|
33
|
+
'pageType', 'pageId', 'menuUrl', 'menuType', 'linkType', 'openMode',
|
|
34
|
+
'showType', 'showOrder', 'pid', 'type', 'sysMenuId', 'tabs', 'pageExtend', 'filterCondition',
|
|
35
|
+
];
|
|
36
|
+
/** 逐层取值:两个桶的键名不同,谁的先命中用谁。 */
|
|
37
|
+
function firstOf(raw, keys) {
|
|
38
|
+
for (const k of keys) {
|
|
39
|
+
const v = raw?.[k];
|
|
40
|
+
if (v !== undefined && v !== null && String(v) !== '')
|
|
41
|
+
return String(v);
|
|
42
|
+
}
|
|
43
|
+
return '';
|
|
44
|
+
}
|
|
45
|
+
export function menuNameOf(raw) {
|
|
46
|
+
return firstOf(raw, NAME_KEYS);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 递归展开菜单树。`depth` 从 0 起,`parentId` 取记录自带的 pid/parentId,
|
|
50
|
+
* 缺失时回落到所在层的父节点 id。
|
|
51
|
+
*/
|
|
52
|
+
export function flattenMenus(nodes, depth = 0, parentId = '0') {
|
|
53
|
+
const out = [];
|
|
54
|
+
for (const raw of nodes || []) {
|
|
55
|
+
if (!raw || typeof raw !== 'object')
|
|
56
|
+
continue;
|
|
57
|
+
const id = String(raw.id ?? '');
|
|
58
|
+
out.push({
|
|
59
|
+
id,
|
|
60
|
+
name: menuNameOf(raw),
|
|
61
|
+
pageType: String(raw.pageType ?? ''),
|
|
62
|
+
pageId: String(raw.pageId ?? ''),
|
|
63
|
+
menuUrl: String(raw.menuUrl ?? ''),
|
|
64
|
+
menuType: String(raw.menuType ?? ''),
|
|
65
|
+
sysMenuId: String(raw.sysMenuId ?? ''),
|
|
66
|
+
parentId: firstOf(raw, PARENT_KEYS) || String(parentId),
|
|
67
|
+
depth,
|
|
68
|
+
raw,
|
|
69
|
+
});
|
|
70
|
+
if (Array.isArray(raw.children) && raw.children.length) {
|
|
71
|
+
out.push(...flattenMenus(raw.children, depth + 1, id));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 选桶。两桶装的是同一批菜单的两种形状(`ebAppMenus` 用 `content`/`pid`,
|
|
78
|
+
* `cusAppMenus` 用 `menuName`/`parentId`),**不能合并**(会翻倍)。
|
|
79
|
+
* 优先 `ebAppMenus` —— 它的键集就是写报文(`savePublishMenu` 的 navigation)的形状。
|
|
80
|
+
*/
|
|
81
|
+
export function pickMenuBucket(data) {
|
|
82
|
+
const eb = data?.ebAppMenus;
|
|
83
|
+
const cus = data?.cusAppMenus;
|
|
84
|
+
if (Array.isArray(eb) && eb.length)
|
|
85
|
+
return { nodes: flattenMenus(eb), bucket: 'ebAppMenus' };
|
|
86
|
+
if (Array.isArray(cus) && cus.length)
|
|
87
|
+
return { nodes: flattenMenus(cus), bucket: 'cusAppMenus' };
|
|
88
|
+
return { nodes: [], bucket: 'ebAppMenus' };
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 按 id 或名称找菜单。id 精确命中优先;否则返回**所有**同名节点
|
|
92
|
+
* (真实数据里同一个应用存在两条「合同门户页面」—— 调用方必须据此报歧义,不能擅自挑一条)。
|
|
93
|
+
*/
|
|
94
|
+
export function findMenus(nodes, query) {
|
|
95
|
+
const q = String(query ?? '').trim();
|
|
96
|
+
if (!q)
|
|
97
|
+
return [];
|
|
98
|
+
const byId = nodes.filter((n) => n.id === q);
|
|
99
|
+
if (byId.length)
|
|
100
|
+
return byId;
|
|
101
|
+
return nodes.filter((n) => n.name === q);
|
|
102
|
+
}
|
|
103
|
+
/** 按名称模糊找候选(用于「找不到」时给提示)。 */
|
|
104
|
+
export function similarMenus(nodes, query, limit = 10) {
|
|
105
|
+
const q = String(query ?? '').trim();
|
|
106
|
+
if (!q)
|
|
107
|
+
return [];
|
|
108
|
+
return nodes
|
|
109
|
+
.filter((n) => n.name.includes(q) || q.includes(n.name))
|
|
110
|
+
.filter((n) => n.name)
|
|
111
|
+
.slice(0, limit);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 平台系统项(回收站 / 设置 / 个人设置 …)。这些菜单由平台维护、指向内置页面,
|
|
115
|
+
* 改名没有语义,调用方应拒绝。
|
|
116
|
+
*/
|
|
117
|
+
export function isSystemMenu(node) {
|
|
118
|
+
return node.pageType === 'setting' || node.pageType === 'BASE';
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 构造改名的写报文:以读回的记录为底,只动名字,再**补上写侧要的嵌套 `page`**。
|
|
122
|
+
*
|
|
123
|
+
* 关键取舍:
|
|
124
|
+
* - 读侧派生键一律摘掉(`children` 等),它们不是 navigation 的一部分。
|
|
125
|
+
* - `page` 必须重建:记录里没有这个键,而写侧认它。缺了就是「LINK 变 EMPTY」那次事故。
|
|
126
|
+
* - `menuUrl` **只在记录里本来就有非空值时**带上;没有就整个省略。服务端只在它为空时才写它,
|
|
127
|
+
* 拿 pageId 顶替会把菜单写脏。
|
|
128
|
+
* - `filterCondition` / `tabs` / `pageExtend` 等一律沿用记录原值,不重造 ——
|
|
129
|
+
* 改名不该顺手改掉别人的筛选条件。
|
|
130
|
+
*/
|
|
131
|
+
export function buildRenameNavigation(node, newName, appId) {
|
|
132
|
+
const nav = { ...node.raw };
|
|
133
|
+
for (const k of MENU_READONLY_KEYS)
|
|
134
|
+
delete nav[k];
|
|
135
|
+
nav.id = node.id;
|
|
136
|
+
// 两个桶的名字键名不同,记录里有哪个就改哪个;content 是写侧主键,始终给。
|
|
137
|
+
nav.content = newName;
|
|
138
|
+
for (const k of ['alias', 'nameAlias', 'realName', 'menuName', 'showName']) {
|
|
139
|
+
if (k in nav)
|
|
140
|
+
nav[k] = newName;
|
|
141
|
+
}
|
|
142
|
+
nav.page = {
|
|
143
|
+
pageId: node.pageId,
|
|
144
|
+
pageName: String(node.raw.pageName || newName),
|
|
145
|
+
pageType: node.pageType,
|
|
146
|
+
terminalScopes: String(node.raw.terminalScopes ?? ''),
|
|
147
|
+
appid: appId,
|
|
148
|
+
};
|
|
149
|
+
// 有才带,没有就省略 —— 不要用 pageId 合成
|
|
150
|
+
if (node.raw.menuUrl !== undefined && String(node.raw.menuUrl) !== '') {
|
|
151
|
+
nav.menuUrl = String(node.raw.menuUrl);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
delete nav.menuUrl;
|
|
155
|
+
}
|
|
156
|
+
return nav;
|
|
157
|
+
}
|
|
158
|
+
/** 归一化比较值:`undefined` 与 `''` 视为等价(键存在与否不代表语义差异)。 */
|
|
159
|
+
function norm(v) {
|
|
160
|
+
return v === undefined || v === null ? '' : String(v);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 比对改名前后,返回**名字之外**发生变化的守卫字段。
|
|
164
|
+
* 返回空数组才算改名干净;非空即调用方应硬失败并点名。
|
|
165
|
+
*/
|
|
166
|
+
export function diffMenuGuard(before, after) {
|
|
167
|
+
const changed = [];
|
|
168
|
+
for (const k of MENU_GUARD_KEYS) {
|
|
169
|
+
if (norm(before.raw?.[k]) !== norm(after.raw?.[k])) {
|
|
170
|
+
changed.push(`${k}: ${JSON.stringify(norm(before.raw?.[k]))} → ${JSON.stringify(norm(after.raw?.[k]))}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return changed;
|
|
174
|
+
}
|
|
175
|
+
/** 把节点表按层级渲染成缩进行(对齐 `role` 命令的树形打印)。 */
|
|
176
|
+
export function renderMenuTree(nodes) {
|
|
177
|
+
return nodes.map((n) => `${' '.repeat(n.depth + 1)}${n.name}`);
|
|
178
|
+
}
|
|
179
|
+
/** 嵌套(非顶层)节点数。 */
|
|
180
|
+
export function nestedCount(nodes) {
|
|
181
|
+
return nodes.filter((n) => n.depth > 0).length;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=menu-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"menu-catalog.js","sourceRoot":"","sources":["../../src/services/menu-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** 展开 `{{}}` 时需要的最少字段信息(ds/fields 的字段对象即可直接传)。 */
|
|
2
|
+
export interface FieldRefSource {
|
|
3
|
+
id?: string;
|
|
4
|
+
fieldId?: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
showName?: string;
|
|
7
|
+
fieldGroup?: {
|
|
8
|
+
name?: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface ExpandResult {
|
|
12
|
+
html: string;
|
|
13
|
+
errors: string[];
|
|
14
|
+
warnings: string[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 生成一个字段引用标记。字段缺 id 时返回 null(调用方据此报错)。
|
|
18
|
+
* `formTitle` 取不到时占位文本退化成只有字段名 —— 那只是显示文本,平台渲染时会按 data-val 取值。
|
|
19
|
+
*/
|
|
20
|
+
export declare function fieldRefSpan(objId: string, field: FieldRefSource): string | null;
|
|
21
|
+
/**
|
|
22
|
+
* 展开富文本里的 `{{字段名}}` / `{{fieldId}}` 为平台字段引用标记。
|
|
23
|
+
*
|
|
24
|
+
* 同一字段出现多次会各展开一份(平台按出现位置逐个记引用,不能去重)。
|
|
25
|
+
* 有 error 时 **html 原样返回** —— 调用方据此中止,不把半截内容写进视图。
|
|
26
|
+
*/
|
|
27
|
+
export declare function expandFieldRefs(html: string, objId: string, fields: FieldRefSource[]): ExpandResult;
|
|
28
|
+
/**
|
|
29
|
+
* 校验富文本里**已展开**的字段引用标记:data-val 里的 fieldId 是否真的在这张表单里。
|
|
30
|
+
* 用于手写 HTML(不走 `{{}}`)的场景,把「静默显示不出值」提前变成一条警告。
|
|
31
|
+
*/
|
|
32
|
+
export declare function auditFieldRefs(html: string, knownFieldIds: Set<string>): string[];
|
|
33
|
+
//# sourceMappingURL=rich-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-text.d.ts","sourceRoot":"","sources":["../../src/services/rich-text.ts"],"names":[],"mappings":"AAuBA,kDAAkD;AAClD,MAAM,WAAW,cAAc;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAiBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAUhF;AAiBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GACpD,YAAY,CAkCd;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CA0BjF"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 自定义文本(富文本列)里的**表单字段引用**。
|
|
3
|
+
*
|
|
4
|
+
* 表单的列表式视图(台账)能加一列「自定义文本」:内容是一段富文本,除了固定文字和图片,
|
|
5
|
+
* 还能通过工具栏的字段图标**插入表单字段**。平台存下来的是一段 HTML,
|
|
6
|
+
* 插入字段的位置是一个 contenteditable=false 的 span:
|
|
7
|
+
*
|
|
8
|
+
* ```html
|
|
9
|
+
* <span contenteditable="false" data-type="list" data-val="{objId.fieldId}">{表名.字段名}</span>
|
|
10
|
+
* ```
|
|
11
|
+
*
|
|
12
|
+
* 其中 `data-val` 里的 `objId.fieldId` 才是身份(平台按它取值),span 里的 `{表名.字段名}`
|
|
13
|
+
* 只是占位显示。**两个值都写错时不报错、只是静默显示不出值**,所以不让调用方直接拼这段 HTML:
|
|
14
|
+
* 模板里写 `{{字段名}}` 或 `{{fieldId}}`,由本模块查表单元数据展开成完整 span。
|
|
15
|
+
*/
|
|
16
|
+
/** 模板里插入字段的写法:`{{字段名}}` / `{{fieldId}}`。 */
|
|
17
|
+
const TOKEN_RE = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
18
|
+
/** 平台自带的字段引用标记(已展开的 span)。先认 span,再单独解析 data-val ——
|
|
19
|
+
* 合成一条正则的话,data-val 写坏时整个匹配不上,等于把「静默显示不出值」漏报掉。 */
|
|
20
|
+
const SPAN_RE = /<span\b[^>]*\bdata-type="list"[^>]*>[\s\S]*?<\/span>/g;
|
|
21
|
+
const DATA_VAL_RE = /\bdata-val="\{([^}]*)\}"/;
|
|
22
|
+
/** HTML 文本节点转义:字段名里可能有 `&`/`<` 之类字符。 */
|
|
23
|
+
function escapeText(s) {
|
|
24
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
25
|
+
}
|
|
26
|
+
/** 字段在表单里的显示名(text 优先,退回 showName)。 */
|
|
27
|
+
function titleOf(f) {
|
|
28
|
+
return String(f.text || f.showName || '').trim();
|
|
29
|
+
}
|
|
30
|
+
/** 字段所属表名(平台放在 fieldGroup.name)。 */
|
|
31
|
+
function formTitleOf(f) {
|
|
32
|
+
return String(f.fieldGroup?.name || '').trim();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 生成一个字段引用标记。字段缺 id 时返回 null(调用方据此报错)。
|
|
36
|
+
* `formTitle` 取不到时占位文本退化成只有字段名 —— 那只是显示文本,平台渲染时会按 data-val 取值。
|
|
37
|
+
*/
|
|
38
|
+
export function fieldRefSpan(objId, field) {
|
|
39
|
+
const fieldId = String(field.fieldId || field.id || '').trim();
|
|
40
|
+
if (!fieldId || !objId)
|
|
41
|
+
return null;
|
|
42
|
+
const formTitle = formTitleOf(field);
|
|
43
|
+
const fieldTitle = titleOf(field);
|
|
44
|
+
const label = formTitle ? `{${formTitle}.${fieldTitle}}` : `{${fieldTitle}}`;
|
|
45
|
+
return ('<span contenteditable="false" data-type="list"' +
|
|
46
|
+
` data-val="{${objId}.${fieldId}}">${escapeText(label)}</span>`);
|
|
47
|
+
}
|
|
48
|
+
/** 按 token 找字段:先 id/fieldId 精确命中,再按显示名;显示名重复时报歧义。 */
|
|
49
|
+
function matchField(token, fields) {
|
|
50
|
+
const byId = fields.find((f) => String(f.fieldId || '') === token || String(f.id || '') === token);
|
|
51
|
+
if (byId)
|
|
52
|
+
return { field: byId };
|
|
53
|
+
const byName = fields.filter((f) => titleOf(f) === token);
|
|
54
|
+
if (byName.length === 1)
|
|
55
|
+
return { field: byName[0] };
|
|
56
|
+
if (byName.length > 1) {
|
|
57
|
+
return { error: `字段名「${token}」在该表单内不唯一(${byName.length} 个),请改用 fieldId` };
|
|
58
|
+
}
|
|
59
|
+
return { error: `未找到字段「${token}」(可用字段名或 fieldId;字段列表用 form read 查)` };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 展开富文本里的 `{{字段名}}` / `{{fieldId}}` 为平台字段引用标记。
|
|
63
|
+
*
|
|
64
|
+
* 同一字段出现多次会各展开一份(平台按出现位置逐个记引用,不能去重)。
|
|
65
|
+
* 有 error 时 **html 原样返回** —— 调用方据此中止,不把半截内容写进视图。
|
|
66
|
+
*/
|
|
67
|
+
export function expandFieldRefs(html, objId, fields) {
|
|
68
|
+
const errors = [];
|
|
69
|
+
const warnings = [];
|
|
70
|
+
if (typeof html !== 'string' || !html)
|
|
71
|
+
return { html: html || '', errors, warnings };
|
|
72
|
+
// fieldMap 里同一字段会有 id / fieldId 两个键,先把重复项去掉再判歧义
|
|
73
|
+
const seen = new Set();
|
|
74
|
+
const uniq = [];
|
|
75
|
+
for (const f of fields) {
|
|
76
|
+
const key = String(f.fieldId || f.id || '');
|
|
77
|
+
if (!key || seen.has(key))
|
|
78
|
+
continue;
|
|
79
|
+
seen.add(key);
|
|
80
|
+
uniq.push(f);
|
|
81
|
+
}
|
|
82
|
+
const out = html.replace(TOKEN_RE, (raw, token) => {
|
|
83
|
+
const name = String(token).trim();
|
|
84
|
+
const hit = matchField(name, uniq);
|
|
85
|
+
if (hit.error) {
|
|
86
|
+
errors.push(hit.error);
|
|
87
|
+
return raw;
|
|
88
|
+
}
|
|
89
|
+
const span = fieldRefSpan(objId, hit.field);
|
|
90
|
+
if (!span) {
|
|
91
|
+
errors.push(`字段「${name}」缺少 fieldId,无法生成引用`);
|
|
92
|
+
return raw;
|
|
93
|
+
}
|
|
94
|
+
if (!formTitleOf(hit.field)) {
|
|
95
|
+
warnings.push(`字段「${name}」的表名缺失,引用标记的占位文本只写了字段名(不影响取值)`);
|
|
96
|
+
}
|
|
97
|
+
return span;
|
|
98
|
+
});
|
|
99
|
+
return { html: errors.length ? html : out, errors, warnings };
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 校验富文本里**已展开**的字段引用标记:data-val 里的 fieldId 是否真的在这张表单里。
|
|
103
|
+
* 用于手写 HTML(不走 `{{}}`)的场景,把「静默显示不出值」提前变成一条警告。
|
|
104
|
+
*/
|
|
105
|
+
export function auditFieldRefs(html, knownFieldIds) {
|
|
106
|
+
const warnings = [];
|
|
107
|
+
if (typeof html !== 'string' || !html)
|
|
108
|
+
return warnings;
|
|
109
|
+
const seen = new Set();
|
|
110
|
+
let m;
|
|
111
|
+
SPAN_RE.lastIndex = 0;
|
|
112
|
+
while ((m = SPAN_RE.exec(html)) !== null) {
|
|
113
|
+
const vm = DATA_VAL_RE.exec(m[0]);
|
|
114
|
+
if (!vm) {
|
|
115
|
+
warnings.push('自定义文本里有一个字段引用标记读不出 data-val(格式应为 data-val="{objId.fieldId}"),平台会静默显示不出值');
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
const ref = vm[1];
|
|
119
|
+
const dot = ref.lastIndexOf('.');
|
|
120
|
+
if (dot <= 0) {
|
|
121
|
+
warnings.push(`字段引用标记 data-val="{${ref}}" 格式不是 {objId.fieldId}`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const fieldId = ref.slice(dot + 1);
|
|
125
|
+
if (seen.has(fieldId))
|
|
126
|
+
continue;
|
|
127
|
+
seen.add(fieldId);
|
|
128
|
+
if (!knownFieldIds.has(fieldId)) {
|
|
129
|
+
warnings.push(`自定义文本里引用了 fieldId=${fieldId},但该表单查不到这个字段(平台会静默显示不出值)`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return warnings;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=rich-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-text.js","sourceRoot":"","sources":["../../src/services/rich-text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ApiClient } from '../core/client.js';
|
|
2
|
+
/** 加签接收人选择方式 */
|
|
3
|
+
export declare const SELECT_MODES: Record<string, number>;
|
|
4
|
+
export declare const SELECT_MODE_LABELS: Record<number, string>;
|
|
5
|
+
/** 默认环节类型 */
|
|
6
|
+
export declare const NODE_TYPES: Record<string, number>;
|
|
7
|
+
export declare const NODE_TYPE_LABELS: Record<number, string>;
|
|
8
|
+
/** 默认会签属性 */
|
|
9
|
+
export declare const SIGN_ATTRS: Record<string, number>;
|
|
10
|
+
export declare const SIGN_ATTR_LABELS: Record<number, string>;
|
|
11
|
+
/** 流转结束后默认流转方式 */
|
|
12
|
+
export declare const FLOW_TYPES: Record<string, number>;
|
|
13
|
+
export declare const FLOW_TYPE_LABELS: Record<number, string>;
|
|
14
|
+
/** 回到本节点后的流转方式 */
|
|
15
|
+
export declare const BACK_FLOW_TYPES: Record<string, number>;
|
|
16
|
+
export declare const BACK_FLOW_TYPE_LABELS: Record<number, string>;
|
|
17
|
+
/** 加签人字段权限 */
|
|
18
|
+
export declare const FIELD_AUTH_TYPES: Record<string, number>;
|
|
19
|
+
export declare const FIELD_AUTH_TYPE_LABELS: Record<number, string>;
|
|
20
|
+
export interface AddStepSettings {
|
|
21
|
+
selectMode: number;
|
|
22
|
+
defNodeType: number;
|
|
23
|
+
defSignAttr: number;
|
|
24
|
+
defFlowType: number;
|
|
25
|
+
backFlowType: number;
|
|
26
|
+
fieldauthType: number;
|
|
27
|
+
/** 允许修改流程表单内容:0 关闭 / 1 开启 */
|
|
28
|
+
defModifyForm: number;
|
|
29
|
+
/** 限制接收范围(只开开关,范围明细另行保存) */
|
|
30
|
+
limitReceiveRange: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare const DEFAULT_ADD_STEP: AddStepSettings;
|
|
33
|
+
/** 回读归一:字符串枚举 → 数字,布尔 → 布尔 */
|
|
34
|
+
export declare function normalizeAddStep(data: any): AddStepSettings;
|
|
35
|
+
export declare function getAddStepSettings(client: ApiClient, baseUrl: string, workflowId: string, nodeId: string): Promise<AddStepSettings>;
|
|
36
|
+
/** 枚举越界检查。返回错误文案数组(空 = 通过)。 */
|
|
37
|
+
export declare function validateAddStep(s: AddStepSettings): string[];
|
|
38
|
+
/**
|
|
39
|
+
* 保存。**枚举一律发数字** —— 把 GET 回读的字符串原样发出去会 500。
|
|
40
|
+
* 返回实际写出的设置,供调用方回读比对。
|
|
41
|
+
*/
|
|
42
|
+
export declare function saveAddStepSettings(client: ApiClient, baseUrl: string, workflowId: string, nodeId: string, s: AddStepSettings): Promise<AddStepSettings>;
|
|
43
|
+
/** 回读比对,返回不一致项 */
|
|
44
|
+
export declare function diffAddStep(before: AddStepSettings, after: AddStepSettings): string[];
|
|
45
|
+
//# sourceMappingURL=workflow-add-step.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-add-step.d.ts","sourceRoot":"","sources":["../../src/services/workflow-add-step.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAkBnD,gBAAgB;AAChB,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAoC,CAAC;AACrF,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAwC,CAAC;AAE/F,aAAa;AACb,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAuC,CAAC;AACtF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAiC,CAAC;AAEtF,aAAa;AACb,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAwC,CAAC;AACvF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAsC,CAAC;AAE3F,kBAAkB;AAClB,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAwB,CAAC;AACvE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAiC,CAAC;AAEtF,kBAAkB;AAClB,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAwC,CAAC;AAC5F,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAExD,CAAC;AAEF,cAAc;AACd,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAuB,CAAC;AAC5E,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAmC,CAAC;AAE9F,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB,EAAE,eAG9B,CAAC;AAEF,8BAA8B;AAC9B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,eAAe,CAkB3D;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GACrE,OAAO,CAAC,eAAe,CAAC,CAQ1B;AAED,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAe5D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,GACzF,OAAO,CAAC,eAAe,CAAC,CAoB1B;AAED,kBAAkB;AAClB,wBAAgB,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE,CAMrF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 节点加签设置(操作菜单「加签」按钮的内部设置)。
|
|
3
|
+
*
|
|
4
|
+
* GET `addstep/getNodeAddStepSetForm` 的返回多包一层:`data.addStepForm.data`。
|
|
5
|
+
*
|
|
6
|
+
* **回读的值不能直接写回去**(2026-09-22 实测):GET 把这些枚举回读成**字符串**
|
|
7
|
+
* `"0"/"1"/"2"`、`limitReceiveRange` 回读成布尔 `false`,原样提交直接 500「系统错误」。
|
|
8
|
+
* 全部转成数字再发就通 —— 与指定流转、节点菜单是同一类读写形状不对称。
|
|
9
|
+
*
|
|
10
|
+
* 另一处文档与实际不符:接口库写 `fieldauthType` 是「1 所有字段权限 / 2 与当前节点一致」,
|
|
11
|
+
* 线上实际枚举是 **0 所有字段权限 / 1 与当前节点保持一致**(页面默认值就是 `"1"`)。
|
|
12
|
+
* 照文档发 `2` 是个枚举里不存在的值。
|
|
13
|
+
*/
|
|
14
|
+
const BASE = '/api/bs/workflow/pathdef';
|
|
15
|
+
/** 加签接收人选择方式 */
|
|
16
|
+
export const SELECT_MODES = { simple: 0, list: 1, chart: 2 };
|
|
17
|
+
export const SELECT_MODE_LABELS = { 0: '简易模式', 1: '列表模式', 2: '流程图模式' };
|
|
18
|
+
/** 默认环节类型 */
|
|
19
|
+
export const NODE_TYPES = { approve: 0, confirm: 1, view: 2 };
|
|
20
|
+
export const NODE_TYPE_LABELS = { 0: '审批', 1: '确认', 2: '查阅' };
|
|
21
|
+
/** 默认会签属性 */
|
|
22
|
+
export const SIGN_ATTRS = { countersign: 0, non: 1, order: 2 };
|
|
23
|
+
export const SIGN_ATTR_LABELS = { 0: '会签', 1: '非会签', 2: '依次逐个处理' };
|
|
24
|
+
/** 流转结束后默认流转方式 */
|
|
25
|
+
export const FLOW_TYPES = { next: 0, back: 1 };
|
|
26
|
+
export const FLOW_TYPE_LABELS = { 0: '自动流转下一节点', 1: '回到本节点' };
|
|
27
|
+
/** 回到本节点后的流转方式 */
|
|
28
|
+
export const BACK_FLOW_TYPES = { operator: 0, next: 1, addstep: 2 };
|
|
29
|
+
export const BACK_FLOW_TYPE_LABELS = {
|
|
30
|
+
0: '由当前节点操作者选择', 1: '流转至下一节点', 2: '流转至加签环节',
|
|
31
|
+
};
|
|
32
|
+
/** 加签人字段权限 */
|
|
33
|
+
export const FIELD_AUTH_TYPES = { all: 0, same: 1 };
|
|
34
|
+
export const FIELD_AUTH_TYPE_LABELS = { 0: '所有字段权限', 1: '与当前节点保持一致' };
|
|
35
|
+
export const DEFAULT_ADD_STEP = {
|
|
36
|
+
selectMode: 1, defNodeType: 0, defSignAttr: 0, defFlowType: 0,
|
|
37
|
+
backFlowType: 0, fieldauthType: 1, defModifyForm: 0, limitReceiveRange: false,
|
|
38
|
+
};
|
|
39
|
+
/** 回读归一:字符串枚举 → 数字,布尔 → 布尔 */
|
|
40
|
+
export function normalizeAddStep(data) {
|
|
41
|
+
const d = data || {};
|
|
42
|
+
const num = (v, fallback) => {
|
|
43
|
+
if (v === undefined || v === null || v === '')
|
|
44
|
+
return fallback;
|
|
45
|
+
if (typeof v === 'boolean')
|
|
46
|
+
return v ? 1 : 0;
|
|
47
|
+
const n = Number(v);
|
|
48
|
+
return Number.isFinite(n) ? n : fallback;
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
selectMode: num(d.selectMode, DEFAULT_ADD_STEP.selectMode),
|
|
52
|
+
defNodeType: num(d.defNodeType, DEFAULT_ADD_STEP.defNodeType),
|
|
53
|
+
defSignAttr: num(d.defSignAttr, DEFAULT_ADD_STEP.defSignAttr),
|
|
54
|
+
defFlowType: num(d.defFlowType, DEFAULT_ADD_STEP.defFlowType),
|
|
55
|
+
backFlowType: num(d.backFlowType, DEFAULT_ADD_STEP.backFlowType),
|
|
56
|
+
fieldauthType: num(d.fieldauthType, DEFAULT_ADD_STEP.fieldauthType),
|
|
57
|
+
defModifyForm: num(d.defModifyForm, DEFAULT_ADD_STEP.defModifyForm),
|
|
58
|
+
limitReceiveRange: d.limitReceiveRange === true || d.limitReceiveRange === 1 || d.limitReceiveRange === '1',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export async function getAddStepSettings(client, baseUrl, workflowId, nodeId) {
|
|
62
|
+
const res = await client.get(`${baseUrl}${BASE}/addstep/getNodeAddStepSetForm?workflowId=${workflowId}&nodeId=${nodeId}`);
|
|
63
|
+
if (res?.code !== 200 || !res?.status)
|
|
64
|
+
throw new Error(`读取加签设置失败: ${res?.msg || '未知错误'}`);
|
|
65
|
+
const form = res?.data?.addStepForm;
|
|
66
|
+
if (!form?.data)
|
|
67
|
+
throw new Error(`加签设置返回结构异常(缺 addStepForm.data),节点 ${nodeId} 可能不支持加签`);
|
|
68
|
+
return normalizeAddStep(form.data);
|
|
69
|
+
}
|
|
70
|
+
/** 枚举越界检查。返回错误文案数组(空 = 通过)。 */
|
|
71
|
+
export function validateAddStep(s) {
|
|
72
|
+
const errors = [];
|
|
73
|
+
const check = (label, value, labels) => {
|
|
74
|
+
if (!(value in labels)) {
|
|
75
|
+
errors.push(`${label} 不支持 ${value},可选: ${Object.entries(labels).map(([k, v]) => `${k}=${v}`).join(' / ')}`);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
check('选择方式', s.selectMode, SELECT_MODE_LABELS);
|
|
79
|
+
check('环节类型', s.defNodeType, NODE_TYPE_LABELS);
|
|
80
|
+
check('会签属性', s.defSignAttr, SIGN_ATTR_LABELS);
|
|
81
|
+
check('流转方式', s.defFlowType, FLOW_TYPE_LABELS);
|
|
82
|
+
check('回到本节点后流转方式', s.backFlowType, BACK_FLOW_TYPE_LABELS);
|
|
83
|
+
check('字段权限', s.fieldauthType, FIELD_AUTH_TYPE_LABELS);
|
|
84
|
+
check('允许修改表单内容', s.defModifyForm, { 0: '关闭', 1: '开启' });
|
|
85
|
+
return errors;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 保存。**枚举一律发数字** —— 把 GET 回读的字符串原样发出去会 500。
|
|
89
|
+
* 返回实际写出的设置,供调用方回读比对。
|
|
90
|
+
*/
|
|
91
|
+
export async function saveAddStepSettings(client, baseUrl, workflowId, nodeId, s) {
|
|
92
|
+
const errors = validateAddStep(s);
|
|
93
|
+
if (errors.length)
|
|
94
|
+
throw new Error(errors.join(';'));
|
|
95
|
+
const payload = {
|
|
96
|
+
workflowId, nodeId,
|
|
97
|
+
selectMode: Number(s.selectMode),
|
|
98
|
+
defNodeType: Number(s.defNodeType),
|
|
99
|
+
defSignAttr: Number(s.defSignAttr),
|
|
100
|
+
defFlowType: Number(s.defFlowType),
|
|
101
|
+
backFlowType: Number(s.backFlowType),
|
|
102
|
+
fieldauthType: Number(s.fieldauthType),
|
|
103
|
+
defModifyForm: Number(s.defModifyForm),
|
|
104
|
+
limitReceiveRange: s.limitReceiveRange ? 1 : 0,
|
|
105
|
+
isSync: false,
|
|
106
|
+
};
|
|
107
|
+
const res = await client.post(`${baseUrl}${BASE}/addstep/saveNodeAddStepSetInfo`, payload);
|
|
108
|
+
if (res?.code !== 200 || res?.status === false) {
|
|
109
|
+
throw new Error(`保存加签设置失败: ${res?.msg || '未知错误'}`);
|
|
110
|
+
}
|
|
111
|
+
return s;
|
|
112
|
+
}
|
|
113
|
+
/** 回读比对,返回不一致项 */
|
|
114
|
+
export function diffAddStep(before, after) {
|
|
115
|
+
const out = [];
|
|
116
|
+
for (const key of Object.keys(before)) {
|
|
117
|
+
if (before[key] !== after[key])
|
|
118
|
+
out.push(`${key}: 期望 ${String(before[key])},回读 ${String(after[key])}`);
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=workflow-add-step.js.map
|