weaver-work-cli 0.1.38 → 0.1.40
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 +7 -3
- package/dist/chunks/{archive-PDV724YK.js → archive-JHTONRST.js} +556 -66
- package/dist/chunks/{archive-oa-4XE4MNXQ.js → archive-oa-FCHLCPHC.js} +2 -2
- package/dist/chunks/{asset-PDL2QE2N.js → asset-RLIHC7DB.js} +2 -2
- package/dist/chunks/asset-idle-KVOFTLCP.js +670 -0
- package/dist/chunks/{attachment-content-MDDGOE5E.js → attachment-content-RZYDB3MB.js} +3 -3
- package/dist/chunks/{blog-UYR3EUXW.js → blog-42OZTJNP.js} +2 -2
- package/dist/chunks/{caizhilian-LG2X5NMF.js → caizhilian-KRK547K5.js} +2 -2
- package/dist/chunks/{calendar-FG4BAZHE.js → calendar-RTWAMKHD.js} +2 -2
- package/dist/chunks/{chunk-J7USS3ED.js → chunk-4CTESSKI.js} +4 -4
- package/dist/chunks/{chunk-OJQUJZQF.js → chunk-4TEDNCON.js} +45 -5
- package/dist/chunks/chunk-57IECMWX.js +487 -0
- package/dist/chunks/{chunk-ELYDWBZJ.js → chunk-7BRU4EFH.js} +13 -7
- package/dist/chunks/{chunk-6LTFIFLM.js → chunk-7E6MUOEK.js} +2 -2
- package/dist/chunks/{chunk-KKRL3REV.js → chunk-7U577Q7U.js} +2 -2
- package/dist/chunks/{chunk-UJJD4QWF.js → chunk-CAQNBBQA.js} +2 -2
- package/dist/chunks/{chunk-CORFRD7Q.js → chunk-CXRQWOZ5.js} +2 -2
- package/dist/chunks/{chunk-GGJFMNJM.js → chunk-FLS4DPGP.js} +110 -16
- package/dist/chunks/{chunk-JSMFPO43.js → chunk-I566ZYNF.js} +1 -1
- package/dist/chunks/{chunk-6FTTSA45.js → chunk-IZSSVYAG.js} +2 -2
- package/dist/chunks/{chunk-XJY7G4DD.js → chunk-JWRZM2H2.js} +3 -3
- package/dist/chunks/{chunk-NI6GIPIM.js → chunk-LFMSDBZN.js} +529 -395
- package/dist/chunks/{chunk-VRYHGG6O.js → chunk-LN447PY2.js} +92 -51
- package/dist/chunks/{chunk-NR6RKXPA.js → chunk-NETCCARD.js} +4 -2
- package/dist/chunks/{chunk-Z32KWY6G.js → chunk-NJKREDA3.js} +1 -1
- package/dist/chunks/{chunk-FUWVHMVV.js → chunk-SPRHHSVC.js} +2 -2
- package/dist/chunks/{chunk-IZUDA353.js → chunk-T6EGVBKU.js} +1 -1
- package/dist/chunks/{chunk-DMV2TOMH.js → chunk-VNBU55SL.js} +428 -145
- package/dist/chunks/{chunk-UZZBA6PV.js → chunk-WFFNM65B.js} +47 -6
- package/dist/chunks/{chunk-EG6ZU444.js → chunk-ZUX3P6BQ.js} +10 -5
- package/dist/chunks/{conflict-BQZEQ4SP.js → conflict-VR55AOOO.js} +2 -2
- package/dist/chunks/{contract-XIRAFTEV.js → contract-HI4FNPYE.js} +2 -2
- package/dist/chunks/{cowork-BLG62BL2.js → cowork-HJLI353D.js} +12 -5
- package/dist/chunks/{ebuilder-form-NUKG5QW4.js → ebuilder-form-HTGI63UU.js} +3 -3
- package/dist/chunks/{ehr-2STW5ILH.js → ehr-GYXIYH3A.js} +2 -2
- package/dist/chunks/env-DW3G4HUO.js +19 -0
- package/dist/chunks/{esb-UUDQUNKY.js → esb-I5INCEFE.js} +4 -4
- package/dist/chunks/factory-TKXGXS6L.js +30 -0
- package/dist/chunks/{fna-6RCY4NU5.js → fna-K2MHTQ24.js} +2 -2
- package/dist/chunks/group-chat-VYBNMJLG.js +18 -0
- package/dist/chunks/{host-FWDOSRH5.js → host-256GVCAH.js} +3 -3
- package/dist/chunks/{host-EJZFROU3.js → host-D5SERMAJ.js} +3 -3
- package/dist/chunks/{host-RHM3NPXV.js → host-JM4YVHFM.js} +3 -3
- package/dist/chunks/{host-7RXEDMAH.js → host-L3VLITMT.js} +3 -3
- package/dist/chunks/{host-UFF33TWJ.js → host-ZUQTJYYK.js} +3 -3
- package/dist/chunks/{hrm-PKJ6ELSH.js → hrm-VLRBKTZB.js} +3 -3
- package/dist/chunks/{im-YJAXS7CO.js → im-QK3VTLXK.js} +8 -8
- package/dist/chunks/{invoice-HWVSXGX6.js → invoice-T5JTA32H.js} +3 -3
- package/dist/chunks/{jiuchuanhui-L7VKILZB.js → jiuchuanhui-P2FNEQVZ.js} +2 -2
- package/dist/chunks/{lazy-dispatch-NMYEIHRH.js → lazy-dispatch-XRRI46M6.js} +5 -5
- package/dist/chunks/{mail-B42RRU7G.js → mail-3Y7MJ6PS.js} +9 -4
- package/dist/chunks/{meeting-CFYVBJSS.js → meeting-M7LTXGJE.js} +11 -10
- package/dist/chunks/{okr-GCLF6V7W.js → okr-OBC6S67L.js} +2 -2
- package/dist/chunks/{plan-ZVL7GBRI.js → plan-5H6I53SK.js} +2 -2
- package/dist/chunks/{project-4YWAAE2K.js → project-L75QZV4S.js} +2 -2
- package/dist/chunks/{registry-EP4VTHZS.js → registry-KMHCPAAD.js} +9 -8
- package/dist/chunks/{registry-OZSMDVPP.js → registry-QGHFNUWS.js} +2 -2
- package/dist/chunks/{registry-FRJ6H7BT.js → registry-RXPN6BBT.js} +4 -4
- package/dist/chunks/{registry-SG2PGVCF.js → registry-UGRBCBHO.js} +3 -3
- package/dist/chunks/{room-recommend-R3JVUUAC.js → room-recommend-A3UDC3CA.js} +4 -4
- package/dist/chunks/{schedule-NIJBTYDO.js → schedule-5GCACCK7.js} +4 -4
- package/dist/chunks/{workflow-BB24DFBY.js → workflow-M5ZJ7DWF.js} +11 -8
- package/dist/core/output.js +16 -6
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/commands.js +109 -56
- package/dist/internal/e10/auth/messages.js +1 -0
- package/dist/internal/e10/auth/session.js +11 -1
- package/dist/internal/e10/auth/xiaoe.js +29 -4
- package/dist/internal/e10/auth-recovery.js +13 -6
- package/dist/internal/e10/client.js +13 -0
- package/dist/internal/e10/context.js +24 -3
- package/dist/internal/e10/request-runtime.js +12 -1
- package/dist/shortcuts/archive/host.js +2 -0
- package/dist/shortcuts/archive/manifest.js +1 -1
- package/dist/shortcuts/archive/operations/borrow-list.js +13 -1
- package/dist/shortcuts/archive/operations/flow-url.js +1 -1
- package/dist/shortcuts/archive/operations/prelib.js +472 -0
- package/dist/shortcuts/archive/operations/registry.js +2 -0
- package/dist/shortcuts/archive/operations/upload.js +1 -1
- package/dist/shortcuts/asset-idle/errors.js +44 -0
- package/dist/shortcuts/asset-idle/host.js +161 -0
- package/dist/shortcuts/asset-idle/index.js +114 -0
- package/dist/shortcuts/asset-idle/manifest.js +159 -0
- package/dist/shortcuts/asset-idle/operations/idle.js +47 -0
- package/dist/shortcuts/asset-idle/operations/registry.js +33 -0
- package/dist/shortcuts/asset-idle/operations/shared.js +142 -0
- package/dist/shortcuts/asset-idle/operations/types.js +9 -0
- package/dist/shortcuts/asset-idle/operations.js +15 -0
- package/dist/shortcuts/cowork/operations/item-write.js +10 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/mail/operations/mail-send.js +8 -2
- package/dist/shortcuts/meeting/operations/eb/catalog.js +5 -1
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +381 -104
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +87 -5
- package/dist/shortcuts/meeting/operations/eb/flow-memory.js +49 -0
- package/dist/shortcuts/meeting/operations/eb/group-chat.js +583 -0
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +19 -3
- package/dist/shortcuts/meeting/operations/eb/room-summary.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/usage-cache.js +99 -0
- package/dist/shortcuts/meeting/operations/from-group-chat.js +35 -12
- package/dist/shortcuts/workflow/host.js +3 -0
- package/dist/shortcuts/workflow/index.js +1 -1
- package/dist/shortcuts/workflow/operations/form.js +65 -171
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +129 -27
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +6 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +60 -117
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +44 -7
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +37 -29
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +48 -8
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +1 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +22 -18
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +17 -9
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +34 -10
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +5 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +9 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +122 -20
- package/docs/_catalog.md +3 -0
- package/docs/asset-idle.md +45 -0
- package/docs/e10-auth.md +16 -1
- package/docs/todo-smart-convert/subgroup-rules.md +1 -1
- package/package.json +1 -1
- package/scripts/mcp-meeting.mjs +234 -0
- package/scripts/package-skill.mjs +2 -0
- package/skill-template/business-info.json +14 -1
- package/skill-template/domains/asset-idle.md +13 -0
- package/skill-template/domains/wenshuding.md +3 -0
- package/skills/weaver-e10-archive-oa/SKILL.md +1 -0
- package/skills/weaver-e10-archive-oa/references/my-borrow.md +49 -0
- package/skills/weaver-e10-asset-idle/SKILL.md +73 -0
- package/skills/weaver-e10-asset-idle/references/idle-list.md +62 -0
- package/skills/weaver-e10-asset-idle/references/idle-stats-and-charts.md +65 -0
- package/skills/weaver-e10-asset-idle/references/source-manifest.json +193 -0
- package/skills/weaver-e10-asset-idle/references/widget-style.md +205 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +29 -11
- package/skills/weaver-e10-caizhilian/references/auth-and-install.md +12 -0
- package/skills/weaver-e10-caizhilian/references/files.md +1 -1
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +1 -1
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +45 -45
- package/skills/weaver-e10-cowork/SKILL.md +2 -0
- package/skills/weaver-e10-cowork/references/cowork-write.md +1 -1
- package/skills/weaver-e10-jucailin/SKILL.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +1 -1
- package/skills/weaver-e10-mail/SKILL.md +3 -0
- package/skills/weaver-e10-mail/references/mail-send.md +2 -0
- package/skills/weaver-e10-meeting/SKILL.md +88 -25
- package/skills/weaver-e10-meeting/references/meeting-minute-file.md +25 -11
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-shared/SKILL.md +5 -5
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +3 -3
- package/skills/weaver-e10-wenshuding/SKILL.md +29 -6
- package/skills/weaver-e10-wenshuding/references/archive-borrow-list.md +14 -0
- package/skills/weaver-e10-wenshuding/references/archive-download.md +2 -0
- package/skills/weaver-e10-wenshuding/references/archive-flow.md +1 -1
- package/skills/weaver-e10-wenshuding/references/archive-prelib-arrange.md +76 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-list.md +107 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-open.md +59 -0
- package/skills/weaver-e10-wenshuding/references/archive-upload.md +4 -1
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +108 -65
- package/skills/weaver-e10-workflow/SKILL.md +9 -2
- package/skills/weaver-e10-workflow/aigroup/default.json +166 -19
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +72 -34
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +113 -25
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +350 -50
- package/dist/chunks/{chunk-2LV74IWP.js → chunk-E7OK5WD5.js} +5 -5
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { archiveValidationError } from '../errors.js';
|
|
3
|
+
import { READ, WRITE, archiveSuccess, schemaOf, } from './types.js';
|
|
4
|
+
import { positiveInt, toStringIdList, unwrapData } from './shared.js';
|
|
5
|
+
import { issueLease, verifyLease } from './confirm.js';
|
|
6
|
+
/**
|
|
7
|
+
* 预归档电子文件库列表链路。
|
|
8
|
+
*
|
|
9
|
+
* 链路(依据真实抓包):
|
|
10
|
+
* 1. getTree(treeType=4, menuSign=preLib)→ 识别电子文件库节点 treeId 与节点名
|
|
11
|
+
* 2. getTreeDetail(treeId)→ url1(列表视图地址,尾段即 listId)+ extraParams(metaFormId / tag)
|
|
12
|
+
* 3. getListDatas(passid=cid=metaFormId)→ 列表列与数据行
|
|
13
|
+
*
|
|
14
|
+
* 智能识别:勾选列表行 → intelligentCate(treeId + checkIds + formId)→ 返回识别任务 taskId。
|
|
15
|
+
*/
|
|
16
|
+
const PRELIB_MENU_SIGN = 'preLib';
|
|
17
|
+
const PRELIB_TREE_TYPE = '4';
|
|
18
|
+
const PRELIB_NODE_TYPE = 2;
|
|
19
|
+
const PRELIB_FORM_TAG = '["",""]';
|
|
20
|
+
const INTELLIGENT_APPLY = 'archive.prelib.intelligent.apply';
|
|
21
|
+
/** 提交整理:勾选列表行 -> prefileBatch/batchSave(treeId + checkIds + formId + autoBatchProduct)。 */
|
|
22
|
+
const ARRANGE_APPLY = 'archive.prelib.arrange.apply';
|
|
23
|
+
/** 永不展示的字段:内部标识,或后续操作要用的隐藏值(id 是智能识别/整理 checkIds 的来源)。 */
|
|
24
|
+
const NON_DISPLAY_FIELDS = new Set([
|
|
25
|
+
'id',
|
|
26
|
+
'rowKey',
|
|
27
|
+
'flowId',
|
|
28
|
+
'form_data_id',
|
|
29
|
+
'form_table_id',
|
|
30
|
+
'ebrecord_rowkey',
|
|
31
|
+
'isFollow',
|
|
32
|
+
'is_flow',
|
|
33
|
+
'isToDo',
|
|
34
|
+
'todoPropSpan',
|
|
35
|
+
'data_status_value',
|
|
36
|
+
]);
|
|
37
|
+
/** 电子文件库节点判定:id 形如 {appId}_{appId}(下划线前后一致)。 */
|
|
38
|
+
function isEfileLibNode(id) {
|
|
39
|
+
if (typeof id !== 'string' || !id.includes('_'))
|
|
40
|
+
return false;
|
|
41
|
+
const [left, right] = id.split('_');
|
|
42
|
+
return Boolean(left && left === right);
|
|
43
|
+
}
|
|
44
|
+
function optionalText(value) {
|
|
45
|
+
if (typeof value !== 'string')
|
|
46
|
+
return undefined;
|
|
47
|
+
const text = value.trim();
|
|
48
|
+
return text ? text : undefined;
|
|
49
|
+
}
|
|
50
|
+
/** 定位电子文件库节点:未传 treeId 时取预归档树第一个电子文件库节点。 */
|
|
51
|
+
async function resolveEfileNode(host, treeId) {
|
|
52
|
+
const response = await host.request({
|
|
53
|
+
method: 'POST',
|
|
54
|
+
path: '/api/archive/core/archivetree/getTree',
|
|
55
|
+
body: {
|
|
56
|
+
treeType: PRELIB_TREE_TYPE,
|
|
57
|
+
menuSign: PRELIB_MENU_SIGN,
|
|
58
|
+
logFlag: PRELIB_MENU_SIGN,
|
|
59
|
+
needControl: true,
|
|
60
|
+
needSysn: true,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const data = unwrapData(response);
|
|
64
|
+
const nodes = Array.isArray(data) ? data : [];
|
|
65
|
+
const efileNodes = nodes
|
|
66
|
+
.filter((item) => isEfileLibNode(item?.id))
|
|
67
|
+
.map((item) => ({ treeId: String(item.id), nodeName: String(item.content ?? '') }));
|
|
68
|
+
if (treeId) {
|
|
69
|
+
const matched = efileNodes.find((item) => item.treeId === treeId);
|
|
70
|
+
// 传入的 treeId 即使不在树里也允许继续,由 getTreeDetail 决定是否报错
|
|
71
|
+
return matched ?? { treeId, nodeName: '' };
|
|
72
|
+
}
|
|
73
|
+
if (efileNodes.length === 0) {
|
|
74
|
+
throw archiveValidationError('prelib_node_missing', '未找到电子文件库节点(预归档树返回为空)。请先重新获取一次:重试本 operation,或用已知 treeId 显式传入;若仍然获取不到,通常是当前账号没有该预归档库权限,此时应停止后续操作(不要猜测 treeId,也不要继续上传)。');
|
|
75
|
+
}
|
|
76
|
+
return efileNodes[0];
|
|
77
|
+
}
|
|
78
|
+
/** getTreeDetail:取列表视图地址与表单标识。 */
|
|
79
|
+
async function fetchTreeDetail(host, treeId) {
|
|
80
|
+
const response = await host.request({
|
|
81
|
+
method: 'POST',
|
|
82
|
+
path: '/api/archive/core/archivetree/getTreeDetail',
|
|
83
|
+
body: {
|
|
84
|
+
treeType: PRELIB_TREE_TYPE,
|
|
85
|
+
rootNode: '',
|
|
86
|
+
rootNodeTag: '',
|
|
87
|
+
needControl: true,
|
|
88
|
+
formTag: PRELIB_FORM_TAG,
|
|
89
|
+
preFileFilterId: '',
|
|
90
|
+
menuSign: PRELIB_MENU_SIGN,
|
|
91
|
+
treeId,
|
|
92
|
+
nodeType: PRELIB_NODE_TYPE,
|
|
93
|
+
logFlag: PRELIB_MENU_SIGN,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
const data = (unwrapData(response) ?? {});
|
|
97
|
+
const url1 = String(data.url1 ?? '').trim();
|
|
98
|
+
const matched = url1.match(/(\d+)\s*$/u);
|
|
99
|
+
const listId = matched?.[1] ?? '';
|
|
100
|
+
const extra = (data.extraParams ?? {});
|
|
101
|
+
const metaFormId = String(extra.metaFormId ?? '').trim();
|
|
102
|
+
const tag = String(extra.tag ?? '').trim();
|
|
103
|
+
if (!listId || !metaFormId) {
|
|
104
|
+
throw archiveValidationError('prelib_detail_invalid', `getTreeDetail 未返回有效的列表视图(url1=${url1 || '空'},metaFormId=${metaFormId || '空'})`);
|
|
105
|
+
}
|
|
106
|
+
const boxUrl = String(data.boxUrl ?? '').trim();
|
|
107
|
+
return { listId, metaFormId, tag, url1, ...(boxUrl ? { boxUrl } : {}) };
|
|
108
|
+
}
|
|
109
|
+
/** getListDatas:按抓包还原的请求体查询电子文件库列表数据。 */
|
|
110
|
+
async function fetchPrelibDatas(host, node, detail, pageNo) {
|
|
111
|
+
const current = positiveInt(pageNo, 'pageNo', 1);
|
|
112
|
+
const [appId] = node.treeId.split('_');
|
|
113
|
+
const paramsJson = JSON.stringify({
|
|
114
|
+
treeType: PRELIB_TREE_TYPE,
|
|
115
|
+
rootNode: '',
|
|
116
|
+
rootNodeTag: '',
|
|
117
|
+
needControl: true,
|
|
118
|
+
formTag: PRELIB_FORM_TAG,
|
|
119
|
+
preFileFilterId: '',
|
|
120
|
+
menuSign: PRELIB_MENU_SIGN,
|
|
121
|
+
id: node.treeId,
|
|
122
|
+
nodeType: PRELIB_NODE_TYPE,
|
|
123
|
+
isLeaf: true,
|
|
124
|
+
content: node.nodeName,
|
|
125
|
+
});
|
|
126
|
+
const response = await host.request({
|
|
127
|
+
method: 'POST',
|
|
128
|
+
path: '/api/ebuilder/form/list/getListDatas',
|
|
129
|
+
query: { passid: detail.metaFormId, cid: detail.metaFormId },
|
|
130
|
+
body: {
|
|
131
|
+
current,
|
|
132
|
+
requiredMatch: 1,
|
|
133
|
+
tableuid: randomBytes(16).toString('hex'),
|
|
134
|
+
mapResult: '1',
|
|
135
|
+
recheckQuery: '1',
|
|
136
|
+
metaFormId: detail.metaFormId,
|
|
137
|
+
tag: detail.tag,
|
|
138
|
+
treeId: node.treeId,
|
|
139
|
+
nodeType: PRELIB_NODE_TYPE,
|
|
140
|
+
systemId: appId,
|
|
141
|
+
metaId: appId,
|
|
142
|
+
hasBtn: '1',
|
|
143
|
+
paramsJson,
|
|
144
|
+
metaName: node.nodeName,
|
|
145
|
+
menuSign: PRELIB_MENU_SIGN,
|
|
146
|
+
searchParamData: { type: 'and', searchType: '2', commonSearchFields: {}, groupFields: {} },
|
|
147
|
+
listId: detail.listId,
|
|
148
|
+
isFollow: 0,
|
|
149
|
+
isShareToMe: 0,
|
|
150
|
+
filterCondition: {},
|
|
151
|
+
browser: 'Chrome',
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
const data = (unwrapData(response) ?? {});
|
|
155
|
+
// 列定义只保留展示需要的三个字段:接口原始列里带大段 Action 配置,
|
|
156
|
+
// 原样返回会被输出层按 arrayLimit 截断,导致 hide 判断缺列
|
|
157
|
+
const columns = (Array.isArray(data.columns) ? data.columns : []).map((item) => ({
|
|
158
|
+
title: String(item?.title ?? ''),
|
|
159
|
+
dataIndex: String(item?.dataIndex ?? ''),
|
|
160
|
+
hide: item?.hide === true,
|
|
161
|
+
}));
|
|
162
|
+
const rows = Array.isArray(data.data)
|
|
163
|
+
? data.data
|
|
164
|
+
: Array.isArray(data.displayData)
|
|
165
|
+
? data.displayData
|
|
166
|
+
: [];
|
|
167
|
+
const displayData = Array.isArray(data.displayData)
|
|
168
|
+
? data.displayData
|
|
169
|
+
: [];
|
|
170
|
+
const visibleColumns = columns
|
|
171
|
+
.filter((item) => item?.hide !== true)
|
|
172
|
+
.map((item) => ({ title: String(item?.title ?? ''), dataIndex: String(item?.dataIndex ?? '') }));
|
|
173
|
+
// 接口 columns 通常只配置了一部分列(187 只返回 5 列),但数据里字段更多;
|
|
174
|
+
// 这里汇总数据中实际存在且可展示的字段,供展示时补齐,避免"显示不全"
|
|
175
|
+
const fieldNames = new Set();
|
|
176
|
+
for (const row of [...rows, ...displayData]) {
|
|
177
|
+
for (const key of Object.keys(row)) {
|
|
178
|
+
if (!key || NON_DISPLAY_FIELDS.has(key) || /(?:Action|Span)$/.test(key))
|
|
179
|
+
continue;
|
|
180
|
+
fieldNames.add(key);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const dataFields = [...fieldNames];
|
|
184
|
+
const pageSize = data.pageSize === undefined ? undefined : Number(data.pageSize);
|
|
185
|
+
const total = data.total === undefined ? undefined : Number(data.total);
|
|
186
|
+
return {
|
|
187
|
+
columns,
|
|
188
|
+
visibleColumns,
|
|
189
|
+
rows,
|
|
190
|
+
displayData,
|
|
191
|
+
dataFields,
|
|
192
|
+
pageNo: Number(data.current ?? current),
|
|
193
|
+
...(pageSize === undefined ? {} : { pageSize }),
|
|
194
|
+
...(total === undefined ? {} : { total }),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const prelibList = {
|
|
198
|
+
name: 'archive.prelib.list',
|
|
199
|
+
resource: 'prelib',
|
|
200
|
+
method: 'list',
|
|
201
|
+
action: 'archive.prelib.list',
|
|
202
|
+
summary: '查询预归档电子文件库列表:treeId → getTreeDetail 取列表视图(url1/metaFormId/tag)→ getListDatas 取列与数据行(只读)',
|
|
203
|
+
capability: 'prelib',
|
|
204
|
+
risk: READ,
|
|
205
|
+
inputSchema: schemaOf({
|
|
206
|
+
treeId: {
|
|
207
|
+
type: 'string',
|
|
208
|
+
description: '电子文件库节点 treeId(形如 {appId}_{appId});不传时取预归档树第一个电子文件库节点',
|
|
209
|
+
},
|
|
210
|
+
pageNo: { type: 'integer', minimum: 1, description: '页码,默认 1' },
|
|
211
|
+
}, { description: '查询电子文件库列表' }),
|
|
212
|
+
handler: async (args, { host }) => {
|
|
213
|
+
const node = await resolveEfileNode(host, optionalText(args.treeId));
|
|
214
|
+
const detail = await fetchTreeDetail(host, node.treeId);
|
|
215
|
+
const page = await fetchPrelibDatas(host, node, detail, args.pageNo);
|
|
216
|
+
// 每行对应的档案打开链接(与 archive.prelib.open 同一模板),供列表第一列渲染成超链接
|
|
217
|
+
const session = await host.getSession();
|
|
218
|
+
const root = String(session?.baseUrl ?? '').replace(/\/+$/, '');
|
|
219
|
+
const openUrls = page.rows.map((row) => {
|
|
220
|
+
const id = String(row?.id ?? '').trim();
|
|
221
|
+
const path = `${PRELIB_FILE_LIB_EDIT_PATH}?${new URLSearchParams({ singleMetaId: id, treeId: node.treeId }).toString()}`;
|
|
222
|
+
return id && root ? `${root}${path}` : '';
|
|
223
|
+
});
|
|
224
|
+
return archiveSuccess('archive.prelib.list', {
|
|
225
|
+
treeId: node.treeId,
|
|
226
|
+
nodeName: node.nodeName,
|
|
227
|
+
listId: detail.listId,
|
|
228
|
+
metaFormId: detail.metaFormId,
|
|
229
|
+
tag: detail.tag,
|
|
230
|
+
url1: detail.url1,
|
|
231
|
+
...(detail.boxUrl ? { boxUrl: detail.boxUrl } : {}),
|
|
232
|
+
...page,
|
|
233
|
+
openUrls,
|
|
234
|
+
}, { count: page.rows.length, nodeName: node.nodeName });
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
const intelligentPrepare = {
|
|
238
|
+
name: 'archive.prelib.intelligent.prepare',
|
|
239
|
+
resource: 'prelib',
|
|
240
|
+
method: 'intelligent',
|
|
241
|
+
action: 'archive.prelib.intelligent.prepare',
|
|
242
|
+
summary: '对电子文件库列表里勾选的数据发起智能识别(预检,不写数据):解析 treeId/formId 并生成确认票据',
|
|
243
|
+
capability: 'prelib',
|
|
244
|
+
risk: READ,
|
|
245
|
+
inputSchema: schemaOf({
|
|
246
|
+
treeId: {
|
|
247
|
+
type: 'string',
|
|
248
|
+
description: '电子文件库节点 treeId;不传时取预归档树第一个电子文件库节点',
|
|
249
|
+
},
|
|
250
|
+
checkIds: {
|
|
251
|
+
type: 'array',
|
|
252
|
+
items: { type: 'string' },
|
|
253
|
+
description: '勾选的数据 ID 列表(取自 archive.prelib.list 返回行的 id)',
|
|
254
|
+
},
|
|
255
|
+
formId: {
|
|
256
|
+
type: 'string',
|
|
257
|
+
description: '表单 ID;不传时取 getTreeDetail 的 extraParams.metaFormId',
|
|
258
|
+
},
|
|
259
|
+
}, { required: ['checkIds'], description: '智能识别预检' }),
|
|
260
|
+
handler: async (args, env) => {
|
|
261
|
+
const checkIds = toStringIdList(args.checkIds, 'checkIds');
|
|
262
|
+
if (!checkIds || checkIds.length === 0) {
|
|
263
|
+
throw archiveValidationError('id_list_required', 'checkIds 必填且至少一项');
|
|
264
|
+
}
|
|
265
|
+
const node = await resolveEfileNode(env.host, optionalText(args.treeId));
|
|
266
|
+
const detail = await fetchTreeDetail(env.host, node.treeId);
|
|
267
|
+
const formId = optionalText(args.formId) ?? detail.metaFormId;
|
|
268
|
+
const { continuation, expiresInMs } = await issueLease(env, INTELLIGENT_APPLY, {
|
|
269
|
+
treeId: node.treeId,
|
|
270
|
+
formId,
|
|
271
|
+
checkIds,
|
|
272
|
+
});
|
|
273
|
+
return archiveSuccess('archive.prelib.intelligent.prepare', {
|
|
274
|
+
preview: { treeId: node.treeId, nodeName: node.nodeName, formId, count: checkIds.length, checkIds },
|
|
275
|
+
hint: `确认后调用 ${INTELLIGENT_APPLY}(CLI:archive run ${INTELLIGENT_APPLY} --input-json '{"continuation":"<token>","confirm":true}')`,
|
|
276
|
+
continuation,
|
|
277
|
+
}, { requiresConfirmation: true, expiresInMs });
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
const intelligentApply = {
|
|
281
|
+
name: INTELLIGENT_APPLY,
|
|
282
|
+
resource: 'prelib',
|
|
283
|
+
method: 'intelligent',
|
|
284
|
+
action: INTELLIGENT_APPLY,
|
|
285
|
+
summary: '对电子文件库列表里勾选的数据发起智能识别(写操作):调用 intelligentCate 提交识别任务,返回 taskId',
|
|
286
|
+
capability: 'prelib',
|
|
287
|
+
risk: WRITE,
|
|
288
|
+
requiresConfirmation: true,
|
|
289
|
+
inputSchema: schemaOf({
|
|
290
|
+
continuation: { type: 'string', description: 'prepare 返回的确认票据' },
|
|
291
|
+
confirm: { type: 'boolean', description: '必须为 true(CLI --yes)' },
|
|
292
|
+
}, { required: ['continuation', 'confirm'], description: '提交智能识别任务' }),
|
|
293
|
+
handler: async (args, env) => {
|
|
294
|
+
const lease = await verifyLease(args, INTELLIGENT_APPLY, env);
|
|
295
|
+
const treeId = String(lease.treeId ?? '').trim();
|
|
296
|
+
const formId = String(lease.formId ?? '').trim();
|
|
297
|
+
const checkIds = Array.isArray(lease.checkIds) ? lease.checkIds.map(String) : [];
|
|
298
|
+
if (!treeId || !formId || checkIds.length === 0) {
|
|
299
|
+
throw archiveValidationError('continuation_payload_invalid', '确认票据缺少 treeId / formId / checkIds');
|
|
300
|
+
}
|
|
301
|
+
const response = await env.host.request({
|
|
302
|
+
method: 'POST',
|
|
303
|
+
path: '/api/archive/core/intelligent/intelligentCate',
|
|
304
|
+
body: {
|
|
305
|
+
treeId,
|
|
306
|
+
checkIds: checkIds.join(','),
|
|
307
|
+
formId,
|
|
308
|
+
logFlag: PRELIB_MENU_SIGN,
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
const data = (unwrapData(response) ?? {});
|
|
312
|
+
const taskId = String(data.taskId ?? '').trim();
|
|
313
|
+
return archiveSuccess(INTELLIGENT_APPLY, {
|
|
314
|
+
treeId,
|
|
315
|
+
formId,
|
|
316
|
+
checkIds,
|
|
317
|
+
...(taskId ? { taskId } : {}),
|
|
318
|
+
hint: '智能识别为异步任务,返回 taskId 表示已提交;识别结果需在系统中查看',
|
|
319
|
+
}, { wrote: true, count: checkIds.length });
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
/** 提交整理预检:与智能识别同参,仅接口不同。 */
|
|
323
|
+
const arrangePrepare = {
|
|
324
|
+
name: 'archive.prelib.arrange.prepare',
|
|
325
|
+
resource: 'prelib',
|
|
326
|
+
method: 'arrange',
|
|
327
|
+
action: 'archive.prelib.arrange.prepare',
|
|
328
|
+
summary: '对电子文件库列表里勾选的数据提交整理(预检,不写数据):解析 treeId/formId 并生成确认票据',
|
|
329
|
+
capability: 'prelib',
|
|
330
|
+
risk: READ,
|
|
331
|
+
inputSchema: schemaOf({
|
|
332
|
+
treeId: {
|
|
333
|
+
type: 'string',
|
|
334
|
+
description: '电子文件库节点 treeId;不传时取预归档树第一个电子文件库节点',
|
|
335
|
+
},
|
|
336
|
+
checkIds: {
|
|
337
|
+
type: 'array',
|
|
338
|
+
items: { type: 'string' },
|
|
339
|
+
description: '勾选的数据 ID 列表(取自 archive.prelib.list 返回行的 id)',
|
|
340
|
+
},
|
|
341
|
+
formId: {
|
|
342
|
+
type: 'string',
|
|
343
|
+
description: '表单 ID;不传时取 getTreeDetail 的 extraParams.metaFormId',
|
|
344
|
+
},
|
|
345
|
+
}, { required: ['checkIds'], description: '提交整理预检' }),
|
|
346
|
+
handler: async (args, env) => {
|
|
347
|
+
const checkIds = toStringIdList(args.checkIds, 'checkIds');
|
|
348
|
+
if (!checkIds || checkIds.length === 0) {
|
|
349
|
+
throw archiveValidationError('id_list_required', 'checkIds 必填且至少一项');
|
|
350
|
+
}
|
|
351
|
+
const node = await resolveEfileNode(env.host, optionalText(args.treeId));
|
|
352
|
+
const detail = await fetchTreeDetail(env.host, node.treeId);
|
|
353
|
+
const formId = optionalText(args.formId) ?? detail.metaFormId;
|
|
354
|
+
const { continuation, expiresInMs } = await issueLease(env, ARRANGE_APPLY, {
|
|
355
|
+
treeId: node.treeId,
|
|
356
|
+
formId,
|
|
357
|
+
checkIds,
|
|
358
|
+
});
|
|
359
|
+
return archiveSuccess('archive.prelib.arrange.prepare', {
|
|
360
|
+
preview: { treeId: node.treeId, nodeName: node.nodeName, formId, count: checkIds.length, checkIds },
|
|
361
|
+
hint: `只有识别状态为「已识别」的数据才会被整理;未识别 / 识别中 / 识别异常的行提交后也会被服务端过滤掉(不报错但实际不处理),建议先做智能识别并确认识别成功。确认后调用 ${ARRANGE_APPLY};服务端会返回实际处理条数,不要声称全部整理完成`,
|
|
362
|
+
continuation,
|
|
363
|
+
}, { requiresConfirmation: true, expiresInMs });
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
/** 提交整理写操作:调 prefileBatch/batchSave,响应只有 msg(无 data)。 */
|
|
367
|
+
const arrangeApply = {
|
|
368
|
+
name: ARRANGE_APPLY,
|
|
369
|
+
resource: 'prelib',
|
|
370
|
+
method: 'arrange',
|
|
371
|
+
action: ARRANGE_APPLY,
|
|
372
|
+
summary: '对电子文件库列表里勾选的数据提交整理(写操作):调用 prefileBatch/batchSave,返回服务端处理说明',
|
|
373
|
+
capability: 'prelib',
|
|
374
|
+
risk: WRITE,
|
|
375
|
+
requiresConfirmation: true,
|
|
376
|
+
inputSchema: schemaOf({
|
|
377
|
+
continuation: { type: 'string', description: 'prepare 返回的确认票据' },
|
|
378
|
+
confirm: { type: 'boolean', description: '必须为 true(CLI --yes)' },
|
|
379
|
+
}, { required: ['continuation', 'confirm'], description: '提交整理' }),
|
|
380
|
+
handler: async (args, env) => {
|
|
381
|
+
const lease = await verifyLease(args, ARRANGE_APPLY, env);
|
|
382
|
+
const treeId = String(lease.treeId ?? '').trim();
|
|
383
|
+
const formId = String(lease.formId ?? '').trim();
|
|
384
|
+
const checkIds = Array.isArray(lease.checkIds) ? lease.checkIds.map(String) : [];
|
|
385
|
+
if (!treeId || !formId || checkIds.length === 0) {
|
|
386
|
+
throw archiveValidationError('continuation_payload_invalid', '确认票据缺少 treeId / formId / checkIds');
|
|
387
|
+
}
|
|
388
|
+
const response = await env.host.request({
|
|
389
|
+
method: 'POST',
|
|
390
|
+
path: '/api/archive/core/prefileBatch/batchSave',
|
|
391
|
+
body: {
|
|
392
|
+
treeId,
|
|
393
|
+
autoBatchProduct: true,
|
|
394
|
+
formId,
|
|
395
|
+
checkIds: checkIds.join(','),
|
|
396
|
+
logFlag: PRELIB_MENU_SIGN,
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
// 该接口不返回 data,处理说明在顶层 msg(例如"选中1条数据包含1条异常数据,系统仅处理0条识别成功的数据!")
|
|
400
|
+
const raw = response;
|
|
401
|
+
const message = String(raw?.msg ?? '').trim();
|
|
402
|
+
return archiveSuccess(ARRANGE_APPLY, {
|
|
403
|
+
treeId,
|
|
404
|
+
formId,
|
|
405
|
+
checkIds,
|
|
406
|
+
...(message ? { message } : {}),
|
|
407
|
+
hint: '提交整理只处理识别状态为「已识别」的数据;未识别 / 识别中 / 识别异常的行会被服务端过滤。必须把服务端 message 如实转达,不要声称全部整理完成;若处理条数为 0,提示用户先做智能识别且识别成功后再整理',
|
|
408
|
+
}, { wrote: true, count: checkIds.length });
|
|
409
|
+
},
|
|
410
|
+
};
|
|
411
|
+
/**
|
|
412
|
+
* 打开档案链接:/sp/custom/archive/fileLibEdit?singleMetaId=行id&treeId=节点treeId
|
|
413
|
+
* treeId 本身就是 ${systemId}_${metadataId} 形式,无需另行拼装 metadataId。
|
|
414
|
+
*/
|
|
415
|
+
const PRELIB_FILE_LIB_EDIT_PATH = '/sp/custom/archive/fileLibEdit';
|
|
416
|
+
const prelibOpen = {
|
|
417
|
+
name: 'archive.prelib.open',
|
|
418
|
+
resource: 'prelib',
|
|
419
|
+
method: 'open',
|
|
420
|
+
action: 'archive.prelib.open',
|
|
421
|
+
summary: '生成预归档电子文件库里指定数据的档案打开链接(只读):按行 id(singleMetaId)与节点 treeId 拼出 fileLibEdit 链接',
|
|
422
|
+
capability: 'prelib',
|
|
423
|
+
risk: READ,
|
|
424
|
+
inputSchema: schemaOf({
|
|
425
|
+
checkIds: {
|
|
426
|
+
type: 'array',
|
|
427
|
+
items: { type: 'string' },
|
|
428
|
+
description: '数据 ID 列表(取自 archive.prelib.list 返回行的 id),即链接的 singleMetaId',
|
|
429
|
+
},
|
|
430
|
+
treeId: {
|
|
431
|
+
type: 'string',
|
|
432
|
+
description: '电子文件库节点 treeId;不传时自动取。treeId 本身即 ${systemId}_${metadataId}',
|
|
433
|
+
},
|
|
434
|
+
}, { required: ['checkIds'], description: '生成档案打开链接' }),
|
|
435
|
+
handler: async (args, env) => {
|
|
436
|
+
const checkIds = toStringIdList(args.checkIds, 'checkIds');
|
|
437
|
+
if (!checkIds || checkIds.length === 0) {
|
|
438
|
+
throw archiveValidationError('id_list_required', 'checkIds 必填且至少一项');
|
|
439
|
+
}
|
|
440
|
+
const node = await resolveEfileNode(env.host, optionalText(args.treeId));
|
|
441
|
+
const [systemId, metadataId = ''] = node.treeId.split('_');
|
|
442
|
+
// 与流程链接(flow-url)保持一致:返回拼好 baseUrl 的完整 URL,可直接点击打开
|
|
443
|
+
const session = await env.host.getSession();
|
|
444
|
+
const root = String(session?.baseUrl ?? '').replace(/\/+$/, '');
|
|
445
|
+
const links = checkIds.map((id) => {
|
|
446
|
+
const path = `${PRELIB_FILE_LIB_EDIT_PATH}?${new URLSearchParams({ singleMetaId: id, treeId: node.treeId }).toString()}`;
|
|
447
|
+
return {
|
|
448
|
+
singleMetaId: id,
|
|
449
|
+
treeId: node.treeId,
|
|
450
|
+
path,
|
|
451
|
+
url: root ? `${root}${path}` : path,
|
|
452
|
+
};
|
|
453
|
+
});
|
|
454
|
+
return archiveSuccess('archive.prelib.open', {
|
|
455
|
+
nodeName: node.nodeName,
|
|
456
|
+
systemId,
|
|
457
|
+
metadataId,
|
|
458
|
+
count: links.length,
|
|
459
|
+
links,
|
|
460
|
+
...(links.length === 1 ? { url: links[0].url } : {}),
|
|
461
|
+
hint: 'CLI 不自动打开浏览器,请在浏览器中打开该 URL(需已登录该环境且有该档案查看权限)',
|
|
462
|
+
});
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
export const prelibOperations = [
|
|
466
|
+
prelibList,
|
|
467
|
+
intelligentPrepare,
|
|
468
|
+
intelligentApply,
|
|
469
|
+
arrangePrepare,
|
|
470
|
+
arrangeApply,
|
|
471
|
+
prelibOpen,
|
|
472
|
+
];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { archiveValidationError } from '../errors.js';
|
|
2
2
|
import { fondsOperations } from './fonds.js';
|
|
3
|
+
import { prelibOperations } from './prelib.js';
|
|
3
4
|
import { archiveInfoOperations } from './archive-info.js';
|
|
4
5
|
import { searchOperations } from './search.js';
|
|
5
6
|
import { borrowCarOperations } from './borrow-car.js';
|
|
@@ -11,6 +12,7 @@ function buildRegistry() {
|
|
|
11
12
|
const registry = new Map();
|
|
12
13
|
const definitions = [
|
|
13
14
|
...fondsOperations,
|
|
15
|
+
...prelibOperations,
|
|
14
16
|
...archiveInfoOperations,
|
|
15
17
|
...searchOperations,
|
|
16
18
|
...borrowCarOperations,
|
|
@@ -28,7 +28,7 @@ async function resolveDefaultTreeId(host) {
|
|
|
28
28
|
}
|
|
29
29
|
const nodes = data.filter(isEfileLibNode);
|
|
30
30
|
if (nodes.length === 0) {
|
|
31
|
-
throw archiveValidationError('tree_id_required', '
|
|
31
|
+
throw archiveValidationError('tree_id_required', '未找到电子文件库节点(预归档树返回为空)。请先重新获取一次:重试本 operation,或用已知 treeId 显式传入;若仍然获取不到,通常是当前账号没有该预归档库权限,此时应停止上传(不要猜测 treeId)。');
|
|
32
32
|
}
|
|
33
33
|
if (nodes.length > 1) {
|
|
34
34
|
throw archiveValidationError('tree_id_ambiguous', `存在多个电子文件库节点(${nodes.map((item) => item.id).join('、')}),请显式传入 treeId`);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
|
+
export class AssetIdleCliError extends CliError {
|
|
3
|
+
type;
|
|
4
|
+
subtype;
|
|
5
|
+
code;
|
|
6
|
+
retryable;
|
|
7
|
+
details;
|
|
8
|
+
constructor(type, subtype, message, options = {}) {
|
|
9
|
+
super(message, options.exitCode ?? ExitCode.InternalError);
|
|
10
|
+
this.name = 'AssetIdleCliError';
|
|
11
|
+
this.type = type;
|
|
12
|
+
this.subtype = subtype;
|
|
13
|
+
this.code = options.code;
|
|
14
|
+
this.retryable = options.retryable ?? false;
|
|
15
|
+
this.details = options.details;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function assetIdleValidationError(subtype, message, details) {
|
|
19
|
+
return new AssetIdleCliError('validation', subtype, message, {
|
|
20
|
+
details,
|
|
21
|
+
exitCode: ExitCode.UsageError,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
export function assetIdleAuthError(subtype, message, details) {
|
|
25
|
+
return new AssetIdleCliError('authentication', subtype, message, {
|
|
26
|
+
details,
|
|
27
|
+
exitCode: ExitCode.AuthError,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export function assetIdleNetworkError(subtype, message, options = {}) {
|
|
31
|
+
return new AssetIdleCliError('network', subtype, message, {
|
|
32
|
+
...options,
|
|
33
|
+
retryable: options.retryable ?? true,
|
|
34
|
+
exitCode: ExitCode.NetworkError,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** 服务端返回的业务失败(HTTP 已成功、resultCode 非 200 或业务信封异常)。 */
|
|
38
|
+
export function assetIdleApiError(subtype, message, options = {}) {
|
|
39
|
+
return new AssetIdleCliError('api', subtype, message, {
|
|
40
|
+
...options,
|
|
41
|
+
retryable: options.retryable ?? false,
|
|
42
|
+
exitCode: ExitCode.GeneralError,
|
|
43
|
+
});
|
|
44
|
+
}
|