weaver-work-cli 0.1.25 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -30
- package/dist/cmd/root.js +1 -0
- package/dist/cmd/setup/index.js +1 -1
- package/dist/core/runtime-agent.js +19 -0
- package/dist/internal/e10/auth/commands.js +48 -33
- package/dist/internal/e10/auth/messages.js +3 -0
- package/dist/internal/e10/auth/session.js +8 -0
- package/dist/internal/e10/auth/xiaoe.js +62 -43
- package/dist/internal/e10/auth-recovery.js +148 -0
- package/dist/internal/e10/client.js +47 -15
- package/dist/internal/e10/context.js +9 -31
- package/dist/internal/e10/index.js +1 -0
- package/dist/internal/e10/request-runtime.js +51 -9
- package/dist/shortcuts/archive/host.js +3 -2
- package/dist/shortcuts/archive/manifest.js +1 -1
- package/dist/shortcuts/archive-oa/constants.js +66 -0
- package/dist/shortcuts/archive-oa/continuation.js +70 -0
- package/dist/shortcuts/archive-oa/errors.js +53 -0
- package/dist/shortcuts/archive-oa/host.js +158 -0
- package/dist/shortcuts/archive-oa/index.js +225 -0
- package/dist/shortcuts/archive-oa/manifest.js +62 -0
- package/dist/shortcuts/archive-oa/operations/borrow-car.js +159 -0
- package/dist/shortcuts/archive-oa/operations/borrow-url.js +108 -0
- package/dist/shortcuts/archive-oa/operations/confirm.js +48 -0
- package/dist/shortcuts/archive-oa/operations/contract.js +120 -0
- package/dist/shortcuts/archive-oa/operations/locate.js +50 -0
- package/dist/shortcuts/archive-oa/operations/registry.js +40 -0
- package/dist/shortcuts/archive-oa/operations/shared.js +181 -0
- package/dist/shortcuts/archive-oa/operations/types.js +45 -0
- package/dist/shortcuts/archive-oa/operations.js +13 -0
- package/dist/shortcuts/asset/host.js +7 -6
- package/dist/shortcuts/blog/host.js +4 -3
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/caizhilian/manifest.js +1 -1
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +34 -59
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +6 -3
- package/dist/shortcuts/fna/manifest.js +10 -5
- package/dist/shortcuts/fna/operations/expense-chart.js +162 -0
- package/dist/shortcuts/fna/operations/registry.js +2 -0
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +2 -0
- package/dist/shortcuts/invoice/host.js +9 -7
- package/dist/shortcuts/invoice/manifest.js +38 -47
- package/dist/shortcuts/invoice/operations/issuing-qys.js +328 -0
- package/dist/shortcuts/invoice/operations/registry.js +2 -3
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +2 -1
- package/dist/shortcuts/meeting/host.js +2 -1
- package/dist/shortcuts/meeting/operations/eb/conflict.js +78 -12
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/endpoints.js +11 -0
- package/dist/shortcuts/workflow/host.js +5 -7
- package/dist/shortcuts/workflow/index.js +6 -36
- package/dist/shortcuts/workflow/operations/chatscene.js +252 -0
- package/dist/shortcuts/workflow/operations/form.js +1047 -191
- package/dist/shortcuts/workflow/operations/read.js +137 -8
- package/dist/shortcuts/workflow/operations/sign-input.js +106 -0
- package/dist/shortcuts/workflow/operations/write.js +9 -1
- package/dist/shortcuts/workflow/stdout-compact.js +16 -1
- package/docs/SKILL.md +1 -1
- package/docs/_catalog.md +1 -1
- package/docs/agent-invoice.md +1 -1
- package/docs/archive-oa.md +79 -0
- package/docs/caizhilian.md +1 -1
- package/docs/e10-auth.md +7 -6
- package/docs/fna.md +7 -3
- package/docs/invoice.md +4 -6
- package/package.json +1 -1
- package/skill-template/business-info.json +20 -1
- package/skill-template/domains/archive-oa.md +19 -0
- package/skill-template/domains/caizhilian.md +2 -1
- package/skill-template/domains/qiyecheng.md +1 -0
- package/skill-template/domains/yepiaotong.md +8 -4
- package/skill-template/skill-template.md +1 -0
- package/skills/weaver-e10-archive-oa/SKILL.md +159 -0
- package/skills/weaver-e10-archive-oa/references/archive-locate.md +49 -0
- package/skills/weaver-e10-archive-oa/references/borrow-car.md +76 -0
- package/skills/weaver-e10-archive-oa/references/borrow-flow.md +53 -0
- package/skills/weaver-e10-archive-oa/references/contract-search.md +63 -0
- package/skills/weaver-e10-archive-oa/references/disabled-capabilities.md +29 -0
- package/skills/weaver-e10-archive-oa/references/qys-contract-search.md +47 -0
- package/skills/weaver-e10-archive-oa/references/source-manifest.json +400 -0
- package/skills/weaver-e10-blog/SKILL.md +6 -1
- package/skills/weaver-e10-blog/references/blog-query.md +3 -1
- package/skills/weaver-e10-builder/SKILL.md +22 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +47 -16
- package/skills/weaver-e10-caizhilian/references/action-flow.md +70 -0
- package/skills/weaver-e10-caizhilian/references/agent-entry.md +12 -4
- package/skills/weaver-e10-caizhilian/references/auth-and-install.md +207 -0
- package/skills/weaver-e10-caizhilian/references/collaboration.md +5 -3
- package/skills/weaver-e10-caizhilian/references/document.md +33 -11
- package/skills/weaver-e10-caizhilian/references/file-collection.md +57 -54
- package/skills/weaver-e10-caizhilian/references/file-upload.md +5 -6
- package/skills/weaver-e10-caizhilian/references/files.md +9 -3
- package/skills/weaver-e10-caizhilian/references/folder.md +48 -16
- package/skills/weaver-e10-caizhilian/references/host-executor-prompt.md +32 -0
- package/skills/weaver-e10-caizhilian/references/host-platform-integration.md +46 -0
- package/skills/weaver-e10-caizhilian/references/rule-index.md +56 -0
- package/skills/weaver-e10-caizhilian/references/setting-attach.md +17 -54
- package/skills/weaver-e10-caizhilian/references/setting-backup.md +16 -63
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +24 -64
- package/skills/weaver-e10-caizhilian/references/setting-storage-docs-summary.md +126 -0
- package/skills/weaver-e10-caizhilian/references/setting-storage-field-map.md +57 -0
- package/skills/weaver-e10-caizhilian/references/setting-storage.md +143 -548
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +7 -7
- package/skills/weaver-e10-caizhilian/references/task-workflow.md +87 -0
- package/skills/weaver-e10-caizhilian/references/withheld.md +21 -45
- package/skills/weaver-e10-caizhilian/references/write-protocol.md +7 -0
- package/skills/weaver-e10-calendar/SKILL.md +6 -1
- package/skills/weaver-e10-esb/SKILL.md +8 -0
- package/skills/weaver-e10-esb/references/input-format.md +3 -1
- package/skills/weaver-e10-esb/references/source-manifest.json +5 -5
- package/skills/weaver-e10-hrm/SKILL.md +6 -1
- package/skills/weaver-e10-hrm/references/employee.md +1 -1
- package/skills/weaver-e10-hrm/references/org.md +1 -1
- package/skills/weaver-e10-hrm/references/position.md +1 -1
- package/skills/weaver-e10-jinchengda/SKILL.md +2 -1
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +1 -1
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +6 -1
- package/skills/weaver-e10-jucailin/SKILL.md +6 -1
- package/skills/weaver-e10-jucailin/references/hr-contact.md +1 -1
- package/skills/weaver-e10-jucailin/references/salary.md +1 -1
- package/skills/weaver-e10-mail/SKILL.md +6 -1
- package/skills/weaver-e10-meeting/SKILL.md +11 -6
- package/skills/weaver-e10-meeting/references/meeting-eb.md +7 -3
- package/skills/weaver-e10-meeting/references/meeting-queries.md +3 -1
- package/skills/weaver-e10-meeting/references/meeting-verification.md +4 -2
- package/skills/weaver-e10-okr/SKILL.md +6 -1
- package/skills/weaver-e10-okr/references/source-manifest.json +5 -5
- package/skills/weaver-e10-plan/SKILL.md +6 -1
- package/skills/weaver-e10-plan/references/plan-overview-and-routing.md +3 -1
- package/skills/weaver-e10-plan/references/plan-report-query.md +3 -1
- package/skills/weaver-e10-plan/references/source-manifest.json +7 -7
- package/skills/weaver-e10-qiyecheng/SKILL.md +16 -6
- package/skills/weaver-e10-qiyecheng/references/catalog.md +6 -3
- package/skills/weaver-e10-qiyecheng/references/expense-center.md +2 -0
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +78 -0
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +87 -33
- package/skills/weaver-e10-shared/SKILL.md +53 -28
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +22 -20
- package/skills/weaver-e10-shared/references/non-interactive-environment.md +13 -13
- package/skills/weaver-e10-shared/references/weaver-e10-installation.md +3 -1
- package/skills/weaver-e10-wenshuding/SKILL.md +6 -1
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +3 -3
- package/skills/weaver-e10-workflow/references/source-manifest.json +33 -24
- package/skills/weaver-e10-workflow/references/workflow-create.md +41 -26
- package/skills/weaver-e10-yepiaotong/SKILL.md +23 -18
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +87 -45
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +152 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +210 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +59 -36
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +63 -512
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +205 -346
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -5
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +231 -344
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +5 -5
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +201 -162
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +121 -145
- package/skills/weaver-e10-yimiaoban/SKILL.md +9 -2
- package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/msg-read.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +9 -9
- package/skills/weaver-e10-ziguanjia/SKILL.md +6 -1
- package/dist/shortcuts/invoice/operations/issuing.js +0 -198
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-field-rules.md +0 -161
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +0 -107
- package/skills/weaver-e10-yepiaotong/references/reim-fast-path.md +0 -119
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { QYS_CONTRACT, QYS_DEFAULT_ARCHIVED_FIELD, QYS_DEFAULT_ARCHIVED_VALUE, WEAVER_CONTRACT, } from '../constants.js';
|
|
2
|
+
import { READ, archiveOaSuccess, schemaOf, SCHEMA_PAGE_NO, SCHEMA_SEARCH_FIELDS, } from './types.js';
|
|
3
|
+
import { assertEnum, buildCommonSearchFields, normalizeListResult, positiveInt, unwrapData } from './shared.js';
|
|
4
|
+
const CONTRACT_LIST_PATH = '/api/ebuilder/form/list/getListDatas';
|
|
5
|
+
function filterPath(profile) {
|
|
6
|
+
return `/api/ebuilder/form/listFilter/showFilters/${profile.listId}`;
|
|
7
|
+
}
|
|
8
|
+
function operationName(profile, action) {
|
|
9
|
+
return profile.source === 'qys'
|
|
10
|
+
? `archive-oa.qys.contract.${action}`
|
|
11
|
+
: `archive-oa.contract.${action}`;
|
|
12
|
+
}
|
|
13
|
+
/** getListDatas 的固定请求体(分页与视图参数)。 */
|
|
14
|
+
function listBody(profile, pageNo, commonSearchFields, matchType) {
|
|
15
|
+
return {
|
|
16
|
+
current: pageNo,
|
|
17
|
+
requiredMatch: 1,
|
|
18
|
+
mapResult: '1',
|
|
19
|
+
recheckQuery: '1',
|
|
20
|
+
cusMenuId: profile.cusMenuId,
|
|
21
|
+
urlPageTitle: profile.urlPageTitle,
|
|
22
|
+
searchParamData: {
|
|
23
|
+
searchType: '2',
|
|
24
|
+
type: matchType,
|
|
25
|
+
commonSearchFields,
|
|
26
|
+
groupFields: {},
|
|
27
|
+
},
|
|
28
|
+
listId: profile.listId,
|
|
29
|
+
isFollow: 0,
|
|
30
|
+
isShareToMe: 0,
|
|
31
|
+
filterCondition: {},
|
|
32
|
+
browser: 'Chrome',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** 搜索字段配置(showFilters):只有源资料收录了该辅助接口才生成。 */
|
|
36
|
+
function makeFieldsOperation(profile) {
|
|
37
|
+
const name = operationName(profile, 'fields');
|
|
38
|
+
return {
|
|
39
|
+
name,
|
|
40
|
+
resource: 'contract',
|
|
41
|
+
method: 'fields',
|
|
42
|
+
action: name,
|
|
43
|
+
summary: `查询${profile.source === 'qys' ? '契约锁' : '泛微'}商务合同可搜索字段配置(构造 commonSearchFields 用)`,
|
|
44
|
+
capability: 'contract-search',
|
|
45
|
+
risk: READ,
|
|
46
|
+
inputSchema: schemaOf({}, { description: '查询合同搜索字段配置,无需入参' }),
|
|
47
|
+
handler: async (_args, env) => {
|
|
48
|
+
const response = await env.host.request({
|
|
49
|
+
method: 'GET',
|
|
50
|
+
path: filterPath(profile),
|
|
51
|
+
operation: name,
|
|
52
|
+
query: { passid: profile.passId, sf_request_type: 'ajax' },
|
|
53
|
+
});
|
|
54
|
+
const data = (unwrapData(response) ?? {});
|
|
55
|
+
const fields = Array.isArray(data.fields)
|
|
56
|
+
? data.fields
|
|
57
|
+
: Array.isArray(data)
|
|
58
|
+
? data
|
|
59
|
+
: [];
|
|
60
|
+
return archiveOaSuccess(name, { fields }, { source: profile.source, listId: profile.listId, count: Array.isArray(fields) ? fields.length : 0 });
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** 商务合同列表查询。 */
|
|
65
|
+
function makeListOperation(profile) {
|
|
66
|
+
const name = operationName(profile, 'list');
|
|
67
|
+
const isQys = profile.source === 'qys';
|
|
68
|
+
return {
|
|
69
|
+
name,
|
|
70
|
+
resource: 'contract',
|
|
71
|
+
method: 'list',
|
|
72
|
+
action: name,
|
|
73
|
+
summary: `查询${isQys ? '契约锁协作采纳(案例)' : '泛微'}商务合同列表`,
|
|
74
|
+
capability: 'contract-search',
|
|
75
|
+
risk: READ,
|
|
76
|
+
inputSchema: schemaOf({
|
|
77
|
+
pageNo: { ...SCHEMA_PAGE_NO, description: '页码,从 1 开始,缺省 1' },
|
|
78
|
+
fields: SCHEMA_SEARCH_FIELDS,
|
|
79
|
+
matchType: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
enum: ['and', 'or'],
|
|
82
|
+
description: '多条件组合方式,缺省 and(源资料约定默认「且」)',
|
|
83
|
+
},
|
|
84
|
+
...(isQys
|
|
85
|
+
? {
|
|
86
|
+
archivedOnly: {
|
|
87
|
+
type: 'boolean',
|
|
88
|
+
description: `默认 true:附加 ${QYS_DEFAULT_ARCHIVED_FIELD}=${QYS_DEFAULT_ARCHIVED_VALUE}(处理进度=已归档)过滤`,
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
: {}),
|
|
92
|
+
}, { description: `查询${isQys ? '契约锁' : '泛微'}商务合同列表` }),
|
|
93
|
+
handler: async (args, env) => {
|
|
94
|
+
const pageNo = positiveInt(args.pageNo, 'pageNo', 1);
|
|
95
|
+
const matchType = args.matchType === undefined ? 'and' : assertEnum(args.matchType, ['and', 'or'], 'matchType');
|
|
96
|
+
const extra = [];
|
|
97
|
+
const archivedOnly = args.archivedOnly === undefined ? true : args.archivedOnly;
|
|
98
|
+
if (isQys && archivedOnly === true) {
|
|
99
|
+
extra.push({
|
|
100
|
+
field: QYS_DEFAULT_ARCHIVED_FIELD,
|
|
101
|
+
conditionType: 'like',
|
|
102
|
+
value: QYS_DEFAULT_ARCHIVED_VALUE,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const commonSearchFields = buildCommonSearchFields(args.fields, extra);
|
|
106
|
+
const response = await env.host.request({
|
|
107
|
+
method: 'POST',
|
|
108
|
+
path: CONTRACT_LIST_PATH,
|
|
109
|
+
operation: name,
|
|
110
|
+
query: { passid: profile.passId, cid: profile.passId, sf_request_type: 'ajax' },
|
|
111
|
+
body: listBody(profile, pageNo, commonSearchFields, matchType),
|
|
112
|
+
});
|
|
113
|
+
const { rows, meta } = normalizeListResult(name, response, profile.source);
|
|
114
|
+
return archiveOaSuccess(name, { rows, searchFields: commonSearchFields }, { ...meta, pageNo, archivedOnly: isQys ? archivedOnly : undefined });
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export const weaverContractFieldsOperation = makeFieldsOperation(WEAVER_CONTRACT);
|
|
119
|
+
export const weaverContractListOperation = makeListOperation(WEAVER_CONTRACT);
|
|
120
|
+
export const qysContractListOperation = makeListOperation(QYS_CONTRACT);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ARCHIVE_LOCATE_PATH } from '../constants.js';
|
|
2
|
+
import { READ, archiveOaSuccess, schemaOf, SCHEMA_PAGE_NO, } from './types.js';
|
|
3
|
+
import { positiveInt, requireText } from './shared.js';
|
|
4
|
+
export const ARCHIVE_LOCATE = 'archive-oa.archive.locate';
|
|
5
|
+
/**
|
|
6
|
+
* 按合同号定位档案。
|
|
7
|
+
*
|
|
8
|
+
* 接口契约要点(源资料实测):合同号必须放在 body 顶层 `htbh`;
|
|
9
|
+
* 放进 `datajson.mainTable` 会被忽略并返回整表默认列表。
|
|
10
|
+
*/
|
|
11
|
+
export const archiveLocateOperation = {
|
|
12
|
+
name: ARCHIVE_LOCATE,
|
|
13
|
+
resource: 'archive',
|
|
14
|
+
method: 'locate',
|
|
15
|
+
action: ARCHIVE_LOCATE,
|
|
16
|
+
summary: '按合同号定位档案:返回档案记录 ID / 题名 / 合同号',
|
|
17
|
+
capability: 'archive-locate',
|
|
18
|
+
risk: READ,
|
|
19
|
+
inputSchema: schemaOf({
|
|
20
|
+
contractNo: { type: 'string', minLength: 1, description: '合同号(对应接口顶层 htbh)' },
|
|
21
|
+
pageNo: { ...SCHEMA_PAGE_NO, description: '页码,从 1 开始,缺省 1' },
|
|
22
|
+
}, { required: ['contractNo'], description: '按合同号定位档案' }),
|
|
23
|
+
handler: async (args, env) => {
|
|
24
|
+
const contractNo = requireText(args.contractNo, 'contractNo');
|
|
25
|
+
const pageNo = positiveInt(args.pageNo, 'pageNo', 1);
|
|
26
|
+
const response = await env.host.request({
|
|
27
|
+
method: 'POST',
|
|
28
|
+
path: ARCHIVE_LOCATE_PATH,
|
|
29
|
+
operation: ARCHIVE_LOCATE,
|
|
30
|
+
body: {
|
|
31
|
+
htbh: contractNo,
|
|
32
|
+
datajson: {
|
|
33
|
+
mainTable: {},
|
|
34
|
+
pageInfo: { pageNo: String(pageNo) },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
const datajson = (response?.datajson ?? {});
|
|
39
|
+
const datas = Array.isArray(datajson.datas) ? datajson.datas : [];
|
|
40
|
+
const rows = datas.map((item) => {
|
|
41
|
+
const mainTable = (item?.mainTable ?? {});
|
|
42
|
+
return {
|
|
43
|
+
id: String(mainTable.id ?? '').trim(),
|
|
44
|
+
title: String(mainTable.folder_title ?? '').trim(),
|
|
45
|
+
contractNo: String(mainTable.hth ?? contractNo).trim(),
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
return archiveOaSuccess(ARCHIVE_LOCATE, { rows, matched: rows.length > 0 }, { count: rows.length, contractNo, pageNo });
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { QYS_BORROW_CAR, QYS_ESB_ADD, WEAVER_BORROW_CAR, WEAVER_ESB_ADD } from '../constants.js';
|
|
2
|
+
import { archiveOaValidationError } from '../errors.js';
|
|
3
|
+
import { createBorrowCarOperations } from './borrow-car.js';
|
|
4
|
+
import { createBorrowStartUrlOperation } from './borrow-url.js';
|
|
5
|
+
import { qysContractListOperation, weaverContractFieldsOperation, weaverContractListOperation, } from './contract.js';
|
|
6
|
+
import { archiveLocateOperation } from './locate.js';
|
|
7
|
+
function buildRegistry() {
|
|
8
|
+
const registry = new Map();
|
|
9
|
+
const definitions = [
|
|
10
|
+
archiveLocateOperation,
|
|
11
|
+
weaverContractFieldsOperation,
|
|
12
|
+
weaverContractListOperation,
|
|
13
|
+
qysContractListOperation,
|
|
14
|
+
...createBorrowCarOperations(WEAVER_BORROW_CAR, WEAVER_ESB_ADD),
|
|
15
|
+
...createBorrowCarOperations(QYS_BORROW_CAR, QYS_ESB_ADD),
|
|
16
|
+
createBorrowStartUrlOperation(WEAVER_BORROW_CAR),
|
|
17
|
+
createBorrowStartUrlOperation(QYS_BORROW_CAR),
|
|
18
|
+
];
|
|
19
|
+
for (const definition of definitions) {
|
|
20
|
+
if (registry.has(definition.name)) {
|
|
21
|
+
throw new Error(`duplicate archive-oa operation: ${definition.name}`);
|
|
22
|
+
}
|
|
23
|
+
registry.set(definition.name, definition);
|
|
24
|
+
}
|
|
25
|
+
return registry;
|
|
26
|
+
}
|
|
27
|
+
const archiveOaOperationRegistry = buildRegistry();
|
|
28
|
+
export function archiveOaOperationDefinitions() {
|
|
29
|
+
return [...archiveOaOperationRegistry.values()];
|
|
30
|
+
}
|
|
31
|
+
export function getArchiveOaOperation(operation) {
|
|
32
|
+
const definition = archiveOaOperationRegistry.get(operation);
|
|
33
|
+
if (!definition) {
|
|
34
|
+
throw archiveOaValidationError('operation_unknown', `archive-oa 不支持操作:${operation}`);
|
|
35
|
+
}
|
|
36
|
+
return definition;
|
|
37
|
+
}
|
|
38
|
+
export function hasArchiveOaOperation(operation) {
|
|
39
|
+
return archiveOaOperationRegistry.has(operation);
|
|
40
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { MAX_BORROW_ITEMS } from '../constants.js';
|
|
2
|
+
import { archiveOaValidationError } from '../errors.js';
|
|
3
|
+
/** 原型污染防护:禁止出现在输入对象中的键。 */
|
|
4
|
+
const FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
|
|
5
|
+
const CONDITION_TYPES = new Set(['like', 'between', 'in', 'inC']);
|
|
6
|
+
export function asObject(value) {
|
|
7
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
8
|
+
throw archiveOaValidationError('input_not_object', '输入必须是 JSON 对象');
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
export function assertNoForbiddenKeys(input) {
|
|
13
|
+
for (const key of Object.keys(input)) {
|
|
14
|
+
if (FORBIDDEN_KEYS.has(key)) {
|
|
15
|
+
throw archiveOaValidationError('forbidden_key', `输入包含非法字段:${key}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** 取出响应中的业务数据。 */
|
|
20
|
+
export function unwrapData(response) {
|
|
21
|
+
if (!response || typeof response !== 'object')
|
|
22
|
+
return response;
|
|
23
|
+
return response.data;
|
|
24
|
+
}
|
|
25
|
+
/** 正整数入参(页码)。 */
|
|
26
|
+
export function positiveInt(value, field, fallback) {
|
|
27
|
+
if (value === undefined || value === null || value === '')
|
|
28
|
+
return fallback;
|
|
29
|
+
const parsed = Number(value);
|
|
30
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
31
|
+
throw archiveOaValidationError('number_invalid', `${field} 必须是正整数`);
|
|
32
|
+
}
|
|
33
|
+
return parsed;
|
|
34
|
+
}
|
|
35
|
+
/** 非空字符串。 */
|
|
36
|
+
export function requireText(value, field) {
|
|
37
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
38
|
+
throw archiveOaValidationError('field_required', `${field} 必填`);
|
|
39
|
+
}
|
|
40
|
+
return value.trim();
|
|
41
|
+
}
|
|
42
|
+
/** 安全布尔。 */
|
|
43
|
+
export function requireBoolean(value, field) {
|
|
44
|
+
if (typeof value !== 'boolean') {
|
|
45
|
+
throw archiveOaValidationError('boolean_invalid', `${field} 必须是布尔值`);
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
/** 校验枚举。 */
|
|
50
|
+
export function assertEnum(value, allowed, field) {
|
|
51
|
+
const text = typeof value === 'string' ? value : String(value);
|
|
52
|
+
if (!allowed.includes(text)) {
|
|
53
|
+
throw archiveOaValidationError('enum_invalid', `${field} 取值必须是 ${allowed.join(' / ')} 之一`);
|
|
54
|
+
}
|
|
55
|
+
return text;
|
|
56
|
+
}
|
|
57
|
+
/** 数字 ID 数组(合同数据行 id / 借阅车记录 id)。 */
|
|
58
|
+
export function requireIdList(value, field, max = MAX_BORROW_ITEMS) {
|
|
59
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
60
|
+
throw archiveOaValidationError('id_list_required', `${field} 必填且至少一项`);
|
|
61
|
+
}
|
|
62
|
+
if (value.length > max) {
|
|
63
|
+
throw archiveOaValidationError('id_list_too_many', `${field} 最多 ${max} 条,当前 ${value.length} 条`);
|
|
64
|
+
}
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
return value.map((item, index) => {
|
|
67
|
+
const text = typeof item === 'string' ? item.trim() : String(item ?? '').trim();
|
|
68
|
+
if (!/^\d+$/.test(text)) {
|
|
69
|
+
throw archiveOaValidationError('id_list_invalid', `${field}[${index}] 必须是数字 ID`);
|
|
70
|
+
}
|
|
71
|
+
if (seen.has(text)) {
|
|
72
|
+
throw archiveOaValidationError('id_list_duplicated', `${field}[${index}] 重复:${text}`);
|
|
73
|
+
}
|
|
74
|
+
seen.add(text);
|
|
75
|
+
return text;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/** 合同号数组(发起借阅的 hth)。 */
|
|
79
|
+
export function requireContractNoList(value, field, max = MAX_BORROW_ITEMS) {
|
|
80
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
81
|
+
throw archiveOaValidationError('contract_no_required', `${field} 必填且至少一项`);
|
|
82
|
+
}
|
|
83
|
+
if (value.length > max) {
|
|
84
|
+
throw archiveOaValidationError('contract_no_too_many', `${field} 最多 ${max} 个,当前 ${value.length} 个`);
|
|
85
|
+
}
|
|
86
|
+
return value.map((item, index) => {
|
|
87
|
+
if (typeof item !== 'string' || !item.trim()) {
|
|
88
|
+
throw archiveOaValidationError('contract_no_invalid', `${field}[${index}] 必须是非空合同号`);
|
|
89
|
+
}
|
|
90
|
+
const text = item.trim();
|
|
91
|
+
if (/[,\s]/.test(text)) {
|
|
92
|
+
throw archiveOaValidationError('contract_no_invalid', `${field}[${index}] 不能包含逗号或空白`);
|
|
93
|
+
}
|
|
94
|
+
return text;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 组装 getListDatas 的 commonSearchFields。
|
|
99
|
+
*
|
|
100
|
+
* 契约:`{ "<field>": [{ "<field>_condition_type": "<type>", "<field>": <value> }] }`。
|
|
101
|
+
* between 的值既支持 `{min,max}` 也支持 `[起,止]`;in / inC 的值必须是数组。
|
|
102
|
+
*/
|
|
103
|
+
export function buildCommonSearchFields(fields, extra = []) {
|
|
104
|
+
const result = {};
|
|
105
|
+
const items = [...extra];
|
|
106
|
+
if (fields !== undefined && fields !== null) {
|
|
107
|
+
if (!Array.isArray(fields)) {
|
|
108
|
+
throw archiveOaValidationError('search_fields_invalid', 'fields 必须是数组');
|
|
109
|
+
}
|
|
110
|
+
for (const [index, raw] of fields.entries()) {
|
|
111
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
112
|
+
throw archiveOaValidationError('search_fields_invalid', `fields[${index}] 必须是对象`);
|
|
113
|
+
}
|
|
114
|
+
const item = raw;
|
|
115
|
+
const field = requireText(item.field, `fields[${index}].field`);
|
|
116
|
+
const conditionType = item.conditionType === undefined || item.conditionType === null
|
|
117
|
+
? 'like'
|
|
118
|
+
: String(item.conditionType);
|
|
119
|
+
if (!CONDITION_TYPES.has(conditionType)) {
|
|
120
|
+
throw archiveOaValidationError('search_condition_invalid', `fields[${index}].conditionType 必须是 like / between / in / inC 之一`);
|
|
121
|
+
}
|
|
122
|
+
if (item.value === undefined || item.value === null) {
|
|
123
|
+
throw archiveOaValidationError('search_value_required', `fields[${index}].value 必填`);
|
|
124
|
+
}
|
|
125
|
+
items.push({ field, conditionType, value: item.value });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const item of items) {
|
|
129
|
+
const value = normalizeConditionValue(item.conditionType, item.value, item.field);
|
|
130
|
+
result[item.field] = [{ [`${item.field}_condition_type`]: item.conditionType, [item.field]: value }];
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
function normalizeConditionValue(conditionType, value, field) {
|
|
135
|
+
if (conditionType === 'between') {
|
|
136
|
+
if (Array.isArray(value)) {
|
|
137
|
+
if (value.length !== 2) {
|
|
138
|
+
throw archiveOaValidationError('search_value_invalid', `${field} 的 between 条件需要两个值`);
|
|
139
|
+
}
|
|
140
|
+
return { min: String(value[0]), max: String(value[1]) };
|
|
141
|
+
}
|
|
142
|
+
if (value && typeof value === 'object') {
|
|
143
|
+
const range = value;
|
|
144
|
+
if (range.min === undefined || range.max === undefined) {
|
|
145
|
+
throw archiveOaValidationError('search_value_invalid', `${field} 的 between 条件需要 min / max`);
|
|
146
|
+
}
|
|
147
|
+
return { min: String(range.min), max: String(range.max) };
|
|
148
|
+
}
|
|
149
|
+
throw archiveOaValidationError('search_value_invalid', `${field} 的 between 条件必须是 {min,max} 或 [起,止]`);
|
|
150
|
+
}
|
|
151
|
+
if (conditionType === 'in' || conditionType === 'inC') {
|
|
152
|
+
if (!Array.isArray(value)) {
|
|
153
|
+
throw archiveOaValidationError('search_value_invalid', `${field} 的 ${conditionType} 条件必须是数组`);
|
|
154
|
+
}
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
159
|
+
/** 从 getListDatas 响应里提取行与列,并对内部 ID 做静默缓存(不回显给模型以外的地方)。 */
|
|
160
|
+
export function normalizeListResult(action, response, source) {
|
|
161
|
+
const data = (unwrapData(response) ?? {});
|
|
162
|
+
const rows = Array.isArray(data.data) ? data.data : [];
|
|
163
|
+
const columns = Array.isArray(data.columns)
|
|
164
|
+
? data.columns.map((column) => ({
|
|
165
|
+
title: String(column?.title ?? ''),
|
|
166
|
+
dataIndex: String(column?.dataIndex ?? ''),
|
|
167
|
+
}))
|
|
168
|
+
: [];
|
|
169
|
+
return {
|
|
170
|
+
rows,
|
|
171
|
+
meta: {
|
|
172
|
+
source,
|
|
173
|
+
count: rows.length,
|
|
174
|
+
current: data.current ?? undefined,
|
|
175
|
+
pageSize: data.pageSize ?? undefined,
|
|
176
|
+
/** 接口可能返回 total=0 但 data 非空,属于正常现象,不做无数据判定。 */
|
|
177
|
+
total: data.total ?? undefined,
|
|
178
|
+
columns,
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const READ = 'read';
|
|
2
|
+
export const READ_BEFORE_WRITE = 'read-before-write';
|
|
3
|
+
export const HIGH_RISK_WRITE = 'high-risk-write';
|
|
4
|
+
export function archiveOaSuccess(action, data, meta) {
|
|
5
|
+
const payload = { ok: true, action, data };
|
|
6
|
+
if (meta && Object.keys(meta).length > 0)
|
|
7
|
+
payload.meta = meta;
|
|
8
|
+
return payload;
|
|
9
|
+
}
|
|
10
|
+
/** 构造「对象类型 + 严格禁止额外字段」的 JSON Schema。 */
|
|
11
|
+
export function schemaOf(properties, options = {}) {
|
|
12
|
+
return {
|
|
13
|
+
type: 'object',
|
|
14
|
+
additionalProperties: false,
|
|
15
|
+
properties,
|
|
16
|
+
...(options.required?.length ? { required: options.required } : {}),
|
|
17
|
+
...(options.description ? { description: options.description } : {}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export const SCHEMA_PAGE_NO = { type: 'integer', minimum: 1 };
|
|
21
|
+
export const SCHEMA_ID_STRING = { type: 'string', pattern: '^\\d+$' };
|
|
22
|
+
export const SCHEMA_ID_LIST = { type: 'array', items: SCHEMA_ID_STRING, minItems: 1 };
|
|
23
|
+
export const SCHEMA_CONTRACT_NO_LIST = {
|
|
24
|
+
type: 'array',
|
|
25
|
+
items: { type: 'string', minLength: 1 },
|
|
26
|
+
minItems: 1,
|
|
27
|
+
};
|
|
28
|
+
export const SCHEMA_SEARCH_FIELDS = {
|
|
29
|
+
type: 'array',
|
|
30
|
+
description: '搜索条件数组,元素为 { field, conditionType, value }',
|
|
31
|
+
items: {
|
|
32
|
+
type: 'object',
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
required: ['field', 'value'],
|
|
35
|
+
properties: {
|
|
36
|
+
field: { type: 'string', minLength: 1, description: '字段内部名,如 hth / khmc / htzje / zxfa' },
|
|
37
|
+
conditionType: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
enum: ['like', 'between', 'in', 'inC'],
|
|
40
|
+
description: '条件类型,缺省 like;between 用 {min,max} 或 [起,止];in/inC 用数组',
|
|
41
|
+
},
|
|
42
|
+
value: { description: '条件值:like 为字符串,between 为对象或二元数组,in/inC 为数组' },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getArchiveOaOperation } from './operations/registry.js';
|
|
2
|
+
import { asObject, assertNoForbiddenKeys } from './operations/shared.js';
|
|
3
|
+
/**
|
|
4
|
+
* 执行一个 archive-oa 操作。操作定义(入参 schema、风险等级、是否必须确认)
|
|
5
|
+
* 全部来自 operations/registry,CLI 侧只负责校验输入形状。
|
|
6
|
+
*/
|
|
7
|
+
export async function executeArchiveOaOperation(operation, rawInput, env) {
|
|
8
|
+
const definition = getArchiveOaOperation(operation);
|
|
9
|
+
const input = asObject(rawInput);
|
|
10
|
+
assertNoForbiddenKeys(input);
|
|
11
|
+
return definition.handler(input, { ctx: env.ctx, host: env.host, continuation: env.continuation });
|
|
12
|
+
}
|
|
13
|
+
export { archiveOaOperationDefinitions, getArchiveOaOperation, hasArchiveOaOperation } from './operations/registry.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
1
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
2
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
3
4
|
import { createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -176,7 +177,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
176
177
|
bigIntStrings: true,
|
|
177
178
|
});
|
|
178
179
|
if (response.status === 401 || response.status === 302) {
|
|
179
|
-
throw ziguanjiaAuthError('session_expired',
|
|
180
|
+
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
180
181
|
}
|
|
181
182
|
if (response.parseError) {
|
|
182
183
|
throw ziguanjiaNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
@@ -242,7 +243,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
242
243
|
bigIntStrings: false,
|
|
243
244
|
});
|
|
244
245
|
if (response.status === 401 || response.status === 302) {
|
|
245
|
-
throw ziguanjiaAuthError('session_expired',
|
|
246
|
+
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
246
247
|
}
|
|
247
248
|
if (response.parseError) {
|
|
248
249
|
throw ziguanjiaNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
@@ -315,7 +316,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
315
316
|
bigIntStrings: true,
|
|
316
317
|
});
|
|
317
318
|
if (response.status === 401 || response.status === 302) {
|
|
318
|
-
throw ziguanjiaAuthError('session_expired',
|
|
319
|
+
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
319
320
|
}
|
|
320
321
|
if (response.parseError) {
|
|
321
322
|
throw ziguanjiaNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
@@ -340,7 +341,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
340
341
|
}
|
|
341
342
|
function handleEbusiness(value) {
|
|
342
343
|
if (isEbSessionExpired(value)) {
|
|
343
|
-
throw ziguanjiaAuthError('session_expired',
|
|
344
|
+
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { ret: ebCode(value) });
|
|
344
345
|
}
|
|
345
346
|
const code = ebCode(value);
|
|
346
347
|
if (!isEbSuccessCode(code)) {
|
|
@@ -363,7 +364,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
363
364
|
bigIntStrings: true,
|
|
364
365
|
});
|
|
365
366
|
if (response.status === 401 || response.status === 302) {
|
|
366
|
-
throw ziguanjiaAuthError('session_expired',
|
|
367
|
+
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
367
368
|
}
|
|
368
369
|
if (response.parseError) {
|
|
369
370
|
throw ziguanjiaNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
@@ -393,7 +394,7 @@ export function createZiguanjiaHost(ctx) {
|
|
|
393
394
|
bigIntStrings: true,
|
|
394
395
|
});
|
|
395
396
|
if (response.status === 401 || response.status === 302) {
|
|
396
|
-
throw ziguanjiaAuthError('session_expired',
|
|
397
|
+
throw ziguanjiaAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
397
398
|
}
|
|
398
399
|
if (response.parseError) {
|
|
399
400
|
throw ziguanjiaNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, { retryable: false });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ExitCode } from '../../core/errors.js';
|
|
2
|
+
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
2
3
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
3
4
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
4
5
|
import { createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -75,7 +76,7 @@ export function createBlogHost(ctx, dependencies = {}) {
|
|
|
75
76
|
}
|
|
76
77
|
function assertSession(value) {
|
|
77
78
|
if (isSessionExpired(value)) {
|
|
78
|
-
throw blogAuthError('session_expired',
|
|
79
|
+
throw blogAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE);
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
async function blogRequest(request) {
|
|
@@ -91,7 +92,7 @@ export function createBlogHost(ctx, dependencies = {}) {
|
|
|
91
92
|
timeoutMs,
|
|
92
93
|
});
|
|
93
94
|
if (response.status === 401 || response.status === 302) {
|
|
94
|
-
throw blogAuthError('session_expired',
|
|
95
|
+
throw blogAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
95
96
|
}
|
|
96
97
|
if (response.parseError) {
|
|
97
98
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -134,7 +135,7 @@ export function createBlogHost(ctx, dependencies = {}) {
|
|
|
134
135
|
headers: { Accept: 'application/octet-stream, */*' },
|
|
135
136
|
});
|
|
136
137
|
if (response.status === 401 || response.status === 302) {
|
|
137
|
-
throw blogAuthError('session_expired',
|
|
138
|
+
throw blogAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
138
139
|
}
|
|
139
140
|
const contentType = response.contentType;
|
|
140
141
|
const declaredLength = Number(response.headers.get('content-length'));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
1
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
2
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
3
4
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -152,7 +153,7 @@ export function createCaizhilianHost(ctx, dependencies = {}) {
|
|
|
152
153
|
async function request(request) {
|
|
153
154
|
const response = await doRequest(request, false).catch((error) => mapRuntimeNetworkError(error));
|
|
154
155
|
if (response.status === 401 || response.status === 302) {
|
|
155
|
-
throw caizhilianAuthError('session_expired',
|
|
156
|
+
throw caizhilianAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
156
157
|
}
|
|
157
158
|
if (response.parseError) {
|
|
158
159
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -183,7 +184,7 @@ export function createCaizhilianHost(ctx, dependencies = {}) {
|
|
|
183
184
|
async function requestBinary(request) {
|
|
184
185
|
const response = await doRequest(request, true).catch((error) => mapRuntimeNetworkError(error));
|
|
185
186
|
if (response.status === 401 || response.status === 302) {
|
|
186
|
-
throw caizhilianAuthError('session_expired',
|
|
187
|
+
throw caizhilianAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
187
188
|
}
|
|
188
189
|
if (response.status < 200 || response.status >= 300) {
|
|
189
190
|
throw new CaizhilianCliError('api', 'http_error', `采知连下载 HTTP ${response.status}`, {
|
|
@@ -19,7 +19,7 @@ const WITHHELD = [
|
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
name: 'caizhilian.system.switch-config',
|
|
22
|
-
reason: '源 switch_config 在 Skill 本地多套环境配置间切换;CLI
|
|
22
|
+
reason: '源 switch_config 在 Skill 本地多套环境配置间切换;CLI 的环境与认证配置体系负责这一职责,业务模块不做环境切换。',
|
|
23
23
|
},
|
|
24
24
|
];
|
|
25
25
|
function buildOperations() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
1
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
2
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
3
4
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
@@ -110,7 +111,7 @@ export function createCalendarHost(ctx, dependencies = {}) {
|
|
|
110
111
|
mapRuntimeNetworkError(error);
|
|
111
112
|
}
|
|
112
113
|
if (response.status === 401 || response.status === 302) {
|
|
113
|
-
throw calendarAuthError('session_expired',
|
|
114
|
+
throw calendarAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
114
115
|
}
|
|
115
116
|
if (response.parseError) {
|
|
116
117
|
if (response.status < 200 || response.status >= 300) {
|