weaver-e10-builder 1.7.0 → 1.7.2
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/assets/icon-names.txt +7438 -0
- package/dist/cli-register.d.ts.map +1 -1
- package/dist/cli-register.js +16 -3
- package/dist/cli-register.js.map +1 -1
- package/dist/commands/app-manager.d.ts +8 -0
- package/dist/commands/app-manager.d.ts.map +1 -0
- package/dist/commands/app-manager.js +330 -0
- package/dist/commands/app-manager.js.map +1 -0
- package/dist/commands/app-setting.d.ts +8 -0
- package/dist/commands/app-setting.d.ts.map +1 -0
- package/dist/commands/app-setting.js +170 -0
- package/dist/commands/app-setting.js.map +1 -0
- package/dist/commands/connector.d.ts +7 -0
- package/dist/commands/connector.d.ts.map +1 -0
- package/dist/commands/connector.js +163 -0
- package/dist/commands/connector.js.map +1 -0
- package/dist/commands/form-association-manage.d.ts.map +1 -1
- package/dist/commands/form-association-manage.js +57 -4
- package/dist/commands/form-association-manage.js.map +1 -1
- package/dist/commands/form-association.d.ts.map +1 -1
- package/dist/commands/form-association.js +4 -2
- package/dist/commands/form-association.js.map +1 -1
- package/dist/commands/form-button-actions-cmd.d.ts.map +1 -1
- package/dist/commands/form-button-actions-cmd.js +180 -18
- package/dist/commands/form-button-actions-cmd.js.map +1 -1
- package/dist/commands/form-button-props-cmd.d.ts.map +1 -1
- package/dist/commands/form-button-props-cmd.js +4 -0
- package/dist/commands/form-button-props-cmd.js.map +1 -1
- package/dist/commands/form-button.d.ts.map +1 -1
- package/dist/commands/form-button.js +11 -0
- package/dist/commands/form-button.js.map +1 -1
- package/dist/commands/form-permission.d.ts.map +1 -1
- package/dist/commands/form-permission.js +310 -84
- package/dist/commands/form-permission.js.map +1 -1
- package/dist/commands/icon.d.ts.map +1 -1
- package/dist/commands/icon.js +63 -1
- package/dist/commands/icon.js.map +1 -1
- package/dist/commands/menu-config.d.ts +3 -0
- package/dist/commands/menu-config.d.ts.map +1 -0
- package/dist/commands/menu-config.js +93 -0
- package/dist/commands/menu-config.js.map +1 -0
- package/dist/commands/menu-permission.d.ts.map +1 -1
- package/dist/commands/menu-permission.js +6 -7
- package/dist/commands/menu-permission.js.map +1 -1
- package/dist/commands/menu.d.ts.map +1 -1
- package/dist/commands/menu.js +2 -5
- package/dist/commands/menu.js.map +1 -1
- package/dist/services/actionflow/components/action_eb_add.js +1 -1
- package/dist/services/actionflow/components/action_eb_add.js.map +1 -1
- 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/enquiry_form.js +4 -4
- package/dist/services/actionflow/components/enquiry_form.js.map +1 -1
- package/dist/services/actionflow/components/meeting_create.d.ts.map +1 -1
- package/dist/services/actionflow/components/meeting_create.js +2 -1
- package/dist/services/actionflow/components/meeting_create.js.map +1 -1
- package/dist/services/actionflow/components/output.d.ts.map +1 -1
- package/dist/services/actionflow/components/output.js +2 -0
- package/dist/services/actionflow/components/output.js.map +1 -1
- package/dist/services/actionflow/context_discovery.d.ts.map +1 -1
- package/dist/services/actionflow/context_discovery.js +3 -0
- package/dist/services/actionflow/context_discovery.js.map +1 -1
- package/dist/services/actionflow/context_preflight.d.ts.map +1 -1
- package/dist/services/actionflow/context_preflight.js +0 -10
- package/dist/services/actionflow/context_preflight.js.map +1 -1
- package/dist/services/actionflow/date_trigger_field.d.ts +3 -0
- package/dist/services/actionflow/date_trigger_field.d.ts.map +1 -0
- package/dist/services/actionflow/date_trigger_field.js +23 -0
- package/dist/services/actionflow/date_trigger_field.js.map +1 -0
- package/dist/services/actionflow/form_source.d.ts +1 -1
- package/dist/services/actionflow/form_source.d.ts.map +1 -1
- package/dist/services/actionflow/form_source.js +9 -1
- package/dist/services/actionflow/form_source.js.map +1 -1
- package/dist/services/actionflow/formula_service.d.ts.map +1 -1
- package/dist/services/actionflow/formula_service.js +4 -12
- package/dist/services/actionflow/formula_service.js.map +1 -1
- package/dist/services/actionflow/generation_service.d.ts.map +1 -1
- package/dist/services/actionflow/generation_service.js +2 -1
- package/dist/services/actionflow/generation_service.js.map +1 -1
- package/dist/services/actionflow/loop_context.d.ts.map +1 -1
- package/dist/services/actionflow/loop_context.js +17 -0
- package/dist/services/actionflow/loop_context.js.map +1 -1
- package/dist/services/actionflow/meeting_secret_level.d.ts +5 -0
- package/dist/services/actionflow/meeting_secret_level.d.ts.map +1 -0
- package/dist/services/actionflow/meeting_secret_level.js +49 -0
- package/dist/services/actionflow/meeting_secret_level.js.map +1 -0
- package/dist/services/actionflow/preflight_service.d.ts +2 -0
- package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
- package/dist/services/actionflow/preflight_service.js +212 -4
- package/dist/services/actionflow/preflight_service.js.map +1 -1
- package/dist/services/actionflow/readback_verifier.d.ts.map +1 -1
- package/dist/services/actionflow/readback_verifier.js +22 -0
- package/dist/services/actionflow/readback_verifier.js.map +1 -1
- package/dist/services/actionflow/runtime_metadata.d.ts +2 -1
- package/dist/services/actionflow/runtime_metadata.d.ts.map +1 -1
- package/dist/services/actionflow/runtime_metadata.js +6 -1
- package/dist/services/actionflow/runtime_metadata.js.map +1 -1
- package/dist/services/actionflow/update_service.d.ts.map +1 -1
- package/dist/services/actionflow/update_service.js +42 -1
- package/dist/services/actionflow/update_service.js.map +1 -1
- package/dist/services/actionflow/webhook_response_context.d.ts +7 -0
- package/dist/services/actionflow/webhook_response_context.d.ts.map +1 -0
- package/dist/services/actionflow/webhook_response_context.js +82 -0
- package/dist/services/actionflow/webhook_response_context.js.map +1 -0
- package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
- package/dist/services/actionflow/workflow_compiler.js +67 -35
- package/dist/services/actionflow/workflow_compiler.js.map +1 -1
- package/dist/services/app-manager.d.ts +128 -0
- package/dist/services/app-manager.d.ts.map +1 -0
- package/dist/services/app-manager.js +420 -0
- package/dist/services/app-manager.js.map +1 -0
- package/dist/services/app-setting.d.ts +109 -0
- package/dist/services/app-setting.d.ts.map +1 -0
- package/dist/services/app-setting.js +410 -0
- package/dist/services/app-setting.js.map +1 -0
- package/dist/services/esb-interface/connector-lock.d.ts +42 -0
- package/dist/services/esb-interface/connector-lock.d.ts.map +1 -0
- package/dist/services/esb-interface/connector-lock.js +79 -0
- package/dist/services/esb-interface/connector-lock.js.map +1 -0
- package/dist/services/esb-interface/connector-update.d.ts +34 -0
- package/dist/services/esb-interface/connector-update.d.ts.map +1 -0
- package/dist/services/esb-interface/connector-update.js +58 -0
- package/dist/services/esb-interface/connector-update.js.map +1 -0
- package/dist/services/form-association.d.ts +28 -1
- package/dist/services/form-association.d.ts.map +1 -1
- package/dist/services/form-association.js +232 -2
- package/dist/services/form-association.js.map +1 -1
- package/dist/services/form-button-action.d.ts +48 -2
- package/dist/services/form-button-action.d.ts.map +1 -1
- package/dist/services/form-button-action.js +68 -2
- package/dist/services/form-button-action.js.map +1 -1
- package/dist/services/form-field-options.d.ts +45 -0
- package/dist/services/form-field-options.d.ts.map +1 -0
- package/dist/services/form-field-options.js +179 -0
- package/dist/services/form-field-options.js.map +1 -0
- package/dist/services/form-permission-archive.d.ts +1 -0
- package/dist/services/form-permission-archive.d.ts.map +1 -1
- package/dist/services/form-permission-archive.js +3 -3
- package/dist/services/form-permission-archive.js.map +1 -1
- package/dist/services/form-permission-edit.d.ts +36 -0
- package/dist/services/form-permission-edit.d.ts.map +1 -1
- package/dist/services/form-permission-edit.js +77 -1
- package/dist/services/form-permission-edit.js.map +1 -1
- package/dist/services/icon-catalog.d.ts +60 -0
- package/dist/services/icon-catalog.d.ts.map +1 -0
- package/dist/services/icon-catalog.js +175 -0
- package/dist/services/icon-catalog.js.map +1 -0
- package/dist/services/icon-path.d.ts +2 -0
- package/dist/services/icon-path.d.ts.map +1 -1
- package/dist/services/icon-path.js +4 -0
- package/dist/services/icon-path.js.map +1 -1
- package/dist/services/menu-config.d.ts +42 -0
- package/dist/services/menu-config.d.ts.map +1 -0
- package/dist/services/menu-config.js +174 -0
- package/dist/services/menu-config.js.map +1 -0
- package/dist/services/menu-permission-config.d.ts +47 -0
- package/dist/services/menu-permission-config.d.ts.map +1 -0
- package/dist/services/menu-permission-config.js +222 -0
- package/dist/services/menu-permission-config.js.map +1 -0
- package/package.json +1 -1
- package/skill-docs/SKILL.md +193 -188
- package/skill-docs/_catalog.md +5 -1
- package/skill-docs/actionflows/SKILL.md +195 -193
- package/skill-docs/actionflows/references/components/calendar/MeetingCreate.md +2 -0
- package/skill-docs/actionflows/references/components/ebuilder/ActionEbAdd.md +5 -1
- package/skill-docs/actionflows/references/components/ebuilder/ActionEbDelete.md +80 -80
- package/skill-docs/actionflows/references/components/ebuilder/ActionEbUpdate.md +75 -75
- package/skill-docs/actionflows/references/components/ebuilder/DateTrigger.md +2 -0
- package/skill-docs/actionflows/references/components/ebuilder/EnquiryForm.md +113 -111
- package/skill-docs/actionflows/references/components/trigger/WebHookTrigger.md +2 -0
- package/skill-docs/actionflows/references/condition_rules.md +100 -100
- package/skill-docs/references/app/guide-app-manager.md +93 -0
- package/skill-docs/references/app/guide-app-settings.md +93 -0
- package/skill-docs/references/common/guide-install.md +2 -0
- package/skill-docs/references/common/ref-cli-commands.md +22 -7
- package/skill-docs/references/form/guide-form-association.md +36 -0
- package/skill-docs/references/form/guide-form-button.md +22 -1
- package/skill-docs/references/form/guide-form-permission.md +17 -5
- package/skill-docs/references/menu/guide-menu-config.md +130 -0
- package/skill-docs/references/menu/guide-menu-permission.md +94 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 连接器(连接系统 systemPool)封存 / 解封。
|
|
3
|
+
*
|
|
4
|
+
* 对齐后端 EsbSytemPoolController(weaver-esb-setting):
|
|
5
|
+
* - POST /api/bs/esb/setting/systemPool/lockByIds 批量封存(status → LOCKED=1)
|
|
6
|
+
* - POST /api/bs/esb/setting/systemPool/unlockByIds 批量解封(status → AVAILABLE=0)
|
|
7
|
+
* 请求体 EsbBatchIDsVO:{ ids: "id1,id2" } —— 逗号分隔字符串,不是数组。
|
|
8
|
+
* 后端对每个 id 校验存在性与编辑权限;若封存的是主系统,会级联设置其全部子系统。
|
|
9
|
+
* - GET /api/bs/esb/setting/systemPool/getPage 分页列表(current/pageSize/name/showDefalt),
|
|
10
|
+
* 返回 WeaTable:{ displayData, current, total, pageSize, ... }
|
|
11
|
+
*/
|
|
12
|
+
const SYSTEM_POOL_BASE = '/api/bs/esb/setting/systemPool';
|
|
13
|
+
/** 封存 / 解封 / 列表三个路径共用同一常量,禁止各写一份 */
|
|
14
|
+
export const SYSTEM_POOL_PAGE_PATH = `${SYSTEM_POOL_BASE}/getPage`;
|
|
15
|
+
export const SYSTEM_POOL_LOCK_PATH = `${SYSTEM_POOL_BASE}/lockByIds`;
|
|
16
|
+
export const SYSTEM_POOL_UNLOCK_PATH = `${SYSTEM_POOL_BASE}/unlockByIds`;
|
|
17
|
+
/** 连接系统状态(EsbStatusEnum):0 正常 / 1 封存 / 2 禁用 */
|
|
18
|
+
export const SYSTEM_POOL_STATUS = { AVAILABLE: 0, LOCKED: 1, FORBIDDEN: 2 };
|
|
19
|
+
/** 归一化 id 入参:去掉空白项与重复项,保留出现顺序 */
|
|
20
|
+
export function normalizeIds(input) {
|
|
21
|
+
const seen = new Set();
|
|
22
|
+
const result = [];
|
|
23
|
+
for (const raw of input) {
|
|
24
|
+
const id = String(raw ?? '').trim();
|
|
25
|
+
if (!id || seen.has(id))
|
|
26
|
+
continue;
|
|
27
|
+
seen.add(id);
|
|
28
|
+
result.push(id);
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
/** 逗号拼接为后端 EsbBatchIDsVO.ids 的字符串格式 */
|
|
33
|
+
export function joinIds(ids) {
|
|
34
|
+
return ids.join(',');
|
|
35
|
+
}
|
|
36
|
+
/** 分页查询连接器(连接系统)列表,返回后端 WeaTable 原始结构 */
|
|
37
|
+
export async function listConnectors(client, query = {}) {
|
|
38
|
+
const params = new URLSearchParams();
|
|
39
|
+
params.set('current', String(query.current ?? 1));
|
|
40
|
+
params.set('pageSize', String(query.pageSize ?? 10));
|
|
41
|
+
if (query.name)
|
|
42
|
+
params.set('name', query.name);
|
|
43
|
+
params.set('showDefalt', String(query.showDefalt ?? true));
|
|
44
|
+
return client.get(`${client.getBaseUrl()}${SYSTEM_POOL_PAGE_PATH}?${params.toString()}`);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 批量封存连接器(级联子系统由后端处理)。
|
|
48
|
+
* 空列表直接抛错——发一个 `ids: ""` 的请求等于什么都没封,还制造一条成功假象。
|
|
49
|
+
*/
|
|
50
|
+
export async function lockConnectors(client, ids) {
|
|
51
|
+
return toggleLock(client, ids, true);
|
|
52
|
+
}
|
|
53
|
+
/** 批量解封连接器 */
|
|
54
|
+
export async function unlockConnectors(client, ids) {
|
|
55
|
+
return toggleLock(client, ids, false);
|
|
56
|
+
}
|
|
57
|
+
async function toggleLock(client, ids, lock) {
|
|
58
|
+
const normalized = normalizeIds(ids);
|
|
59
|
+
if (normalized.length === 0) {
|
|
60
|
+
throw new Error(`ids 必填且不能为空:${lock ? '封存' : '解封'}至少需要一个连接器 id`);
|
|
61
|
+
}
|
|
62
|
+
return client.post(`${client.getBaseUrl()}${lock ? SYSTEM_POOL_LOCK_PATH : SYSTEM_POOL_UNLOCK_PATH}`, { ids: joinIds(normalized) });
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 按名称解析连接器 id:先按 name 精确匹配,唯一命中直接返回;
|
|
66
|
+
* 多个或零个命中时改用「id 直接就是数字」的兜底(调用方通常也允许直接传 id)。
|
|
67
|
+
* 返回 { matched: 命中的 displayData 项 },调用方据此决定是否继续。
|
|
68
|
+
*/
|
|
69
|
+
export async function findConnectorsByName(client, name) {
|
|
70
|
+
const keyword = name.trim();
|
|
71
|
+
if (!keyword)
|
|
72
|
+
return [];
|
|
73
|
+
const res = await listConnectors(client, { name: keyword, current: 1, pageSize: 50 });
|
|
74
|
+
const table = res?.data ?? res ?? {};
|
|
75
|
+
const rows = Array.isArray(table.displayData) ? table.displayData : [];
|
|
76
|
+
const exact = rows.filter((row) => String(row?.name ?? '').trim() === keyword);
|
|
77
|
+
return exact.length > 0 ? exact : rows;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=connector-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-lock.js","sourceRoot":"","sources":["../../../src/services/esb-interface/connector-lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ApiClient } from '../../core/client.js';
|
|
2
|
+
/** 编辑 / 列表路径共用同一常量,禁止各写一份 */
|
|
3
|
+
export declare const SYSTEM_POOL_UPDATE_PATH = "/api/bs/esb/setting/systemPool/updateById";
|
|
4
|
+
export type ConnectorUpdateClient = Pick<ApiClient, 'post' | 'getBaseUrl'>;
|
|
5
|
+
/** 允许通过编辑接口提交的字段(白名单),与前端编辑表单对齐 */
|
|
6
|
+
export declare const CONNECTOR_EDITABLE_FIELDS: readonly ["name", "company", "website", "product", "productWebsite", "edition", "description", "icon", "connectorType"];
|
|
7
|
+
export type ConnectorEditableField = (typeof CONNECTOR_EDITABLE_FIELDS)[number];
|
|
8
|
+
export interface ConnectorUpdateInput {
|
|
9
|
+
/** 连接器 id,必填 */
|
|
10
|
+
id: string | number;
|
|
11
|
+
name?: string;
|
|
12
|
+
company?: string;
|
|
13
|
+
website?: string;
|
|
14
|
+
product?: string;
|
|
15
|
+
productWebsite?: string;
|
|
16
|
+
edition?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
icon?: string;
|
|
19
|
+
connectorType?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 组装 updateById 请求体的纯函数(可单测):
|
|
23
|
+
* - id 必填且不能为空白
|
|
24
|
+
* - 至少带一个可编辑字段(否则等于空更新,制造成功假象)
|
|
25
|
+
* - name 若提供则不能为空白(前端表单必填,后端多语言同步也依赖它)
|
|
26
|
+
* - 丢弃白名单之外的字段,避免把临时/展示字段发上去
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildUpdatePayload(input: ConnectorUpdateInput): {
|
|
29
|
+
id: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
};
|
|
32
|
+
/** 编辑连接器信息(对应后端 updateById,单条操作) */
|
|
33
|
+
export declare function updateConnector(client: ConnectorUpdateClient, input: ConnectorUpdateInput): Promise<any>;
|
|
34
|
+
//# sourceMappingURL=connector-update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-update.d.ts","sourceRoot":"","sources":["../../../src/services/esb-interface/connector-update.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AActD,6BAA6B;AAC7B,eAAO,MAAM,uBAAuB,8CAAmC,CAAC;AAExE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC;AAE3E,mCAAmC;AACnC,eAAO,MAAM,yBAAyB,yHAU5B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,MAAM,WAAW,oBAAoB;IACnC,gBAAgB;IAChB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,oBAAoB,GAC1B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAmBxC;AAED,oCAAoC;AACpC,wBAAsB,eAAe,CACnC,MAAM,EAAE,qBAAqB,EAC7B,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,GAAG,CAAC,CAMd"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 连接器(连接系统 systemPool)信息编辑。
|
|
3
|
+
*
|
|
4
|
+
* 对齐后端 EsbSytemPoolController(weaver-esb-setting):
|
|
5
|
+
* - POST /api/bs/esb/setting/systemPool/updateById
|
|
6
|
+
* 请求体为 EsbSystemPoolEntity JSON(id 必填,**不是** EsbBatchIDsVO)。
|
|
7
|
+
* 后端逐条校验存在性与编辑权限;name/company/product/description 会同步多语言默认值;
|
|
8
|
+
* categoryBrowser[0] 会覆盖 category(为空时后端默认 99999);parentId 沿用原值,改不了。
|
|
9
|
+
*/
|
|
10
|
+
const SYSTEM_POOL_BASE = '/api/bs/esb/setting/systemPool';
|
|
11
|
+
/** 编辑 / 列表路径共用同一常量,禁止各写一份 */
|
|
12
|
+
export const SYSTEM_POOL_UPDATE_PATH = `${SYSTEM_POOL_BASE}/updateById`;
|
|
13
|
+
/** 允许通过编辑接口提交的字段(白名单),与前端编辑表单对齐 */
|
|
14
|
+
export const CONNECTOR_EDITABLE_FIELDS = [
|
|
15
|
+
'name',
|
|
16
|
+
'company',
|
|
17
|
+
'website',
|
|
18
|
+
'product',
|
|
19
|
+
'productWebsite',
|
|
20
|
+
'edition',
|
|
21
|
+
'description',
|
|
22
|
+
'icon',
|
|
23
|
+
'connectorType',
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* 组装 updateById 请求体的纯函数(可单测):
|
|
27
|
+
* - id 必填且不能为空白
|
|
28
|
+
* - 至少带一个可编辑字段(否则等于空更新,制造成功假象)
|
|
29
|
+
* - name 若提供则不能为空白(前端表单必填,后端多语言同步也依赖它)
|
|
30
|
+
* - 丢弃白名单之外的字段,避免把临时/展示字段发上去
|
|
31
|
+
*/
|
|
32
|
+
export function buildUpdatePayload(input) {
|
|
33
|
+
const id = String(input?.id ?? '').trim();
|
|
34
|
+
if (!id)
|
|
35
|
+
throw new Error('id 必填且不能为空');
|
|
36
|
+
const payload = { id };
|
|
37
|
+
let fieldCount = 0;
|
|
38
|
+
for (const field of CONNECTOR_EDITABLE_FIELDS) {
|
|
39
|
+
const value = input[field];
|
|
40
|
+
if (value === undefined || value === null)
|
|
41
|
+
continue;
|
|
42
|
+
if (typeof value === 'string' && !value.trim()) {
|
|
43
|
+
throw new Error(`字段 ${field} 不能为空白字符串(不修改就不要传)`);
|
|
44
|
+
}
|
|
45
|
+
payload[field] = value;
|
|
46
|
+
fieldCount++;
|
|
47
|
+
}
|
|
48
|
+
if (fieldCount === 0) {
|
|
49
|
+
throw new Error(`至少需要提供一个要修改的字段(${CONNECTOR_EDITABLE_FIELDS.join('/')})`);
|
|
50
|
+
}
|
|
51
|
+
return payload;
|
|
52
|
+
}
|
|
53
|
+
/** 编辑连接器信息(对应后端 updateById,单条操作) */
|
|
54
|
+
export async function updateConnector(client, input) {
|
|
55
|
+
const payload = buildUpdatePayload(input);
|
|
56
|
+
return client.post(`${client.getBaseUrl()}${SYSTEM_POOL_UPDATE_PATH}`, payload);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=connector-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-update.js","sourceRoot":"","sources":["../../../src/services/esb-interface/connector-update.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,MAAM,gBAAgB,GAAG,gCAAgC,CAAC;AAE1D,6BAA6B;AAC7B,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,gBAAgB,aAAa,CAAC;AAIxE,mCAAmC;AACnC,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,MAAM;IACN,SAAS;IACT,SAAS;IACT,SAAS;IACT,gBAAgB;IAChB,SAAS;IACT,aAAa;IACb,MAAM;IACN,eAAe;CACP,CAAC;AAkBX;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAA2B;IAE3B,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;IAEvC,MAAM,OAAO,GAA4B,EAAE,EAAE,EAAE,CAAC;IAChD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,MAAM,KAAK,IAAI,yBAAyB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAI,KAA4C,CAAC,KAAK,CAAC,CAAC;QACnE,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,oBAAoB,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;QACvB,UAAU,EAAE,CAAC;IACf,CAAC;IACD,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,kBAAkB,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,OAAiD,CAAC;AAC3D,CAAC;AAED,oCAAoC;AACpC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA6B,EAC7B,KAA2B;IAE3B,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,IAAI,CAChB,GAAG,MAAM,CAAC,UAAU,EAAE,GAAG,uBAAuB,EAAE,EAClD,OAAO,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ApiClient } from '../core/client.js';
|
|
2
|
-
type Client = Pick<ApiClient, 'get' | 'post'
|
|
2
|
+
type Client = Pick<ApiClient, 'get' | 'post'> & Partial<Pick<ApiClient, 'postForm'>>;
|
|
3
3
|
export declare const ASSOCIATION_BASE = "/api/bs/ebuilder/form/association";
|
|
4
4
|
export interface AssociationMapping {
|
|
5
5
|
targetField: string;
|
|
@@ -15,7 +15,17 @@ export interface AssociationOptions {
|
|
|
15
15
|
mappings?: AssociationMapping[];
|
|
16
16
|
permissions?: any[];
|
|
17
17
|
action?: string;
|
|
18
|
+
order?: number;
|
|
19
|
+
selected?: boolean;
|
|
20
|
+
group?: string | null;
|
|
18
21
|
}
|
|
22
|
+
/** 分组名称支持多语言对象;命令行统一取可读文本。 */
|
|
23
|
+
export declare function groupNameText(value: unknown): string;
|
|
24
|
+
/** 校验 0~100 的安全级别范围。 */
|
|
25
|
+
export declare function parseSeclevel(range: string): {
|
|
26
|
+
minShowlevel: string;
|
|
27
|
+
maxShowlevel: string;
|
|
28
|
+
};
|
|
19
29
|
export declare function associationLayouts(values: string[]): string;
|
|
20
30
|
export declare function associationTerminals(values: string[]): string[];
|
|
21
31
|
/** 详情返回明文条件,所有写操作均需压缩;不能因只改布局而损坏原权限条件。 */
|
|
@@ -80,6 +90,23 @@ export declare class AssociationService {
|
|
|
80
90
|
target: any[];
|
|
81
91
|
}>;
|
|
82
92
|
private mapped;
|
|
93
|
+
listGroups(): Promise<any[]>;
|
|
94
|
+
private findGroupIndex;
|
|
95
|
+
resolveGroup(selector: string): Promise<any | null>;
|
|
96
|
+
private saveGroups;
|
|
97
|
+
addGroup(name: string, order?: number): Promise<any>;
|
|
98
|
+
updateGroup(selector: string, patch: {
|
|
99
|
+
name?: string;
|
|
100
|
+
order?: number;
|
|
101
|
+
}): Promise<any>;
|
|
102
|
+
deleteGroup(selector: string): Promise<any>;
|
|
103
|
+
/** 按给定 ID 顺序重排全部页签(updateOrderV2 会把顺序写成 1..N)。 */
|
|
104
|
+
reorder(ids: string[]): Promise<any>;
|
|
105
|
+
/** 修改单条权限的安全级别(读整行 → 改 levelScope → saveOrUpdate → 回读)。 */
|
|
106
|
+
setSecurityLevel(id: string, permSelector: string, scope: {
|
|
107
|
+
minShowlevel: string;
|
|
108
|
+
maxShowlevel: string;
|
|
109
|
+
}): Promise<any>;
|
|
83
110
|
create(options: AssociationOptions): Promise<any>;
|
|
84
111
|
update(id: string, options: AssociationOptions): Promise<any>;
|
|
85
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-association.d.ts","sourceRoot":"","sources":["../../src/services/form-association.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGnD,KAAK,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"form-association.d.ts","sourceRoot":"","sources":["../../src/services/form-association.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { randomInt } from 'node:crypto';
|
|
2
2
|
import { lzwCompress } from '../core/lzw.js';
|
|
3
3
|
export const ASSOCIATION_BASE = '/api/bs/ebuilder/form/association';
|
|
4
|
+
/** 分组名称支持多语言对象;命令行统一取可读文本。 */
|
|
5
|
+
export function groupNameText(value) {
|
|
6
|
+
if (typeof value === 'string')
|
|
7
|
+
return value;
|
|
8
|
+
if (value && typeof value === 'object') {
|
|
9
|
+
const record = value;
|
|
10
|
+
for (const key of ['name', 'zh', 'cn', 'default', 'nameAlias']) {
|
|
11
|
+
if (typeof record[key] === 'string' && record[key])
|
|
12
|
+
return String(record[key]);
|
|
13
|
+
}
|
|
14
|
+
return JSON.stringify(value);
|
|
15
|
+
}
|
|
16
|
+
return value === undefined || value === null ? '' : String(value);
|
|
17
|
+
}
|
|
18
|
+
/** 校验 0~100 的安全级别范围。 */
|
|
19
|
+
export function parseSeclevel(range) {
|
|
20
|
+
const match = /^(\d{1,3})\s*-\s*(\d{1,3})$/.exec(String(range).trim());
|
|
21
|
+
if (!match)
|
|
22
|
+
throw new Error('--seclevel 格式应为 min-max,如 30-100');
|
|
23
|
+
const min = Number(match[1]);
|
|
24
|
+
const max = Number(match[2]);
|
|
25
|
+
if (min > max)
|
|
26
|
+
throw new Error('--seclevel 最小值不能大于最大值');
|
|
27
|
+
if (min < 0 || max > 100)
|
|
28
|
+
throw new Error('--seclevel 范围须在 0~100');
|
|
29
|
+
return { minShowlevel: String(min), maxShowlevel: String(max) };
|
|
30
|
+
}
|
|
31
|
+
function groupIdOf(group) {
|
|
32
|
+
if (group === undefined || group === null)
|
|
33
|
+
return '';
|
|
34
|
+
const id = typeof group === 'object' ? group.id : group;
|
|
35
|
+
return id === undefined || id === null || String(id) === '0' ? '' : String(id);
|
|
36
|
+
}
|
|
4
37
|
function data(response, operation) {
|
|
5
38
|
if (response?.code !== 200 || response?.status === false || response?.fail === true || response?.data == null)
|
|
6
39
|
throw new Error(`${operation}失败: ${response?.msg || '返回数据无效'}`);
|
|
@@ -312,6 +345,168 @@ export class AssociationService {
|
|
|
312
345
|
const fields = await this.fields(view);
|
|
313
346
|
return buildAssociationMappings(mappings, fields.source, fields.target);
|
|
314
347
|
}
|
|
348
|
+
// ── 分组 ──────────────────────────────────────────────
|
|
349
|
+
async listGroups() {
|
|
350
|
+
const result = data(await this.client.get(`${this.base}${ASSOCIATION_BASE}/getAssociationGroupList/${this.objId}?apid=${this.appId}`, this.headers()), '读取关联分组');
|
|
351
|
+
if (!Array.isArray(result))
|
|
352
|
+
throw new Error('关联分组接口返回结构无效');
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
findGroupIndex(groups, selector) {
|
|
356
|
+
const key = String(selector ?? '').trim();
|
|
357
|
+
if (!key)
|
|
358
|
+
throw new Error('请指定分组 ID 或名称');
|
|
359
|
+
const byId = groups.findIndex(g => String(g.id) === key);
|
|
360
|
+
if (byId >= 0)
|
|
361
|
+
return byId;
|
|
362
|
+
const byName = groups.filter(g => groupNameText(g.groupName) === key);
|
|
363
|
+
if (byName.length === 1)
|
|
364
|
+
return groups.findIndex(g => groupNameText(g.groupName) === key);
|
|
365
|
+
if (byName.length > 1)
|
|
366
|
+
throw new Error(`分组名称「${key}」有 ${byName.length} 条,请改用分组 ID`);
|
|
367
|
+
const existing = groups.map(g => `${groupNameText(g.groupName) || '(未命名)'}(${g.id})`).join('、');
|
|
368
|
+
throw new Error(`没有 ID 或名称匹配「${key}」的关联分组${existing ? `。现有:${existing}` : ''}`);
|
|
369
|
+
}
|
|
370
|
+
async resolveGroup(selector) {
|
|
371
|
+
if (selector === null || ['none', '无', '0', ''].includes(String(selector).trim()))
|
|
372
|
+
return null;
|
|
373
|
+
const groups = await this.listGroups();
|
|
374
|
+
return groups[this.findGroupIndex(groups, selector)];
|
|
375
|
+
}
|
|
376
|
+
async saveGroups(groups) {
|
|
377
|
+
const payload = groups.map(g => ({
|
|
378
|
+
id: g.id === undefined || g.id === null ? '' : String(g.id),
|
|
379
|
+
groupName: g.groupName,
|
|
380
|
+
}));
|
|
381
|
+
if (!this.client.postForm)
|
|
382
|
+
throw new Error('当前客户端不支持表单提交,无法保存关联分组');
|
|
383
|
+
const query = new URLSearchParams({ apid: this.appId, tpaid: this.objId }).toString();
|
|
384
|
+
const form = new URLSearchParams({ objId: this.objId, groups: JSON.stringify(payload) }).toString();
|
|
385
|
+
const response = await this.client.postForm(`${this.base}${ASSOCIATION_BASE}/save?${query}`, form, this.headers());
|
|
386
|
+
if (response?.code !== 200 || response?.status === false || response?.fail === true) {
|
|
387
|
+
throw new Error(`保存关联分组失败: ${response?.msg || '返回数据无效'}`);
|
|
388
|
+
}
|
|
389
|
+
return this.listGroups();
|
|
390
|
+
}
|
|
391
|
+
async addGroup(name, order) {
|
|
392
|
+
const groupName = String(name ?? '').trim();
|
|
393
|
+
if (!groupName)
|
|
394
|
+
throw new Error('分组名称不能为空');
|
|
395
|
+
const groups = await this.listGroups();
|
|
396
|
+
if (groups.some(g => groupNameText(g.groupName) === groupName))
|
|
397
|
+
throw new Error(`分组「${groupName}」已存在`);
|
|
398
|
+
const index = order === undefined ? groups.length : order - 1;
|
|
399
|
+
if (!Number.isInteger(index) || index < 0 || index > groups.length) {
|
|
400
|
+
throw new Error(`--order 需在 1~${groups.length + 1}(当前分组数 ${groups.length})`);
|
|
401
|
+
}
|
|
402
|
+
const next = [...groups];
|
|
403
|
+
next.splice(index, 0, { id: '', groupName });
|
|
404
|
+
const after = await this.saveGroups(next);
|
|
405
|
+
const created = after.filter(g => groupNameText(g.groupName) === groupName);
|
|
406
|
+
if (created.length !== 1)
|
|
407
|
+
throw new Error('分组保存后回读不到唯一的新分组');
|
|
408
|
+
return { success: true, verified: true, group: created[0], groups: after };
|
|
409
|
+
}
|
|
410
|
+
async updateGroup(selector, patch) {
|
|
411
|
+
if (patch.name === undefined && patch.order === undefined)
|
|
412
|
+
throw new Error('请至少指定 --name 或 --order');
|
|
413
|
+
const groups = await this.listGroups();
|
|
414
|
+
const index = this.findGroupIndex(groups, selector);
|
|
415
|
+
const current = groups[index];
|
|
416
|
+
const group = { ...current };
|
|
417
|
+
if (patch.name !== undefined) {
|
|
418
|
+
const name = String(patch.name).trim();
|
|
419
|
+
if (!name)
|
|
420
|
+
throw new Error('分组名称不能为空');
|
|
421
|
+
if (groups.some((g, i) => i !== index && groupNameText(g.groupName) === name)) {
|
|
422
|
+
throw new Error(`分组「${name}」已存在`);
|
|
423
|
+
}
|
|
424
|
+
group.groupName = name;
|
|
425
|
+
}
|
|
426
|
+
let next = groups.map((g, i) => (i === index ? group : g));
|
|
427
|
+
if (patch.order !== undefined) {
|
|
428
|
+
if (!Number.isInteger(patch.order) || patch.order < 1 || patch.order > groups.length) {
|
|
429
|
+
throw new Error(`--order 需在 1~${groups.length}`);
|
|
430
|
+
}
|
|
431
|
+
next = next.filter((_, i) => i !== index);
|
|
432
|
+
next.splice(patch.order - 1, 0, group);
|
|
433
|
+
}
|
|
434
|
+
const after = await this.saveGroups(next);
|
|
435
|
+
const saved = after.find(g => String(g.id) === String(current.id));
|
|
436
|
+
if (!saved)
|
|
437
|
+
throw new Error('分组保存后回读不到目标分组');
|
|
438
|
+
if (patch.name !== undefined && groupNameText(saved.groupName) !== String(patch.name).trim()) {
|
|
439
|
+
throw new Error('分组名称回读不一致');
|
|
440
|
+
}
|
|
441
|
+
return { success: true, verified: true, group: saved, groups: after };
|
|
442
|
+
}
|
|
443
|
+
async deleteGroup(selector) {
|
|
444
|
+
const groups = await this.listGroups();
|
|
445
|
+
const index = this.findGroupIndex(groups, selector);
|
|
446
|
+
const target = groups[index];
|
|
447
|
+
const after = await this.saveGroups(groups.filter((_, i) => i !== index));
|
|
448
|
+
if (after.some(g => String(g.id) === String(target.id)))
|
|
449
|
+
throw new Error(`分组 ${target.id} 仍在列表里,删除未生效`);
|
|
450
|
+
return { success: true, verified: true, groupId: String(target.id), groupName: groupNameText(target.groupName), groups: after };
|
|
451
|
+
}
|
|
452
|
+
/** 按给定 ID 顺序重排全部页签(updateOrderV2 会把顺序写成 1..N)。 */
|
|
453
|
+
async reorder(ids) {
|
|
454
|
+
const unique = ids.map(String).filter(Boolean);
|
|
455
|
+
if (!unique.length)
|
|
456
|
+
throw new Error('至少指定一个关联页签 ID');
|
|
457
|
+
if (new Set(unique).size !== unique.length)
|
|
458
|
+
throw new Error('关联页签 ID 不能重复');
|
|
459
|
+
const before = await this.list();
|
|
460
|
+
const known = new Set(before.map(a => String(a.id)));
|
|
461
|
+
const missing = unique.filter(id => !known.has(id));
|
|
462
|
+
if (missing.length)
|
|
463
|
+
throw new Error(`以下关联页签不属于本表单: ${missing.join(', ')}`);
|
|
464
|
+
const uncovered = before.map(a => String(a.id)).filter(id => !unique.includes(id));
|
|
465
|
+
if (uncovered.length)
|
|
466
|
+
throw new Error(`排序必须给出全部页签 ID,缺少: ${uncovered.join(', ')}`);
|
|
467
|
+
const response = await this.client.post(`${this.base}${ASSOCIATION_BASE}/updateOrderV2?apid=${this.appId}`, { orderIds: unique }, this.headers());
|
|
468
|
+
if (response?.code !== 200 || response?.status === false || response?.fail === true) {
|
|
469
|
+
throw new Error(`保存关联排序失败: ${response?.msg || '返回数据无效'}`);
|
|
470
|
+
}
|
|
471
|
+
const after = await this.list();
|
|
472
|
+
const sorted = [...after].sort((a, b) => Number(a.order) - Number(b.order));
|
|
473
|
+
const got = sorted.map(a => String(a.id));
|
|
474
|
+
if (got.join(',') !== unique.join(',')) {
|
|
475
|
+
throw new Error(`排序已提交,但回读顺序不一致 —— 期望 ${unique.join(',')},回读 ${got.join(',')}`);
|
|
476
|
+
}
|
|
477
|
+
return { success: true, verified: true, orderIds: unique };
|
|
478
|
+
}
|
|
479
|
+
/** 修改单条权限的安全级别(读整行 → 改 levelScope → saveOrUpdate → 回读)。 */
|
|
480
|
+
async setSecurityLevel(id, permSelector, scope) {
|
|
481
|
+
const draft = structuredClone(await this.get(id));
|
|
482
|
+
const perms = draft.associationPermissions || [];
|
|
483
|
+
if (!perms.length)
|
|
484
|
+
throw new Error('该关联无权限条目');
|
|
485
|
+
let index;
|
|
486
|
+
if (/^\d+$/.test(permSelector)) {
|
|
487
|
+
index = Number(permSelector) - 1;
|
|
488
|
+
if (index < 0 || index >= perms.length)
|
|
489
|
+
throw new Error(`--perm 序号 ${permSelector} 越界(共 ${perms.length} 条权限)`);
|
|
490
|
+
}
|
|
491
|
+
else {
|
|
492
|
+
index = perms.findIndex(p => p.selectedType === permSelector);
|
|
493
|
+
if (index < 0)
|
|
494
|
+
throw new Error(`未找到 selectedType="${permSelector}" 的权限`);
|
|
495
|
+
}
|
|
496
|
+
draft.associationPermissions = perms.map((p, i) => i === index
|
|
497
|
+
? { ...p, levelScope: { ...(p.levelScope || {}), ...scope } }
|
|
498
|
+
: p);
|
|
499
|
+
data(await this.client.post(`${this.base}${ASSOCIATION_BASE}/saveOrUpdate?${this.query()}`, serializeAssociation(draft), this.headers()), '更新权限安全级别');
|
|
500
|
+
const after = await this.get(id);
|
|
501
|
+
const saved = after.associationPermissions?.[index];
|
|
502
|
+
if (!saved)
|
|
503
|
+
throw new Error('已提交,但回读不到目标权限');
|
|
504
|
+
if (String(saved.levelScope?.minShowlevel ?? '') !== scope.minShowlevel
|
|
505
|
+
|| String(saved.levelScope?.maxShowlevel ?? '') !== scope.maxShowlevel) {
|
|
506
|
+
throw new Error('权限安全级别回读不一致');
|
|
507
|
+
}
|
|
508
|
+
return { success: true, verified: true, permIndex: index + 1, selectedType: saved.selectedType, levelScope: saved.levelScope };
|
|
509
|
+
}
|
|
315
510
|
async create(options) {
|
|
316
511
|
if (!options.name?.trim() || !options.view)
|
|
317
512
|
throw new Error('创建需指定页签名称和目标视图');
|
|
@@ -320,15 +515,22 @@ export class AssociationService {
|
|
|
320
515
|
const before = await this.list();
|
|
321
516
|
if (before.some(a => a.pageName === options.name))
|
|
322
517
|
throw new Error('同名页签已存在,请按 ID 修改,避免重复创建');
|
|
518
|
+
if (options.order !== undefined && (!Number.isInteger(options.order) || options.order < 1)) {
|
|
519
|
+
throw new Error('--order 需为 1 或正整数');
|
|
520
|
+
}
|
|
521
|
+
const group = options.group !== undefined ? await this.resolveGroup(options.group ?? 'none') : undefined;
|
|
323
522
|
const view = await this.resolveView(options.view, options.targetApp);
|
|
324
523
|
const link = { openMode: '1', name: view.name, autoFillParams: true,
|
|
325
524
|
icon: { path: '#icon-eBuilder-o', style: { color: '#5d9cec', fillType: 'borderColor', borderColor: '#5d9cec' } },
|
|
326
525
|
page: { pageId: view.id, parentId: `Form_${view.objId}`, openMode: '1', pageName: view.name, pageType: 'VIEWPORT', appid: view.appId, pageViewType: view.viewType, dsDataset: {} },
|
|
327
526
|
params: await this.mapped(options.mappings || [], view) };
|
|
328
527
|
const draft = {
|
|
329
|
-
objId: this.objId, pageName: options.name, open: options.enabled ?? true,
|
|
528
|
+
objId: this.objId, pageName: options.name, open: options.enabled ?? true,
|
|
529
|
+
selected: options.selected ?? false, confirm: options.selected ? 1 : 0,
|
|
330
530
|
showLayout: associationLayouts(options.layouts || ['显示']), applicable: associationTerminals(options.terminals || ['PC', 'MOBILE']),
|
|
331
531
|
associationPermissions: options.permissions, customTips: { tipsSql: '', tipsCustomApi: '' },
|
|
532
|
+
...(options.order !== undefined ? { order: options.order } : {}),
|
|
533
|
+
...(options.group !== undefined ? { group: group ? { id: String(group.id) } : null } : {}),
|
|
332
534
|
associationActions: [{ name: view.name, conditionTxt: '', id: `-${Date.now()}${randomInt(1000)}`, enable: 1,
|
|
333
535
|
actionType: 'openpage', buttonId: '', windowSize: 30, executeSelectedDatas: 0, url: JSON.stringify(link), openType: '1', index: 0,
|
|
334
536
|
interfacePath: '', desc: '', urlType: '0', urlFieldId: '', interfaceType: '', confirmTitle: '', ecode: '', littlecardName: '自定义小卡片', littlecardJson: '',
|
|
@@ -366,6 +568,26 @@ export class AssociationService {
|
|
|
366
568
|
draft.showLayout = associationLayouts(options.layouts);
|
|
367
569
|
if (options.terminals)
|
|
368
570
|
draft.applicable = associationTerminals(options.terminals);
|
|
571
|
+
if (options.order !== undefined) {
|
|
572
|
+
if (!Number.isInteger(options.order) || options.order < 1)
|
|
573
|
+
throw new Error('--order 需为 1 或正整数');
|
|
574
|
+
draft.order = options.order;
|
|
575
|
+
}
|
|
576
|
+
if (options.selected !== undefined) {
|
|
577
|
+
draft.selected = options.selected;
|
|
578
|
+
// confirm=1 时平台会先把本表单其它页签全部置为未选中,再保存本页签。
|
|
579
|
+
draft.confirm = options.selected ? 1 : 0;
|
|
580
|
+
}
|
|
581
|
+
if (options.permissions !== undefined) {
|
|
582
|
+
if (!Array.isArray(options.permissions) || !options.permissions.length) {
|
|
583
|
+
throw new Error('--permissions 需为非空数组(整组替换;清空权限请勿用此参数)');
|
|
584
|
+
}
|
|
585
|
+
draft.associationPermissions = options.permissions;
|
|
586
|
+
}
|
|
587
|
+
if (options.group !== undefined) {
|
|
588
|
+
const group = await this.resolveGroup(options.group ?? 'none');
|
|
589
|
+
draft.group = group ? { id: String(group.id) } : null;
|
|
590
|
+
}
|
|
369
591
|
const enabled = options.enabled;
|
|
370
592
|
if (options.targetApp && !options.view)
|
|
371
593
|
throw new Error('--target-app 必须同时指定 --view');
|
|
@@ -401,8 +623,13 @@ export function verifyAssociation(expected, actual) {
|
|
|
401
623
|
const canonical = (value) => JSON.stringify(value, (_key, v) => v && typeof v === 'object' && !Array.isArray(v) ? Object.fromEntries(Object.keys(v).sort().map(k => [k, v[k]])) : v);
|
|
402
624
|
const equal = (a, b, label) => { if (canonical(a) !== canonical(b))
|
|
403
625
|
throw new Error(`已保存,但 ${label} 回读不一致`); };
|
|
404
|
-
|
|
626
|
+
// confirm 只是本次请求的“重置其它页签选中状态”信号,平台不持久化;不要拿它做回读断言。
|
|
627
|
+
for (const key of ['objId', 'pageName', 'open', 'selected'])
|
|
405
628
|
equal(expected[key], actual[key], key);
|
|
629
|
+
if (expected.order !== undefined)
|
|
630
|
+
equal(Number(expected.order), Number(actual.order), 'order');
|
|
631
|
+
if (expected.group !== undefined)
|
|
632
|
+
equal(groupIdOf(expected.group), groupIdOf(actual.group), '分组');
|
|
406
633
|
equal(String(expected.showLayout || '').split(',').sort(), String(actual.showLayout || '').split(',').sort(), '布局');
|
|
407
634
|
equal([...(expected.applicable || [])].sort(), [...(actual.applicable || [])].sort(), '适用终端');
|
|
408
635
|
equal(expected.associationActions.length, actual.associationActions?.length, '动作数量');
|
|
@@ -420,6 +647,9 @@ export function verifyAssociation(expected, actual) {
|
|
|
420
647
|
const after = actual.associationPermissions[i];
|
|
421
648
|
for (const key of ['selectedType', 'dataid'])
|
|
422
649
|
equal(permission[key], after[key], `权限 ${key}`);
|
|
650
|
+
if (permission.levelScope !== undefined) {
|
|
651
|
+
equal([String(permission.levelScope?.minShowlevel ?? ''), String(permission.levelScope?.maxShowlevel ?? '')], [String(after.levelScope?.minShowlevel ?? ''), String(after.levelScope?.maxShowlevel ?? '')], '权限安全级别');
|
|
652
|
+
}
|
|
423
653
|
const root = (p) => p.condition?.rootdata ? JSON.parse(p.condition.rootdata) : null;
|
|
424
654
|
equal(root(permission), root(after), '原权限条件');
|
|
425
655
|
});
|