weaver-work-cli 0.1.36 → 0.1.39
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 +4 -2
- package/dist/chunks/{archive-XBVH7JU7.js → archive-ENZYBBME.js} +559 -68
- package/dist/chunks/{archive-oa-MZM3EKFQ.js → archive-oa-YWLEC5V4.js} +4 -3
- package/dist/chunks/{asset-4XO7UOUW.js → asset-OOV6DWPA.js} +8 -7
- package/dist/chunks/asset-idle-RE632MY5.js +670 -0
- package/dist/chunks/{attachment-content-VXSWANAC.js → attachment-content-RWN2FCLL.js} +3 -3
- package/dist/chunks/{blog-PGZKOPSC.js → blog-PEPOJAL7.js} +5 -4
- package/dist/chunks/{caizhilian-BH4ZVGUN.js → caizhilian-WYIQDVPJ.js} +5 -4
- package/dist/chunks/{calendar-MXEMTIO4.js → calendar-CIARBAOX.js} +4 -3
- package/dist/chunks/{chunk-NCOVUAZK.js → chunk-36DIFZAH.js} +4 -3
- package/dist/chunks/{chunk-I6QGIBDM.js → chunk-BJGXMFGD.js} +4 -3
- package/dist/chunks/{chunk-TC6MZAO3.js → chunk-CQHGNCK2.js} +52 -2
- package/dist/chunks/{chunk-WXFPWCXG.js → chunk-EINRJHQ3.js} +3 -3
- package/dist/chunks/{chunk-JUXVYKII.js → chunk-EZGFHJFW.js} +201 -19
- package/dist/chunks/{chunk-VPUTVEMC.js → chunk-F2EQXUEE.js} +436 -290
- package/dist/chunks/{chunk-JYKABYCV.js → chunk-GVPJZXJ2.js} +3 -3
- package/dist/chunks/{chunk-6LLJFKJE.js → chunk-HJYVHXUQ.js} +1 -1
- package/dist/chunks/{chunk-T72N74ZT.js → chunk-I2HB737U.js} +5 -4
- package/dist/chunks/{chunk-VPXOPQJI.js → chunk-K3RUEEOL.js} +4 -2
- package/dist/chunks/{chunk-HXJQI5NM.js → chunk-KTCB5R5H.js} +3 -2
- package/dist/chunks/{chunk-XMGSYD6S.js → chunk-L4N7B7ZD.js} +4 -4
- package/dist/chunks/{chunk-QYGO5EE2.js → chunk-MUQUHKPG.js} +4 -3
- package/dist/chunks/{chunk-QHFANTX7.js → chunk-NLK2RZKG.js} +1348 -90
- package/dist/chunks/{chunk-F746NKNF.js → chunk-P2DAISYW.js} +1 -1
- package/dist/chunks/{chunk-BPE37FPB.js → chunk-T7JDJJ7H.js} +3 -3
- package/dist/chunks/{chunk-JNG42JKG.js → chunk-XXJOSZTQ.js} +6 -6
- package/dist/chunks/{chunk-5DQEEGCC.js → chunk-YS5DPN4T.js} +1 -1
- package/dist/chunks/{chunk-EG6ZU444.js → chunk-ZUX3P6BQ.js} +10 -5
- package/dist/chunks/{chunk-JCSN3JGM.js → chunk-ZXRNHZTE.js} +7 -6
- package/dist/chunks/{conflict-JAB2LJEZ.js → conflict-DRMDOL56.js} +2 -2
- package/dist/chunks/{contract-XI2EEIZU.js → contract-73MERZWN.js} +4 -3
- package/dist/chunks/{cowork-SCPGLBA4.js → cowork-HNGBPD7A.js} +4 -3
- package/dist/chunks/{ebuilder-form-EYLHNOTA.js → ebuilder-form-OY6DVNRK.js} +3 -3
- package/dist/chunks/{ehr-EAP77IMT.js → ehr-RAQNEQO7.js} +4 -3
- package/dist/chunks/{esb-2TGGXEE7.js → esb-6XV7C7YV.js} +4 -4
- package/dist/chunks/{fna-2X7ZE7BU.js → fna-XTSRB7G7.js} +4 -3
- package/dist/chunks/{host-Q4LZGCRU.js → host-3F5UM5GN.js} +3 -3
- package/dist/chunks/{host-XCLDDXKQ.js → host-A7J6GDUP.js} +3 -3
- package/dist/chunks/{host-I4NRK4MX.js → host-VGPVP7YF.js} +3 -3
- package/dist/chunks/{host-C6EL2RKL.js → host-YAQAPYNP.js} +3 -3
- package/dist/chunks/{host-UEI5FGDM.js → host-YMBXWFWX.js} +3 -3
- package/dist/chunks/{hrm-YXERJM76.js → hrm-TLHKC545.js} +3 -3
- package/dist/chunks/{im-A4VZN2TQ.js → im-YOUCFMUK.js} +3 -3
- package/dist/chunks/{invoice-2Z6YPMIS.js → invoice-WNBS2B4C.js} +3 -3
- package/dist/chunks/{jiuchuanhui-AR5GMKZB.js → jiuchuanhui-XABWS5RN.js} +4 -3
- package/dist/chunks/{lazy-dispatch-QXW7P4X3.js → lazy-dispatch-NLZ5UQQI.js} +5 -5
- package/dist/chunks/{mail-7GZ6CPBJ.js → mail-LRYMBFNL.js} +4 -3
- package/dist/chunks/{meeting-3NMGA3MB.js → meeting-ESXL6MFI.js} +13 -12
- package/dist/chunks/{okr-BZ6XUOAG.js → okr-EOV65SSF.js} +4 -3
- package/dist/chunks/{plan-DR5CMUYP.js → plan-YFPVKW6Y.js} +4 -3
- package/dist/chunks/{project-6J63MK33.js → project-MDVZUYQW.js} +4 -3
- package/dist/chunks/{registry-VRTNC6UR.js → registry-QCLZEDAP.js} +8 -8
- package/dist/chunks/{registry-KDD7DHNK.js → registry-VT5Y2HLA.js} +4 -4
- package/dist/chunks/{registry-TKX2E7C7.js → registry-YX4CSEMD.js} +3 -3
- package/dist/chunks/{room-recommend-XCWRMB5P.js → room-recommend-L3MWH4JW.js} +4 -4
- package/dist/chunks/{schedule-IVBICP32.js → schedule-UASAVDVD.js} +4 -4
- package/dist/chunks/{workflow-D74NFK3C.js → workflow-KDGIUCNW.js} +9 -6
- package/dist/core/output.js +16 -6
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/messages.js +1 -0
- package/dist/internal/e10/auth-recovery.js +127 -7
- package/dist/internal/e10/client.js +16 -2
- package/dist/internal/e10/context.js +16 -3
- package/dist/internal/e10/request-runtime.js +106 -8
- package/dist/shortcuts/archive/host.js +5 -2
- 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/archive-oa/host.js +2 -1
- package/dist/shortcuts/asset/host.js +6 -5
- 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/blog/host.js +3 -2
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +2 -1
- package/dist/shortcuts/cowork/host.js +2 -1
- package/dist/shortcuts/ebuilder-form/host.js +3 -1
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +2 -1
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/invoice/host.js +5 -4
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +2 -1
- package/dist/shortcuts/meeting/host.js +3 -2
- package/dist/shortcuts/meeting/invitation/text.js +71 -0
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +1073 -50
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +60 -1
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/invitation.js +122 -9
- 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/host.js +3 -0
- package/dist/shortcuts/workflow/index.js +1 -1
- package/dist/shortcuts/workflow/operations/form.js +44 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +77 -26
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +6 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +59 -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 +20 -6
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +22 -18
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +34 -10
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +9 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +110 -20
- package/docs/_catalog.md +3 -0
- package/docs/asset-idle.md +45 -0
- package/docs/e10-auth.md +1 -1
- package/docs/todo-smart-convert/subgroup-rules.md +1 -1
- package/package.json +1 -1
- 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-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-meeting/SKILL.md +250 -301
- package/skills/weaver-e10-meeting/references/meeting-eb.md +203 -0
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +37 -5
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- 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 +5 -2
- package/skills/weaver-e10-workflow/aigroup/default.json +154 -19
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +59 -27
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +113 -25
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +292 -42
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
|
-
import { isE10AuthenticationRequired, recoverXiaoEAuthSession, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
2
|
+
import { classifyE10Redirect, isE10AuthenticationRequired, recoverXiaoEAuthSession, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
3
3
|
import { startFetchTiming } from './fetch-timing.js';
|
|
4
4
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
5
5
|
const DEFAULT_BIG_INT_STRINGS = true;
|
|
6
|
+
/** 下载直传最多跟几跳:E10 -> 对象存储通常 1 跳,留一点余量但不允许成环。 */
|
|
7
|
+
const MAX_DOWNLOAD_REDIRECTS = 3;
|
|
6
8
|
const RESERVED_HEADERS = [
|
|
7
9
|
'authorization',
|
|
8
10
|
'cookie',
|
|
@@ -63,16 +65,18 @@ export class E10RequestRuntime {
|
|
|
63
65
|
}
|
|
64
66
|
stripReservedHeaders(mutable.headers);
|
|
65
67
|
const requestEteamsId = this.session.eteamsId;
|
|
66
|
-
let
|
|
68
|
+
let attempt = await this.executeRequest(mutable, request.trustedHeaders);
|
|
67
69
|
if (!mutable.streamBody
|
|
68
|
-
|
|
70
|
+
// 已交接给文件服务的响应不是 E10 的接口回答,登录态不该由它判定。
|
|
71
|
+
&& !attempt.fromFileRedirect
|
|
72
|
+
&& isE10AuthenticationRequired(authenticationProbe(mutable, attempt.parsed))
|
|
69
73
|
&& await this.recoverExpiredSession(requestEteamsId)) {
|
|
70
74
|
// Authentication rejection is a definitive pre-business failure. Retry
|
|
71
75
|
// exactly once with the new session; never retry transport/partial errors.
|
|
72
|
-
|
|
76
|
+
attempt = await this.executeRequest(mutable, request.trustedHeaders);
|
|
73
77
|
}
|
|
74
|
-
await this.runAfterResponse(mutable, this.sessionContext(), parsed);
|
|
75
|
-
return parsed;
|
|
78
|
+
await this.runAfterResponse(mutable, this.sessionContext(), attempt.parsed);
|
|
79
|
+
return attempt.parsed;
|
|
76
80
|
}
|
|
77
81
|
catch (error) {
|
|
78
82
|
await this.runOnError(mutable, this.sessionContext(), error);
|
|
@@ -84,7 +88,74 @@ export class E10RequestRuntime {
|
|
|
84
88
|
const headers = this.composeHeaders(request, trustedHeaders);
|
|
85
89
|
const init = this.buildFetchInit(request, headers);
|
|
86
90
|
const response = await this.fetchWithTimeout(url, init, request.timeoutMs);
|
|
87
|
-
|
|
91
|
+
// 二进制下载:E10 常以 302 把文件交接给文件服务/对象存储。这里直接跟过去
|
|
92
|
+
// 取字节,既不会把「文件流」当成登录失效,也不会触发无谓的重新登录。
|
|
93
|
+
const followed = request.responseType === 'binary'
|
|
94
|
+
? await this.followDownloadRedirect(response, request, url)
|
|
95
|
+
: { response, followed: false };
|
|
96
|
+
if (followed.followed && (followed.response.status === 401 || followed.response.status === 403)) {
|
|
97
|
+
// 这是文件服务对直链的回答(签名过期/无权限),与 E10 登录态无关:
|
|
98
|
+
// 报清楚,别让调用方误以为要重新登录。
|
|
99
|
+
throw new E10ApiError('network', 'download_file_service_denied', `文件服务拒绝下载(HTTP ${followed.response.status}),直链可能已过期,请重试下载`, {
|
|
100
|
+
retryable: true,
|
|
101
|
+
exitCode: ExitCode.NetworkError,
|
|
102
|
+
details: { status: followed.response.status },
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
parsed: await this.readResponse(followed.response, request.responseType, request.bigIntStrings, request.maxResponseBytes, request.timeoutMs),
|
|
107
|
+
fromFileRedirect: followed.followed,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 跟随下载直传的 3xx。仅当跳转目标是文件服务(非登录页)时才跟随,最多
|
|
112
|
+
* `MAX_DOWNLOAD_REDIRECTS` 跳;登录类跳转原样返回,交给上层认证恢复处理。
|
|
113
|
+
* 凭证规则:同源才继续带 Cookie/eteamsid,跨域(对象存储)不带任何鉴权头。
|
|
114
|
+
*/
|
|
115
|
+
async followDownloadRedirect(response, request, requestUrl) {
|
|
116
|
+
const baseOrigin = safeOrigin(this.session.getBaseUrl());
|
|
117
|
+
let current = response;
|
|
118
|
+
let currentUrl = requestUrl;
|
|
119
|
+
let followed = false;
|
|
120
|
+
for (let hop = 0; hop < MAX_DOWNLOAD_REDIRECTS; hop += 1) {
|
|
121
|
+
const kind = classifyE10Redirect({
|
|
122
|
+
status: current.status,
|
|
123
|
+
headers: current.headers,
|
|
124
|
+
requestPath: request.path,
|
|
125
|
+
});
|
|
126
|
+
if (kind !== 'file')
|
|
127
|
+
return { response: current, followed };
|
|
128
|
+
const location = current.headers.get('location');
|
|
129
|
+
if (!location)
|
|
130
|
+
return { response: current, followed };
|
|
131
|
+
let next;
|
|
132
|
+
try {
|
|
133
|
+
next = new URL(location, currentUrl);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return { response: current, followed };
|
|
137
|
+
}
|
|
138
|
+
if (!/^https?:$/u.test(next.protocol))
|
|
139
|
+
return { response: current, followed };
|
|
140
|
+
const sameOrigin = baseOrigin !== '' && safeOrigin(next.toString()) === baseOrigin;
|
|
141
|
+
current = await this.fetchWithTimeout(next, this.buildDownloadRedirectInit(sameOrigin), request.timeoutMs);
|
|
142
|
+
currentUrl = next;
|
|
143
|
+
followed = true;
|
|
144
|
+
}
|
|
145
|
+
return { response: current, followed };
|
|
146
|
+
}
|
|
147
|
+
buildDownloadRedirectInit(sameOrigin) {
|
|
148
|
+
const headers = {
|
|
149
|
+
Accept: 'application/octet-stream, */*',
|
|
150
|
+
'User-Agent': this.session.uaHeader(),
|
|
151
|
+
};
|
|
152
|
+
if (sameOrigin) {
|
|
153
|
+
headers.Cookie = this.attachSessionTicket
|
|
154
|
+
? this.session.cookieHeaderWithSessionTicket()
|
|
155
|
+
: this.session.cookieHeader();
|
|
156
|
+
headers.eteamsid = this.session.eteamsId;
|
|
157
|
+
}
|
|
158
|
+
return { method: 'GET', headers, redirect: 'manual' };
|
|
88
159
|
}
|
|
89
160
|
async recoverExpiredSession(requestEteamsId) {
|
|
90
161
|
// Another concurrent request may already have refreshed the shared session
|
|
@@ -130,6 +201,7 @@ export class E10RequestRuntime {
|
|
|
130
201
|
timeoutMs: request.timeoutMs || DEFAULT_TIMEOUT_MS,
|
|
131
202
|
responseType: request.responseType || 'json',
|
|
132
203
|
bigIntStrings: request.bigIntStrings ?? DEFAULT_BIG_INT_STRINGS,
|
|
204
|
+
followRedirects: request.followRedirects === true,
|
|
133
205
|
};
|
|
134
206
|
}
|
|
135
207
|
sessionContext() {
|
|
@@ -199,7 +271,8 @@ export class E10RequestRuntime {
|
|
|
199
271
|
const init = {
|
|
200
272
|
method: request.method,
|
|
201
273
|
headers,
|
|
202
|
-
|
|
274
|
+
// 文件下载允许跟随重定向(302 → 文件服务);其余请求保持 manual 以便识别登录跳转
|
|
275
|
+
redirect: request.followRedirects ? 'follow' : 'manual',
|
|
203
276
|
};
|
|
204
277
|
if (request.streamBody) {
|
|
205
278
|
init.body = request.streamBody;
|
|
@@ -276,6 +349,31 @@ export class E10RequestRuntime {
|
|
|
276
349
|
export function parseJsonPreservingBigInts(text) {
|
|
277
350
|
return JSON.parse(quoteLargeJsonIntegers(text));
|
|
278
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* 组装认证探测入参。二进制响应不能把文件字节交给关键词扫描(乱码里出现
|
|
354
|
+
* 「login」会误判成登录失效),只保留状态码与跳转目标;同时带上请求路径,
|
|
355
|
+
* 让「下载接口 -> 文件服务」的 3xx 能被识别为交接而不是失效。
|
|
356
|
+
*/
|
|
357
|
+
function authenticationProbe(request, response) {
|
|
358
|
+
if ('content' in response) {
|
|
359
|
+
return { status: response.status, headers: response.headers, requestPath: request.path };
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
status: response.status,
|
|
363
|
+
headers: response.headers,
|
|
364
|
+
requestPath: request.path,
|
|
365
|
+
text: response.text,
|
|
366
|
+
value: response.value,
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function safeOrigin(rawUrl) {
|
|
370
|
+
try {
|
|
371
|
+
return new URL(rawUrl).origin.toLowerCase();
|
|
372
|
+
}
|
|
373
|
+
catch {
|
|
374
|
+
return '';
|
|
375
|
+
}
|
|
376
|
+
}
|
|
279
377
|
const LONG_INTEGER_MIN_DIGITS = 16;
|
|
280
378
|
// 一趟扫描把 JSON 拆成「字符串字面量」与「数字」两类 token:字符串整体跳过,
|
|
281
379
|
// 数字只在它是纯整数且位数够长时补引号。逐字符拼串在 MB 级响应上要 100 ms 以上,
|
|
@@ -2,6 +2,7 @@ import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js
|
|
|
2
2
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
3
3
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
4
4
|
import { E10ApiError, createE10RequestRuntime } from '../../internal/e10/request-runtime.js';
|
|
5
|
+
import { isE10SessionExpiredResponse } from '../../internal/e10/auth-recovery.js';
|
|
5
6
|
import { ArchiveCliError, archiveAuthError, archiveNetworkError, archiveValidationError, } from './errors.js';
|
|
6
7
|
function inferProfile(ctx) {
|
|
7
8
|
const options = ctx.getGlobalOptions();
|
|
@@ -134,6 +135,8 @@ export function createArchiveHost(ctx, dependencies = {}) {
|
|
|
134
135
|
formData: multipart,
|
|
135
136
|
headers: { 'X-Requested-With': 'XMLHttpRequest', ...extraHeaders },
|
|
136
137
|
timeoutMs,
|
|
138
|
+
// 下载接口常 302 重定向到文件服务/CDN,需跟随,避免被误判为登录失效
|
|
139
|
+
followRedirects: true,
|
|
137
140
|
})
|
|
138
141
|
: await rt.requestJson({
|
|
139
142
|
module: 'archive',
|
|
@@ -151,7 +154,7 @@ export function createArchiveHost(ctx, dependencies = {}) {
|
|
|
151
154
|
}
|
|
152
155
|
async function request(request) {
|
|
153
156
|
const response = await doRequest(request, false).catch((error) => mapRuntimeNetworkError(error));
|
|
154
|
-
if (response
|
|
157
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
155
158
|
throw archiveAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
156
159
|
}
|
|
157
160
|
if (response.parseError) {
|
|
@@ -182,7 +185,7 @@ export function createArchiveHost(ctx, dependencies = {}) {
|
|
|
182
185
|
}
|
|
183
186
|
async function requestBinary(request) {
|
|
184
187
|
const response = await doRequest(request, true).catch((error) => mapRuntimeNetworkError(error));
|
|
185
|
-
if (response
|
|
188
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
186
189
|
throw archiveAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status });
|
|
187
190
|
}
|
|
188
191
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -25,7 +25,7 @@ export const archiveManifest = {
|
|
|
25
25
|
rules: [
|
|
26
26
|
'写操作(*.apply)必须先执行同名的 prepare 拿到 continuation,再带 confirm=true 执行 apply;CLI 用 --yes 表示确认。',
|
|
27
27
|
'借阅单下载为异步任务:apply 会轮询打包进度,完成后把 zip 保存到当前用户的「下载」目录(可用 output 指定路径)。',
|
|
28
|
-
'发起借阅/续借只返回流程创建页 URL,CLI
|
|
28
|
+
'发起借阅/续借只返回流程创建页 URL,CLI 不自动打开浏览器;应以 Markdown 超链接(a 标签)返回,由客户端决定打开方式。',
|
|
29
29
|
'借阅车/借阅单列表优先自定义接口,接口未发布时自动回退 ebuilder 列表链路,回退时行的字段更少(提供 fields/display)。',
|
|
30
30
|
],
|
|
31
31
|
operations: archiveOperations,
|
|
@@ -194,7 +194,19 @@ const borrowListDetail = {
|
|
|
194
194
|
}
|
|
195
195
|
const session = await host.getSession();
|
|
196
196
|
const detail = await fetchBorrowDetail(host, session.userId, String(dataId));
|
|
197
|
-
|
|
197
|
+
// 档案题名补可点击链接:arcDangan.id 形如 {档案ID}_{表单ID},拼成与全文检索一致的 archiveView
|
|
198
|
+
const root = String(session?.baseUrl ?? '').replace(/\/+$/, '');
|
|
199
|
+
const details = detail.details.map((item) => ({
|
|
200
|
+
...item,
|
|
201
|
+
arcDangan: item.arcDangan.map((arc) => {
|
|
202
|
+
const [arcId, arcFormId = ''] = String(arc.id ?? '').split('_');
|
|
203
|
+
if (!arcId || !arcFormId)
|
|
204
|
+
return arc;
|
|
205
|
+
const viewPath = `/sp/custom/archive/archiveView?arcId=${arcId}&arcFormId=${arcFormId}`;
|
|
206
|
+
return { ...arc, viewPath, url: root ? `${root}${viewPath}` : viewPath };
|
|
207
|
+
}),
|
|
208
|
+
}));
|
|
209
|
+
return archiveSuccess('archive.borrow-list.detail', { ...detail, details }, { count: details.length });
|
|
198
210
|
},
|
|
199
211
|
};
|
|
200
212
|
export const borrowListOperations = [borrowListList, borrowListDetail];
|
|
@@ -67,7 +67,7 @@ function flowResult(action, baseUrl, workflowId, params, extra = {}) {
|
|
|
67
67
|
workflowId,
|
|
68
68
|
url: buildFlowUrl(baseUrl, workflowId, params),
|
|
69
69
|
params,
|
|
70
|
-
hint: 'CLI
|
|
70
|
+
hint: 'CLI 不自动打开浏览器,也不要执行 open/start 自动打开;请把 url 以 Markdown 超链接(a 标签)返回,由客户端决定打开方式',
|
|
71
71
|
}, { wrote: true });
|
|
72
72
|
}
|
|
73
73
|
const flowBorrowCarPrepare = {
|