weaver-e10-builder 1.6.13 → 1.6.15
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/cli-register.d.ts.map +1 -1
- package/dist/cli-register.js +14 -2
- package/dist/cli-register.js.map +1 -1
- package/dist/commands/actionflow.d.ts.map +1 -1
- package/dist/commands/actionflow.js +4 -0
- package/dist/commands/actionflow.js.map +1 -1
- package/dist/commands/designer-event.d.ts +3 -0
- package/dist/commands/designer-event.d.ts.map +1 -0
- package/dist/commands/designer-event.js +106 -0
- package/dist/commands/designer-event.js.map +1 -0
- package/dist/commands/designer-source.d.ts +3 -0
- package/dist/commands/designer-source.d.ts.map +1 -0
- package/dist/commands/designer-source.js +51 -0
- package/dist/commands/designer-source.js.map +1 -0
- package/dist/commands/form-browser-scope-rules.d.ts +2 -1
- package/dist/commands/form-browser-scope-rules.d.ts.map +1 -1
- package/dist/commands/form-browser-scope-rules.js +8 -4
- package/dist/commands/form-browser-scope-rules.js.map +1 -1
- package/dist/commands/form-browser-scope-tree.js +1 -1
- package/dist/commands/form-browser-scope-tree.js.map +1 -1
- package/dist/commands/form-field-linkage.d.ts.map +1 -1
- package/dist/commands/form-field-linkage.js +6 -11
- package/dist/commands/form-field-linkage.js.map +1 -1
- package/dist/commands/form-layout-detail-settings.d.ts +3 -0
- package/dist/commands/form-layout-detail-settings.d.ts.map +1 -0
- package/dist/commands/form-layout-detail-settings.js +36 -0
- package/dist/commands/form-layout-detail-settings.js.map +1 -0
- package/dist/commands/form-list-columns.d.ts.map +1 -1
- package/dist/commands/form-list-columns.js +178 -5
- package/dist/commands/form-list-columns.js.map +1 -1
- package/dist/commands/form-list-config.d.ts.map +1 -1
- package/dist/commands/form-list-config.js +81 -5
- package/dist/commands/form-list-config.js.map +1 -1
- package/dist/commands/form-list-event.d.ts.map +1 -1
- package/dist/commands/form-list-event.js +2 -1
- package/dist/commands/form-list-event.js.map +1 -1
- package/dist/commands/form-list-hierarchy.d.ts.map +1 -1
- package/dist/commands/form-list-hierarchy.js +2 -1
- package/dist/commands/form-list-hierarchy.js.map +1 -1
- package/dist/commands/form-list-utils.d.ts.map +1 -1
- package/dist/commands/form-list-utils.js +4 -3
- package/dist/commands/form-list-utils.js.map +1 -1
- package/dist/commands/form-list.d.ts.map +1 -1
- package/dist/commands/form-list.js +2 -1
- package/dist/commands/form-list.js.map +1 -1
- package/dist/commands/form-nlist.d.ts.map +1 -1
- package/dist/commands/form-nlist.js +77 -0
- package/dist/commands/form-nlist.js.map +1 -1
- package/dist/commands/form-permission.d.ts.map +1 -1
- package/dist/commands/form-permission.js +743 -77
- package/dist/commands/form-permission.js.map +1 -1
- package/dist/commands/page-combination.d.ts +3 -0
- package/dist/commands/page-combination.d.ts.map +1 -0
- package/dist/commands/page-combination.js +86 -0
- package/dist/commands/page-combination.js.map +1 -0
- package/dist/commands/page-permission.d.ts +3 -0
- package/dist/commands/page-permission.d.ts.map +1 -0
- package/dist/commands/page-permission.js +46 -0
- package/dist/commands/page-permission.js.map +1 -0
- package/dist/commands/role.d.ts.map +1 -1
- package/dist/commands/role.js +3 -2
- package/dist/commands/role.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 +7 -0
- package/dist/services/actionflow/components/action_eb_update.js.map +1 -1
- package/dist/services/actionflow/components/action_eb_update_compiler.js +4 -4
- package/dist/services/actionflow/components/action_eb_update_compiler.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/form_data_builder.d.ts.map +1 -1
- package/dist/services/actionflow/components/form_data_builder.js +131 -4
- package/dist/services/actionflow/components/form_data_builder.js.map +1 -1
- package/dist/services/actionflow/components/multiple_execution.js +7 -7
- package/dist/services/actionflow/components/multiple_execution.js.map +1 -1
- package/dist/services/actionflow/components/output.d.ts.map +1 -1
- package/dist/services/actionflow/components/output.js +4 -1
- package/dist/services/actionflow/components/output.js.map +1 -1
- package/dist/services/actionflow/components/send_message.d.ts.map +1 -1
- package/dist/services/actionflow/components/send_message.js +2 -1
- package/dist/services/actionflow/components/send_message.js.map +1 -1
- package/dist/services/actionflow/context_discovery.d.ts +2 -0
- package/dist/services/actionflow/context_discovery.d.ts.map +1 -1
- package/dist/services/actionflow/context_discovery.js +32 -4
- 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 +33 -5
- 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 +3 -2
- package/dist/services/actionflow/filter_rules.js.map +1 -1
- package/dist/services/actionflow/formula_service.d.ts +2 -0
- package/dist/services/actionflow/formula_service.d.ts.map +1 -1
- package/dist/services/actionflow/formula_service.js +20 -15
- package/dist/services/actionflow/formula_service.js.map +1 -1
- package/dist/services/actionflow/preflight_service.d.ts +8 -0
- package/dist/services/actionflow/preflight_service.d.ts.map +1 -1
- package/dist/services/actionflow/preflight_service.js +89 -15
- 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 +115 -0
- package/dist/services/actionflow/readback_verifier.js.map +1 -1
- package/dist/services/actionflow/workflow_compiler.d.ts +1 -1
- package/dist/services/actionflow/workflow_compiler.d.ts.map +1 -1
- package/dist/services/actionflow/workflow_compiler.js +151 -34
- package/dist/services/actionflow/workflow_compiler.js.map +1 -1
- package/dist/services/designer-event.d.ts +54 -0
- package/dist/services/designer-event.d.ts.map +1 -0
- package/dist/services/designer-event.js +312 -0
- package/dist/services/designer-event.js.map +1 -0
- package/dist/services/designer-source.d.ts +46 -0
- package/dist/services/designer-source.d.ts.map +1 -0
- package/dist/services/designer-source.js +145 -0
- package/dist/services/designer-source.js.map +1 -0
- package/dist/services/field-identity.d.ts +3 -0
- package/dist/services/field-identity.d.ts.map +1 -0
- package/dist/services/field-identity.js +8 -0
- package/dist/services/field-identity.js.map +1 -0
- package/dist/services/form-layout-detail-advanced.d.ts +10 -0
- package/dist/services/form-layout-detail-advanced.d.ts.map +1 -0
- package/dist/services/form-layout-detail-advanced.js +134 -0
- package/dist/services/form-layout-detail-advanced.js.map +1 -0
- package/dist/services/form-layout-detail-settings.d.ts +151 -0
- package/dist/services/form-layout-detail-settings.d.ts.map +1 -0
- package/dist/services/form-layout-detail-settings.js +131 -0
- package/dist/services/form-layout-detail-settings.js.map +1 -0
- package/dist/services/form-list-columns.d.ts.map +1 -1
- package/dist/services/form-list-columns.js +2 -1
- package/dist/services/form-list-columns.js.map +1 -1
- package/dist/services/form-list-config.d.ts +36 -1
- package/dist/services/form-list-config.d.ts.map +1 -1
- package/dist/services/form-list-config.js +252 -23
- package/dist/services/form-list-config.js.map +1 -1
- package/dist/services/form-list-fields.d.ts +3 -1
- package/dist/services/form-list-fields.d.ts.map +1 -1
- package/dist/services/form-list-fields.js +95 -16
- package/dist/services/form-list-fields.js.map +1 -1
- package/dist/services/form-list-search-group.d.ts.map +1 -1
- package/dist/services/form-list-search-group.js +3 -2
- package/dist/services/form-list-search-group.js.map +1 -1
- package/dist/services/form-list-search.d.ts.map +1 -1
- package/dist/services/form-list-search.js +3 -13
- package/dist/services/form-list-search.js.map +1 -1
- package/dist/services/form-list-table-fields.d.ts +58 -0
- package/dist/services/form-list-table-fields.d.ts.map +1 -0
- package/dist/services/form-list-table-fields.js +265 -0
- package/dist/services/form-list-table-fields.js.map +1 -0
- package/dist/services/form-nlist-field-attrs.d.ts +43 -0
- package/dist/services/form-nlist-field-attrs.d.ts.map +1 -0
- package/dist/services/form-nlist-field-attrs.js +170 -0
- package/dist/services/form-nlist-field-attrs.js.map +1 -0
- package/dist/services/form-nlist.d.ts.map +1 -1
- package/dist/services/form-nlist.js +4 -3
- package/dist/services/form-nlist.js.map +1 -1
- package/dist/services/form-permission-edit.d.ts +115 -0
- package/dist/services/form-permission-edit.d.ts.map +1 -0
- package/dist/services/form-permission-edit.js +552 -0
- package/dist/services/form-permission-edit.js.map +1 -0
- package/dist/services/matrix-condition.d.ts +0 -30
- package/dist/services/matrix-condition.d.ts.map +1 -1
- package/dist/services/matrix-condition.js +3 -2
- package/dist/services/matrix-condition.js.map +1 -1
- package/dist/services/page-combination.d.ts +58 -0
- package/dist/services/page-combination.d.ts.map +1 -0
- package/dist/services/page-combination.js +296 -0
- package/dist/services/page-combination.js.map +1 -0
- package/dist/services/page-permission.d.ts +74 -0
- package/dist/services/page-permission.d.ts.map +1 -0
- package/dist/services/page-permission.js +287 -0
- package/dist/services/page-permission.js.map +1 -0
- package/dist/services/report/verify.d.ts.map +1 -1
- package/dist/services/report/verify.js +1 -7
- package/dist/services/report/verify.js.map +1 -1
- package/dist/services/role-function-permission.d.ts +8 -1
- package/dist/services/role-function-permission.d.ts.map +1 -1
- package/dist/services/role-function-permission.js +23 -8
- package/dist/services/role-function-permission.js.map +1 -1
- package/package.json +3 -3
- package/skill-docs/SKILL.md +14 -4
- package/skill-docs/_catalog.md +7 -0
- package/skill-docs/actionflows/SKILL.md +7 -3
- package/skill-docs/actionflows/references/components/ebuilder/ActionEbAdd.md +5 -1
- package/skill-docs/actionflows/references/components/ebuilder/ActionEbUpdate.md +5 -1
- package/skill-docs/actionflows/references/components/ebuilder/EnquiryForm.md +2 -0
- package/skill-docs/actionflows/references/components/personnel/HrmEmployeeUpdate.md +1 -0
- package/skill-docs/actionflows/references/components/personnel/PersonnelOnboarding.md +1 -0
- package/skill-docs/actionflows/references/trigger_runtime_notes.md +1 -1
- package/skill-docs/references/common/ref-cli-commands.md +22 -7
- package/skill-docs/references/ebuilder-designer/events/actions-integration.md +88 -0
- package/skill-docs/references/ebuilder-designer/events/actions-interaction.md +108 -0
- package/skill-docs/references/ebuilder-designer/events/guide-events.md +57 -0
- package/skill-docs/references/ebuilder-designer/guide-designer.md +296 -288
- package/skill-docs/references/ebuilder-designer/guide-page-combination.md +142 -0
- package/skill-docs/references/ebuilder-designer/guide-page-permission.md +145 -0
- package/skill-docs/references/ebuilder-designer/page-source/page-source-guide.md +129 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-chart.md +49 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-coverage.json +372 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-date.md +54 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-dialogs.md +279 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-form.md +255 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-foundations.md +401 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-index.md +34 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-list.md +297 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-native.md +193 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-navigation.md +156 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-other.md +242 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-refresh.md +132 -0
- package/skill-docs/references/ebuilder-designer/page-source/sdk-sql.md +39 -0
- package/skill-docs/references/form/guide-form-permission.md +185 -0
- package/skill-docs/references/form/guide-form-view.md +725 -624
- package/skill-docs/references/form/layout/detail-advanced.md +124 -0
- package/skill-docs/references/form/layout/detail-settings.md +106 -0
- package/skill-docs/references/form/layout/layout-overview.md +2 -0
- package/skill-docs/references/hrm/guide-role.md +4 -4
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
1
2
|
import { AuthSession } from '../core/auth.js';
|
|
2
3
|
import { ApiClient } from '../core/client.js';
|
|
3
4
|
import { resolveFormId } from '../services/form-id.js';
|
|
4
5
|
import { ARCHIVE_ORG_TYPES, ARCHIVE_TARGETS, ARCHIVE_TARGET_ALIASES, FIELD_ORG_TYPE_LABELS, archiveFileRightsIncludeView, archiveRightsIncludeView, archiveRowKey, buildArchiveRow, buildMatrixValueRelation, ebFormValueFields, matrixValueFields, normalizeArchiveRow, parseArchiveFileRights, parseArchiveRights, resolveFieldOrgType, verifyArchiveRow, } from '../services/form-permission-archive.js';
|
|
5
6
|
import { MATRIX_COND_FUNC_HINT, buildMatrixConditionData, ebFormCondColumns, matrixCondColumns, parseMatrixConditionArgs, pickCondFields, } from '../services/matrix-condition.js';
|
|
7
|
+
import { PERMISSION_CODE_TYPES, PERMISSION_ORG_TYPES, PERMISSION_TARGETS, PERMISSION_TARGET_ALIASES, addPermissionRow, applyPermissionSettings, buildPermissionRow, buildSyncPermissionList, findRightRow, matrixValueCandidates, parseOnOff, parsePermissionFileRights, parsePermissionRights, permissionRightLabels, normalizeFileRightType, readPermissionDetail, resolvePermissionEbForm, resolvePermissionField, resolvePermissionMatrix, targetOfCodeType, updatePermissionDetail, verifyAddedRow, } from '../services/form-permission-edit.js';
|
|
6
8
|
import { fetchFields } from './form-list-utils.js';
|
|
7
9
|
/**
|
|
8
10
|
* Form permission management.
|
|
@@ -41,6 +43,7 @@ const RIGHT_TYPES = {
|
|
|
41
43
|
'1': '查看',
|
|
42
44
|
'2': '编辑',
|
|
43
45
|
'3': '删除',
|
|
46
|
+
'4': '评论',
|
|
44
47
|
'5': '归档查看',
|
|
45
48
|
'6': '归档编辑',
|
|
46
49
|
'7': '归档删除',
|
|
@@ -48,11 +51,6 @@ const RIGHT_TYPES = {
|
|
|
48
51
|
'9': '数据导入',
|
|
49
52
|
'93': '删除导入数据',
|
|
50
53
|
};
|
|
51
|
-
const DATA_RIGHT_ALIASES = {
|
|
52
|
-
'1': '1', view: '1', read: '1',
|
|
53
|
-
'2': '2', edit: '2', update: '2',
|
|
54
|
-
'3': '3', delete: '3', remove: '3',
|
|
55
|
-
};
|
|
56
54
|
// 导入导出权限(codeType=data_imp_exp,独立分类——不在共享 dataRightList 里):
|
|
57
55
|
// rightType 8=导出、9=导入(追加)、93=删除导入数据;93 必须与 9 同选(只勾"删除导入数据"平台语义为更新导入的一部分)。
|
|
58
56
|
// importType "0,1":0=追加导入、1=更新导入(勾 93 时须带 1)。
|
|
@@ -61,10 +59,6 @@ const IMP_EXP_RIGHT_ALIASES = {
|
|
|
61
59
|
'9': '9', import: '9',
|
|
62
60
|
'93': '93', 'delete-import': '93', 'del-import': '93',
|
|
63
61
|
};
|
|
64
|
-
const FILE_RIGHT_ALIASES = {
|
|
65
|
-
'401': '401', view: '401', read: '401',
|
|
66
|
-
'402': '402', download: '402',
|
|
67
|
-
};
|
|
68
62
|
function parseRightValues(values, aliases, label) {
|
|
69
63
|
const tokens = values.flatMap((value) => value.split(',')).map((value) => value.trim().toLowerCase()).filter(Boolean);
|
|
70
64
|
const invalid = tokens.filter((value) => !aliases[value]);
|
|
@@ -73,7 +67,112 @@ function parseRightValues(values, aliases, label) {
|
|
|
73
67
|
return [...new Set(tokens.map((value) => aliases[value]))].sort((a, b) => Number(a) - Number(b)).join(',');
|
|
74
68
|
}
|
|
75
69
|
function rightTypeLabel(value) {
|
|
76
|
-
return String(value).split(',').map((
|
|
70
|
+
return String(value).split(',').map((v) => v.trim()).filter(Boolean)
|
|
71
|
+
.sort((a, b) => Number(a) - Number(b))
|
|
72
|
+
.map((item) => RIGHT_TYPES[item] || item).join('、');
|
|
73
|
+
}
|
|
74
|
+
/** 解析 JSON 参数;`@file` 读文件。 */
|
|
75
|
+
function jsonArg(value, label) {
|
|
76
|
+
if (value === undefined)
|
|
77
|
+
return undefined;
|
|
78
|
+
let text = String(value);
|
|
79
|
+
if (text.startsWith('@'))
|
|
80
|
+
text = readFileSync(text.slice(1), 'utf-8');
|
|
81
|
+
try {
|
|
82
|
+
return JSON.parse(text);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new Error(`${label} 不是合法 JSON`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** 取已注册的子命令(commander 重复调用 .command(name) 会抛错)。 */
|
|
89
|
+
function subCommand(parent, name) {
|
|
90
|
+
const found = parent.commands.find((cmd) => cmd.name() === name);
|
|
91
|
+
if (!found)
|
|
92
|
+
throw new Error(`内部错误: 找不到子命令 ${name}`);
|
|
93
|
+
return found;
|
|
94
|
+
}
|
|
95
|
+
/** 权限「通用设置」选项(创建/共享权限共用)。 */
|
|
96
|
+
function addPermissionSettingOptions(cmd) {
|
|
97
|
+
return cmd
|
|
98
|
+
.option('--same-layout <on|off>', 'PC移动统一布局(开=移动端沿用 PC 布局)')
|
|
99
|
+
.option('--layout <layoutId>', '关联 PC 布局 ID')
|
|
100
|
+
.option('--edit-layout <layoutId>', '编辑布局 ID')
|
|
101
|
+
.option('--mobile-layout <layoutId>', '关联移动布局 ID')
|
|
102
|
+
.option('--mobile-edit-layout <layoutId>', '移动端编辑布局 ID')
|
|
103
|
+
.option('--layout-order <n>', '布局优先级(0 最高)')
|
|
104
|
+
.option('--desc <text>', '权限描述')
|
|
105
|
+
.option('--desc-label-id <id>', '权限描述的多语言标签 ID(纯文本描述留空)')
|
|
106
|
+
.option('--condition <json>', '权限条件(条件树 JSON,或 @文件)')
|
|
107
|
+
.option('--clear-condition', '清空权限条件')
|
|
108
|
+
.option('--org-virtual-type <type>', '组织维度类型')
|
|
109
|
+
.option('--contain-extra <on|off>', '含兼职人员(岗位/角色等授权时)')
|
|
110
|
+
.option('--min-seclevel <n>', '最小安全级别(0~100)')
|
|
111
|
+
.option('--max-seclevel <n>', '最大安全级别(0~100)')
|
|
112
|
+
.option('--exclude-obj <json>', '排除项(排除对象 JSON,或 @文件)')
|
|
113
|
+
.option('--sync-forms <objId...>', '同步至其他表单(表单 objId,可多个)');
|
|
114
|
+
}
|
|
115
|
+
/** 从 commander 的 raw 选项收集设置;未传的键不出现在结果里。 */
|
|
116
|
+
function collectPermissionSettings(raw) {
|
|
117
|
+
const settings = {};
|
|
118
|
+
if (raw.layout !== undefined)
|
|
119
|
+
settings.layoutId = raw.layout;
|
|
120
|
+
if (raw.editLayout !== undefined)
|
|
121
|
+
settings.editLayoutId = raw.editLayout;
|
|
122
|
+
if (raw.mobileLayout !== undefined)
|
|
123
|
+
settings.mobileLayoutId = raw.mobileLayout;
|
|
124
|
+
if (raw.mobileEditLayout !== undefined)
|
|
125
|
+
settings.mobileEditLayoutId = raw.mobileEditLayout;
|
|
126
|
+
if (raw.sameLayout !== undefined)
|
|
127
|
+
settings.sameLayout = raw.sameLayout;
|
|
128
|
+
if (raw.layoutOrder !== undefined)
|
|
129
|
+
settings.layoutOrder = raw.layoutOrder;
|
|
130
|
+
if (raw.desc !== undefined)
|
|
131
|
+
settings.desc = raw.desc;
|
|
132
|
+
if (raw.descLabelId !== undefined)
|
|
133
|
+
settings.descLabelId = raw.descLabelId;
|
|
134
|
+
if (raw.condition !== undefined) {
|
|
135
|
+
const text = String(raw.condition);
|
|
136
|
+
settings.condition = text.startsWith('@') ? readFileSync(text.slice(1), 'utf-8') : text;
|
|
137
|
+
}
|
|
138
|
+
if (raw.clearCondition)
|
|
139
|
+
settings.clearCondition = '1';
|
|
140
|
+
if (raw.orgVirtualType !== undefined)
|
|
141
|
+
settings.orgVirtualType = raw.orgVirtualType;
|
|
142
|
+
if (raw.containExtra !== undefined)
|
|
143
|
+
settings.containExtra = raw.containExtra;
|
|
144
|
+
if (raw.minSeclevel !== undefined)
|
|
145
|
+
settings.minShowlevel = raw.minSeclevel;
|
|
146
|
+
if (raw.maxSeclevel !== undefined)
|
|
147
|
+
settings.maxShowlevel = raw.maxSeclevel;
|
|
148
|
+
if (raw.excludeObj !== undefined) {
|
|
149
|
+
const text = String(raw.excludeObj);
|
|
150
|
+
settings.excludeObj = text.startsWith('@') ? readFileSync(text.slice(1), 'utf-8') : text;
|
|
151
|
+
}
|
|
152
|
+
return settings;
|
|
153
|
+
}
|
|
154
|
+
function resolveTarget(value) {
|
|
155
|
+
const raw = String(value ?? 'general').trim();
|
|
156
|
+
const target = PERMISSION_TARGET_ALIASES[raw] ?? PERMISSION_TARGET_ALIASES[raw.toLowerCase()];
|
|
157
|
+
if (!target)
|
|
158
|
+
throw new Error(`不支持的 --target: ${raw},可选: ${Object.keys(PERMISSION_TARGETS).join(' / ')}`);
|
|
159
|
+
return target;
|
|
160
|
+
}
|
|
161
|
+
function normalizeExportFieldRange(value) {
|
|
162
|
+
const v = String(value).trim();
|
|
163
|
+
if (v === 'all' || v === 'allField')
|
|
164
|
+
return 'allField';
|
|
165
|
+
if (v === 'listShowField')
|
|
166
|
+
return 'listShowField';
|
|
167
|
+
throw new Error('--export-field-range 只支持 listShowField(列表显示字段)/ allField(全部字段)');
|
|
168
|
+
}
|
|
169
|
+
function requireOrgId(orgType, orgId) {
|
|
170
|
+
if (orgType === 'all' || orgType === 'externalAll')
|
|
171
|
+
return '0';
|
|
172
|
+
const id = String(orgId ?? '').trim();
|
|
173
|
+
if (!id)
|
|
174
|
+
throw new Error(`--org-type ${orgType} 需要 --org-id(组织对象的 ID)`);
|
|
175
|
+
return id;
|
|
77
176
|
}
|
|
78
177
|
export function registerFormPermissionCommands(form, program) {
|
|
79
178
|
const permCmd = form.command('permission').description('表单权限管理(增删查)');
|
|
@@ -123,63 +222,460 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
123
222
|
console.log(`\n共 ${total} 条权限`);
|
|
124
223
|
});
|
|
125
224
|
// ─── ADD ────────────────────────────────────────────────
|
|
126
|
-
const dataCmd = permCmd.command('data').description('
|
|
225
|
+
const dataCmd = permCmd.command('data').description('表单数据权限(共享权限:通用对象 / 创建人 / 字段 / 矩阵 / 政务单位)');
|
|
226
|
+
/**
|
|
227
|
+
* 解析授权对象,产出写进 permission 的字段补丁。
|
|
228
|
+
*
|
|
229
|
+
* `baseCodeType` 用于「通用对象」:创建权限是 obj、共享权限是 obj_data_admin;
|
|
230
|
+
* 改已有行时传入原 codeType,避免 update 把创建权限改成共享权限。
|
|
231
|
+
*/
|
|
232
|
+
async function resolveTargetPatch(client, baseUrl, appId, objId, raw, mode, baseCodeType) {
|
|
233
|
+
const target = resolveTarget(raw.target);
|
|
234
|
+
if (mode === 'create' && target !== 'general') {
|
|
235
|
+
throw new Error('创建权限只支持通用对象;创建人/字段/矩阵/政务单位相关请用 `form permission data`');
|
|
236
|
+
}
|
|
237
|
+
switch (target) {
|
|
238
|
+
case 'general': {
|
|
239
|
+
const orgType = String(raw.orgType ?? '');
|
|
240
|
+
if (!PERMISSION_ORG_TYPES[orgType]) {
|
|
241
|
+
throw new Error(`不支持的 --org-type: ${orgType || '(空)'},可选: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`);
|
|
242
|
+
}
|
|
243
|
+
const orgId = requireOrgId(orgType, raw.orgId);
|
|
244
|
+
if (raw.creatorRelated !== undefined && !/^[0-7]$/.test(String(raw.creatorRelated))) {
|
|
245
|
+
throw new Error('--creator-related 需是 0~7');
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
target,
|
|
249
|
+
patch: {
|
|
250
|
+
codeType: baseCodeType || (mode === 'create' ? PERMISSION_CODE_TYPES.create : PERMISSION_CODE_TYPES.share),
|
|
251
|
+
orgType, orgId,
|
|
252
|
+
orgName: raw.orgName || PERMISSION_ORG_TYPES[orgType],
|
|
253
|
+
orgTypeName: PERMISSION_ORG_TYPES[orgType],
|
|
254
|
+
...(raw.creatorRelated !== undefined ? { creatorRelated: String(raw.creatorRelated) } : {}),
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
case 'creator': {
|
|
259
|
+
const level = String(raw.creatorRelated ?? '0');
|
|
260
|
+
if (!/^[0-7]$/.test(level))
|
|
261
|
+
throw new Error('--creator-related 需是 0~7');
|
|
262
|
+
return {
|
|
263
|
+
target,
|
|
264
|
+
patch: {
|
|
265
|
+
codeType: PERMISSION_CODE_TYPES.creator, orgType: 'creatorRelated', orgId: '',
|
|
266
|
+
orgName: '', orgTypeName: PERMISSION_TARGETS.creator, creatorRelated: level,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
case 'field': {
|
|
271
|
+
if (!raw.field)
|
|
272
|
+
throw new Error('--target field 需要 --field(字段 id 或字段名)');
|
|
273
|
+
const record = await resolvePermissionField(client, baseUrl, appId, objId, String(raw.field), raw.subFormId);
|
|
274
|
+
const explicit = String(raw.orgType ?? '');
|
|
275
|
+
let mapped;
|
|
276
|
+
if (explicit) {
|
|
277
|
+
if (!FIELD_ORG_TYPE_LABELS[explicit]) {
|
|
278
|
+
throw new Error(`未知的字段相关类型: ${explicit},可选: ${Object.keys(FIELD_ORG_TYPE_LABELS).join(' / ')}`);
|
|
279
|
+
}
|
|
280
|
+
mapped = { orgType: explicit, label: FIELD_ORG_TYPE_LABELS[explicit] };
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
mapped = resolveFieldOrgType(record.type, record.title);
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
target,
|
|
287
|
+
patch: {
|
|
288
|
+
codeType: PERMISSION_CODE_TYPES.field, orgType: mapped.orgType, orgId: record.fieldId,
|
|
289
|
+
orgName: record.title, orgTypeName: mapped.label, creatorRelated: String(raw.creatorRelated ?? '0'),
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
case 'matrix': {
|
|
294
|
+
const useEbForm = Boolean(raw.ebForm);
|
|
295
|
+
const spec = String(raw.ebForm ?? raw.matrix ?? '');
|
|
296
|
+
if (!spec)
|
|
297
|
+
throw new Error('--target matrix 需要 --matrix(真矩阵)或 --eb-form(e-Builder 表单)');
|
|
298
|
+
const source = useEbForm
|
|
299
|
+
? await resolvePermissionEbForm(client, baseUrl, appId, spec)
|
|
300
|
+
: await resolvePermissionMatrix(client, baseUrl, appId, spec);
|
|
301
|
+
let relation;
|
|
302
|
+
if (raw.matrixValueRaw) {
|
|
303
|
+
const parsed = jsonArg(String(raw.matrixValueRaw), '--matrix-value-raw');
|
|
304
|
+
if (!Array.isArray(parsed) || !parsed.length)
|
|
305
|
+
throw new Error('--matrix-value-raw 需是非空 JSON 数组');
|
|
306
|
+
relation = buildMatrixValueRelation(parsed.map((v) => ({
|
|
307
|
+
valueId: String(v?.valueId ?? ''), valueName: String(v?.valueName ?? ''), valueType: String(v?.valueType ?? ''),
|
|
308
|
+
})));
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
const candidates = await matrixValueCandidates(client, baseUrl, appId, source);
|
|
312
|
+
const fallback = useEbForm
|
|
313
|
+
? (candidates.find((c) => c.valueType === 'system_creator') ?? candidates[0])
|
|
314
|
+
: candidates[0];
|
|
315
|
+
const tokens = raw.matrixValue?.length ? raw.matrixValue : (fallback ? [fallback.valueName] : []);
|
|
316
|
+
if (!tokens.length)
|
|
317
|
+
throw new Error('该来源没有可用取值字段,请用 --matrix-value-raw 明写');
|
|
318
|
+
relation = buildMatrixValueRelation(tokens.map((t) => parseMatrixValueToken(t, candidates)));
|
|
319
|
+
}
|
|
320
|
+
let matrixConditionData = '';
|
|
321
|
+
if (raw.matrixConditionRaw !== undefined) {
|
|
322
|
+
const parsed = jsonArg(String(raw.matrixConditionRaw), '--matrix-condition-raw');
|
|
323
|
+
matrixConditionData = typeof parsed === 'string' ? parsed : JSON.stringify(parsed);
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
target,
|
|
327
|
+
patch: {
|
|
328
|
+
codeType: source.codeType, orgType: source.codeType, orgId: source.id,
|
|
329
|
+
orgName: source.name, orgTypeName: source.orgTypeName,
|
|
330
|
+
matrixValueRelation: relation, matrixConditionData,
|
|
331
|
+
},
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
case 'govern': {
|
|
335
|
+
if (!raw.governJson)
|
|
336
|
+
throw new Error('--target govern 需要 --govern-json(政务单位关系 JSON)');
|
|
337
|
+
const parsed = jsonArg(String(raw.governJson), '--govern-json');
|
|
338
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
339
|
+
throw new Error('--govern-json 需要是 JSON 对象');
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
target,
|
|
343
|
+
patch: {
|
|
344
|
+
codeType: PERMISSION_CODE_TYPES.govern, orgType: 'govern', orgId: '1',
|
|
345
|
+
orgName: '', orgTypeName: PERMISSION_TARGETS.govern,
|
|
346
|
+
governDataRelation: JSON.stringify(parsed),
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function printPermission(result, raw, json) {
|
|
353
|
+
const label = result.rights || permissionRightLabels(result.rightType);
|
|
354
|
+
if (json) {
|
|
355
|
+
console.log(JSON.stringify({ success: true, changed: true, ...result }, null, 2));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
console.log(`${result.action || '权限'}已保存: [${result.id}] ${result.subject || result.orgName || ''} ${label}`);
|
|
359
|
+
if (result.fileRight)
|
|
360
|
+
console.log(` 附件权限: ${result.fileRight}`);
|
|
361
|
+
if (result.syncCount !== undefined)
|
|
362
|
+
console.log(` 同步至其他表单: ${result.syncCount} 个`);
|
|
363
|
+
if (result.needsRebuild) {
|
|
364
|
+
console.error(` 注意: 该权限需要重构,执行: e10-cli form permission rebuild ${raw.objId} ${raw.appId} ${result.id}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
127
367
|
dataCmd.command('add')
|
|
128
|
-
.description('
|
|
368
|
+
.description('添加共享权限(通用对象 / 创建人相关 / 字段相关 / 矩阵相关 / 政务单位相关)并回读')
|
|
129
369
|
.argument('<objId>', '表单 objId')
|
|
130
370
|
.argument('<appId>', '应用 ID')
|
|
131
|
-
.
|
|
132
|
-
.option('--org-
|
|
133
|
-
.option('--org-
|
|
134
|
-
.
|
|
135
|
-
.
|
|
136
|
-
.option('--
|
|
137
|
-
.
|
|
371
|
+
.option('--target <type>', `授权对象类别: ${Object.keys(PERMISSION_TARGETS).join(' / ')}`, 'general')
|
|
372
|
+
.option('--org-type <type>', `通用对象类型: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`)
|
|
373
|
+
.option('--org-id <id>', '授权对象 ID(all / externalAll 自动为 0)')
|
|
374
|
+
.option('--org-name <name>', '授权对象名称(缺省用类型名)')
|
|
375
|
+
.requiredOption('--rights <rights...>', '数据权限,可组合: view/edit/delete/comment 或 1/2/3/4')
|
|
376
|
+
.option('--file-rights <rights...>', '附件权限,可组合: view/download/edit 或 401/402/403')
|
|
377
|
+
.option('--file-right-type <type>', '附件赋权类型: temporary 临时赋权 / insert 插入赋权', 'temporary')
|
|
378
|
+
.option('--creator-related <level>', '创建人关系: 0~7(--target creator 用)', '0')
|
|
379
|
+
.option('--field <fieldIdOrName>', '字段相关:字段 id 或字段名')
|
|
380
|
+
.option('--sub-form-id <id>', '字段相关:明细字段所属子表 id')
|
|
381
|
+
.option('--matrix <idOrName>', '矩阵相关:矩阵 id 或名称')
|
|
382
|
+
.option('--eb-form <idOrName>', '矩阵相关:e-Builder 表单 id 或名称')
|
|
383
|
+
.option('--matrix-value <spec...>', '矩阵相关:取值字段(名称或 id:名称:valueType)')
|
|
384
|
+
.option('--matrix-value-raw <json>', '矩阵相关:取值字段原始 JSON 数组')
|
|
385
|
+
.option('--matrix-condition-raw <json>', '矩阵相关:条件树原始 JSON')
|
|
386
|
+
.option('--govern-json <json>', '政务单位相关:governDataRelation JSON')
|
|
387
|
+
.action(async (objId, appId, raw) => {
|
|
138
388
|
try {
|
|
139
389
|
const opts = program.opts();
|
|
140
390
|
const auth = await AuthSession.fromOptions(opts);
|
|
141
391
|
if (!auth)
|
|
142
392
|
throw new Error('无法加载认证');
|
|
143
|
-
if (!ORG_TYPES[cmdOpts.orgType])
|
|
144
|
-
throw new Error(`不支持的 --org-type: ${cmdOpts.orgType}`);
|
|
145
|
-
const orgId = cmdOpts.orgType === 'all' ? '0' : (cmdOpts.orgId || '');
|
|
146
|
-
if (cmdOpts.orgType !== 'all' && !orgId)
|
|
147
|
-
throw new Error('--org-id 不能为空(all 类型除外)');
|
|
148
|
-
const orgName = cmdOpts.orgName || ORG_TYPES[cmdOpts.orgType];
|
|
149
|
-
const rightType = parseRightValues(cmdOpts.rights, DATA_RIGHT_ALIASES, '数据权限');
|
|
150
|
-
const fileRight = cmdOpts.fileRights?.length
|
|
151
|
-
? parseRightValues(cmdOpts.fileRights, FILE_RIGHT_ALIASES, '附件权限') : '';
|
|
152
393
|
const client = new ApiClient(auth);
|
|
153
394
|
const baseUrl = auth.getBaseUrl();
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
throw new Error(listed?.msg || '权限回读失败');
|
|
170
|
-
const saved = (listed?.data?.rightList?.dataRightList || []).find((item) => String(item.id) === id);
|
|
171
|
-
if (!saved || String(saved.rightType) !== rightType || String(saved.orgType) !== cmdOpts.orgType
|
|
172
|
-
|| (fileRight && String(saved.fileRight || '') !== fileRight))
|
|
173
|
-
throw new Error('数据权限保存后回读不一致');
|
|
174
|
-
const result = { id, orgType: cmdOpts.orgType, orgId, orgName, rightType, rights: rightTypeLabel(rightType), fileRight };
|
|
175
|
-
console.log(opts.json ? JSON.stringify({ success: true, ...result }, null, 2)
|
|
176
|
-
: `数据权限已添加: [${id}] ${orgName} ${result.rights}${fileRight ? `;附件=${fileRight}` : ''}`);
|
|
177
|
-
if (added?.data?.[0]?.isShowRebuild === 2) {
|
|
178
|
-
console.error(` 注意: 该权限需要重构,执行: e10-cli form permission rebuild ${objId} ${appId} ${id}`);
|
|
395
|
+
const { target, patch } = await resolveTargetPatch(client, baseUrl, appId, objId, raw, 'share');
|
|
396
|
+
const rightType = parsePermissionRights(raw.rights, 'share');
|
|
397
|
+
const fileRight = raw.fileRights?.length ? parsePermissionFileRights(raw.fileRights) : '401,402';
|
|
398
|
+
const fileRightType = normalizeFileRightType(raw.fileRightType || 'temporary');
|
|
399
|
+
const row = buildPermissionRow({
|
|
400
|
+
objId, appId, mode: 'share', target, rightType, fileRight, fileRightType, ...patch,
|
|
401
|
+
});
|
|
402
|
+
applyPermissionSettings(row, collectPermissionSettings(raw));
|
|
403
|
+
const id = await addPermissionRow(client, baseUrl, appId, objId, row);
|
|
404
|
+
await verifyAddedRow(client, baseUrl, appId, objId, id, row);
|
|
405
|
+
let syncCount;
|
|
406
|
+
if (raw.syncForms?.length) {
|
|
407
|
+
const detail = await readPermissionDetail(client, baseUrl, appId, objId, id);
|
|
408
|
+
const after = await updatePermissionDetail(client, baseUrl, appId, objId, { ...detail.permission, id }, buildSyncPermissionList(raw.syncForms));
|
|
409
|
+
syncCount = after.syncPermissionList.length;
|
|
179
410
|
}
|
|
411
|
+
const subject = row.orgName || row.orgTypeName || '';
|
|
412
|
+
printPermission({
|
|
413
|
+
action: '共享权限', id, target, orgType: row.orgType, orgId: row.orgId, orgName: row.orgName,
|
|
414
|
+
subject, rightType, rights: permissionRightLabels(rightType), fileRight,
|
|
415
|
+
...(syncCount !== undefined ? { syncCount } : {}),
|
|
416
|
+
}, { objId, appId }, Boolean(opts.json));
|
|
180
417
|
}
|
|
181
418
|
catch (error) {
|
|
182
|
-
console.error(
|
|
419
|
+
console.error(`添加共享权限失败: ${error.message}`);
|
|
420
|
+
process.exitCode = 1;
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
addPermissionSettingOptions(subCommand(dataCmd, 'add'));
|
|
424
|
+
async function runDataUpdate(mode, objId, appId, raw) {
|
|
425
|
+
const opts = program.opts();
|
|
426
|
+
const auth = await AuthSession.fromOptions(opts);
|
|
427
|
+
if (!auth)
|
|
428
|
+
throw new Error('无法加载认证');
|
|
429
|
+
const client = new ApiClient(auth);
|
|
430
|
+
const baseUrl = auth.getBaseUrl();
|
|
431
|
+
const rightId = String(raw.rightId);
|
|
432
|
+
const located = await findRightRow(client, baseUrl, appId, objId, rightId);
|
|
433
|
+
if (mode === 'share' && located.bucket !== 'share') {
|
|
434
|
+
throw new Error(`权限 ${rightId} 是创建权限,请用 form permission create update`);
|
|
435
|
+
}
|
|
436
|
+
if (mode === 'create' && located.bucket !== 'create') {
|
|
437
|
+
throw new Error(`权限 ${rightId} 是共享权限,请用 form permission data update`);
|
|
438
|
+
}
|
|
439
|
+
const detail = await readPermissionDetail(client, baseUrl, appId, objId, rightId);
|
|
440
|
+
const permission = { ...detail.permission };
|
|
441
|
+
const changed = [];
|
|
442
|
+
const touchesTarget = ['target', 'orgType', 'orgId', 'orgName', 'field', 'subFormId',
|
|
443
|
+
'matrix', 'ebForm', 'matrixValue', 'matrixValueRaw', 'matrixConditionRaw', 'governJson']
|
|
444
|
+
.some((key) => raw[key] !== undefined);
|
|
445
|
+
if (touchesTarget) {
|
|
446
|
+
const target = raw.target ? resolveTarget(raw.target) : targetOfCodeType(permission.codeType);
|
|
447
|
+
const { patch } = await resolveTargetPatch(client, baseUrl, appId, objId, { ...raw, target }, mode, target === 'general' ? String(permission.codeType) : undefined);
|
|
448
|
+
Object.assign(permission, patch);
|
|
449
|
+
// orgName/orgTypeName 只是回显名,getPermissionAndSyncList 不回传;实际值以 getRightList 为准
|
|
450
|
+
changed.push(...Object.keys(patch).filter((key) => key !== 'orgName' && key !== 'orgTypeName'));
|
|
451
|
+
}
|
|
452
|
+
if (raw.creatorRelated !== undefined && !touchesTarget) {
|
|
453
|
+
const level = String(raw.creatorRelated);
|
|
454
|
+
if (!/^[0-7]$/.test(level))
|
|
455
|
+
throw new Error('--creator-related 需是 0~7');
|
|
456
|
+
permission.creatorRelated = level;
|
|
457
|
+
changed.push('creatorRelated');
|
|
458
|
+
}
|
|
459
|
+
if (raw.rights?.length) {
|
|
460
|
+
permission.rightType = parsePermissionRights(raw.rights, mode);
|
|
461
|
+
changed.push('rightType');
|
|
462
|
+
}
|
|
463
|
+
if (raw.fileRights?.length) {
|
|
464
|
+
permission.fileRight = parsePermissionFileRights(raw.fileRights);
|
|
465
|
+
changed.push('fileRight');
|
|
466
|
+
}
|
|
467
|
+
if (raw.fileRightType !== undefined) {
|
|
468
|
+
permission.fileRightType = normalizeFileRightType(raw.fileRightType);
|
|
469
|
+
changed.push('fileRightType');
|
|
470
|
+
}
|
|
471
|
+
changed.push(...applyPermissionSettings(permission, collectPermissionSettings(raw)));
|
|
472
|
+
const syncList = raw.syncForms?.length
|
|
473
|
+
? buildSyncPermissionList(raw.syncForms)
|
|
474
|
+
: detail.syncPermissionList;
|
|
475
|
+
if (!changed.length && !raw.syncForms?.length) {
|
|
476
|
+
throw new Error('未指定任何要修改的项');
|
|
477
|
+
}
|
|
478
|
+
const after = await updatePermissionDetail(client, baseUrl, appId, objId, permission, syncList, {
|
|
479
|
+
changedKeys: [...new Set(changed)],
|
|
480
|
+
});
|
|
481
|
+
if (raw.syncForms?.length) {
|
|
482
|
+
const want = new Set(syncList.map((s) => String(s.objId)));
|
|
483
|
+
const got = new Set(after.syncPermissionList.map((s) => String(s.objId)));
|
|
484
|
+
const missing = [...want].filter((id) => !got.has(id));
|
|
485
|
+
if (missing.length)
|
|
486
|
+
throw new Error(`同步至其他表单未生效: ${missing.join(', ')}`);
|
|
487
|
+
}
|
|
488
|
+
const subject = permission.orgName || permission.orgTypeName || '';
|
|
489
|
+
printPermission({
|
|
490
|
+
action: '权限', id: rightId, target: targetOfCodeType(permission.codeType),
|
|
491
|
+
orgType: permission.orgType, orgId: permission.orgId, orgName: permission.orgName,
|
|
492
|
+
subject, rightType: permission.rightType, rights: permissionRightLabels(permission.rightType),
|
|
493
|
+
fileRight: permission.fileRight,
|
|
494
|
+
...(raw.syncForms?.length ? { syncCount: after.syncPermissionList.length } : {}),
|
|
495
|
+
...(Number(after.permission.isShowRebuild) === 2 ? { needsRebuild: true } : {}),
|
|
496
|
+
}, { objId, appId }, Boolean(opts.json));
|
|
497
|
+
}
|
|
498
|
+
dataCmd.command('update')
|
|
499
|
+
.description('修改共享权限(整行回写,只改点名项;可改授权对象/权限/附件/布局/优先级/描述/条件/同步表单)')
|
|
500
|
+
.argument('<objId>', '表单 objId')
|
|
501
|
+
.argument('<appId>', '应用 ID')
|
|
502
|
+
.requiredOption('--right-id <id>', '权限 ID(form permission list 里的 [id])')
|
|
503
|
+
.option('--target <type>', `改成哪类授权对象: ${Object.keys(PERMISSION_TARGETS).join(' / ')}`)
|
|
504
|
+
.option('--org-type <type>', `通用对象类型: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`)
|
|
505
|
+
.option('--org-id <id>', '授权对象 ID(all / externalAll 自动为 0)')
|
|
506
|
+
.option('--org-name <name>', '授权对象名称')
|
|
507
|
+
.option('--rights <rights...>', '数据权限,可组合: view/edit/delete/comment 或 1/2/3/4')
|
|
508
|
+
.option('--file-rights <rights...>', '附件权限,可组合: view/download/edit 或 401/402/403')
|
|
509
|
+
.option('--file-right-type <type>', '附件赋权类型: temporary / insert')
|
|
510
|
+
.option('--creator-related <level>', '创建人关系: 0~7')
|
|
511
|
+
.option('--field <fieldIdOrName>', '字段相关:字段 id 或字段名')
|
|
512
|
+
.option('--sub-form-id <id>', '字段相关:明细字段所属子表 id')
|
|
513
|
+
.option('--matrix <idOrName>', '矩阵相关:矩阵 id 或名称')
|
|
514
|
+
.option('--eb-form <idOrName>', '矩阵相关:e-Builder 表单 id 或名称')
|
|
515
|
+
.option('--matrix-value <spec...>', '矩阵相关:取值字段(名称或 id:名称:valueType)')
|
|
516
|
+
.option('--matrix-value-raw <json>', '矩阵相关:取值字段原始 JSON 数组')
|
|
517
|
+
.option('--matrix-condition-raw <json>', '矩阵相关:条件树原始 JSON')
|
|
518
|
+
.option('--govern-json <json>', '政务单位相关:governDataRelation JSON')
|
|
519
|
+
.action(async (objId, appId, raw) => {
|
|
520
|
+
try {
|
|
521
|
+
await runDataUpdate('share', objId, appId, raw);
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
console.error(`修改共享权限失败: ${error.message}`);
|
|
525
|
+
process.exitCode = 1;
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
addPermissionSettingOptions(subCommand(dataCmd, 'update'));
|
|
529
|
+
dataCmd.command('show')
|
|
530
|
+
.description('查看一条共享权限的完整配置(含同步列表)')
|
|
531
|
+
.argument('<objId>', '表单 objId')
|
|
532
|
+
.argument('<appId>', '应用 ID')
|
|
533
|
+
.requiredOption('--right-id <id>', '权限 ID')
|
|
534
|
+
.action(async (objId, appId, raw) => {
|
|
535
|
+
try {
|
|
536
|
+
const opts = program.opts();
|
|
537
|
+
const auth = await AuthSession.fromOptions(opts);
|
|
538
|
+
if (!auth)
|
|
539
|
+
throw new Error('无法加载认证');
|
|
540
|
+
const detail = await readPermissionDetail(new ApiClient(auth), auth.getBaseUrl(), appId, objId, String(raw.rightId));
|
|
541
|
+
if (opts.json) {
|
|
542
|
+
console.log(JSON.stringify(detail, null, 2));
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
const p = detail.permission;
|
|
546
|
+
console.log(`[${p.id}] ${p.orgName || p.orgTypeName || ''} ${permissionRightLabels(p.rightType)} (${p.codeType}/${p.orgType})`);
|
|
547
|
+
const extras = [];
|
|
548
|
+
if (p.fileRight)
|
|
549
|
+
extras.push(`附件=${p.fileRight}(${p.fileRightType || ''})`);
|
|
550
|
+
if (p.layoutId)
|
|
551
|
+
extras.push(`PC布局=${p.layoutId}`);
|
|
552
|
+
if (p.mobileLayoutId)
|
|
553
|
+
extras.push(`移动布局=${p.mobileLayoutId}`);
|
|
554
|
+
if (p.editLayoutId)
|
|
555
|
+
extras.push(`编辑布局=${p.editLayoutId}`);
|
|
556
|
+
if (p.mobileEditLayoutId)
|
|
557
|
+
extras.push(`移动编辑布局=${p.mobileEditLayoutId}`);
|
|
558
|
+
if (String(p.isPcMobileSameLayout) === '1')
|
|
559
|
+
extras.push('PC移动统一布局');
|
|
560
|
+
if (p.layoutOrder !== undefined)
|
|
561
|
+
extras.push(`优先级=${p.layoutOrder}`);
|
|
562
|
+
if (p.rightDesc)
|
|
563
|
+
extras.push(`描述=${p.rightDesc}`);
|
|
564
|
+
if (p.conditionData)
|
|
565
|
+
extras.push('有权限条件');
|
|
566
|
+
if (extras.length)
|
|
567
|
+
console.log(` ${extras.join(' ')}`);
|
|
568
|
+
for (const s of detail.syncPermissionList) {
|
|
569
|
+
console.log(` 同步至: ${s.objId} ${s.tableName || ''} ${s.tableType || ''}`);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
catch (error) {
|
|
573
|
+
console.error(`读取权限失败: ${error.message}`);
|
|
574
|
+
process.exitCode = 1;
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
// ─── CREATE(创建权限:谁能新建记录)─────────────────────
|
|
578
|
+
const createCmd = permCmd.command('create')
|
|
579
|
+
.description('创建权限(谁能新建记录;共享数据权限请用 `form permission data`)');
|
|
580
|
+
createCmd.command('add')
|
|
581
|
+
.description('添加创建权限并回读')
|
|
582
|
+
.argument('<objId>', '表单 objId')
|
|
583
|
+
.argument('<appId>', '应用 ID')
|
|
584
|
+
.requiredOption('--org-type <type>', `授权对象类型: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`)
|
|
585
|
+
.option('--org-id <id>', '授权对象 ID(all / externalAll 自动为 0)')
|
|
586
|
+
.option('--org-name <name>', '授权对象名称(缺省用类型名)')
|
|
587
|
+
.option('--creator-related <level>', '上下级关系: 0~7(人员/部门/分部授权时)', '0')
|
|
588
|
+
.option('--rights <rights...>', '创建权限(目前只有 create / 0)', ['create'])
|
|
589
|
+
.action(async (objId, appId, raw) => {
|
|
590
|
+
try {
|
|
591
|
+
const opts = program.opts();
|
|
592
|
+
const auth = await AuthSession.fromOptions(opts);
|
|
593
|
+
if (!auth)
|
|
594
|
+
throw new Error('无法加载认证');
|
|
595
|
+
const client = new ApiClient(auth);
|
|
596
|
+
const baseUrl = auth.getBaseUrl();
|
|
597
|
+
const { patch } = await resolveTargetPatch(client, baseUrl, appId, objId, raw, 'create');
|
|
598
|
+
const rightType = parsePermissionRights(raw.rights, 'create');
|
|
599
|
+
const row = buildPermissionRow({ objId, appId, mode: 'create', target: 'general', rightType, ...patch });
|
|
600
|
+
applyPermissionSettings(row, collectPermissionSettings(raw));
|
|
601
|
+
const id = await addPermissionRow(client, baseUrl, appId, objId, row);
|
|
602
|
+
await verifyAddedRow(client, baseUrl, appId, objId, id, row);
|
|
603
|
+
let syncCount;
|
|
604
|
+
if (raw.syncForms?.length) {
|
|
605
|
+
const detail = await readPermissionDetail(client, baseUrl, appId, objId, id);
|
|
606
|
+
const after = await updatePermissionDetail(client, baseUrl, appId, objId, { ...detail.permission, id }, buildSyncPermissionList(raw.syncForms));
|
|
607
|
+
syncCount = after.syncPermissionList.length;
|
|
608
|
+
}
|
|
609
|
+
printPermission({
|
|
610
|
+
action: '创建权限', id, target: 'general', orgType: row.orgType, orgId: row.orgId, orgName: row.orgName,
|
|
611
|
+
subject: row.orgName || row.orgTypeName, rightType, rights: permissionRightLabels(rightType),
|
|
612
|
+
...(syncCount !== undefined ? { syncCount } : {}),
|
|
613
|
+
}, { objId, appId }, Boolean(opts.json));
|
|
614
|
+
}
|
|
615
|
+
catch (error) {
|
|
616
|
+
console.error(`添加创建权限失败: ${error.message}`);
|
|
617
|
+
process.exitCode = 1;
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
addPermissionSettingOptions(subCommand(createCmd, 'add'));
|
|
621
|
+
createCmd.command('update')
|
|
622
|
+
.description('修改创建权限(整行回写,只改点名项)')
|
|
623
|
+
.argument('<objId>', '表单 objId')
|
|
624
|
+
.argument('<appId>', '应用 ID')
|
|
625
|
+
.requiredOption('--right-id <id>', '权限 ID(form permission list 里的 [id])')
|
|
626
|
+
.option('--org-type <type>', `授权对象类型: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`)
|
|
627
|
+
.option('--org-id <id>', '授权对象 ID(all / externalAll 自动为 0)')
|
|
628
|
+
.option('--org-name <name>', '授权对象名称')
|
|
629
|
+
.option('--creator-related <level>', '上下级关系: 0~7(人员/部门/分部授权时)')
|
|
630
|
+
.option('--rights <rights...>', '创建权限(目前只有 create / 0)')
|
|
631
|
+
.action(async (objId, appId, raw) => {
|
|
632
|
+
try {
|
|
633
|
+
await runDataUpdate('create', objId, appId, raw);
|
|
634
|
+
}
|
|
635
|
+
catch (error) {
|
|
636
|
+
console.error(`修改创建权限失败: ${error.message}`);
|
|
637
|
+
process.exitCode = 1;
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
addPermissionSettingOptions(subCommand(createCmd, 'update'));
|
|
641
|
+
createCmd.command('show')
|
|
642
|
+
.description('查看一条创建权限的完整配置(含同步列表)')
|
|
643
|
+
.argument('<objId>', '表单 objId')
|
|
644
|
+
.argument('<appId>', '应用 ID')
|
|
645
|
+
.requiredOption('--right-id <id>', '权限 ID')
|
|
646
|
+
.action(async (objId, appId, raw) => {
|
|
647
|
+
try {
|
|
648
|
+
const opts = program.opts();
|
|
649
|
+
const auth = await AuthSession.fromOptions(opts);
|
|
650
|
+
if (!auth)
|
|
651
|
+
throw new Error('无法加载认证');
|
|
652
|
+
const detail = await readPermissionDetail(new ApiClient(auth), auth.getBaseUrl(), appId, objId, String(raw.rightId));
|
|
653
|
+
if (opts.json) {
|
|
654
|
+
console.log(JSON.stringify(detail, null, 2));
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const p = detail.permission;
|
|
658
|
+
console.log(`[${p.id}] ${p.orgName || p.orgTypeName || ''} ${permissionRightLabels(p.rightType)} (${p.codeType}/${p.orgType})`);
|
|
659
|
+
const extras = [];
|
|
660
|
+
if (p.layoutId)
|
|
661
|
+
extras.push(`PC布局=${p.layoutId}`);
|
|
662
|
+
if (p.mobileLayoutId)
|
|
663
|
+
extras.push(`移动布局=${p.mobileLayoutId}`);
|
|
664
|
+
if (String(p.isPcMobileSameLayout) === '1')
|
|
665
|
+
extras.push('PC移动统一布局');
|
|
666
|
+
if (p.layoutOrder !== undefined)
|
|
667
|
+
extras.push(`优先级=${p.layoutOrder}`);
|
|
668
|
+
if (p.rightDesc)
|
|
669
|
+
extras.push(`描述=${p.rightDesc}`);
|
|
670
|
+
if (p.conditionData)
|
|
671
|
+
extras.push('有权限条件');
|
|
672
|
+
if (extras.length)
|
|
673
|
+
console.log(` ${extras.join(' ')}`);
|
|
674
|
+
for (const s of detail.syncPermissionList)
|
|
675
|
+
console.log(` 同步至: ${s.objId} ${s.tableName || ''}`);
|
|
676
|
+
}
|
|
677
|
+
catch (error) {
|
|
678
|
+
console.error(`读取权限失败: ${error.message}`);
|
|
183
679
|
process.exitCode = 1;
|
|
184
680
|
}
|
|
185
681
|
});
|
|
@@ -187,6 +683,13 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
187
683
|
// 用户反馈:想加导入导出权限却加到了共享里。共享(dataRightList/obj_data_admin)只有 查看/编辑/删除 三种,
|
|
188
684
|
// 导入导出是独立分类(impRightList/data_imp_exp),rightType: 8导出/9导入(追加)/93删除导入数据。
|
|
189
685
|
const impCmd = permCmd.command('imp-exp').description('导入导出权限(独立分类,勿用 data add——共享权限只有 查看/编辑/删除)');
|
|
686
|
+
async function readImpRights(client, baseUrl, appId, objId) {
|
|
687
|
+
const listed = await client.get(`${baseUrl}/api/bs/ebuilder/form/permission/getRightList?objId=${objId}&apid=${appId}&belongId=${objId}&type=imp`, { ebbusinessid: appId });
|
|
688
|
+
if (listed?.code !== 200 || !listed?.status)
|
|
689
|
+
throw new Error(listed?.msg || '查询失败');
|
|
690
|
+
const items = listed?.data?.rightList?.impRightList || [];
|
|
691
|
+
return Array.isArray(items) ? items : (items?.pageDatas?.result || []);
|
|
692
|
+
}
|
|
190
693
|
impCmd.command('list')
|
|
191
694
|
.description('查看导入导出权限列表')
|
|
192
695
|
.argument('<objId>', '表单 objId')
|
|
@@ -199,12 +702,7 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
199
702
|
throw new Error('无法加载认证');
|
|
200
703
|
const client = new ApiClient(auth);
|
|
201
704
|
const baseUrl = auth.getBaseUrl();
|
|
202
|
-
const
|
|
203
|
-
if (listed?.code !== 200 || !listed?.status)
|
|
204
|
-
throw new Error(listed?.msg || '查询失败');
|
|
205
|
-
let items = listed?.data?.rightList?.impRightList || [];
|
|
206
|
-
if (!Array.isArray(items))
|
|
207
|
-
items = items?.pageDatas?.result || [];
|
|
705
|
+
const items = await readImpRights(client, baseUrl, appId, objId);
|
|
208
706
|
if (opts.json) {
|
|
209
707
|
console.log(JSON.stringify(items, null, 2));
|
|
210
708
|
return;
|
|
@@ -238,14 +736,14 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
238
736
|
.description('添加导入导出权限并回读(rightType: export=8 / import=9 / delete-import=93,93 须与 9 同选)')
|
|
239
737
|
.argument('<objId>', '表单 objId')
|
|
240
738
|
.argument('<appId>', '应用 ID')
|
|
241
|
-
.requiredOption('--org-type <type>', `授权对象类型: ${Object.keys(
|
|
242
|
-
.option('--org-id <id>', '授权对象 ID(all
|
|
243
|
-
.option('--org-name <name>', '
|
|
739
|
+
.requiredOption('--org-type <type>', `授权对象类型: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`)
|
|
740
|
+
.option('--org-id <id>', '授权对象 ID(all / externalAll 自动为 0)')
|
|
741
|
+
.option('--org-name <name>', '授权对象名称(缺省用类型名)', '')
|
|
244
742
|
.requiredOption('--rights <rights...>', '权限组合: export / import / delete-import(或 8/9/93)')
|
|
245
743
|
.option('--update-import', '允许更新导入(importType 加 1;默认仅追加导入 importType=0)')
|
|
246
744
|
.option('--export-details', '导出明细数据(明细表)')
|
|
247
745
|
.option('--export-attachment', '导出附件')
|
|
248
|
-
.option('--export-field-range <range>', '导出字段范围: listShowField 列表显示字段 /
|
|
746
|
+
.option('--export-field-range <range>', '导出字段范围: listShowField 列表显示字段 / allField 全部字段', 'listShowField')
|
|
249
747
|
.option('--creator-related <level>', '权限关系: 0 本人 / 1 上级 / 5 本岗位', '0')
|
|
250
748
|
.action(async (objId, appId, cmdOpts) => {
|
|
251
749
|
try {
|
|
@@ -253,12 +751,10 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
253
751
|
const auth = await AuthSession.fromOptions(opts);
|
|
254
752
|
if (!auth)
|
|
255
753
|
throw new Error('无法加载认证');
|
|
256
|
-
if (!
|
|
754
|
+
if (!PERMISSION_ORG_TYPES[cmdOpts.orgType])
|
|
257
755
|
throw new Error(`不支持的 --org-type: ${cmdOpts.orgType}`);
|
|
258
|
-
const orgId = cmdOpts.orgType
|
|
259
|
-
|
|
260
|
-
throw new Error('--org-id 不能为空(all 类型除外)');
|
|
261
|
-
const orgName = cmdOpts.orgName || ORG_TYPES[cmdOpts.orgType];
|
|
756
|
+
const orgId = requireOrgId(cmdOpts.orgType, cmdOpts.orgId);
|
|
757
|
+
const orgName = cmdOpts.orgName || PERMISSION_ORG_TYPES[cmdOpts.orgType];
|
|
262
758
|
const rightType = parseRightValues(cmdOpts.rights, IMP_EXP_RIGHT_ALIASES, '导入导出权限');
|
|
263
759
|
if (rightType.includes('93') && !rightType.includes('9')) {
|
|
264
760
|
throw new Error('delete-import(93) 必须与 import(9) 同选(删除导入数据依附于导入)');
|
|
@@ -270,9 +766,9 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
270
766
|
const perm = {
|
|
271
767
|
belong: 'obj', belongId: objId, codeType: 'data_imp_exp',
|
|
272
768
|
exportDetails: cmdOpts.exportDetails ? 1 : 0,
|
|
273
|
-
exportFieldRange: cmdOpts.exportFieldRange,
|
|
769
|
+
exportFieldRange: normalizeExportFieldRange(cmdOpts.exportFieldRange),
|
|
274
770
|
layoutOrder: 0, orgType: cmdOpts.orgType, creatorRelated: cmdOpts.creatorRelated,
|
|
275
|
-
orgId, orgVirtualType: '', orgTypeName:
|
|
771
|
+
orgId, orgVirtualType: '', orgTypeName: PERMISSION_ORG_TYPES[cmdOpts.orgType],
|
|
276
772
|
rightType, importType, excludeObj: '', isPcMobileSameLayout: '0',
|
|
277
773
|
orgName, conditionData: '',
|
|
278
774
|
...(cmdOpts.exportAttachment ? { exportAttachment: true } : {}),
|
|
@@ -284,15 +780,16 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
284
780
|
if (!id)
|
|
285
781
|
throw new Error('添加响应未返回权限 ID');
|
|
286
782
|
// 回读校验(type=imp 走导入导出分类)
|
|
287
|
-
const
|
|
288
|
-
if (listed?.code !== 200 || !listed?.status)
|
|
289
|
-
throw new Error(listed?.msg || '权限回读失败');
|
|
290
|
-
let items = listed?.data?.rightList?.impRightList || [];
|
|
291
|
-
if (!Array.isArray(items))
|
|
292
|
-
items = items?.pageDatas?.result || [];
|
|
783
|
+
const items = await readImpRights(client, baseUrl, appId, objId);
|
|
293
784
|
const saved = items.find((item) => String(item.id) === id);
|
|
294
785
|
if (!saved || String(saved.rightType) !== rightType)
|
|
295
786
|
throw new Error('导入导出权限保存后回读不一致');
|
|
787
|
+
if (String(saved.orgType) !== String(cmdOpts.orgType)) {
|
|
788
|
+
throw new Error('导入导出权限保存后回读不一致(授权对象类型被平台改写)');
|
|
789
|
+
}
|
|
790
|
+
if (!['all', 'externalAll'].includes(cmdOpts.orgType) && String(saved.orgId ?? '') !== String(orgId)) {
|
|
791
|
+
throw new Error('导入导出权限保存后回读不一致(授权对象 ID 被平台改写)');
|
|
792
|
+
}
|
|
296
793
|
const label = rightTypeLabel(rightType);
|
|
297
794
|
if (opts.json)
|
|
298
795
|
console.log(JSON.stringify({ success: true, id, orgName, orgType: cmdOpts.orgType, orgId, rightType, label, importType }, null, 2));
|
|
@@ -307,6 +804,175 @@ export function registerFormPermissionCommands(form, program) {
|
|
|
307
804
|
process.exitCode = 1;
|
|
308
805
|
}
|
|
309
806
|
});
|
|
807
|
+
impCmd.command('update')
|
|
808
|
+
.description('修改导入导出权限(整行回写,只改点名项)')
|
|
809
|
+
.argument('<objId>', '表单 objId')
|
|
810
|
+
.argument('<appId>', '应用 ID')
|
|
811
|
+
.requiredOption('--right-id <id>', '权限 ID(form permission imp-exp list 里的 [id])')
|
|
812
|
+
.option('--org-type <type>', `授权对象类型: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`)
|
|
813
|
+
.option('--org-id <id>', '授权对象 ID(all / externalAll 自动为 0)')
|
|
814
|
+
.option('--org-name <name>', '授权对象名称')
|
|
815
|
+
.option('--rights <rights...>', '权限组合: export / import / delete-import(或 8/9/93)')
|
|
816
|
+
.option('--update-import <on|off>', '允许更新导入(importType 加 1)')
|
|
817
|
+
.option('--export-details <on|off>', '导出明细数据(明细表)')
|
|
818
|
+
.option('--export-attachment <on|off>', '导出附件')
|
|
819
|
+
.option('--export-field-range <range>', '导出字段范围: listShowField 列表显示字段 / allField 全部字段')
|
|
820
|
+
.option('--creator-related <level>', '权限关系: 0 本人 / 1 上级 / 5 本岗位')
|
|
821
|
+
.action(async (objId, appId, raw) => {
|
|
822
|
+
try {
|
|
823
|
+
const opts = program.opts();
|
|
824
|
+
const auth = await AuthSession.fromOptions(opts);
|
|
825
|
+
if (!auth)
|
|
826
|
+
throw new Error('无法加载认证');
|
|
827
|
+
const client = new ApiClient(auth);
|
|
828
|
+
const baseUrl = auth.getBaseUrl();
|
|
829
|
+
const rightId = String(raw.rightId);
|
|
830
|
+
const current = (await readImpRights(client, baseUrl, appId, objId))
|
|
831
|
+
.find((r) => String(r.id) === rightId);
|
|
832
|
+
if (!current)
|
|
833
|
+
throw new Error(`导入导出权限 ${rightId} 不存在`);
|
|
834
|
+
const permission = {
|
|
835
|
+
id: rightId,
|
|
836
|
+
belong: current.belong || 'obj',
|
|
837
|
+
belongId: current.belongId || objId,
|
|
838
|
+
codeType: 'data_imp_exp',
|
|
839
|
+
orgType: current.orgType,
|
|
840
|
+
orgId: current.orgId ?? '',
|
|
841
|
+
orgName: current.orgName ?? '',
|
|
842
|
+
orgTypeName: current.orgTypeName ?? '',
|
|
843
|
+
rightType: String(current.rightType ?? ''),
|
|
844
|
+
importType: String(current.importType ?? '0'),
|
|
845
|
+
exportDetails: Number(current.exportDetails ?? 0),
|
|
846
|
+
exportFieldRange: current.exportFieldRange || 'listShowField',
|
|
847
|
+
exportAttachment: Boolean(current.exportAttachment),
|
|
848
|
+
creatorRelated: String(current.creatorRelated ?? '0'),
|
|
849
|
+
layoutOrder: Number(current.layoutOrder ?? 0),
|
|
850
|
+
isPcMobileSameLayout: String(current.isPcMobileSameLayout ?? '0'),
|
|
851
|
+
orgVirtualType: current.orgVirtualType ?? '',
|
|
852
|
+
excludeObj: current.excludeObj ?? '',
|
|
853
|
+
conditionData: current.conditionData ?? '',
|
|
854
|
+
};
|
|
855
|
+
const changed = [];
|
|
856
|
+
if (raw.orgType !== undefined) {
|
|
857
|
+
const orgType = String(raw.orgType);
|
|
858
|
+
if (!PERMISSION_ORG_TYPES[orgType]) {
|
|
859
|
+
throw new Error(`不支持的 --org-type: ${orgType},可选: ${Object.keys(PERMISSION_ORG_TYPES).join(' / ')}`);
|
|
860
|
+
}
|
|
861
|
+
permission.orgType = orgType;
|
|
862
|
+
permission.orgId = requireOrgId(orgType, raw.orgId);
|
|
863
|
+
permission.orgName = raw.orgName || PERMISSION_ORG_TYPES[orgType];
|
|
864
|
+
permission.orgTypeName = PERMISSION_ORG_TYPES[orgType];
|
|
865
|
+
changed.push('orgType', 'orgId');
|
|
866
|
+
}
|
|
867
|
+
else if (raw.orgId !== undefined) {
|
|
868
|
+
throw new Error('改授权对象需要同时给 --org-type(判断对象种类)');
|
|
869
|
+
}
|
|
870
|
+
if (raw.rights?.length) {
|
|
871
|
+
const rightType = parseRightValues(raw.rights, IMP_EXP_RIGHT_ALIASES, '导入导出权限');
|
|
872
|
+
if (rightType.includes('93') && !rightType.includes('9')) {
|
|
873
|
+
throw new Error('delete-import(93) 必须与 import(9) 同选');
|
|
874
|
+
}
|
|
875
|
+
permission.rightType = rightType;
|
|
876
|
+
changed.push('rightType');
|
|
877
|
+
}
|
|
878
|
+
if (raw.updateImport !== undefined || permission.rightType.includes('93')) {
|
|
879
|
+
const wantsUpdate = raw.updateImport !== undefined
|
|
880
|
+
? parseOnOff(raw.updateImport, '--update-import') : true;
|
|
881
|
+
permission.importType = wantsUpdate || permission.rightType.includes('93') ? '0,1' : '0';
|
|
882
|
+
if (changed.some((k) => k === 'rightType') || raw.updateImport !== undefined)
|
|
883
|
+
changed.push('importType');
|
|
884
|
+
}
|
|
885
|
+
if (raw.exportDetails !== undefined) {
|
|
886
|
+
permission.exportDetails = parseOnOff(raw.exportDetails, '--export-details') ? 1 : 0;
|
|
887
|
+
changed.push('exportDetails');
|
|
888
|
+
}
|
|
889
|
+
if (raw.exportAttachment !== undefined) {
|
|
890
|
+
permission.exportAttachment = parseOnOff(raw.exportAttachment, '--export-attachment');
|
|
891
|
+
changed.push('exportAttachment');
|
|
892
|
+
}
|
|
893
|
+
if (raw.exportFieldRange !== undefined) {
|
|
894
|
+
permission.exportFieldRange = normalizeExportFieldRange(raw.exportFieldRange);
|
|
895
|
+
changed.push('exportFieldRange');
|
|
896
|
+
}
|
|
897
|
+
if (raw.creatorRelated !== undefined) {
|
|
898
|
+
const level = String(raw.creatorRelated);
|
|
899
|
+
if (!/^[0-7]$/.test(level))
|
|
900
|
+
throw new Error('--creator-related 需是 0~7');
|
|
901
|
+
permission.creatorRelated = level;
|
|
902
|
+
changed.push('creatorRelated');
|
|
903
|
+
}
|
|
904
|
+
if (!changed.length)
|
|
905
|
+
throw new Error('未指定任何要修改的项');
|
|
906
|
+
const q = new URLSearchParams({ objId, apid: appId, tpaid: objId }).toString();
|
|
907
|
+
const saved = await client.post(`${baseUrl}/api/bs/ebuilder/form/permission/updateAndSyncPermission?${q}`, { permission, sourceChanged: true, syncPermissionList: [] }, { ebbusinessid: appId });
|
|
908
|
+
if (saved?.code !== 200 || !saved?.status)
|
|
909
|
+
throw new Error(saved?.msg || '保存失败');
|
|
910
|
+
const after = (await readImpRights(client, baseUrl, appId, objId))
|
|
911
|
+
.find((r) => String(r.id) === rightId);
|
|
912
|
+
if (!after)
|
|
913
|
+
throw new Error('已提交,但权限列表里找不到该行');
|
|
914
|
+
const mismatch = [];
|
|
915
|
+
const cmp = (key) => {
|
|
916
|
+
if (['orgName', 'orgTypeName'].includes(key))
|
|
917
|
+
return;
|
|
918
|
+
if (String(after[key] ?? '') !== String(permission[key] ?? '')) {
|
|
919
|
+
mismatch.push(`${key}: 期望 ${permission[key] ?? ''},回读 ${after[key] ?? ''}`);
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
for (const key of new Set(changed)) {
|
|
923
|
+
if (key === 'orgId' && ['all', 'externalAll'].includes(String(permission.orgType)))
|
|
924
|
+
continue;
|
|
925
|
+
cmp(key);
|
|
926
|
+
}
|
|
927
|
+
if (mismatch.length)
|
|
928
|
+
throw new Error(`导入导出权限保存后回读不一致 —— ${mismatch.join(';')}`);
|
|
929
|
+
const label = rightTypeLabel(String(permission.rightType));
|
|
930
|
+
if (opts.json) {
|
|
931
|
+
console.log(JSON.stringify({ success: true, id: rightId, orgType: permission.orgType, orgId: permission.orgId, rightType: permission.rightType, label, importType: permission.importType }, null, 2));
|
|
932
|
+
}
|
|
933
|
+
else {
|
|
934
|
+
console.log(`导入导出权限已修改: [${rightId}] ${permission.orgName || permission.orgTypeName} ${label}${permission.importType === '0,1' ? '(含更新导入)' : ''}`);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
catch (error) {
|
|
938
|
+
console.error(`修改导入导出权限失败: ${error.message}`);
|
|
939
|
+
process.exitCode = 1;
|
|
940
|
+
}
|
|
941
|
+
});
|
|
942
|
+
impCmd.command('show')
|
|
943
|
+
.description('查看一条导入导出权限的完整配置')
|
|
944
|
+
.argument('<objId>', '表单 objId')
|
|
945
|
+
.argument('<appId>', '应用 ID')
|
|
946
|
+
.requiredOption('--right-id <id>', '权限 ID')
|
|
947
|
+
.action(async (objId, appId, raw) => {
|
|
948
|
+
try {
|
|
949
|
+
const opts = program.opts();
|
|
950
|
+
const auth = await AuthSession.fromOptions(opts);
|
|
951
|
+
if (!auth)
|
|
952
|
+
throw new Error('无法加载认证');
|
|
953
|
+
const items = await readImpRights(new ApiClient(auth), auth.getBaseUrl(), appId, objId);
|
|
954
|
+
const row = items.find((r) => String(r.id) === String(raw.rightId));
|
|
955
|
+
if (!row)
|
|
956
|
+
throw new Error(`导入导出权限 ${raw.rightId} 不存在`);
|
|
957
|
+
if (opts.json) {
|
|
958
|
+
console.log(JSON.stringify(row, null, 2));
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
console.log(`[${row.id}] ${row.orgName || row.orgTypeName}(${row.orgType}/${row.orgId ?? ''}) ${row.rightTypeName || rightTypeLabel(row.rightType)}`);
|
|
962
|
+
if (row.importType)
|
|
963
|
+
console.log(` importType=${row.importType}`);
|
|
964
|
+
if (row.exportFieldRange)
|
|
965
|
+
console.log(` 导出字段范围=${row.exportFieldRange}`);
|
|
966
|
+
if (row.exportDetails)
|
|
967
|
+
console.log(' 导出明细');
|
|
968
|
+
if (row.exportAttachment)
|
|
969
|
+
console.log(' 导出附件');
|
|
970
|
+
}
|
|
971
|
+
catch (error) {
|
|
972
|
+
console.error(`读取导入导出权限失败: ${error.message}`);
|
|
973
|
+
process.exitCode = 1;
|
|
974
|
+
}
|
|
975
|
+
});
|
|
310
976
|
permCmd.command('add')
|
|
311
977
|
.description('添加表单权限')
|
|
312
978
|
.argument('<objId>', '表单 objId')
|