@alphalawyer/alpha-classic-cli 0.1.1
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 +212 -0
- package/assets/alpha-classic-skill/SKILL.md +60 -0
- package/assets/alpha-classic-skill/references/alpha-classic-appro.md +354 -0
- package/assets/alpha-classic-skill/references/alpha-classic-matter.md +267 -0
- package/assets/alpha-classic-skill/references/alpha-classic-shared.md +43 -0
- package/assets/claude/alpha-classic-cli.md +115 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4041 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,4041 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { createRequire as createRequire2 } from "module";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
|
|
7
|
+
// src/auth/login.ts
|
|
8
|
+
import { createRequire } from "module";
|
|
9
|
+
import os from "os";
|
|
10
|
+
import open from "open";
|
|
11
|
+
|
|
12
|
+
// src/util/base-url.ts
|
|
13
|
+
function normalizeBaseUrl(value) {
|
|
14
|
+
const trimmed = value.trim();
|
|
15
|
+
if (!trimmed) {
|
|
16
|
+
throw new Error("Base URL is required.");
|
|
17
|
+
}
|
|
18
|
+
return trimmed.replace(/\/+$/, "");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/config/environments.ts
|
|
22
|
+
var DEFAULT_ENVIRONMENT_NAME = "dev";
|
|
23
|
+
var PRESETS = {
|
|
24
|
+
local: {
|
|
25
|
+
label: "Local development",
|
|
26
|
+
baseUrl: "http://localhost:3000",
|
|
27
|
+
apiBaseUrl: "http://localhost:8080"
|
|
28
|
+
},
|
|
29
|
+
dev: {
|
|
30
|
+
label: "Development",
|
|
31
|
+
baseUrl: "https://dev.alphalawyer.cn",
|
|
32
|
+
apiBaseUrl: "https://dev.alphalawyer.cn"
|
|
33
|
+
},
|
|
34
|
+
test: {
|
|
35
|
+
label: "Testing",
|
|
36
|
+
baseUrl: "https://test.alphalawyer.cn",
|
|
37
|
+
apiBaseUrl: "https://test.alphalawyer.cn"
|
|
38
|
+
},
|
|
39
|
+
prod: {
|
|
40
|
+
label: "Production",
|
|
41
|
+
baseUrl: "https://alphalawyer.cn",
|
|
42
|
+
apiBaseUrl: "https://alphalawyer.cn"
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var BUILD_ENVIRONMENT_NAME = resolveBuildEnvironmentName();
|
|
46
|
+
function listEnvironmentPresets() {
|
|
47
|
+
return Object.keys(PRESETS).map(
|
|
48
|
+
(name) => normalizePreset(name, PRESETS[name])
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
function getEnvironmentPreset(name) {
|
|
52
|
+
if (!name) {
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
const normalized = name.trim().toLowerCase();
|
|
56
|
+
const preset = PRESETS[normalized];
|
|
57
|
+
return preset ? normalizePreset(normalized, preset) : void 0;
|
|
58
|
+
}
|
|
59
|
+
function getEnvironmentPresetOrThrow(name) {
|
|
60
|
+
const preset = getEnvironmentPreset(name);
|
|
61
|
+
if (!preset) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Unknown environment: ${name}. Supported: ${listEnvironmentPresets().map((item) => item.name).join(", ")}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
return preset;
|
|
67
|
+
}
|
|
68
|
+
function getDefaultEnvironmentPreset() {
|
|
69
|
+
return getEnvironmentPresetOrThrow(BUILD_ENVIRONMENT_NAME);
|
|
70
|
+
}
|
|
71
|
+
function normalizePreset(name, preset) {
|
|
72
|
+
return {
|
|
73
|
+
name,
|
|
74
|
+
label: preset.label,
|
|
75
|
+
baseUrl: normalizeBaseUrl(preset.baseUrl),
|
|
76
|
+
apiBaseUrl: normalizeBaseUrl(preset.apiBaseUrl)
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function resolveBuildEnvironmentName() {
|
|
80
|
+
const rawName = "dev".trim() ? "dev" : DEFAULT_ENVIRONMENT_NAME;
|
|
81
|
+
const normalized = rawName.trim().toLowerCase();
|
|
82
|
+
if (normalized in PRESETS) {
|
|
83
|
+
return normalized;
|
|
84
|
+
}
|
|
85
|
+
return DEFAULT_ENVIRONMENT_NAME;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/util/errors.ts
|
|
89
|
+
var ApiError = class extends Error {
|
|
90
|
+
constructor(message, code, status) {
|
|
91
|
+
super(message);
|
|
92
|
+
this.code = code;
|
|
93
|
+
this.status = status;
|
|
94
|
+
this.name = "ApiError";
|
|
95
|
+
}
|
|
96
|
+
code;
|
|
97
|
+
status;
|
|
98
|
+
};
|
|
99
|
+
var AuthError = class extends ApiError {
|
|
100
|
+
constructor(message, code, status) {
|
|
101
|
+
super(message, code, status);
|
|
102
|
+
this.name = "AuthError";
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var PermissionError = class extends ApiError {
|
|
106
|
+
constructor(message, code, status) {
|
|
107
|
+
super(message, code, status);
|
|
108
|
+
this.name = "PermissionError";
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// src/http/api-client.ts
|
|
113
|
+
var RESULT_CODE_SUCCESS = 200;
|
|
114
|
+
var RESULT_CODE_AUTH = 401;
|
|
115
|
+
var RESULT_CODE_PERMISSION = 403;
|
|
116
|
+
var DEVICE_TYPE_AI = "ai";
|
|
117
|
+
var ApiClient = class {
|
|
118
|
+
sessionStore;
|
|
119
|
+
apiBaseUrl;
|
|
120
|
+
timeoutMs;
|
|
121
|
+
constructor(options) {
|
|
122
|
+
this.sessionStore = options.sessionStore;
|
|
123
|
+
this.apiBaseUrl = options.apiBaseUrl ? normalizeBaseUrl(options.apiBaseUrl) : void 0;
|
|
124
|
+
this.timeoutMs = options.timeoutMs ?? 15e3;
|
|
125
|
+
}
|
|
126
|
+
async createCliDeviceAuth(baseUrl, payload) {
|
|
127
|
+
return this.postEnvelope(
|
|
128
|
+
baseUrl,
|
|
129
|
+
"/user/api/v1/cli-device-auth/create",
|
|
130
|
+
payload,
|
|
131
|
+
{ session: null }
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
async pollCliDeviceAuth(baseUrl, deviceCode) {
|
|
135
|
+
return this.postEnvelope(
|
|
136
|
+
baseUrl,
|
|
137
|
+
`/user/api/v1/cli-device-auth/poll/${encodeURIComponent(deviceCode)}`,
|
|
138
|
+
{},
|
|
139
|
+
{ session: null }
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
async refreshSession(session) {
|
|
143
|
+
const current = session ?? await this.sessionStore.getSession();
|
|
144
|
+
if (!current?.refreshToken) {
|
|
145
|
+
throw new AuthError("Token invalid or expired. Run: alpha-classic-cli login");
|
|
146
|
+
}
|
|
147
|
+
const baseUrl = current.baseUrl ?? current.apiBaseUrl;
|
|
148
|
+
const nextTokens = await this.postEnvelope(
|
|
149
|
+
baseUrl,
|
|
150
|
+
"/user/api/v1/token/refresh",
|
|
151
|
+
current.refreshToken,
|
|
152
|
+
{
|
|
153
|
+
contentType: "text/plain;charset=UTF-8",
|
|
154
|
+
session: current,
|
|
155
|
+
allowRefresh: false
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
const nextSession = {
|
|
159
|
+
...current,
|
|
160
|
+
token: nextTokens.token,
|
|
161
|
+
refreshToken: nextTokens.refreshToken ?? current.refreshToken,
|
|
162
|
+
tokenExpireTime: nextTokens.tokenExpireTime ?? current.tokenExpireTime,
|
|
163
|
+
refreshTokenExpireTime: nextTokens.refreshTokenExpireTime ?? current.refreshTokenExpireTime,
|
|
164
|
+
deviceType: current.deviceType ?? DEVICE_TYPE_AI,
|
|
165
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
166
|
+
};
|
|
167
|
+
await this.sessionStore.saveSession(nextSession);
|
|
168
|
+
return nextSession;
|
|
169
|
+
}
|
|
170
|
+
async request(method, path4, options) {
|
|
171
|
+
const session = await this.sessionStore.getSession();
|
|
172
|
+
if (options?.requireAuth !== false && !session?.token) {
|
|
173
|
+
throw new Error("Not logged in. Run: alpha-classic-cli login");
|
|
174
|
+
}
|
|
175
|
+
const baseUrl = this.apiBaseUrl ?? session?.apiBaseUrl ?? session?.baseUrl;
|
|
176
|
+
if (!baseUrl) {
|
|
177
|
+
throw new Error("API base URL is not configured. Rebuild this CLI with npm run build:<env>.");
|
|
178
|
+
}
|
|
179
|
+
return this.requestWithSession(method, baseUrl, path4, {
|
|
180
|
+
...options,
|
|
181
|
+
session,
|
|
182
|
+
allowRefresh: true
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
async check() {
|
|
186
|
+
return this.request("GET", "/im/v1/users/me", { requireAuth: true });
|
|
187
|
+
}
|
|
188
|
+
async postEnvelope(baseUrl, path4, data, options) {
|
|
189
|
+
const response = await this.fetchJson(
|
|
190
|
+
"POST",
|
|
191
|
+
baseUrl,
|
|
192
|
+
path4,
|
|
193
|
+
{
|
|
194
|
+
data,
|
|
195
|
+
headers: {
|
|
196
|
+
"Content-Type": options?.contentType ?? "application/json"
|
|
197
|
+
},
|
|
198
|
+
session: options?.session ?? null
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
return this.unwrapResponse("POST", baseUrl, path4, response, {
|
|
202
|
+
data,
|
|
203
|
+
contentType: options?.contentType,
|
|
204
|
+
session: options?.session ?? null,
|
|
205
|
+
allowRefresh: options?.allowRefresh ?? false
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
async requestWithSession(method, baseUrl, path4, options) {
|
|
209
|
+
const response = await this.fetchJson(method, baseUrl, path4, options);
|
|
210
|
+
return this.unwrapResponse(method, baseUrl, path4, response, {
|
|
211
|
+
data: options.data,
|
|
212
|
+
headers: options.headers,
|
|
213
|
+
session: options.session,
|
|
214
|
+
allowRefresh: options.allowRefresh,
|
|
215
|
+
params: options.params
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
async unwrapResponse(method, baseUrl, path4, response, retry) {
|
|
219
|
+
const envelope = asResultEnvelope(response.body);
|
|
220
|
+
if (envelope) {
|
|
221
|
+
const code = envelope.code ?? envelope.resultCode;
|
|
222
|
+
const success = envelope.success ?? envelope.isSuccess;
|
|
223
|
+
if (success !== false && (code === void 0 || Number(code) === RESULT_CODE_SUCCESS)) {
|
|
224
|
+
return envelope.data;
|
|
225
|
+
}
|
|
226
|
+
if (Number(code) === RESULT_CODE_AUTH && retry.allowRefresh) {
|
|
227
|
+
return this.retryAfterRefresh(method, baseUrl, path4, retry);
|
|
228
|
+
}
|
|
229
|
+
throwApiEnvelopeError(envelope, response.status);
|
|
230
|
+
}
|
|
231
|
+
if (response.status === RESULT_CODE_AUTH && retry.allowRefresh) {
|
|
232
|
+
return this.retryAfterRefresh(method, baseUrl, path4, retry);
|
|
233
|
+
}
|
|
234
|
+
if (response.status === RESULT_CODE_AUTH) {
|
|
235
|
+
throw new AuthError("Token invalid or expired.", void 0, response.status);
|
|
236
|
+
}
|
|
237
|
+
if (response.status === RESULT_CODE_PERMISSION) {
|
|
238
|
+
throw new PermissionError("Permission denied.", void 0, response.status);
|
|
239
|
+
}
|
|
240
|
+
if (response.status >= 200 && response.status < 300) {
|
|
241
|
+
return response.body;
|
|
242
|
+
}
|
|
243
|
+
throw new ApiError(
|
|
244
|
+
`API request failed: ${response.status} ${response.statusText}`,
|
|
245
|
+
void 0,
|
|
246
|
+
response.status
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
async retryAfterRefresh(method, baseUrl, path4, retry) {
|
|
250
|
+
if (!retry.session) {
|
|
251
|
+
throw new AuthError("Token invalid or expired. Run: alpha-classic-cli login");
|
|
252
|
+
}
|
|
253
|
+
const nextSession = await this.refreshSession(retry.session);
|
|
254
|
+
return this.requestWithSession(method, baseUrl, path4, {
|
|
255
|
+
data: retry.data,
|
|
256
|
+
params: retry.params,
|
|
257
|
+
headers: {
|
|
258
|
+
...retry.headers ?? {},
|
|
259
|
+
...retry.contentType ? { "Content-Type": retry.contentType } : {}
|
|
260
|
+
},
|
|
261
|
+
session: nextSession,
|
|
262
|
+
allowRefresh: false
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
async fetchJson(method, baseUrl, path4, options) {
|
|
266
|
+
const url = new URL(path4.startsWith("/") ? path4 : `/${path4}`, normalizeBaseUrl(baseUrl));
|
|
267
|
+
for (const [key, value] of Object.entries(options.params ?? {})) {
|
|
268
|
+
if (value !== void 0 && value !== null) {
|
|
269
|
+
url.searchParams.set(key, String(value));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const controller = new AbortController();
|
|
273
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
274
|
+
try {
|
|
275
|
+
const response = await fetch(url, {
|
|
276
|
+
method: method.toUpperCase(),
|
|
277
|
+
headers: {
|
|
278
|
+
Accept: "application/json",
|
|
279
|
+
...options.data !== void 0 ? { "Content-Type": "application/json" } : {},
|
|
280
|
+
...options.headers ?? {},
|
|
281
|
+
...options.session?.token ? { token: options.session.token } : {},
|
|
282
|
+
deviceType: options.session?.deviceType ?? DEVICE_TYPE_AI
|
|
283
|
+
},
|
|
284
|
+
body: options.data !== void 0 ? typeof options.data === "string" ? options.data : JSON.stringify(options.data) : void 0,
|
|
285
|
+
signal: controller.signal
|
|
286
|
+
});
|
|
287
|
+
const text = await response.text();
|
|
288
|
+
return {
|
|
289
|
+
status: response.status,
|
|
290
|
+
statusText: response.statusText,
|
|
291
|
+
body: text ? parseJson(text) : null
|
|
292
|
+
};
|
|
293
|
+
} catch (error) {
|
|
294
|
+
if (error instanceof Error) {
|
|
295
|
+
throw new ApiError(
|
|
296
|
+
`${error.message} - ${method.toUpperCase()} ${normalizeBaseUrl(baseUrl)}${path4}`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
throw error;
|
|
300
|
+
} finally {
|
|
301
|
+
clearTimeout(timeout);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
function asResultEnvelope(value) {
|
|
306
|
+
if (!value || typeof value !== "object") {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
const record = value;
|
|
310
|
+
const hasModernEnvelope = typeof record.success === "boolean" && (record.code === void 0 || typeof record.code === "number") && (record.msg === void 0 || typeof record.msg === "string");
|
|
311
|
+
const hasLegacyEnvelope = typeof record.isSuccess === "boolean" && (record.resultCode === void 0 || typeof record.resultCode === "number" || typeof record.resultCode === "string") && (record.resultMsg === void 0 || typeof record.resultMsg === "string");
|
|
312
|
+
if ("data" in record && (hasModernEnvelope || hasLegacyEnvelope)) {
|
|
313
|
+
return value;
|
|
314
|
+
}
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
function throwApiEnvelopeError(envelope, status) {
|
|
318
|
+
const code = envelope.code ?? envelope.resultCode;
|
|
319
|
+
const message = envelope.msg ?? envelope.resultMsg ?? envelope.message ?? "API request failed.";
|
|
320
|
+
if (Number(code) === RESULT_CODE_AUTH) {
|
|
321
|
+
throw new AuthError(message, code, status);
|
|
322
|
+
}
|
|
323
|
+
if (Number(code) === RESULT_CODE_PERMISSION) {
|
|
324
|
+
throw new PermissionError(message, code, status);
|
|
325
|
+
}
|
|
326
|
+
throw new ApiError(message, code, status);
|
|
327
|
+
}
|
|
328
|
+
function parseJson(text) {
|
|
329
|
+
try {
|
|
330
|
+
return JSON.parse(text);
|
|
331
|
+
} catch {
|
|
332
|
+
return text;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/util/jwt.ts
|
|
337
|
+
function decodeAlphaJwtClaims(token) {
|
|
338
|
+
if (!token) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
const [, payload] = token.split(".");
|
|
342
|
+
if (!payload) {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
try {
|
|
346
|
+
return JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
347
|
+
} catch {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// src/auth/login.ts
|
|
353
|
+
var CLIENT_NAME = "alpha-classic-cli";
|
|
354
|
+
var DEVICE_TYPE_AI2 = "ai";
|
|
355
|
+
var DEFAULT_LOGIN_TIMEOUT_MS = 3e5;
|
|
356
|
+
var DEFAULT_POLL_INTERVAL_MS = 2e3;
|
|
357
|
+
var PENDING_AUTHORIZATION_MESSAGE_PREFIX = "\u6388\u6743\u5C1A\u672A\u786E\u8BA4";
|
|
358
|
+
var require2 = createRequire(import.meta.url);
|
|
359
|
+
var qrCodeTerminal = require2("qrcode-terminal");
|
|
360
|
+
async function createLoginDeviceAuthorization(options, sessionStore) {
|
|
361
|
+
const context = await resolveLoginContext(options, sessionStore);
|
|
362
|
+
emitProgress(options.onProgress, "login: creating CLI device authorization");
|
|
363
|
+
const auth = await context.apiClient.createCliDeviceAuth(context.baseUrl, {
|
|
364
|
+
client: CLIENT_NAME,
|
|
365
|
+
deviceName: buildDeviceName()
|
|
366
|
+
});
|
|
367
|
+
await sessionStore.saveConfig({
|
|
368
|
+
environment: context.environment.name,
|
|
369
|
+
baseUrl: context.baseUrl,
|
|
370
|
+
apiBaseUrl: context.apiBaseUrl,
|
|
371
|
+
timeoutMs: context.timeoutMs
|
|
372
|
+
});
|
|
373
|
+
return {
|
|
374
|
+
baseUrl: context.baseUrl,
|
|
375
|
+
apiBaseUrl: context.apiBaseUrl,
|
|
376
|
+
timeoutMs: context.timeoutMs,
|
|
377
|
+
auth
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
async function pollLoginDeviceAuthorization(options, sessionStore, deviceCode) {
|
|
381
|
+
const context = await resolveLoginContext(options, sessionStore);
|
|
382
|
+
const auth = {
|
|
383
|
+
deviceCode,
|
|
384
|
+
verificationUriComplete: ""
|
|
385
|
+
};
|
|
386
|
+
emitProgress(options.onProgress, "login: waiting for browser authorization");
|
|
387
|
+
const loginVO = await waitForDeviceAuthorization(
|
|
388
|
+
context.apiClient,
|
|
389
|
+
context.baseUrl,
|
|
390
|
+
auth,
|
|
391
|
+
context.timeoutMs,
|
|
392
|
+
options.onProgress
|
|
393
|
+
);
|
|
394
|
+
return saveLoginSession(context, loginVO, sessionStore, options);
|
|
395
|
+
}
|
|
396
|
+
async function runLogin(options, sessionStore) {
|
|
397
|
+
if (options.token) {
|
|
398
|
+
return runTokenLogin(options, sessionStore);
|
|
399
|
+
}
|
|
400
|
+
const context = await resolveLoginContext(options, sessionStore);
|
|
401
|
+
const authResult = await createLoginDeviceAuthorization(
|
|
402
|
+
{
|
|
403
|
+
...options,
|
|
404
|
+
apiClient: context.apiClient,
|
|
405
|
+
timeoutMs: context.timeoutMs
|
|
406
|
+
},
|
|
407
|
+
sessionStore
|
|
408
|
+
);
|
|
409
|
+
emitDeviceAuthorizationPrompt(authResult.auth, options.onProgress);
|
|
410
|
+
if (options.openBrowser !== false) {
|
|
411
|
+
const openBrowser = typeof options.openBrowser === "function" ? options.openBrowser : async (url) => {
|
|
412
|
+
await open(url, { wait: false });
|
|
413
|
+
};
|
|
414
|
+
try {
|
|
415
|
+
await openBrowser(authResult.auth.verificationUriComplete);
|
|
416
|
+
} catch {
|
|
417
|
+
emitProgress(
|
|
418
|
+
options.onProgress,
|
|
419
|
+
`login: failed to open browser automatically, please open ${authResult.auth.verificationUriComplete}`
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
emitProgress(options.onProgress, "login: waiting for browser authorization");
|
|
424
|
+
const loginVO = await waitForDeviceAuthorization(
|
|
425
|
+
context.apiClient,
|
|
426
|
+
context.baseUrl,
|
|
427
|
+
authResult.auth,
|
|
428
|
+
context.timeoutMs,
|
|
429
|
+
options.onProgress
|
|
430
|
+
);
|
|
431
|
+
emitProgress(options.onProgress, "login: browser authorization completed");
|
|
432
|
+
return saveLoginSession(context, loginVO, sessionStore, options);
|
|
433
|
+
}
|
|
434
|
+
async function runTokenLogin(options, sessionStore) {
|
|
435
|
+
if (!options.token) {
|
|
436
|
+
throw new Error("Missing token.");
|
|
437
|
+
}
|
|
438
|
+
const environment = getDefaultEnvironmentPreset();
|
|
439
|
+
const currentUser = await verifyToken(environment.apiBaseUrl, options.token);
|
|
440
|
+
const currentUserData = getCurrentUserData(currentUser);
|
|
441
|
+
const userId = options.userId ?? currentUserData?.accid ?? currentUserData?.id ?? currentUserData?.user_id;
|
|
442
|
+
const userName = options.name ?? currentUserData?.name ?? currentUserData?.userName;
|
|
443
|
+
const officeId = options.officeId ?? currentUserData?.office_id ?? currentUserData?.officeId;
|
|
444
|
+
const officeName = currentUserData?.officeName;
|
|
445
|
+
const session = {
|
|
446
|
+
token: options.token,
|
|
447
|
+
baseUrl: environment.baseUrl,
|
|
448
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
449
|
+
deviceType: DEVICE_TYPE_AI2,
|
|
450
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
451
|
+
...userId ? { userId } : {},
|
|
452
|
+
...userName ? { name: userName, userName } : {},
|
|
453
|
+
...officeId ? { officeId } : {},
|
|
454
|
+
...officeName ? { officeName } : {}
|
|
455
|
+
};
|
|
456
|
+
await sessionStore.saveConfig({
|
|
457
|
+
environment: environment.name,
|
|
458
|
+
baseUrl: environment.baseUrl,
|
|
459
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
460
|
+
...officeId ? { defaultOfficeId: officeId } : {}
|
|
461
|
+
});
|
|
462
|
+
await sessionStore.saveSession(session);
|
|
463
|
+
return session;
|
|
464
|
+
}
|
|
465
|
+
async function resolveLoginContext(options, sessionStore) {
|
|
466
|
+
const config = await sessionStore.getConfig();
|
|
467
|
+
const environment = getDefaultEnvironmentPreset();
|
|
468
|
+
const baseUrl = normalizeBaseUrl(config.baseUrl ?? environment.baseUrl);
|
|
469
|
+
const apiBaseUrl = normalizeBaseUrl(config.apiBaseUrl ?? environment.apiBaseUrl);
|
|
470
|
+
const timeoutMs = options.timeoutMs ?? config.timeoutMs ?? DEFAULT_LOGIN_TIMEOUT_MS;
|
|
471
|
+
const apiClient = options.apiClient ?? new ApiClient({
|
|
472
|
+
sessionStore,
|
|
473
|
+
apiBaseUrl,
|
|
474
|
+
timeoutMs
|
|
475
|
+
});
|
|
476
|
+
return {
|
|
477
|
+
environment,
|
|
478
|
+
baseUrl,
|
|
479
|
+
apiBaseUrl,
|
|
480
|
+
timeoutMs,
|
|
481
|
+
apiClient
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
async function waitForDeviceAuthorization(apiClient, baseUrl, auth, timeoutMs, reporter) {
|
|
485
|
+
const deadline = resolveDeadline(auth, timeoutMs);
|
|
486
|
+
const intervalMs = resolvePollIntervalMs(auth);
|
|
487
|
+
while (Date.now() <= deadline) {
|
|
488
|
+
try {
|
|
489
|
+
return await apiClient.pollCliDeviceAuth(baseUrl, auth.deviceCode);
|
|
490
|
+
} catch (error) {
|
|
491
|
+
if (!isPendingAuthorization(error)) {
|
|
492
|
+
throw error;
|
|
493
|
+
}
|
|
494
|
+
emitProgress(reporter, "login: authorization is still pending");
|
|
495
|
+
}
|
|
496
|
+
await sleep(Math.min(intervalMs, Math.max(0, deadline - Date.now())));
|
|
497
|
+
}
|
|
498
|
+
throw new Error("Timed out waiting for Alpha device authorization.");
|
|
499
|
+
}
|
|
500
|
+
async function saveLoginSession(context, loginVO, sessionStore, options) {
|
|
501
|
+
const tokenDto = loginVO.jwtTokenDTO;
|
|
502
|
+
if (!tokenDto?.token) {
|
|
503
|
+
throw new Error("Device authorization succeeded but token payload is incomplete.");
|
|
504
|
+
}
|
|
505
|
+
const jwtClaims = decodeAlphaJwtClaims(tokenDto.token);
|
|
506
|
+
const userInfo = loginVO.userDTO ?? loginVO.userVO ?? loginVO;
|
|
507
|
+
const userName = userInfo.name ?? userInfo.userName ?? jwtClaims?.user_name;
|
|
508
|
+
const userId = userInfo.id ?? jwtClaims?.user_id;
|
|
509
|
+
const officeId = userInfo.officeId ?? userInfo.office_id ?? loginVO.officeId ?? jwtClaims?.office_id;
|
|
510
|
+
const officeName = userInfo.officeName ?? loginVO.officeName ?? jwtClaims?.office_name;
|
|
511
|
+
const session = {
|
|
512
|
+
token: tokenDto.token,
|
|
513
|
+
...tokenDto.refreshToken ? { refreshToken: tokenDto.refreshToken } : {},
|
|
514
|
+
...tokenDto.tokenExpireTime !== void 0 || jwtClaims?.exp !== void 0 ? { tokenExpireTime: tokenDto.tokenExpireTime ?? jwtClaims?.exp } : {},
|
|
515
|
+
...tokenDto.refreshTokenExpireTime !== void 0 ? { refreshTokenExpireTime: tokenDto.refreshTokenExpireTime } : {},
|
|
516
|
+
...userId ? { userId } : {},
|
|
517
|
+
...userName ? { userName, name: userName } : {},
|
|
518
|
+
...officeId ? { officeId } : {},
|
|
519
|
+
...officeName ? { officeName } : {},
|
|
520
|
+
baseUrl: context.baseUrl,
|
|
521
|
+
apiBaseUrl: context.apiBaseUrl,
|
|
522
|
+
deviceType: DEVICE_TYPE_AI2,
|
|
523
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
524
|
+
};
|
|
525
|
+
emitProgress(options.onProgress, "login: saving local config and session");
|
|
526
|
+
await sessionStore.saveConfig({
|
|
527
|
+
environment: context.environment.name,
|
|
528
|
+
baseUrl: context.baseUrl,
|
|
529
|
+
apiBaseUrl: context.apiBaseUrl,
|
|
530
|
+
timeoutMs: context.timeoutMs,
|
|
531
|
+
...officeId ? { defaultOfficeId: officeId } : {}
|
|
532
|
+
});
|
|
533
|
+
await sessionStore.saveSession(session);
|
|
534
|
+
emitProgress(options.onProgress, "login: local session saved");
|
|
535
|
+
return session;
|
|
536
|
+
}
|
|
537
|
+
function getCurrentUserData(response) {
|
|
538
|
+
return "data" in response && response.data ? response.data : response;
|
|
539
|
+
}
|
|
540
|
+
async function verifyToken(apiBaseUrl, token) {
|
|
541
|
+
const url = new URL("/im/v1/users/me", apiBaseUrl);
|
|
542
|
+
const response = await fetch(url, {
|
|
543
|
+
method: "GET",
|
|
544
|
+
headers: {
|
|
545
|
+
Accept: "application/json",
|
|
546
|
+
token,
|
|
547
|
+
deviceType: DEVICE_TYPE_AI2
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
const text = await response.text();
|
|
551
|
+
const body = text ? parseJson2(text) : {};
|
|
552
|
+
if (!response.ok) {
|
|
553
|
+
throw new Error(`Login verification failed: ${response.status} ${response.statusText}`);
|
|
554
|
+
}
|
|
555
|
+
const currentUser = body;
|
|
556
|
+
if (currentUser.isSuccess === false) {
|
|
557
|
+
throw new Error(currentUser.resultMsg ?? "Login verification failed.");
|
|
558
|
+
}
|
|
559
|
+
return currentUser;
|
|
560
|
+
}
|
|
561
|
+
function emitDeviceAuthorizationPrompt(auth, reporter) {
|
|
562
|
+
emitProgress(reporter, `login: user code ${auth.userCode ?? "(not provided)"}`);
|
|
563
|
+
const qrcode = buildTerminalQrCode(auth.verificationUriComplete);
|
|
564
|
+
if (qrcode) {
|
|
565
|
+
emitProgress(reporter, "login: scan this QR code to authorize");
|
|
566
|
+
emitRawProgress(reporter, `
|
|
567
|
+
${qrcode}
|
|
568
|
+
`);
|
|
569
|
+
}
|
|
570
|
+
emitProgress(reporter, `login: open ${auth.verificationUriComplete}`);
|
|
571
|
+
}
|
|
572
|
+
function emitProgress(reporter, message) {
|
|
573
|
+
reporter?.(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN", { hour12: false })}] ${message}`);
|
|
574
|
+
}
|
|
575
|
+
function emitRawProgress(reporter, message) {
|
|
576
|
+
reporter?.(message);
|
|
577
|
+
}
|
|
578
|
+
function buildTerminalQrCode(value) {
|
|
579
|
+
let rendered = "";
|
|
580
|
+
qrCodeTerminal.generate(value, { small: true }, (qrcode) => {
|
|
581
|
+
rendered = qrcode;
|
|
582
|
+
});
|
|
583
|
+
return rendered;
|
|
584
|
+
}
|
|
585
|
+
function buildDeviceName() {
|
|
586
|
+
return `${os.hostname()} (${process.platform} ${process.arch})`;
|
|
587
|
+
}
|
|
588
|
+
function isPendingAuthorization(error) {
|
|
589
|
+
return error instanceof ApiError && error.message.startsWith(PENDING_AUTHORIZATION_MESSAGE_PREFIX);
|
|
590
|
+
}
|
|
591
|
+
function resolveDeadline(auth, timeoutMs) {
|
|
592
|
+
const serverExpireMs = typeof auth.expiresIn === "number" && auth.expiresIn > 0 ? auth.expiresIn * 1e3 : timeoutMs;
|
|
593
|
+
return Date.now() + Math.min(timeoutMs, serverExpireMs);
|
|
594
|
+
}
|
|
595
|
+
function resolvePollIntervalMs(auth) {
|
|
596
|
+
if (typeof auth.interval !== "number" || auth.interval <= 0) {
|
|
597
|
+
return DEFAULT_POLL_INTERVAL_MS;
|
|
598
|
+
}
|
|
599
|
+
return Math.max(1e3, auth.interval * 1e3);
|
|
600
|
+
}
|
|
601
|
+
function sleep(ms) {
|
|
602
|
+
return new Promise((resolve) => {
|
|
603
|
+
setTimeout(resolve, ms);
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
function parseJson2(text) {
|
|
607
|
+
try {
|
|
608
|
+
return JSON.parse(text);
|
|
609
|
+
} catch {
|
|
610
|
+
return text;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// src/output/envelope.ts
|
|
615
|
+
function printJson(value) {
|
|
616
|
+
console.log(JSON.stringify(value, null, 2));
|
|
617
|
+
}
|
|
618
|
+
function printSuccess(data, meta) {
|
|
619
|
+
const envelope = {
|
|
620
|
+
ok: true,
|
|
621
|
+
data,
|
|
622
|
+
...meta ? { meta } : {}
|
|
623
|
+
};
|
|
624
|
+
printJson(envelope);
|
|
625
|
+
}
|
|
626
|
+
function printError(type, message, options) {
|
|
627
|
+
const envelope = {
|
|
628
|
+
ok: false,
|
|
629
|
+
error: {
|
|
630
|
+
type,
|
|
631
|
+
message,
|
|
632
|
+
...options?.hint ? { hint: options.hint } : {},
|
|
633
|
+
...options?.detail !== void 0 ? { detail: options.detail } : {}
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
console.error(JSON.stringify(envelope, null, 2));
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// src/commands/api.ts
|
|
640
|
+
async function runApiCommand(method, apiPath, options, sessionStore) {
|
|
641
|
+
const config = await sessionStore.getConfig();
|
|
642
|
+
const environment = getDefaultEnvironmentPreset();
|
|
643
|
+
const client = new ApiClient({
|
|
644
|
+
sessionStore,
|
|
645
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
646
|
+
timeoutMs: config.timeoutMs
|
|
647
|
+
});
|
|
648
|
+
const data = await client.request(method, apiPath, {
|
|
649
|
+
params: options.params ? parseJsonObject(options.params, "--params") : void 0,
|
|
650
|
+
data: options.data ? JSON.parse(options.data) : void 0
|
|
651
|
+
});
|
|
652
|
+
printSuccess(data);
|
|
653
|
+
}
|
|
654
|
+
function parseJsonObject(value, flagName) {
|
|
655
|
+
const parsed = JSON.parse(value);
|
|
656
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
657
|
+
throw new Error(`${flagName} must be a JSON object.`);
|
|
658
|
+
}
|
|
659
|
+
return parsed;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// src/commands/appro.ts
|
|
663
|
+
var APPRO_SCOPE_TO_ENUM = {
|
|
664
|
+
my: "SELF_APPROVAL",
|
|
665
|
+
started: "SELF_STARTED",
|
|
666
|
+
cc: "CC_SELF",
|
|
667
|
+
all: "ALL_APPROVAL"
|
|
668
|
+
};
|
|
669
|
+
async function runApproList(options, sessionStore) {
|
|
670
|
+
const scope = parseApproScope(options.scope);
|
|
671
|
+
const page = clampPage(options.page ?? 1);
|
|
672
|
+
const limit = clampLimit(options.limit ?? 10);
|
|
673
|
+
const approTypes = parseNumberList(options.approType);
|
|
674
|
+
const status = parseApproStatus(options.status);
|
|
675
|
+
const config = await sessionStore.getConfig();
|
|
676
|
+
const environment = getDefaultEnvironmentPreset();
|
|
677
|
+
const client = new ApiClient({
|
|
678
|
+
sessionStore,
|
|
679
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
680
|
+
timeoutMs: config.timeoutMs
|
|
681
|
+
});
|
|
682
|
+
const starter = await resolveStarterFilter(client, options);
|
|
683
|
+
const response = await client.request(
|
|
684
|
+
"POST",
|
|
685
|
+
"/appro/api/v2/approval/search",
|
|
686
|
+
{
|
|
687
|
+
data: {
|
|
688
|
+
approvalAboutSelfEnum: APPRO_SCOPE_TO_ENUM[scope],
|
|
689
|
+
limit,
|
|
690
|
+
offset: (page - 1) * limit,
|
|
691
|
+
orderType: "DESC",
|
|
692
|
+
outlook: options.keyword?.trim() ?? "",
|
|
693
|
+
pageIndex: page,
|
|
694
|
+
pageSize: limit,
|
|
695
|
+
selectApproFlow: 0,
|
|
696
|
+
approTypes,
|
|
697
|
+
startUserIds: starter.ids,
|
|
698
|
+
...status.status !== void 0 ? { status: status.status } : {},
|
|
699
|
+
...status.preStatus !== void 0 ? { preStatus: status.preStatus } : {}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
);
|
|
703
|
+
if (response.isSuccess === false) {
|
|
704
|
+
throw new Error(response.resultMsg ?? response.message ?? "Appro list request failed.");
|
|
705
|
+
}
|
|
706
|
+
const responseData = unwrapEnvelopeData(response);
|
|
707
|
+
const items = responseData?.items ?? [];
|
|
708
|
+
if (options.countOnly) {
|
|
709
|
+
printSuccess({
|
|
710
|
+
"\u8303\u56F4": formatApproScope(scope),
|
|
711
|
+
"\u72B6\u6001": status.label,
|
|
712
|
+
"\u53D1\u8D77\u4EBA": starter.names,
|
|
713
|
+
"\u603B\u6570": responseData?.totalCount ?? items.length
|
|
714
|
+
});
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
printSuccess({
|
|
718
|
+
"\u8303\u56F4": formatApproScope(scope),
|
|
719
|
+
"\u603B\u6570": responseData?.totalCount ?? items.length,
|
|
720
|
+
"\u9875\u7801": responseData?.pageIndex ?? page,
|
|
721
|
+
"\u6BCF\u9875\u6570\u91CF": responseData?.pageSize ?? limit,
|
|
722
|
+
"\u53D1\u8D77\u4EBA\u7B5B\u9009": starter.names,
|
|
723
|
+
"\u5BA1\u6279\u5217\u8868": items.map((item) => toApproSummary(item, scope))
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
async function runApproInitiators(options, sessionStore) {
|
|
727
|
+
const limit = clampLimit(options.limit ?? 50);
|
|
728
|
+
const config = await sessionStore.getConfig();
|
|
729
|
+
const environment = getDefaultEnvironmentPreset();
|
|
730
|
+
const client = new ApiClient({
|
|
731
|
+
sessionStore,
|
|
732
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
733
|
+
timeoutMs: config.timeoutMs
|
|
734
|
+
});
|
|
735
|
+
const initiators = await fetchApproInitiators(client, {
|
|
736
|
+
includeLeft: options.includeLeft ?? false
|
|
737
|
+
});
|
|
738
|
+
const keyword = options.keyword?.trim();
|
|
739
|
+
const filtered = keyword ? initiators.filter((user) => user.name.includes(keyword)) : initiators;
|
|
740
|
+
printSuccess({
|
|
741
|
+
"\u603B\u6570": filtered.length,
|
|
742
|
+
"\u53D1\u8D77\u4EBA\u5217\u8868": filtered.slice(0, limit).map((user) => ({
|
|
743
|
+
"\u53D1\u8D77\u4EBAID": user.id,
|
|
744
|
+
"\u59D3\u540D": user.name,
|
|
745
|
+
"\u624B\u673A\u53F7": user.phone,
|
|
746
|
+
"\u90AE\u7BB1": user.email,
|
|
747
|
+
"\u72B6\u6001": user.status
|
|
748
|
+
}))
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
async function runApproDetail(options, sessionStore) {
|
|
752
|
+
const approId = options.id.trim();
|
|
753
|
+
if (!approId) {
|
|
754
|
+
throw new Error("Missing appro id. Use: alpha-classic-cli appro detail --id <approId>");
|
|
755
|
+
}
|
|
756
|
+
const config = await sessionStore.getConfig();
|
|
757
|
+
const environment = getDefaultEnvironmentPreset();
|
|
758
|
+
const client = new ApiClient({
|
|
759
|
+
sessionStore,
|
|
760
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
761
|
+
timeoutMs: config.timeoutMs
|
|
762
|
+
});
|
|
763
|
+
const response = await client.request(
|
|
764
|
+
"GET",
|
|
765
|
+
`/appro/api/v2/appros/${encodeURIComponent(approId)}`
|
|
766
|
+
);
|
|
767
|
+
if (response.isSuccess === false) {
|
|
768
|
+
throw new Error(response.resultMsg ?? response.message ?? "Appro detail request failed.");
|
|
769
|
+
}
|
|
770
|
+
const detail = unwrapEnvelopeData(response);
|
|
771
|
+
if (!detail?.approDO) {
|
|
772
|
+
throw new Error("\u5BA1\u6279\u4E0D\u5B58\u5728\u6216\u5F53\u524D\u7528\u6237\u65E0\u6743\u67E5\u770B\u3002");
|
|
773
|
+
}
|
|
774
|
+
const commentsLimit = clampCommentLimit(options.comments ?? 10);
|
|
775
|
+
const feeds = commentsLimit > 0 ? await fetchApproFeeds(client, detail, {
|
|
776
|
+
approId,
|
|
777
|
+
limit: commentsLimit
|
|
778
|
+
}) : {
|
|
779
|
+
"\u7528\u6237\u8BC4\u8BBA": { "\u603B\u6570": 0, "\u8BC4\u8BBA\u5217\u8868": [] },
|
|
780
|
+
"\u5BA1\u6279\u52A8\u6001": { "\u603B\u6570": 0, "\u52A8\u6001\u5217\u8868": [] }
|
|
781
|
+
};
|
|
782
|
+
const attachmentDetails = await fetchApproAttachmentDetails(client, detail);
|
|
783
|
+
printSuccess(toApproDetailOutput(detail, feeds, attachmentDetails));
|
|
784
|
+
}
|
|
785
|
+
function toApproSummary(item, _scope) {
|
|
786
|
+
const merged = {
|
|
787
|
+
...item.extra ?? {},
|
|
788
|
+
...item.expandApproVO ?? {}
|
|
789
|
+
};
|
|
790
|
+
return {
|
|
791
|
+
"\u5BA1\u6279ID": item.id ?? "",
|
|
792
|
+
"\u5BA1\u6279\u7C7B\u578B": item.approTypeName ?? formatApproType(item.approType),
|
|
793
|
+
"\u91CD\u8981\u4FE1\u606F": stripHtml(item.outlook ?? stringField(merged, "outlook")),
|
|
794
|
+
"\u9879\u76EEID": item.matterId ?? "",
|
|
795
|
+
"\u9879\u76EE\u540D\u79F0": item.matterName ?? stringField(merged, "matterName"),
|
|
796
|
+
"\u9879\u76EE\u7F16\u53F7": item.matterNo ?? "",
|
|
797
|
+
"\u5BA2\u6237": item.customerStr ?? "",
|
|
798
|
+
"\u53D1\u8D77\u4EBA": item.startUserName ?? "",
|
|
799
|
+
// Approval list rows use the approval lifecycle status from Alpha Web's
|
|
800
|
+
// statusMap. This is different from filter statuses under "我审批的".
|
|
801
|
+
"\u72B6\u6001": item.statusStr ?? formatApproStatus(item.status, item.preStatus, "all"),
|
|
802
|
+
"\u5F53\u524D\u8282\u70B9": item.nodeName ?? "",
|
|
803
|
+
"\u53D1\u8D77\u65F6\u95F4": formatDateTime(item.createDate),
|
|
804
|
+
"\u5230\u8FBE\u5F53\u524D\u8282\u70B9\u65F6\u95F4": formatDateTime(item.arriveCurrentNodeDate),
|
|
805
|
+
"\u6D41\u7A0B\u4EFB\u52A1ID": item.flowTaskId ?? ""
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
async function resolveStarterFilter(client, options) {
|
|
809
|
+
const starterId = options.starterId?.trim();
|
|
810
|
+
if (starterId) {
|
|
811
|
+
return { ids: [starterId], names: [starterId] };
|
|
812
|
+
}
|
|
813
|
+
const starterName = options.starterName?.trim();
|
|
814
|
+
if (!starterName) {
|
|
815
|
+
return { ids: [], names: [] };
|
|
816
|
+
}
|
|
817
|
+
const initiators = await fetchApproInitiators(client, { includeLeft: false });
|
|
818
|
+
const exactMatches = initiators.filter((user) => user.name === starterName);
|
|
819
|
+
const fuzzyMatches = exactMatches.length ? exactMatches : initiators.filter((user) => user.name.includes(starterName));
|
|
820
|
+
if (fuzzyMatches.length === 0) {
|
|
821
|
+
throw new Error(`\u672A\u627E\u5230\u53D1\u8D77\u4EBA\uFF1A${starterName}\u3002\u53EF\u5148\u8FD0\u884C alpha-classic-cli appro initiators --keyword ${starterName}`);
|
|
822
|
+
}
|
|
823
|
+
if (fuzzyMatches.length > 1) {
|
|
824
|
+
const candidates = fuzzyMatches.slice(0, 10).map((user) => `${user.name}(${user.id})`).join("\uFF0C");
|
|
825
|
+
throw new Error(`\u53D1\u8D77\u4EBA\u540D\u79F0\u4E0D\u552F\u4E00\uFF1A${starterName}\u3002\u5019\u9009\uFF1A${candidates}\u3002\u8BF7\u6539\u7528 --starter-id\u3002`);
|
|
826
|
+
}
|
|
827
|
+
const [match] = fuzzyMatches;
|
|
828
|
+
return { ids: [match.id], names: [match.name] };
|
|
829
|
+
}
|
|
830
|
+
async function fetchApproInitiators(client, options) {
|
|
831
|
+
const response = await client.request(
|
|
832
|
+
"GET",
|
|
833
|
+
"/user/api/v1/users/listOfficeUser",
|
|
834
|
+
{
|
|
835
|
+
params: {
|
|
836
|
+
deleted: 0,
|
|
837
|
+
...options.includeLeft ? {} : { status: 1 }
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
);
|
|
841
|
+
if (response.isSuccess === false) {
|
|
842
|
+
throw new Error(response.resultMsg ?? response.message ?? "Appro initiators request failed.");
|
|
843
|
+
}
|
|
844
|
+
const data = unwrapEnvelopeData(response);
|
|
845
|
+
return (data ?? []).map((user) => ({
|
|
846
|
+
id: user.id ?? user.user_id ?? user.userId ?? "",
|
|
847
|
+
name: user.name ?? user.userName ?? "",
|
|
848
|
+
phone: user.phone ?? "",
|
|
849
|
+
email: user.email ?? "",
|
|
850
|
+
status: formatRawStatus(user.status)
|
|
851
|
+
})).filter((user) => user.id && user.name);
|
|
852
|
+
}
|
|
853
|
+
function toApproDetailOutput(detail, feeds, attachmentDetails) {
|
|
854
|
+
const appro = detail.approDO ?? {};
|
|
855
|
+
const files = detail.files ?? [];
|
|
856
|
+
const flows = detail.flowsDto?.length ? detail.flowsDto : detail.flows ?? [];
|
|
857
|
+
const attachments = getApproAttachmentRefs(detail);
|
|
858
|
+
return {
|
|
859
|
+
"\u5BA1\u6279\u6982\u89C8": {
|
|
860
|
+
"\u5BA1\u6279ID": appro.id ?? "",
|
|
861
|
+
"\u5BA1\u6279\u7C7B\u578B": appro.approTypeName ?? formatApproType(appro.approType),
|
|
862
|
+
"\u91CD\u8981\u4FE1\u606F": stripHtml(appro.outlook ?? ""),
|
|
863
|
+
"\u72B6\u6001": appro.statusStr ?? formatApproStatus(appro.status, appro.preStatus, "started"),
|
|
864
|
+
"\u5F53\u524D\u8282\u70B9": appro.nodeName ?? "",
|
|
865
|
+
"\u53D1\u8D77\u4EBA": appro.startUserName ?? "",
|
|
866
|
+
"\u53D1\u8D77\u65F6\u95F4": formatDateTime(appro.createDate),
|
|
867
|
+
"\u66F4\u65B0\u65F6\u95F4": formatDateTime(appro.modifyDate),
|
|
868
|
+
"\u5BA1\u6279\u7F16\u53F7": detail.code ?? appro.code ?? "",
|
|
869
|
+
"\u8BC4\u8BBA\u548C\u52A8\u6001\u6570\u91CF": detail.countFeeds ?? 0,
|
|
870
|
+
"\u6D41\u7A0B\u4EFB\u52A1ID": detail.flowTaskId ?? ""
|
|
871
|
+
},
|
|
872
|
+
"\u9879\u76EE\u4FE1\u606F": {
|
|
873
|
+
"\u9879\u76EEID": detail.matterId ?? appro.matterId ?? "",
|
|
874
|
+
"\u9879\u76EE\u540D\u79F0": detail.matterName ?? appro.matterName ?? "",
|
|
875
|
+
"\u9879\u76EE\u7F16\u53F7": detail.matterNo ?? appro.matterNo ?? "",
|
|
876
|
+
"\u9879\u76EE\u7C7B\u578B": [detail.pMatterTypeName, detail.matterTypeName, detail.matterType ?? appro.matterType].filter(Boolean).join(" / "),
|
|
877
|
+
"\u9879\u76EE\u72B6\u6001": detail.matterStatus ?? appro.matterStatus ?? "",
|
|
878
|
+
"\u9879\u76EE\u6240\u5C5E": detail.depOrOwnerName ?? detail.matterOwner ?? appro.matterOwner ?? "",
|
|
879
|
+
"\u5BA2\u6237": appro.customerStr ?? ""
|
|
880
|
+
},
|
|
881
|
+
"\u5BA1\u6279\u8868\u5355": formatApproForm(detail),
|
|
882
|
+
"\u5BA1\u6279\u6D41\u7A0B": flows.map(toApproFlowSummary),
|
|
883
|
+
"\u9644\u4EF6": attachments.length ? attachments.map((attachment) => toApproAttachmentSummary(attachment, attachmentDetails.get(attachment.fileId))) : files.map((file) => toApproFileSummary(file)),
|
|
884
|
+
...feeds
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
async function fetchApproAttachmentDetails(client, detail) {
|
|
888
|
+
const refsWithTicket = getApproAttachmentRefs(detail).filter((ref) => ref.fileId && ref.ticket);
|
|
889
|
+
const groups = /* @__PURE__ */ new Map();
|
|
890
|
+
for (const ref of refsWithTicket) {
|
|
891
|
+
const ticket = ref.ticket ?? "";
|
|
892
|
+
groups.set(ticket, [...groups.get(ticket) ?? [], ref.fileId]);
|
|
893
|
+
}
|
|
894
|
+
const details = /* @__PURE__ */ new Map();
|
|
895
|
+
await Promise.all(
|
|
896
|
+
[...groups.entries()].map(async ([ticket, fileIds]) => {
|
|
897
|
+
const response = await client.request(
|
|
898
|
+
"GET",
|
|
899
|
+
"/common/api/v1/file/batch",
|
|
900
|
+
{
|
|
901
|
+
params: {
|
|
902
|
+
fileIds: [...new Set(fileIds)].join(",")
|
|
903
|
+
},
|
|
904
|
+
headers: {
|
|
905
|
+
"deviceType": "web",
|
|
906
|
+
"file-ticket": ticket
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
);
|
|
910
|
+
if (response.isSuccess === false) {
|
|
911
|
+
throw new Error(response.resultMsg ?? response.message ?? "Appro attachment detail request failed.");
|
|
912
|
+
}
|
|
913
|
+
const data = unwrapEnvelopeData(response);
|
|
914
|
+
for (const file of data ?? []) {
|
|
915
|
+
if (file.id) {
|
|
916
|
+
details.set(file.id, file);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
})
|
|
920
|
+
);
|
|
921
|
+
return details;
|
|
922
|
+
}
|
|
923
|
+
function getApproAttachmentRefs(detail) {
|
|
924
|
+
const refs = [];
|
|
925
|
+
for (const file of detail.files ?? []) {
|
|
926
|
+
const fileId = file.id === void 0 || file.id === null ? "" : String(file.id);
|
|
927
|
+
if (fileId) {
|
|
928
|
+
refs.push({ fileId, legacyFile: file });
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
for (const field of detail.fieldsDtos ?? []) {
|
|
932
|
+
if (field.widgetName !== "Attachment") {
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
const fileIds = normalizeStringList(field.value);
|
|
936
|
+
const ticket = typeof field.extraValue === "string" ? field.extraValue : void 0;
|
|
937
|
+
for (const fileId of fileIds) {
|
|
938
|
+
refs.push({
|
|
939
|
+
fileId,
|
|
940
|
+
ticket,
|
|
941
|
+
fieldLabel: field.label
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return dedupeApproAttachmentRefs(refs);
|
|
946
|
+
}
|
|
947
|
+
function dedupeApproAttachmentRefs(refs) {
|
|
948
|
+
const seen = /* @__PURE__ */ new Set();
|
|
949
|
+
return refs.filter((ref) => {
|
|
950
|
+
if (!ref.fileId || seen.has(ref.fileId)) {
|
|
951
|
+
return false;
|
|
952
|
+
}
|
|
953
|
+
seen.add(ref.fileId);
|
|
954
|
+
return true;
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
async function fetchApproFeeds(client, detail, options) {
|
|
958
|
+
const approType = detail.approDO?.approType;
|
|
959
|
+
if (approType === void 0 || approType === null || approType === "") {
|
|
960
|
+
return {
|
|
961
|
+
"\u7528\u6237\u8BC4\u8BBA": { "\u603B\u6570": 0, "\u8BC4\u8BBA\u5217\u8868": [] },
|
|
962
|
+
"\u5BA1\u6279\u52A8\u6001": { "\u603B\u6570": 0, "\u52A8\u6001\u5217\u8868": [] },
|
|
963
|
+
"\u63D0\u793A": "\u5BA1\u6279\u7C7B\u578B\u7F3A\u5931\uFF0C\u65E0\u6CD5\u67E5\u8BE2\u8BC4\u8BBA\u548C\u52A8\u6001\u3002"
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
const [comments, dynamics] = await Promise.all([
|
|
967
|
+
fetchApproFeedPage(client, {
|
|
968
|
+
approId: options.approId,
|
|
969
|
+
approType,
|
|
970
|
+
feedType: 1,
|
|
971
|
+
limit: options.limit
|
|
972
|
+
}),
|
|
973
|
+
fetchApproFeedPage(client, {
|
|
974
|
+
approId: options.approId,
|
|
975
|
+
approType,
|
|
976
|
+
feedType: 2,
|
|
977
|
+
limit: options.limit
|
|
978
|
+
})
|
|
979
|
+
]);
|
|
980
|
+
const { items: commentItems, ...commentPage } = comments;
|
|
981
|
+
const { items: dynamicItems, ...dynamicPage } = dynamics;
|
|
982
|
+
return {
|
|
983
|
+
"\u7528\u6237\u8BC4\u8BBA": {
|
|
984
|
+
...commentPage,
|
|
985
|
+
"\u8BC4\u8BBA\u5217\u8868": commentItems.map(toApproCommentSummary)
|
|
986
|
+
},
|
|
987
|
+
"\u5BA1\u6279\u52A8\u6001": {
|
|
988
|
+
...dynamicPage,
|
|
989
|
+
"\u52A8\u6001\u5217\u8868": dynamicItems.map(toApproDynamicSummary)
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
async function fetchApproFeedPage(client, options) {
|
|
994
|
+
try {
|
|
995
|
+
const response = await client.request("GET", "/appro/api/v1/feeds", {
|
|
996
|
+
params: {
|
|
997
|
+
approveId: options.approId,
|
|
998
|
+
approveType: options.approType,
|
|
999
|
+
// Alpha Web uses feedType, not seedType:
|
|
1000
|
+
// 1 = user comments, 2 = approval dynamics.
|
|
1001
|
+
feedType: options.feedType,
|
|
1002
|
+
pageIndex: 1,
|
|
1003
|
+
pageSize: options.limit,
|
|
1004
|
+
orderBy: "gmt_create",
|
|
1005
|
+
orderType: "desc"
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
if (response.isSuccess === false) {
|
|
1009
|
+
return {
|
|
1010
|
+
"\u603B\u6570": 0,
|
|
1011
|
+
"\u9875\u7801": 1,
|
|
1012
|
+
"\u6BCF\u9875\u6570\u91CF": options.limit,
|
|
1013
|
+
items: [],
|
|
1014
|
+
"\u63D0\u793A": response.resultMsg ?? response.message ?? "\u67E5\u8BE2\u5931\u8D25\u3002"
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
const data = unwrapEnvelopeData(response) ?? {};
|
|
1018
|
+
const items = data.items ?? data.entities ?? [];
|
|
1019
|
+
return {
|
|
1020
|
+
"\u603B\u6570": data.totalCount ?? data.entityCount ?? items.length,
|
|
1021
|
+
"\u9875\u7801": data.pageIndex ?? data.No ?? 1,
|
|
1022
|
+
"\u6BCF\u9875\u6570\u91CF": data.pageSize ?? options.limit,
|
|
1023
|
+
items
|
|
1024
|
+
};
|
|
1025
|
+
} catch (error) {
|
|
1026
|
+
return {
|
|
1027
|
+
"\u603B\u6570": 0,
|
|
1028
|
+
"\u9875\u7801": 1,
|
|
1029
|
+
"\u6BCF\u9875\u6570\u91CF": options.limit,
|
|
1030
|
+
items: [],
|
|
1031
|
+
"\u63D0\u793A": error instanceof Error ? error.message : String(error)
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
function unwrapEnvelopeData(response) {
|
|
1036
|
+
if (response && typeof response === "object" && "data" in response && ("isSuccess" in response || "resultMsg" in response || "message" in response)) {
|
|
1037
|
+
return response.data;
|
|
1038
|
+
}
|
|
1039
|
+
return response;
|
|
1040
|
+
}
|
|
1041
|
+
function formatApproForm(detail) {
|
|
1042
|
+
const approType = detail.approDO?.approType;
|
|
1043
|
+
const approTypeName = detail.approDO?.approTypeName ?? formatApproType(approType);
|
|
1044
|
+
return {
|
|
1045
|
+
"\u8868\u5355\u7C7B\u578B": approTypeName,
|
|
1046
|
+
"\u4E1A\u52A1\u5206\u7EC4": formatApproBusinessGroups(detail)
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
function formatApproBusinessGroups(detail) {
|
|
1050
|
+
const approType = numericCode(detail.approDO?.approType);
|
|
1051
|
+
if (approType === 1) {
|
|
1052
|
+
return formatInvoiceBusinessGroups(detail);
|
|
1053
|
+
}
|
|
1054
|
+
const fields = formatApproBusinessFields(detail);
|
|
1055
|
+
const patterns = getApproBusinessGroupPatterns(approType);
|
|
1056
|
+
return withSupplementFields(detail, splitBusinessFieldsIntoGroups(fields, patterns));
|
|
1057
|
+
}
|
|
1058
|
+
function formatInvoiceBusinessGroups(detail) {
|
|
1059
|
+
const record = detailRecord(detail);
|
|
1060
|
+
const appro = detail.approDO ?? {};
|
|
1061
|
+
const invoiceDto = objectField(appro, "invoiceDTO");
|
|
1062
|
+
const invoiceInfo = objectField(invoiceDto, "invoiceInfoVO");
|
|
1063
|
+
const relationIncomes = valueFrom(invoiceDto, record, "relationInvoceDTOS");
|
|
1064
|
+
const relationContracts = record.relationInvoiceContractDTOS ?? record.contracts;
|
|
1065
|
+
return withSupplementFields(detail, [
|
|
1066
|
+
buildBusinessGroup("\u57FA\u672C\u4FE1\u606F", (add) => {
|
|
1067
|
+
add("\u7533\u8BF7\u4EBA", invoiceInfo.applicantName ?? appro.startUserName);
|
|
1068
|
+
add("\u6240\u5C5E\u9879\u76EE", invoiceInfo.matterName ?? appro.matterName ?? detail.matterName);
|
|
1069
|
+
add("\u9879\u76EE\u7F16\u53F7", invoiceInfo.matterNo ?? appro.matterNo ?? detail.matterNo);
|
|
1070
|
+
add("\u6240\u5C5E", invoiceInfo.departmentName ?? record.depOrOwnerName ?? appro.matterOwner);
|
|
1071
|
+
add("\u5BA2\u6237", invoiceInfo.customers ?? record.clientNameForSearch ?? appro.customerStr);
|
|
1072
|
+
}),
|
|
1073
|
+
buildBusinessGroup("\u5173\u8054\u6536\u6B3E\u4FE1\u606F", (add) => {
|
|
1074
|
+
add("\u6536\u6B3E\u5217\u8868", relationIncomes);
|
|
1075
|
+
}),
|
|
1076
|
+
buildBusinessGroup("\u5173\u8054\u5408\u540C\u4FE1\u606F", (add) => {
|
|
1077
|
+
add("\u5408\u540C\u5217\u8868", relationContracts);
|
|
1078
|
+
}),
|
|
1079
|
+
buildBusinessGroup("\u4E13\u7968\u4FE1\u606F", (add) => {
|
|
1080
|
+
add("\u53D1\u7968\u62AC\u5934", invoiceInfo.invoiceTitle ?? appro.company);
|
|
1081
|
+
add("\u7EB3\u7A0E\u4EBA\u8BC6\u522B\u53F7", invoiceInfo.taxPayerId ?? appro.taxNumber);
|
|
1082
|
+
add("\u53D1\u7968\u7C7B\u578B", formatInvoiceType(invoiceInfo.invoiceType ?? appro.invoiceType));
|
|
1083
|
+
add("\u7A0E\u91D1\u7C7B\u578B", invoiceInfo.vatTypeName ?? appro.vatTypeName ?? invoiceInfo.vatType);
|
|
1084
|
+
add("\u53D1\u7968\u91D1\u989D", invoiceInfo.invoiceTotal ?? appro.money);
|
|
1085
|
+
add("\u5F8B\u5E08\u8D39\u91D1\u989D", invoiceInfo.lawyerValue ?? record.lawyerValue);
|
|
1086
|
+
add("\u7A0E\u91D1", invoiceInfo.vatValue ?? record.vatValue);
|
|
1087
|
+
add("\u5F00\u6237\u884C", invoiceInfo.openBank ?? appro.bank);
|
|
1088
|
+
add("\u8D26\u53F7", invoiceInfo.account ?? appro.account);
|
|
1089
|
+
add("\u7535\u8BDD", invoiceInfo.phoneNumber ?? appro.phone);
|
|
1090
|
+
add("\u5355\u4F4D\u5730\u5740", invoiceInfo.workAddress ?? appro.address);
|
|
1091
|
+
add("\u90AE\u7F16", invoiceInfo.zipCode ?? appro.postCode);
|
|
1092
|
+
add("\u53D1\u7968\u65E5\u671F", invoiceInfo.invoiceDate);
|
|
1093
|
+
add("\u53D1\u7968\u53F7\u7801", invoiceInfo.invoiceNumber);
|
|
1094
|
+
}),
|
|
1095
|
+
buildBusinessGroup("\u5907\u6CE8", (add) => {
|
|
1096
|
+
add("\u5907\u6CE8", invoiceInfo.remark ?? appro.remark ?? record.remark);
|
|
1097
|
+
})
|
|
1098
|
+
]);
|
|
1099
|
+
}
|
|
1100
|
+
function getApproBusinessGroupPatterns(approType) {
|
|
1101
|
+
switch (approType) {
|
|
1102
|
+
case 0:
|
|
1103
|
+
return [
|
|
1104
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u57FA\u672C\u4FE1\u606F", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5173\u8054\u9879\u76EE", "\u9879\u76EE\u7F16\u53F7", "\u9879\u76EE\u6240\u5C5E"] },
|
|
1105
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u76D6\u7AE0\u4FE1\u606F", labels: ["\u76D6\u7AE0\u6587\u4E66"] },
|
|
1106
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5907\u6CE8", labels: ["\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1107
|
+
];
|
|
1108
|
+
case 2:
|
|
1109
|
+
return [
|
|
1110
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u57FA\u672C\u4FE1\u606F", labels: ["\u5173\u8054\u9879\u76EE", "\u9879\u76EE\u7F16\u53F7", "\u7533\u8BF7\u65E5\u671F"] },
|
|
1111
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u62A5\u9500\u660E\u7EC6", labels: ["\u62A5\u9500\u603B\u989D", "\u62A5\u9500\u660E\u7EC6"] },
|
|
1112
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5907\u6CE8", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1113
|
+
];
|
|
1114
|
+
case 3:
|
|
1115
|
+
return [
|
|
1116
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u57FA\u672C\u4FE1\u606F", labels: ["\u9879\u76EE\u540D\u79F0", "\u9879\u76EE\u7F16\u53F7"] },
|
|
1117
|
+
{
|
|
1118
|
+
"\u5206\u7EC4\u540D\u79F0": "\u91D1\u989D\u6C47\u603B",
|
|
1119
|
+
labels: ["\u5408\u540C\u603B\u989D", "\u53D1\u7968\u603B\u989D", "\u6536\u6B3E\u603B\u989D", "\u8D26\u5355\u603B\u989D", "\u8D39\u7528\u603B\u989D", "\u5E94\u6536\u603B\u989D"]
|
|
1120
|
+
},
|
|
1121
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u7ED3\u9879\u8BF4\u660E", labels: ["\u7ED3\u9879\u8BF4\u660E"] },
|
|
1122
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5907\u6CE8", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1123
|
+
];
|
|
1124
|
+
case 4:
|
|
1125
|
+
return [
|
|
1126
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5408\u540C\u4FE1\u606F", labels: ["\u5408\u540C\u540D\u79F0", "\u5173\u8054\u9879\u76EE", "\u9879\u76EE\u7F16\u53F7", "\u5408\u540C\u7F16\u53F7", "\u59D4\u6258\u65B9", "\u5408\u540C\u91D1\u989D", "\u6807\u7684\u989D", "\u6743\u76CA\u91D1\u989D", "\u8BA1\u8D39\u65B9\u5F0F", "\u751F\u6548\u65E5\u671F", "\u7ED3\u675F\u65E5\u671F"] },
|
|
1127
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u76D6\u7AE0\u4FE1\u606F", labels: ["\u76D6\u7AE0\u7533\u8BF7\u4EBA", "\u5370\u7AE0\u7C7B\u578B", "\u7B7E\u7F72\u65B9\u5F0F", "\u76D6\u7AE0\u4EFD\u6570", "\u7B7E\u7F72\u65B9"] },
|
|
1128
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5907\u6CE8", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1129
|
+
];
|
|
1130
|
+
case 5:
|
|
1131
|
+
case 7:
|
|
1132
|
+
case 8:
|
|
1133
|
+
case 9:
|
|
1134
|
+
case 10:
|
|
1135
|
+
case 11:
|
|
1136
|
+
case 12:
|
|
1137
|
+
case 16:
|
|
1138
|
+
return [
|
|
1139
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u9879\u76EE\u57FA\u672C\u4FE1\u606F", labels: ["\u9879\u76EE\u540D\u79F0", "\u9879\u76EE\u7F16\u53F7", "\u9879\u76EE\u7C7B\u578B", "\u9879\u76EE\u72B6\u6001", "\u9879\u76EE\u7B49\u7EA7", "\u6CD5\u5F8B\u9886\u57DF", "\u9879\u76EE\u6240\u5C5E", "\u6848\u6E90\u5F8B\u5E08", "\u627F\u529E\u5F8B\u5E08", "\u5BA2\u6237", "\u5BF9\u65B9\u5F53\u4E8B\u4EBA", "\u5176\u4ED6\u5F53\u4E8B\u4EBA", "\u5F00\u59CB\u65E5\u671F", "\u7ED3\u675F\u65E5\u671F"] },
|
|
1140
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u9879\u76EE\u8865\u5145\u4FE1\u606F", labels: ["\u9879\u76EE\u8865\u5145\u4FE1\u606F"] },
|
|
1141
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5F53\u524D\u7A0B\u5E8F\u4FE1\u606F", labels: ["\u5F53\u524D\u7A0B\u5E8F\u4FE1\u606F"] },
|
|
1142
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u9879\u76EE\u8BE6\u60C5", labels: ["\u9879\u76EE\u8BE6\u60C5", "\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] },
|
|
1143
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u9879\u76EE\u6210\u5458", labels: ["\u9879\u76EE\u6210\u5458"] }
|
|
1144
|
+
];
|
|
1145
|
+
case 13:
|
|
1146
|
+
return [
|
|
1147
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u57FA\u672C\u4FE1\u606F", labels: ["\u5173\u8054\u9879\u76EE"] },
|
|
1148
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u4EFB\u52A1\u540D\u79F0", labels: ["\u4EFB\u52A1\u5217\u8868"] },
|
|
1149
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5907\u6CE8", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1150
|
+
];
|
|
1151
|
+
case 14:
|
|
1152
|
+
return [
|
|
1153
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u9879\u76EE\u57FA\u672C\u4FE1\u606F", labels: ["\u9879\u76EE\u540D\u79F0", "\u9879\u76EE\u7F16\u53F7"] },
|
|
1154
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5F52\u6863\u4FE1\u606F", labels: ["\u5F52\u6863\u7F16\u53F7"] },
|
|
1155
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u9879\u76EE\u53D8\u52A8\u4FE1\u606F", labels: ["\u9879\u76EE\u53D8\u52A8\u4FE1\u606F"] },
|
|
1156
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5907\u6CE8", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1157
|
+
];
|
|
1158
|
+
case 15:
|
|
1159
|
+
return [
|
|
1160
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u9879\u76EE\u57FA\u672C\u4FE1\u606F", labels: ["\u9879\u76EE\u540D\u79F0", "\u9879\u76EE\u7F16\u53F7"] },
|
|
1161
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u501F\u9605\u4FE1\u606F", labels: ["\u501F\u9605\u4FE1\u606F"] },
|
|
1162
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u5907\u6CE8", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1163
|
+
];
|
|
1164
|
+
default:
|
|
1165
|
+
return [
|
|
1166
|
+
{ "\u5206\u7EC4\u540D\u79F0": "\u57FA\u672C\u4FE1\u606F", labels: ["\u91CD\u8981\u4FE1\u606F", "\u5907\u6CE8", "\u539F\u56E0", "\u7ED3\u679C\u8BF4\u660E"] }
|
|
1167
|
+
];
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
function splitBusinessFieldsIntoGroups(fields, patterns) {
|
|
1171
|
+
const matched = /* @__PURE__ */ new Set();
|
|
1172
|
+
const groups = [];
|
|
1173
|
+
for (const pattern of patterns) {
|
|
1174
|
+
const fieldLabels = new Set(pattern.labels);
|
|
1175
|
+
const groupFields = fields.filter((field) => fieldLabels.has(field["\u5B57\u6BB5\u540D\u79F0"]));
|
|
1176
|
+
for (const field of groupFields) {
|
|
1177
|
+
matched.add(field["\u5B57\u6BB5\u540D\u79F0"]);
|
|
1178
|
+
}
|
|
1179
|
+
if (groupFields.length) {
|
|
1180
|
+
groups.push({
|
|
1181
|
+
"\u5206\u7EC4\u540D\u79F0": pattern["\u5206\u7EC4\u540D\u79F0"],
|
|
1182
|
+
"\u5B57\u6BB5": groupFields
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
const leftovers = fields.filter((field) => !matched.has(field["\u5B57\u6BB5\u540D\u79F0"]));
|
|
1187
|
+
if (leftovers.length) {
|
|
1188
|
+
groups.push({
|
|
1189
|
+
"\u5206\u7EC4\u540D\u79F0": "\u5176\u4ED6\u4FE1\u606F",
|
|
1190
|
+
"\u5B57\u6BB5": leftovers
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
return groups.length ? groups : [{ "\u5206\u7EC4\u540D\u79F0": "\u4E1A\u52A1\u4FE1\u606F", "\u5B57\u6BB5": fields }];
|
|
1194
|
+
}
|
|
1195
|
+
function withSupplementFields(detail, groups) {
|
|
1196
|
+
const supplementFields = formatApproCustomFields(detail).map((field) => ({
|
|
1197
|
+
"\u5B57\u6BB5\u540D\u79F0": String(field["\u5B57\u6BB5\u540D\u79F0"] ?? ""),
|
|
1198
|
+
"\u503C": field["\u503C"]
|
|
1199
|
+
})).filter((field) => field["\u5B57\u6BB5\u540D\u79F0"]);
|
|
1200
|
+
if (!supplementFields.length) {
|
|
1201
|
+
return groups;
|
|
1202
|
+
}
|
|
1203
|
+
return [
|
|
1204
|
+
...groups,
|
|
1205
|
+
{
|
|
1206
|
+
"\u5206\u7EC4\u540D\u79F0": "\u8865\u5145\u4FE1\u606F",
|
|
1207
|
+
"\u5B57\u6BB5": supplementFields
|
|
1208
|
+
}
|
|
1209
|
+
];
|
|
1210
|
+
}
|
|
1211
|
+
function buildBusinessGroup(name, build) {
|
|
1212
|
+
const fields = [];
|
|
1213
|
+
build((label, value) => addBusinessField(fields, label, value));
|
|
1214
|
+
return {
|
|
1215
|
+
"\u5206\u7EC4\u540D\u79F0": name,
|
|
1216
|
+
"\u5B57\u6BB5": fields
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
function formatApproBusinessFields(detail) {
|
|
1220
|
+
const approType = numericCode(detail.approDO?.approType);
|
|
1221
|
+
const fields = [];
|
|
1222
|
+
const add = (label, value) => addBusinessField(fields, label, value);
|
|
1223
|
+
if ([5, 7, 8, 9, 10, 11, 12, 16].includes(approType ?? -999)) {
|
|
1224
|
+
addProjectBusinessFields(detail, add);
|
|
1225
|
+
} else {
|
|
1226
|
+
switch (approType) {
|
|
1227
|
+
case 0:
|
|
1228
|
+
addSealBusinessFields(detail, add);
|
|
1229
|
+
break;
|
|
1230
|
+
case 1:
|
|
1231
|
+
addInvoiceBusinessFields(detail, add);
|
|
1232
|
+
break;
|
|
1233
|
+
case 2:
|
|
1234
|
+
addReimburseBusinessFields(detail, add);
|
|
1235
|
+
break;
|
|
1236
|
+
case 3:
|
|
1237
|
+
addCloseMatterBusinessFields(detail, add);
|
|
1238
|
+
break;
|
|
1239
|
+
case 4:
|
|
1240
|
+
addContractBusinessFields(detail, add);
|
|
1241
|
+
break;
|
|
1242
|
+
case 13:
|
|
1243
|
+
addTaskBusinessFields(detail, add);
|
|
1244
|
+
break;
|
|
1245
|
+
case 14:
|
|
1246
|
+
addFilingBusinessFields(detail, add);
|
|
1247
|
+
break;
|
|
1248
|
+
case 15:
|
|
1249
|
+
addBorrowBusinessFields(detail, add);
|
|
1250
|
+
break;
|
|
1251
|
+
default:
|
|
1252
|
+
addGenericBusinessFields(detail, add);
|
|
1253
|
+
break;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
addGenericBusinessFields(detail, add);
|
|
1257
|
+
return dedupeBusinessFields(fields);
|
|
1258
|
+
}
|
|
1259
|
+
function formatApproCustomFields(detail) {
|
|
1260
|
+
if (detail.fieldsDtos?.length) {
|
|
1261
|
+
return detail.fieldsDtos.map((field) => ({
|
|
1262
|
+
"\u5B57\u6BB5\u540D\u79F0": field.label ?? "",
|
|
1263
|
+
"\u503C": formatApproCustomFieldValue(field)
|
|
1264
|
+
})).filter((field) => field["\u5B57\u6BB5\u540D\u79F0"]);
|
|
1265
|
+
}
|
|
1266
|
+
return Object.entries(detail.formFields ?? {}).map(([key, value]) => ({
|
|
1267
|
+
"\u5B57\u6BB5\u540D\u79F0": key,
|
|
1268
|
+
"\u503C": normalizeFieldValue(value)
|
|
1269
|
+
}));
|
|
1270
|
+
}
|
|
1271
|
+
function formatApproCustomFieldValue(field) {
|
|
1272
|
+
switch (field.widgetName) {
|
|
1273
|
+
case "Attachment":
|
|
1274
|
+
return formatAttachmentFieldValue(field.value);
|
|
1275
|
+
case "RelateClientField":
|
|
1276
|
+
case "RelateMemberField":
|
|
1277
|
+
case "RelateDepartmentField":
|
|
1278
|
+
case "RelateMatterField":
|
|
1279
|
+
return namesFromExtraValue(field.extraValue);
|
|
1280
|
+
case "DateRangeField": {
|
|
1281
|
+
const values = normalizeStringList(field.value);
|
|
1282
|
+
return values.length ? values.join(" ~ ") : "";
|
|
1283
|
+
}
|
|
1284
|
+
default:
|
|
1285
|
+
return normalizeFieldValue(field.value);
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
function namesFromExtraValue(value) {
|
|
1289
|
+
if (Array.isArray(value)) {
|
|
1290
|
+
return value.map((item) => {
|
|
1291
|
+
if (item && typeof item === "object") {
|
|
1292
|
+
const record = item;
|
|
1293
|
+
return record.name ?? record.userName ?? record.departmentName ?? record.matterName;
|
|
1294
|
+
}
|
|
1295
|
+
return item;
|
|
1296
|
+
}).map((item) => String(item ?? "").trim()).filter(Boolean).join(",");
|
|
1297
|
+
}
|
|
1298
|
+
return typeof value === "string" ? stripHtml(value) : "";
|
|
1299
|
+
}
|
|
1300
|
+
function formatReimburseDetails(value) {
|
|
1301
|
+
const parsed = normalizeBusinessValue(value);
|
|
1302
|
+
if (!Array.isArray(parsed)) {
|
|
1303
|
+
return parsed ?? "";
|
|
1304
|
+
}
|
|
1305
|
+
return parsed.map((item) => {
|
|
1306
|
+
if (!item || typeof item !== "object") {
|
|
1307
|
+
return normalizeBusinessValue(item);
|
|
1308
|
+
}
|
|
1309
|
+
const record = item;
|
|
1310
|
+
return {
|
|
1311
|
+
"\u8D39\u7528\u91D1\u989D": formatFeeAmount(record.amount ?? record.feeSpendAmount),
|
|
1312
|
+
"\u8D39\u7528\u7C7B\u578B": record.feeTypeName ?? record.expenseType ?? record.feeCurrency,
|
|
1313
|
+
"\u8D39\u7528\u65E5\u671F": normalizeBusinessValue(record.feeDate ?? record.createDate, "\u8D39\u7528\u65E5\u671F"),
|
|
1314
|
+
"\u7ECF\u624B\u4EBA": record.handlerName,
|
|
1315
|
+
"\u5907\u6CE8": record.remark,
|
|
1316
|
+
"\u9644\u4EF6\u4E2A\u6570": countFileIds(record.fileIds)
|
|
1317
|
+
};
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
function formatFeeAmount(value) {
|
|
1321
|
+
if (typeof value === "number") {
|
|
1322
|
+
return value > 1e3 && Number.isInteger(value) ? value / 100 : value;
|
|
1323
|
+
}
|
|
1324
|
+
return value ?? "";
|
|
1325
|
+
}
|
|
1326
|
+
function countFileIds(value) {
|
|
1327
|
+
return normalizeStringList(value).length;
|
|
1328
|
+
}
|
|
1329
|
+
function addProjectBusinessFields(detail, add) {
|
|
1330
|
+
const record = detailRecord(detail);
|
|
1331
|
+
const appro = detail.approDO ?? {};
|
|
1332
|
+
add("\u9879\u76EE\u540D\u79F0", detail.matterName ?? appro.matterName);
|
|
1333
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? appro.matterNo);
|
|
1334
|
+
add("\u9879\u76EE\u7C7B\u578B", [record.pMatterTypeName, record.matterTypeName, detail.matterType ?? appro.matterType]);
|
|
1335
|
+
add("\u9879\u76EE\u72B6\u6001", detail.matterStatus ?? appro.matterStatus);
|
|
1336
|
+
add("\u9879\u76EE\u7B49\u7EA7", formatMatterLevel(record.level));
|
|
1337
|
+
add("\u6CD5\u5F8B\u9886\u57DF", record.lawField);
|
|
1338
|
+
add("\u9879\u76EE\u6240\u5C5E", record.belong ?? detail.depOrOwnerName ?? detail.matterOwner ?? appro.matterOwner);
|
|
1339
|
+
add("\u5BA2\u6237", record.clientNameForSearch ?? record.clients ?? appro.customerStr);
|
|
1340
|
+
add("\u5BF9\u65B9\u5F53\u4E8B\u4EBA", record.litigants);
|
|
1341
|
+
add("\u5176\u4ED6\u5F53\u4E8B\u4EBA", record.relevants);
|
|
1342
|
+
add("\u6848\u6E90\u5F8B\u5E08", record.attorneys);
|
|
1343
|
+
add("\u627F\u529E\u5F8B\u5E08", record.undertakeAttorneys);
|
|
1344
|
+
add("\u9879\u76EE\u6210\u5458", record.members);
|
|
1345
|
+
add("\u5F00\u59CB\u65E5\u671F", record.beginDate);
|
|
1346
|
+
add("\u7ED3\u675F\u65E5\u671F", record.endDate);
|
|
1347
|
+
add("\u9879\u76EE\u8BE6\u60C5", record.remark);
|
|
1348
|
+
add("\u5F53\u524D\u7A0B\u5E8F\u4FE1\u606F", record.process);
|
|
1349
|
+
add("\u9879\u76EE\u8865\u5145\u4FE1\u606F", record.expandInfo ?? record.expandInfoList);
|
|
1350
|
+
}
|
|
1351
|
+
function addContractBusinessFields(detail, add) {
|
|
1352
|
+
const record = detailRecord(detail);
|
|
1353
|
+
const appro = detail.approDO ?? {};
|
|
1354
|
+
add("\u5408\u540C\u540D\u79F0", record.contractName ?? record.contractNameForSearch);
|
|
1355
|
+
add("\u5173\u8054\u9879\u76EE", detail.matterName ?? appro.matterName);
|
|
1356
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? appro.matterNo);
|
|
1357
|
+
add("\u59D4\u6258\u65B9", record.contractEntrustClientsList ?? record.contractEntrustClients);
|
|
1358
|
+
add("\u5408\u540C\u91D1\u989D", record.estimatedContractAmount);
|
|
1359
|
+
add("\u6807\u7684\u989D", record.targetAmount);
|
|
1360
|
+
add("\u6743\u76CA\u91D1\u989D", record.equityAmount);
|
|
1361
|
+
add("\u8BA1\u8D39\u65B9\u5F0F", record.paymentTypes);
|
|
1362
|
+
add("\u751F\u6548\u65E5\u671F", record.effectiveDate);
|
|
1363
|
+
add("\u7ED3\u675F\u65E5\u671F", record.endDate);
|
|
1364
|
+
add("\u5408\u540C\u7F16\u53F7", record.code);
|
|
1365
|
+
add("\u76D6\u7AE0\u7533\u8BF7\u4EBA", record.stampApplicantName);
|
|
1366
|
+
add("\u5370\u7AE0\u7C7B\u578B", record.stampTypeNames);
|
|
1367
|
+
add("\u7B7E\u7F72\u65B9\u5F0F", formatSignType(record.signType));
|
|
1368
|
+
add("\u76D6\u7AE0\u4EFD\u6570", record.stampAmount);
|
|
1369
|
+
add("\u7B7E\u7F72\u65B9", record.signatoryList);
|
|
1370
|
+
}
|
|
1371
|
+
function addInvoiceBusinessFields(detail, add) {
|
|
1372
|
+
const record = detailRecord(detail);
|
|
1373
|
+
const appro = detail.approDO ?? {};
|
|
1374
|
+
const invoice = objectField(appro, "invoiceDTO");
|
|
1375
|
+
add("\u5173\u8054\u9879\u76EE", detail.matterName ?? appro.matterName);
|
|
1376
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? appro.matterNo);
|
|
1377
|
+
add("\u53D1\u7968\u7C7B\u578B", formatInvoiceType(valueFrom(invoice, appro, "invoiceType")));
|
|
1378
|
+
add("\u5F00\u7968\u5355\u4F4D", valueFrom(invoice, appro, "company"));
|
|
1379
|
+
add("\u53D1\u7968\u91D1\u989D", valueFrom(invoice, appro, "money"));
|
|
1380
|
+
add("\u7A0E\u53F7", valueFrom(invoice, appro, "taxNumber"));
|
|
1381
|
+
add("\u5F00\u6237\u884C\u53CA\u8D26\u53F7", valueFrom(invoice, appro, "account"));
|
|
1382
|
+
add("\u5355\u4F4D\u5730\u5740", valueFrom(invoice, appro, "address"));
|
|
1383
|
+
add("\u7535\u8BDD", valueFrom(invoice, appro, "phone"));
|
|
1384
|
+
add("\u90AE\u7F16", valueFrom(invoice, appro, "postCode"));
|
|
1385
|
+
add("\u5173\u8054\u5408\u540C", record.contracts);
|
|
1386
|
+
}
|
|
1387
|
+
function addReimburseBusinessFields(detail, add) {
|
|
1388
|
+
const record = detailRecord(detail);
|
|
1389
|
+
const appro = detail.approDO ?? {};
|
|
1390
|
+
add("\u62A5\u9500\u603B\u989D", record.totalMoney);
|
|
1391
|
+
add("\u7533\u8BF7\u65E5\u671F", record.applyDate ?? appro.createDate);
|
|
1392
|
+
add("\u5173\u8054\u9879\u76EE", detail.matterName ?? appro.matterName);
|
|
1393
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? appro.matterNo);
|
|
1394
|
+
add("\u62A5\u9500\u660E\u7EC6", formatReimburseDetails(record.feeSpendDetails));
|
|
1395
|
+
}
|
|
1396
|
+
function addSealBusinessFields(detail, add) {
|
|
1397
|
+
const record = detailRecord(detail);
|
|
1398
|
+
add("\u5173\u8054\u9879\u76EE", detail.matterName ?? record.matterName);
|
|
1399
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? record.matterNo);
|
|
1400
|
+
add("\u9879\u76EE\u6240\u5C5E", detail.depOrOwnerName ?? record.depOrOwnerName);
|
|
1401
|
+
add("\u76D6\u7AE0\u6587\u4E66", record.sealApproDOs ?? record.files);
|
|
1402
|
+
}
|
|
1403
|
+
function addCloseMatterBusinessFields(detail, add) {
|
|
1404
|
+
const record = detailRecord(detail);
|
|
1405
|
+
const additional = objectField(record, "matterAdditional");
|
|
1406
|
+
add("\u9879\u76EE\u540D\u79F0", detail.matterName ?? record.matterName);
|
|
1407
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? record.matterNo);
|
|
1408
|
+
add("\u5408\u540C\u603B\u989D", additional.contractValue);
|
|
1409
|
+
add("\u53D1\u7968\u603B\u989D", additional.invoiceValue);
|
|
1410
|
+
add("\u6536\u6B3E\u603B\u989D", additional.incomeValue);
|
|
1411
|
+
add("\u8D26\u5355\u603B\u989D", additional.billValue);
|
|
1412
|
+
add("\u8D39\u7528\u603B\u989D", additional.expenseValue);
|
|
1413
|
+
add("\u5E94\u6536\u603B\u989D", additional.shouldValue);
|
|
1414
|
+
add("\u7ED3\u9879\u8BF4\u660E", record.resultDesc);
|
|
1415
|
+
}
|
|
1416
|
+
function addTaskBusinessFields(detail, add) {
|
|
1417
|
+
const record = detailRecord(detail);
|
|
1418
|
+
add("\u5173\u8054\u9879\u76EE", detail.matterName ?? record.matterName);
|
|
1419
|
+
add("\u4EFB\u52A1\u5217\u8868", record.taskSimpleDTOList);
|
|
1420
|
+
}
|
|
1421
|
+
function addFilingBusinessFields(detail, add) {
|
|
1422
|
+
const record = detailRecord(detail);
|
|
1423
|
+
add("\u9879\u76EE\u540D\u79F0", detail.matterName ?? record.matterName);
|
|
1424
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? record.matterNo);
|
|
1425
|
+
add("\u5F52\u6863\u7F16\u53F7", record.filingNo);
|
|
1426
|
+
add("\u9879\u76EE\u53D8\u52A8\u4FE1\u606F", objectField(record, "differencesDTO").differences);
|
|
1427
|
+
}
|
|
1428
|
+
function addBorrowBusinessFields(detail, add) {
|
|
1429
|
+
const record = detailRecord(detail);
|
|
1430
|
+
add("\u9879\u76EE\u540D\u79F0", detail.matterName ?? record.matterName);
|
|
1431
|
+
add("\u9879\u76EE\u7F16\u53F7", detail.matterNo ?? record.matterNo);
|
|
1432
|
+
add("\u501F\u9605\u4FE1\u606F", record.borrowInfo ?? record.borrowRecord ?? record.archiveBorrow);
|
|
1433
|
+
}
|
|
1434
|
+
function addGenericBusinessFields(detail, add) {
|
|
1435
|
+
const record = detailRecord(detail);
|
|
1436
|
+
const appro = detail.approDO ?? {};
|
|
1437
|
+
add("\u91CD\u8981\u4FE1\u606F", appro.outlook);
|
|
1438
|
+
add("\u5907\u6CE8", record.remark ?? appro.remark);
|
|
1439
|
+
add("\u539F\u56E0", record.reason ?? appro.reason);
|
|
1440
|
+
add("\u7ED3\u679C\u8BF4\u660E", record.resultDesc ?? record.result);
|
|
1441
|
+
}
|
|
1442
|
+
function addBusinessField(fields, label, value) {
|
|
1443
|
+
const normalized = normalizeBusinessValue(value, label);
|
|
1444
|
+
if (isEmptyBusinessValue(normalized)) {
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
fields.push({
|
|
1448
|
+
"\u5B57\u6BB5\u540D\u79F0": label,
|
|
1449
|
+
"\u503C": normalized
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
function dedupeBusinessFields(fields) {
|
|
1453
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1454
|
+
return fields.filter((field) => {
|
|
1455
|
+
if (seen.has(field["\u5B57\u6BB5\u540D\u79F0"])) {
|
|
1456
|
+
return false;
|
|
1457
|
+
}
|
|
1458
|
+
seen.add(field["\u5B57\u6BB5\u540D\u79F0"]);
|
|
1459
|
+
return true;
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
function detailRecord(detail) {
|
|
1463
|
+
return detail;
|
|
1464
|
+
}
|
|
1465
|
+
function objectField(source, key) {
|
|
1466
|
+
const value = source[key];
|
|
1467
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1468
|
+
return value;
|
|
1469
|
+
}
|
|
1470
|
+
return {};
|
|
1471
|
+
}
|
|
1472
|
+
function valueFrom(preferred, fallback, key) {
|
|
1473
|
+
return preferred[key] ?? fallback[key];
|
|
1474
|
+
}
|
|
1475
|
+
function numericCode(value) {
|
|
1476
|
+
if (typeof value === "number") {
|
|
1477
|
+
return value;
|
|
1478
|
+
}
|
|
1479
|
+
if (typeof value === "string") {
|
|
1480
|
+
const parsed = Number.parseInt(value, 10);
|
|
1481
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
1482
|
+
}
|
|
1483
|
+
return void 0;
|
|
1484
|
+
}
|
|
1485
|
+
function normalizeBusinessValue(value, label) {
|
|
1486
|
+
if ((typeof value === "number" || typeof value === "string") && label && (label.includes("\u65E5\u671F") || label.includes("\u65F6\u95F4"))) {
|
|
1487
|
+
return formatDateTime(value);
|
|
1488
|
+
}
|
|
1489
|
+
if (Array.isArray(value)) {
|
|
1490
|
+
return value.map((item) => normalizeBusinessValue(item)).filter((item) => !isEmptyBusinessValue(item));
|
|
1491
|
+
}
|
|
1492
|
+
if (typeof value === "string") {
|
|
1493
|
+
const trimmed = stripHtml(value);
|
|
1494
|
+
if (!trimmed) {
|
|
1495
|
+
return "";
|
|
1496
|
+
}
|
|
1497
|
+
const parsed = parseMaybeJson(trimmed);
|
|
1498
|
+
if (parsed !== void 0) {
|
|
1499
|
+
return normalizeBusinessValue(parsed);
|
|
1500
|
+
}
|
|
1501
|
+
return trimmed;
|
|
1502
|
+
}
|
|
1503
|
+
if (value && typeof value === "object") {
|
|
1504
|
+
const record = value;
|
|
1505
|
+
const compact = {};
|
|
1506
|
+
for (const [key, item] of Object.entries(record)) {
|
|
1507
|
+
const normalized = normalizeBusinessValue(item);
|
|
1508
|
+
if (!isEmptyBusinessValue(normalized)) {
|
|
1509
|
+
compact[key] = normalized;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return compact;
|
|
1513
|
+
}
|
|
1514
|
+
return value ?? "";
|
|
1515
|
+
}
|
|
1516
|
+
function parseMaybeJson(value) {
|
|
1517
|
+
if (!/^[\[{]/.test(value)) {
|
|
1518
|
+
return void 0;
|
|
1519
|
+
}
|
|
1520
|
+
try {
|
|
1521
|
+
return JSON.parse(value);
|
|
1522
|
+
} catch {
|
|
1523
|
+
return void 0;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
function isEmptyBusinessValue(value) {
|
|
1527
|
+
if (value === void 0 || value === null || value === "") {
|
|
1528
|
+
return true;
|
|
1529
|
+
}
|
|
1530
|
+
if (Array.isArray(value)) {
|
|
1531
|
+
return value.length === 0;
|
|
1532
|
+
}
|
|
1533
|
+
if (typeof value === "object") {
|
|
1534
|
+
return Object.keys(value).length === 0;
|
|
1535
|
+
}
|
|
1536
|
+
return false;
|
|
1537
|
+
}
|
|
1538
|
+
function toApproFlowSummary(flow) {
|
|
1539
|
+
return {
|
|
1540
|
+
"\u8282\u70B9ID": flow.id ?? "",
|
|
1541
|
+
"\u8282\u70B9\u540D\u79F0": flow.name ?? "",
|
|
1542
|
+
"\u8282\u70B9\u7C7B\u578B": flow.nodeType ?? "",
|
|
1543
|
+
"\u8282\u70B9\u72B6\u6001": formatFlowStatus(flow.status),
|
|
1544
|
+
"\u662F\u5426\u5F53\u524D\u8282\u70B9": flow.isCurrentNode ?? flow.currentNode ?? false,
|
|
1545
|
+
"\u5BA1\u6279\u65B9\u5F0F": flow.approvalOperateType ?? "",
|
|
1546
|
+
"\u64CD\u4F5C\u65F6\u95F4": formatDateTime(flow.modifyDate ?? flow.arriveDate ?? flow.createDate),
|
|
1547
|
+
"\u5BA1\u6279\u4EBA": (flow.flowUsers ?? []).map(toApproFlowUserSummary)
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
function toApproFlowUserSummary(user) {
|
|
1551
|
+
return {
|
|
1552
|
+
"\u7528\u6237ID": user.userId ?? "",
|
|
1553
|
+
"\u59D3\u540D": user.name ?? "",
|
|
1554
|
+
"\u5904\u7406\u72B6\u6001": formatFlowUserStatus(user.status),
|
|
1555
|
+
"\u4EBA\u5458\u72B6\u6001": formatUserStatus(user.userStatus),
|
|
1556
|
+
"\u5904\u7406\u65F6\u95F4": formatDateTime(user.modifyDate ?? user.createDate)
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
function toApproFileSummary(file) {
|
|
1560
|
+
return {
|
|
1561
|
+
"\u6587\u4EF6\u540D": file.fileName ?? "",
|
|
1562
|
+
"\u5927\u5C0F": formatFileSize(file.fileSize)
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
function toApproAttachmentSummary(ref, detail) {
|
|
1566
|
+
const legacyFile = ref.legacyFile;
|
|
1567
|
+
return {
|
|
1568
|
+
"\u6587\u4EF6\u540D": detail?.fileName ?? legacyFile?.fileName ?? "",
|
|
1569
|
+
"\u5927\u5C0F": formatFileSize(detail?.fileSize ?? legacyFile?.fileSize)
|
|
1570
|
+
};
|
|
1571
|
+
}
|
|
1572
|
+
function toApproCommentSummary(feed) {
|
|
1573
|
+
return {
|
|
1574
|
+
"\u8BC4\u8BBAID": feed.id ?? "",
|
|
1575
|
+
"\u7C7B\u578B": formatFeedType(feed.feedType),
|
|
1576
|
+
"\u8BC4\u8BBA\u4EBA": feed.createUserName ?? "",
|
|
1577
|
+
"\u8BC4\u8BBA\u4EBAID": feed.createUserId ?? "",
|
|
1578
|
+
"\u5185\u5BB9": stripHtml(feed.content ?? ""),
|
|
1579
|
+
"\u8BC4\u8BBA\u65F6\u95F4": formatDateTime(feed.gmtCreate)
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
function toApproDynamicSummary(feed) {
|
|
1583
|
+
return {
|
|
1584
|
+
"\u52A8\u6001ID": feed.id ?? "",
|
|
1585
|
+
"\u7C7B\u578B": formatFeedType(feed.feedType),
|
|
1586
|
+
"\u64CD\u4F5C": feed.action ?? "",
|
|
1587
|
+
"\u64CD\u4F5C\u4EBA": feed.createUserName ?? "",
|
|
1588
|
+
"\u64CD\u4F5C\u4EBAID": feed.createUserId ?? "",
|
|
1589
|
+
"\u5185\u5BB9": stripHtml(feed.content ?? ""),
|
|
1590
|
+
"\u52A8\u6001\u65F6\u95F4": formatDateTime(feed.gmtCreate)
|
|
1591
|
+
};
|
|
1592
|
+
}
|
|
1593
|
+
function formatFeedType(value) {
|
|
1594
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1595
|
+
switch (code) {
|
|
1596
|
+
case 1:
|
|
1597
|
+
return "\u7528\u6237\u8BC4\u8BBA";
|
|
1598
|
+
case 2:
|
|
1599
|
+
return "\u5BA1\u6279\u52A8\u6001";
|
|
1600
|
+
default:
|
|
1601
|
+
return code === void 0 || Number.isNaN(code) ? "" : `\u672A\u77E5\u7C7B\u578B(${code})`;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
function parseApproScope(value) {
|
|
1605
|
+
const scope = (value ?? "my").trim().toLowerCase();
|
|
1606
|
+
if (scope === "my" || scope === "mine" || scope === "approval" || scope === "\u6211\u5BA1\u6279\u7684") {
|
|
1607
|
+
return "my";
|
|
1608
|
+
}
|
|
1609
|
+
if (scope === "started" || scope === "start" || scope === "\u6211\u53D1\u8D77\u7684") {
|
|
1610
|
+
return "started";
|
|
1611
|
+
}
|
|
1612
|
+
if (scope === "cc" || scope === "copyto" || scope === "copy" || scope === "\u6284\u9001\u6211\u7684") {
|
|
1613
|
+
return "cc";
|
|
1614
|
+
}
|
|
1615
|
+
if (scope === "all" || scope === "allapproval" || scope === "\u5168\u90E8" || scope === "\u5168\u90E8\u5BA1\u6279") {
|
|
1616
|
+
return "all";
|
|
1617
|
+
}
|
|
1618
|
+
throw new Error(
|
|
1619
|
+
"Invalid appro scope. Supported: my, started, cc, all, \u6211\u5BA1\u6279\u7684, \u6211\u53D1\u8D77\u7684, \u6284\u9001\u6211\u7684, \u5168\u90E8\u5BA1\u6279."
|
|
1620
|
+
);
|
|
1621
|
+
}
|
|
1622
|
+
function formatApproScope(scope) {
|
|
1623
|
+
switch (scope) {
|
|
1624
|
+
case "my":
|
|
1625
|
+
return "\u6211\u5BA1\u6279\u7684";
|
|
1626
|
+
case "started":
|
|
1627
|
+
return "\u6211\u53D1\u8D77\u7684";
|
|
1628
|
+
case "cc":
|
|
1629
|
+
return "\u6284\u9001\u6211\u7684";
|
|
1630
|
+
case "all":
|
|
1631
|
+
return "\u5168\u90E8\u5BA1\u6279";
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
function parseApproStatus(value) {
|
|
1635
|
+
const raw = value?.trim();
|
|
1636
|
+
if (!raw || raw === "" || raw.toLowerCase() === "all" || raw === "\u6240\u6709\u72B6\u6001" || raw === "\u5168\u90E8\u72B6\u6001") {
|
|
1637
|
+
return { label: "\u6240\u6709\u72B6\u6001" };
|
|
1638
|
+
}
|
|
1639
|
+
const normalized = raw.toLowerCase();
|
|
1640
|
+
const aliases = {
|
|
1641
|
+
pending: { status: 1, label: "\u5F85\u6211\u5BA1\u6279" },
|
|
1642
|
+
todo: { status: 1, label: "\u5F85\u6211\u5BA1\u6279" },
|
|
1643
|
+
"\u5F85\u6211\u5BA1\u6279": { status: 1, label: "\u5F85\u6211\u5BA1\u6279" },
|
|
1644
|
+
"\u6211\u5DF2\u901A\u8FC7": { status: 2, label: "\u6211\u5DF2\u901A\u8FC7" },
|
|
1645
|
+
"\u6211\u5DF2\u9A73\u56DE": { status: 3, label: "\u6211\u5DF2\u9A73\u56DE" },
|
|
1646
|
+
"\u4ED6\u4EBA\u5DF2\u5904\u7406": { status: 4, label: "\u4ED6\u4EBA\u5DF2\u5904\u7406" },
|
|
1647
|
+
"\u6211\u8F6C\u7B7E\u7684": { status: 5, label: "\u6211\u8F6C\u7B7E\u7684" },
|
|
1648
|
+
"\u5BA1\u6279\u4E2D": { status: 0, label: "\u5BA1\u6279\u4E2D" },
|
|
1649
|
+
"\u5DF2\u901A\u8FC7": { status: 1, label: "\u5DF2\u901A\u8FC7" },
|
|
1650
|
+
"\u5DF2\u9A73\u56DE": { status: 2, label: "\u5DF2\u9A73\u56DE" },
|
|
1651
|
+
"\u91CD\u65B0\u53D1\u8D77": { status: 3, label: "\u91CD\u65B0\u53D1\u8D77" },
|
|
1652
|
+
"\u9A73\u56DE\u540E\u91CD\u65B0\u53D1\u8D77": { status: 3, preStatus: 2, label: "\u9A73\u56DE\u540E\u91CD\u65B0\u53D1\u8D77" },
|
|
1653
|
+
"\u5DF2\u64A4\u56DE": { status: 4, label: "\u5DF2\u64A4\u56DE" },
|
|
1654
|
+
"\u64A4\u56DE\u540E\u91CD\u65B0\u53D1\u8D77": { status: 3, preStatus: 4, label: "\u64A4\u56DE\u540E\u91CD\u65B0\u53D1\u8D77" },
|
|
1655
|
+
"\u5DF2\u5220\u9664": { status: -1, label: "\u5DF2\u5220\u9664" },
|
|
1656
|
+
passed: { status: 1, label: "\u5DF2\u901A\u8FC7" },
|
|
1657
|
+
rejected: { status: 2, label: "\u5DF2\u9A73\u56DE" },
|
|
1658
|
+
processing: { status: 0, label: "\u5BA1\u6279\u4E2D" },
|
|
1659
|
+
withdrawn: { status: 4, label: "\u5DF2\u64A4\u56DE" },
|
|
1660
|
+
deleted: { status: -1, label: "\u5DF2\u5220\u9664" }
|
|
1661
|
+
};
|
|
1662
|
+
if (normalized in aliases) {
|
|
1663
|
+
return aliases[normalized];
|
|
1664
|
+
}
|
|
1665
|
+
if (normalized.includes(",")) {
|
|
1666
|
+
const [statusPart, preStatusPart] = normalized.split(",");
|
|
1667
|
+
const status = Number.parseInt(statusPart.trim(), 10);
|
|
1668
|
+
const preStatus = Number.parseInt((preStatusPart ?? "").trim(), 10);
|
|
1669
|
+
if (Number.isNaN(status) || Number.isNaN(preStatus)) {
|
|
1670
|
+
throw new Error("Invalid appro status pair. Use status,preStatus such as 3,2.");
|
|
1671
|
+
}
|
|
1672
|
+
return { status, preStatus, label: formatApproStatus(status, preStatus, "all") };
|
|
1673
|
+
}
|
|
1674
|
+
const parsed = Number.parseInt(normalized, 10);
|
|
1675
|
+
if (Number.isNaN(parsed)) {
|
|
1676
|
+
throw new Error("Invalid appro status. Use a numeric status or all.");
|
|
1677
|
+
}
|
|
1678
|
+
return { status: parsed, label: `\u72B6\u6001(${parsed})` };
|
|
1679
|
+
}
|
|
1680
|
+
function parseNumberList(value) {
|
|
1681
|
+
if (!value || value.trim() === "" || value.trim().toLowerCase() === "all") {
|
|
1682
|
+
return [];
|
|
1683
|
+
}
|
|
1684
|
+
return value.split(",").map((part) => {
|
|
1685
|
+
const parsed = Number.parseInt(part.trim(), 10);
|
|
1686
|
+
if (Number.isNaN(parsed)) {
|
|
1687
|
+
throw new Error(`Invalid appro type: ${part}`);
|
|
1688
|
+
}
|
|
1689
|
+
return parsed;
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
function formatApproStatus(status, preStatus, scope) {
|
|
1693
|
+
const code = typeof status === "string" ? Number.parseInt(status, 10) : status;
|
|
1694
|
+
const preCode = typeof preStatus === "string" ? Number.parseInt(preStatus, 10) : preStatus;
|
|
1695
|
+
if (code === 3 && preCode === 2) {
|
|
1696
|
+
return "\u9A73\u56DE\u540E\u91CD\u65B0\u53D1\u8D77";
|
|
1697
|
+
}
|
|
1698
|
+
if (code === 3 && preCode === 4) {
|
|
1699
|
+
return "\u64A4\u56DE\u540E\u91CD\u65B0\u53D1\u8D77";
|
|
1700
|
+
}
|
|
1701
|
+
if (scope === "my") {
|
|
1702
|
+
switch (code) {
|
|
1703
|
+
case 1:
|
|
1704
|
+
return "\u5F85\u6211\u5BA1\u6279";
|
|
1705
|
+
case 2:
|
|
1706
|
+
return "\u6211\u5DF2\u901A\u8FC7";
|
|
1707
|
+
case 3:
|
|
1708
|
+
return "\u6211\u5DF2\u9A73\u56DE";
|
|
1709
|
+
case 4:
|
|
1710
|
+
return "\u4ED6\u4EBA\u5DF2\u5904\u7406";
|
|
1711
|
+
case 5:
|
|
1712
|
+
return "\u6211\u8F6C\u7B7E\u7684";
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
switch (code) {
|
|
1716
|
+
case 0:
|
|
1717
|
+
return "\u5BA1\u6279\u4E2D";
|
|
1718
|
+
case 1:
|
|
1719
|
+
return "\u5DF2\u901A\u8FC7";
|
|
1720
|
+
case 2:
|
|
1721
|
+
return "\u5DF2\u9A73\u56DE";
|
|
1722
|
+
case 3:
|
|
1723
|
+
return "\u91CD\u65B0\u53D1\u8D77";
|
|
1724
|
+
case 4:
|
|
1725
|
+
return "\u5DF2\u64A4\u56DE";
|
|
1726
|
+
case 5:
|
|
1727
|
+
return "\u5DF2\u9A73\u56DE";
|
|
1728
|
+
case 6:
|
|
1729
|
+
return "\u91CD\u65B0\u53D1\u8D77";
|
|
1730
|
+
case -1:
|
|
1731
|
+
return "\u5DF2\u5220\u9664";
|
|
1732
|
+
default:
|
|
1733
|
+
return code === void 0 || Number.isNaN(code) ? "" : `\u672A\u77E5\u72B6\u6001(${code})`;
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
function formatApproType(value) {
|
|
1737
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1738
|
+
switch (code) {
|
|
1739
|
+
case 0:
|
|
1740
|
+
return "\u76D6\u7AE0\u5BA1\u6279";
|
|
1741
|
+
case 1:
|
|
1742
|
+
return "\u53D1\u7968\u5BA1\u6279";
|
|
1743
|
+
case 2:
|
|
1744
|
+
return "\u62A5\u9500\u5BA1\u6279";
|
|
1745
|
+
case 3:
|
|
1746
|
+
return "\u7ED3\u9879\u5BA1\u6279";
|
|
1747
|
+
case 4:
|
|
1748
|
+
return "\u5408\u540C\u5BA1\u6279";
|
|
1749
|
+
case 5:
|
|
1750
|
+
return "\u7ACB\u9879\u5BA1\u6279";
|
|
1751
|
+
case 6:
|
|
1752
|
+
return "\u91CD\u542F\u9879\u76EE\u5BA1\u6279";
|
|
1753
|
+
case 7:
|
|
1754
|
+
return "\u7F16\u8F91\u9879\u76EE\u5BA1\u6279";
|
|
1755
|
+
case 8:
|
|
1756
|
+
return "\u9884\u7ACB\u9879\u5BA1\u6279";
|
|
1757
|
+
case 9:
|
|
1758
|
+
return "\u7F16\u8F91\u9884\u7ACB\u9879\u5BA1\u6279";
|
|
1759
|
+
case 10:
|
|
1760
|
+
return "\u9884\u7ACB\u9879\u8F6C\u8FDB\u884C\u4E2D\u5BA1\u6279";
|
|
1761
|
+
case 13:
|
|
1762
|
+
return "\u5B8C\u6210\u4EFB\u52A1\u5BA1\u6279";
|
|
1763
|
+
case 14:
|
|
1764
|
+
return "\u5F52\u6863\u5BA1\u6279";
|
|
1765
|
+
default:
|
|
1766
|
+
return code === void 0 || Number.isNaN(code) ? "" : `\u5BA1\u6279\u7C7B\u578B(${code})`;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
function formatMatterLevel(value) {
|
|
1770
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1771
|
+
switch (code) {
|
|
1772
|
+
case 1:
|
|
1773
|
+
return "\u65E0";
|
|
1774
|
+
case 2:
|
|
1775
|
+
return "\u4F4E";
|
|
1776
|
+
case 3:
|
|
1777
|
+
return "\u4E2D";
|
|
1778
|
+
case 4:
|
|
1779
|
+
return "\u9AD8";
|
|
1780
|
+
default:
|
|
1781
|
+
return value === void 0 || value === null || value === "" ? "" : String(value);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
function formatSignType(value) {
|
|
1785
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1786
|
+
switch (code) {
|
|
1787
|
+
case 0:
|
|
1788
|
+
return "\u7EBF\u4E0B\u7B7E\u7F72";
|
|
1789
|
+
case 1:
|
|
1790
|
+
return "\u7EBF\u4E0A\u7B7E\u7F72";
|
|
1791
|
+
default:
|
|
1792
|
+
return value === void 0 || value === null || value === "" ? "" : String(value);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
function formatInvoiceType(value) {
|
|
1796
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1797
|
+
switch (code) {
|
|
1798
|
+
case 1:
|
|
1799
|
+
return "\u589E\u503C\u7A0E\u4E13\u7528\u53D1\u7968";
|
|
1800
|
+
case 2:
|
|
1801
|
+
return "\u589E\u503C\u7A0E\u666E\u901A\u53D1\u7968";
|
|
1802
|
+
case 3:
|
|
1803
|
+
return "\u7535\u5B50\u4E13\u7528\u53D1\u7968";
|
|
1804
|
+
case 4:
|
|
1805
|
+
return "\u7535\u5B50\u666E\u901A\u53D1\u7968";
|
|
1806
|
+
default:
|
|
1807
|
+
return value === void 0 || value === null || value === "" ? "" : String(value);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
function formatFlowStatus(value) {
|
|
1811
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1812
|
+
switch (code) {
|
|
1813
|
+
case 0:
|
|
1814
|
+
return "\u672A\u5904\u7406";
|
|
1815
|
+
case 1:
|
|
1816
|
+
return "\u5F85\u5904\u7406";
|
|
1817
|
+
case 2:
|
|
1818
|
+
return "\u5DF2\u901A\u8FC7";
|
|
1819
|
+
case 3:
|
|
1820
|
+
return "\u5DF2\u9A73\u56DE";
|
|
1821
|
+
case 4:
|
|
1822
|
+
return "\u5DF2\u64A4\u56DE";
|
|
1823
|
+
default:
|
|
1824
|
+
return code === void 0 || Number.isNaN(code) ? "" : `\u672A\u77E5\u72B6\u6001(${code})`;
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
function formatFlowUserStatus(value) {
|
|
1828
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1829
|
+
switch (code) {
|
|
1830
|
+
case 0:
|
|
1831
|
+
return "\u672A\u5904\u7406";
|
|
1832
|
+
case 1:
|
|
1833
|
+
return "\u5F85\u5904\u7406";
|
|
1834
|
+
case 2:
|
|
1835
|
+
return "\u5DF2\u901A\u8FC7";
|
|
1836
|
+
case 3:
|
|
1837
|
+
return "\u5DF2\u9A73\u56DE";
|
|
1838
|
+
case 4:
|
|
1839
|
+
return "\u5DF2\u8F6C\u7B7E";
|
|
1840
|
+
default:
|
|
1841
|
+
return code === void 0 || Number.isNaN(code) ? "" : `\u672A\u77E5\u72B6\u6001(${code})`;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
function formatUserStatus(value) {
|
|
1845
|
+
const code = typeof value === "string" ? Number.parseInt(value, 10) : value;
|
|
1846
|
+
switch (code) {
|
|
1847
|
+
case 0:
|
|
1848
|
+
return "\u79BB\u804C";
|
|
1849
|
+
case 1:
|
|
1850
|
+
return "\u5728\u804C";
|
|
1851
|
+
default:
|
|
1852
|
+
return code === void 0 || Number.isNaN(code) ? "" : `\u672A\u77E5\u72B6\u6001(${code})`;
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
function formatRawStatus(value) {
|
|
1856
|
+
if (value === void 0 || value === null || value === "") {
|
|
1857
|
+
return "";
|
|
1858
|
+
}
|
|
1859
|
+
return String(value);
|
|
1860
|
+
}
|
|
1861
|
+
function normalizeFieldValue(value) {
|
|
1862
|
+
if (typeof value === "string") {
|
|
1863
|
+
return stripHtml(value);
|
|
1864
|
+
}
|
|
1865
|
+
return value ?? "";
|
|
1866
|
+
}
|
|
1867
|
+
function normalizeStringList(value) {
|
|
1868
|
+
if (Array.isArray(value)) {
|
|
1869
|
+
return value.map((item) => String(item)).filter(Boolean);
|
|
1870
|
+
}
|
|
1871
|
+
if (typeof value === "string") {
|
|
1872
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
1873
|
+
}
|
|
1874
|
+
return [];
|
|
1875
|
+
}
|
|
1876
|
+
function formatAttachmentFieldValue(value) {
|
|
1877
|
+
const count = normalizeStringList(value).length;
|
|
1878
|
+
return count ? `${count}\u4E2A\u9644\u4EF6\uFF0C\u8BE6\u89C1\u9876\u5C42\u9644\u4EF6` : "";
|
|
1879
|
+
}
|
|
1880
|
+
function formatDateTime(value) {
|
|
1881
|
+
if (value === void 0 || value === null || value === "") {
|
|
1882
|
+
return "";
|
|
1883
|
+
}
|
|
1884
|
+
const date = parseDateTime(value);
|
|
1885
|
+
if (!date) {
|
|
1886
|
+
return String(value);
|
|
1887
|
+
}
|
|
1888
|
+
const year = date.getFullYear();
|
|
1889
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
1890
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
1891
|
+
const hour = String(date.getHours()).padStart(2, "0");
|
|
1892
|
+
const minute = String(date.getMinutes()).padStart(2, "0");
|
|
1893
|
+
const second = String(date.getSeconds()).padStart(2, "0");
|
|
1894
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
|
1895
|
+
}
|
|
1896
|
+
function parseDateTime(value) {
|
|
1897
|
+
if (typeof value === "number") {
|
|
1898
|
+
return dateFromTimestamp(value);
|
|
1899
|
+
}
|
|
1900
|
+
const trimmed = value.trim();
|
|
1901
|
+
if (!trimmed) {
|
|
1902
|
+
return null;
|
|
1903
|
+
}
|
|
1904
|
+
if (/^\d+$/.test(trimmed)) {
|
|
1905
|
+
return dateFromTimestamp(Number.parseInt(trimmed, 10));
|
|
1906
|
+
}
|
|
1907
|
+
const parsed = new Date(trimmed);
|
|
1908
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
1909
|
+
}
|
|
1910
|
+
function dateFromTimestamp(timestamp) {
|
|
1911
|
+
if (!Number.isFinite(timestamp)) {
|
|
1912
|
+
return null;
|
|
1913
|
+
}
|
|
1914
|
+
const milliseconds = Math.abs(timestamp) < 1e10 ? timestamp * 1e3 : timestamp;
|
|
1915
|
+
const date = new Date(milliseconds);
|
|
1916
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
1917
|
+
}
|
|
1918
|
+
function formatFileSize(size) {
|
|
1919
|
+
if (!size || size <= 0) {
|
|
1920
|
+
return "0B";
|
|
1921
|
+
}
|
|
1922
|
+
if (size < 1024) {
|
|
1923
|
+
return `${size}B`;
|
|
1924
|
+
}
|
|
1925
|
+
if (size < 1024 * 1024) {
|
|
1926
|
+
return `${Number((size / 1024).toFixed(2))}KB`;
|
|
1927
|
+
}
|
|
1928
|
+
return `${Number((size / 1024 / 1024).toFixed(2))}MB`;
|
|
1929
|
+
}
|
|
1930
|
+
function stringField(source, key) {
|
|
1931
|
+
const value = source[key];
|
|
1932
|
+
return typeof value === "string" ? value : "";
|
|
1933
|
+
}
|
|
1934
|
+
function stripHtml(value) {
|
|
1935
|
+
return value.replace(/<[^>]*>/g, "").replace(/\s+/g, " ").trim();
|
|
1936
|
+
}
|
|
1937
|
+
function clampPage(page) {
|
|
1938
|
+
if (!Number.isFinite(page) || page < 1) {
|
|
1939
|
+
return 1;
|
|
1940
|
+
}
|
|
1941
|
+
return Math.floor(page);
|
|
1942
|
+
}
|
|
1943
|
+
function clampLimit(limit) {
|
|
1944
|
+
if (!Number.isFinite(limit) || limit < 1) {
|
|
1945
|
+
return 10;
|
|
1946
|
+
}
|
|
1947
|
+
return Math.min(Math.floor(limit), 50);
|
|
1948
|
+
}
|
|
1949
|
+
function clampCommentLimit(limit) {
|
|
1950
|
+
if (!Number.isFinite(limit) || limit < 0) {
|
|
1951
|
+
return 10;
|
|
1952
|
+
}
|
|
1953
|
+
return Math.min(Math.floor(limit), 50);
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
// src/commands/capabilities.ts
|
|
1957
|
+
function runCapabilities(version) {
|
|
1958
|
+
const environment = getDefaultEnvironmentPreset();
|
|
1959
|
+
printSuccess({
|
|
1960
|
+
"\u5DE5\u5177": {
|
|
1961
|
+
"\u540D\u79F0": "alpha-classic-cli",
|
|
1962
|
+
"\u7248\u672C": version,
|
|
1963
|
+
"\u6240\u5C5E\u7CFB\u7EDF": "Alpha \u5F8B\u6240\u7BA1\u7406\u7CFB\u7EDF",
|
|
1964
|
+
"\u8BF4\u660E": "Alpha Classic CLI\uFF0C\u7528\u4E8E\u67E5\u8BE2 Alpha \u5F8B\u6240\u7BA1\u7406\u7CFB\u7EDF\u4E1A\u52A1\u6570\u636E\u7684 AI-friendly CLI"
|
|
1965
|
+
},
|
|
1966
|
+
"\u73AF\u5883": {
|
|
1967
|
+
"\u5F53\u524D\u73AF\u5883": environment.name,
|
|
1968
|
+
"baseUrl": environment.baseUrl,
|
|
1969
|
+
"apiBaseUrl": environment.apiBaseUrl,
|
|
1970
|
+
"\u662F\u5426\u6784\u5EFA\u65F6\u9501\u5B9A": true,
|
|
1971
|
+
"\u5207\u6362\u65B9\u5F0F": "\u91CD\u65B0\u6784\u5EFA\u5BF9\u5E94\u73AF\u5883\u7248\u672C\uFF0C\u4F8B\u5982 npm run build:dev"
|
|
1972
|
+
},
|
|
1973
|
+
"\u8BA4\u8BC1": {
|
|
1974
|
+
"\u68C0\u67E5\u767B\u5F55": "alpha-classic-cli doctor",
|
|
1975
|
+
"\u9ED8\u8BA4\u767B\u5F55": "alpha-classic-cli login",
|
|
1976
|
+
"Agent \u4E24\u9636\u6BB5\u767B\u5F55": [
|
|
1977
|
+
"alpha-classic-cli login --no-wait --json",
|
|
1978
|
+
"alpha-classic-cli login --device-code <device_code>"
|
|
1979
|
+
],
|
|
1980
|
+
"\u8C03\u8BD5 fallback": "alpha-classic-cli login --token <token>",
|
|
1981
|
+
"\u767B\u51FA": "alpha-classic-cli logout",
|
|
1982
|
+
"\u8BF7\u6C42\u5934": ["token: <token>", "deviceType: ai"],
|
|
1983
|
+
"\u6CE8\u610F": "\u4E0D\u8981\u8F93\u51FA token/refreshToken\uFF0C\u4E0D\u8981\u628A token \u5199\u5165\u56DE\u7B54\u6216 URL\u3002"
|
|
1984
|
+
},
|
|
1985
|
+
"\u7248\u672C": {
|
|
1986
|
+
"\u673A\u5668\u53EF\u8BFB": "alpha-classic-cli version",
|
|
1987
|
+
"\u7EAF\u6587\u672C": "alpha-classic-cli --version"
|
|
1988
|
+
},
|
|
1989
|
+
"\u667A\u80FD\u4F53\u5B89\u88C5": {
|
|
1990
|
+
"Codex": "alpha-classic-cli install --agent codex",
|
|
1991
|
+
"Claude Code": "alpha-classic-cli install --agent claude",
|
|
1992
|
+
"Alpha-claw": "alpha-classic-cli install --agent alphaclaw",
|
|
1993
|
+
"\u5168\u90E8\u652F\u6301\u7684\u667A\u80FD\u4F53": "alpha-classic-cli install --agent all",
|
|
1994
|
+
"\u5378\u8F7D Codex": "alpha-classic-cli uninstall --agent codex",
|
|
1995
|
+
"\u5378\u8F7D Claude Code": "alpha-classic-cli uninstall --agent claude",
|
|
1996
|
+
"\u5378\u8F7D Alpha-claw": "alpha-classic-cli uninstall --agent alphaclaw",
|
|
1997
|
+
"\u5378\u8F7D\u5168\u90E8": "alpha-classic-cli uninstall --agent all",
|
|
1998
|
+
"\u8BF4\u660E": "\u7528\u6237\u81EA\u884C\u9009\u62E9\u5B89\u88C5\u76EE\u6807\uFF1BAlpha-claw \u4F1A\u6309 CLI \u6784\u5EFA\u73AF\u5883\u5B89\u88C5\u5230\u5BF9\u5E94 .openclaw-<env>alphaclaw \u5DE5\u4F5C\u533A\u3002"
|
|
1999
|
+
},
|
|
2000
|
+
"\u8F93\u51FA\u534F\u8BAE": {
|
|
2001
|
+
"\u6210\u529F": { "ok": true, "data": "\u4E1A\u52A1\u6570\u636E" },
|
|
2002
|
+
"\u5931\u8D25": {
|
|
2003
|
+
"ok": false,
|
|
2004
|
+
"error": {
|
|
2005
|
+
"type": "runtime",
|
|
2006
|
+
"message": "\u9519\u8BEF\u4FE1\u606F",
|
|
2007
|
+
"hint": "\u53EF\u9009\u63D0\u793A"
|
|
2008
|
+
}
|
|
2009
|
+
},
|
|
2010
|
+
"\u8BF4\u660E": "\u5916\u5C42 ok/data/error \u4E3A\u673A\u5668\u534F\u8BAE\uFF0Cdata \u5185\u4E1A\u52A1\u5B57\u6BB5\u4F18\u5148\u4F7F\u7528\u4E2D\u6587\u3002"
|
|
2011
|
+
},
|
|
2012
|
+
"\u547D\u4EE4": [
|
|
2013
|
+
{
|
|
2014
|
+
"\u6A21\u5757": "matter",
|
|
2015
|
+
"\u4E2D\u6587\u540D": "\u9879\u76EE",
|
|
2016
|
+
"\u80FD\u529B": "\u67E5\u8BE2\u9879\u76EE\u5217\u8868",
|
|
2017
|
+
"\u547D\u4EE4": "alpha-classic-cli matter search",
|
|
2018
|
+
"\u522B\u540D": ["alpha-classic-cli project search"],
|
|
2019
|
+
"\u53C2\u6570": {
|
|
2020
|
+
"--keyword": "\u53EF\u9009\u3002\u9879\u76EE\u540D\u79F0\u3001\u7F16\u53F7\u3001\u5BA2\u6237\u540D\u7B49\u81EA\u7136\u8BED\u8A00\u5173\u952E\u8BCD\u3002",
|
|
2021
|
+
"--status": "\u53EF\u9009\u3002\u9879\u76EE\u72B6\u6001\uFF1A\u9884\u7ACB\u9879\u3001\u8FDB\u884C\u4E2D\u3001\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879\u3001\u5DF2\u5B8C\u7ED3\u3001\u5DF2\u6401\u7F6E\u3001\u5DF2\u5F52\u6863\u3001\u5168\u90E8\uFF1B\u9ED8\u8BA4 \u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879\u3002\u5BF9\u5E94\u8BF7\u6C42\u4F53 matterStatusSet\uFF1A\u9884\u7ACB\u9879=[0]\uFF0C\u8FDB\u884C\u4E2D=[2]\uFF0C\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879=[2,0]\uFF0C\u5DF2\u5B8C\u7ED3=[4]\uFF0C\u5DF2\u6401\u7F6E=[7]\uFF0C\u5DF2\u5F52\u6863=[6]\uFF0C\u5168\u90E8=[0,2,4,6,7]\u3002",
|
|
2022
|
+
"--scope": "\u53EF\u9009\u3002\u9879\u76EE\u8303\u56F4\uFF1A\u6240\u6709\u9879\u76EE\u3001\u6211\u5173\u6CE8\u7684\u3001\u5DF2\u52A0\u5165\u7684\uFF1B\u9ED8\u8BA4 \u6240\u6709\u9879\u76EE\u3002\u6240\u6709\u9879\u76EE\u6309\u524D\u7AEF\u9ED8\u8BA4\u7B5B\u9009\u4F20\u5B8C\u6574\u8BF7\u6C42\u4F53\uFF1B\u6211\u5173\u6CE8\u7684\u6309\u524D\u7AEF\u53EA\u4F20 isView=true\u3001matchedName\u3001queryOrderPage\uFF0C\u4E0D\u4F20 matterStatusSet\uFF1B\u5DF2\u52A0\u5165\u7684\u6309\u5F53\u524D\u7528\u6237\u548C\u5168\u90E8\u9879\u76EE\u89D2\u8272\u751F\u6210 memberOfRoles\u3002",
|
|
2023
|
+
"--limit": "\u53EF\u9009\u3002\u9ED8\u8BA4 10\uFF0C\u6700\u5927 50\u3002",
|
|
2024
|
+
"--page": "\u53EF\u9009\u3002\u4ECE 1 \u5F00\u59CB\uFF0C\u9ED8\u8BA4 1\u3002"
|
|
2025
|
+
},
|
|
2026
|
+
"\u8F93\u51FA\u5B57\u6BB5": {
|
|
2027
|
+
"\u9879\u76EE\u72B6\u6001": "\u672C\u6B21\u67E5\u8BE2\u4F7F\u7528\u7684\u9879\u76EE\u72B6\u6001\u7B5B\u9009",
|
|
2028
|
+
"\u9879\u76EE\u8303\u56F4": "\u672C\u6B21\u67E5\u8BE2\u4F7F\u7528\u7684\u9879\u76EE\u8303\u56F4\u7B5B\u9009",
|
|
2029
|
+
"\u603B\u6570": "\u5339\u914D\u9879\u76EE\u603B\u6570",
|
|
2030
|
+
"\u9875\u7801": "\u5F53\u524D\u9875\u7801",
|
|
2031
|
+
"\u6BCF\u9875\u6570\u91CF": "\u672C\u6B21\u67E5\u8BE2 pageSize",
|
|
2032
|
+
"\u5C55\u793A\u5B57\u6BB5": "\u9879\u76EE\u5217\u8868\u5B9E\u9645\u5C55\u793A\u5B57\u6BB5\uFF1A\u56FA\u5B9A\u5B57\u6BB5\u52A0 /matterserver/api/v1/customFields/dashboard/MATTER_LIST \u8FD4\u56DE\u7684 selectedFields \u987A\u5E8F\u3002",
|
|
2033
|
+
"\u9879\u76EE\u72B6\u6001\u7EDF\u8BA1": "\u6309\u72B6\u6001\u805A\u5408\u7684\u9879\u76EE\u6570\u91CF",
|
|
2034
|
+
"\u9879\u76EE\u5217\u8868": [
|
|
2035
|
+
"\u9879\u76EEID",
|
|
2036
|
+
"\u9879\u76EE\u540D\u79F0",
|
|
2037
|
+
"\u9879\u76EE\u72B6\u6001",
|
|
2038
|
+
"\u9879\u76EE\u5BA2\u6237",
|
|
2039
|
+
"\u9879\u76EE\u7C7B\u578B",
|
|
2040
|
+
"dashboard selectedFields \u5BF9\u5E94\u5B57\u6BB5"
|
|
2041
|
+
]
|
|
2042
|
+
},
|
|
2043
|
+
"\u793A\u4F8B": "alpha-classic-cli matter search --keyword \u5408\u540C --limit 10"
|
|
2044
|
+
},
|
|
2045
|
+
{
|
|
2046
|
+
"\u6A21\u5757": "matter",
|
|
2047
|
+
"\u4E2D\u6587\u540D": "\u9879\u76EE",
|
|
2048
|
+
"\u80FD\u529B": "\u67E5\u8BE2\u9879\u76EE\u8BE6\u60C5/\u6982\u89C8",
|
|
2049
|
+
"\u547D\u4EE4": "alpha-classic-cli matter detail",
|
|
2050
|
+
"\u53C2\u6570": {
|
|
2051
|
+
"--id": "\u5FC5\u586B\u3002\u9879\u76EEID\uFF0C\u901A\u5E38\u5148\u901A\u8FC7 matter search \u83B7\u53D6\u3002",
|
|
2052
|
+
"--logs": "\u53EF\u9009\u3002\u6700\u8FD1\u52A8\u6001\u6570\u91CF\uFF0C\u9ED8\u8BA4 5\uFF0C\u6700\u5927 20\uFF1B\u4F20 0 \u53EF\u8DF3\u8FC7\u52A8\u6001\u3002"
|
|
2053
|
+
},
|
|
2054
|
+
"\u8F93\u51FA\u5B57\u6BB5": {
|
|
2055
|
+
"\u9879\u76EE\u6982\u89C8": [
|
|
2056
|
+
"\u9879\u76EEID",
|
|
2057
|
+
"\u9879\u76EE\u540D\u79F0",
|
|
2058
|
+
"\u9879\u76EE\u7F16\u53F7",
|
|
2059
|
+
"\u9879\u76EE\u72B6\u6001",
|
|
2060
|
+
"\u9879\u76EE\u7C7B\u578B",
|
|
2061
|
+
"\u9879\u76EE\u7B49\u7EA7",
|
|
2062
|
+
"\u5BA2\u6237",
|
|
2063
|
+
"\u5176\u4ED6\u5F53\u4E8B\u4EBA",
|
|
2064
|
+
"\u6240\u5C5E",
|
|
2065
|
+
"\u6848\u6E90\u5F8B\u5E08",
|
|
2066
|
+
"\u627F\u529E\u5F8B\u5E08",
|
|
2067
|
+
"\u4E3B\u529E\u5F8B\u5E08",
|
|
2068
|
+
"\u534F\u529E\u5F8B\u5E08",
|
|
2069
|
+
"\u9879\u76EE\u6210\u5458",
|
|
2070
|
+
"\u6848\u7531",
|
|
2071
|
+
"\u4EE3\u7406\u5BA1\u7EA7",
|
|
2072
|
+
"\u670D\u52A1\u5185\u5BB9",
|
|
2073
|
+
"\u5F00\u59CB\u65E5\u671F",
|
|
2074
|
+
"\u7ED3\u675F\u65E5\u671F",
|
|
2075
|
+
"\u7ACB\u9879\u65F6\u95F4",
|
|
2076
|
+
"\u7ED3\u9879\u65F6\u95F4",
|
|
2077
|
+
"\u5F52\u6863\u65E5\u671F",
|
|
2078
|
+
"\u5F52\u6863\u7F16\u53F7",
|
|
2079
|
+
"\u9879\u76EE\u8BE6\u60C5"
|
|
2080
|
+
],
|
|
2081
|
+
"\u6700\u8FD1\u52A8\u6001": ["\u52A8\u6001ID", "\u7C7B\u578B", "\u65F6\u95F4", "\u5185\u5BB9"]
|
|
2082
|
+
},
|
|
2083
|
+
"\u793A\u4F8B": "alpha-classic-cli matter detail --id <matterId> --logs 5"
|
|
2084
|
+
},
|
|
2085
|
+
{
|
|
2086
|
+
"\u6A21\u5757": "matter",
|
|
2087
|
+
"\u4E2D\u6587\u540D": "\u9879\u76EE",
|
|
2088
|
+
"\u80FD\u529B": "\u67E5\u8BE2\u9879\u76EE\u4E0B\u4EFB\u52A1\u5217\u8868",
|
|
2089
|
+
"\u547D\u4EE4": "alpha-classic-cli matter task",
|
|
2090
|
+
"\u53C2\u6570": {
|
|
2091
|
+
"--id": "\u5FC5\u586B\u3002\u9879\u76EEID\uFF0C\u901A\u5E38\u5148\u901A\u8FC7 matter search \u83B7\u53D6\u3002",
|
|
2092
|
+
"--state": "\u53EF\u9009\u3002\u4EFB\u52A1\u72B6\u6001\uFF1Aall\u3001\u672A\u5B8C\u6210\u3001\u5DF2\u5B8C\u6210\uFF0C\u9ED8\u8BA4\u672A\u5B8C\u6210\u3002",
|
|
2093
|
+
"--page": "\u53EF\u9009\u3002\u4ECE 1 \u5F00\u59CB\uFF0C\u9ED8\u8BA4 1\u3002",
|
|
2094
|
+
"--limit": "\u53EF\u9009\u3002\u9ED8\u8BA4 20\uFF0C\u6700\u5927 50\u3002",
|
|
2095
|
+
"--type": "\u53EF\u9009\u3002task \u6216 group\uFF0C\u9ED8\u8BA4 task\u3002",
|
|
2096
|
+
"--attention": "\u53EF\u9009\u3002all \u6216 \u6211\u5173\u6CE8\u7684\uFF0C\u9ED8\u8BA4 all\u3002"
|
|
2097
|
+
},
|
|
2098
|
+
"\u8F93\u51FA\u5B57\u6BB5": {
|
|
2099
|
+
"\u9879\u76EEID": "\u5F53\u524D\u9879\u76EEID",
|
|
2100
|
+
"\u9879\u76EE\u540D\u79F0": "\u5F53\u524D\u9879\u76EE\u540D\u79F0",
|
|
2101
|
+
"\u9879\u76EE\u7C7B\u578B": "\u5F53\u524D\u9879\u76EE\u7C7B\u578B",
|
|
2102
|
+
"\u72B6\u6001": "\u67E5\u8BE2\u72B6\u6001",
|
|
2103
|
+
"\u5173\u6CE8": "\u67E5\u8BE2\u5173\u6CE8\u8303\u56F4",
|
|
2104
|
+
"\u7C7B\u578B": "\u67E5\u8BE2\u4EFB\u52A1\u7C7B\u578B",
|
|
2105
|
+
"\u603B\u6570": "\u5339\u914D\u4EFB\u52A1\u603B\u6570",
|
|
2106
|
+
"\u9875\u7801": "\u5F53\u524D\u9875\u7801",
|
|
2107
|
+
"\u6BCF\u9875\u6570\u91CF": "\u672C\u6B21\u67E5\u8BE2 pageSize",
|
|
2108
|
+
"\u4EFB\u52A1\u5217\u8868": [
|
|
2109
|
+
"\u4EFB\u52A1ID",
|
|
2110
|
+
"\u4EFB\u52A1\u540D\u79F0",
|
|
2111
|
+
"\u4EFB\u52A1\u7EC4",
|
|
2112
|
+
"\u72B6\u6001",
|
|
2113
|
+
"\u8D1F\u8D23\u4EBA",
|
|
2114
|
+
"\u53C2\u4E0E\u4EBA",
|
|
2115
|
+
"\u5230\u671F\u65F6\u95F4",
|
|
2116
|
+
"\u5F00\u59CB\u65F6\u95F4",
|
|
2117
|
+
"\u7ED3\u675F\u65F6\u95F4",
|
|
2118
|
+
"\u8BA1\u65F6\u603B\u65F6\u957F",
|
|
2119
|
+
"\u68C0\u67E5\u9879",
|
|
2120
|
+
"\u8BC4\u8BBA\u6570",
|
|
2121
|
+
"\u9644\u4EF6\u6570",
|
|
2122
|
+
"\u662F\u5426\u5173\u6CE8",
|
|
2123
|
+
"\u65F6\u95F4\u7C7B\u578B",
|
|
2124
|
+
"\u5168\u5929\u7C7B\u578B",
|
|
2125
|
+
"\u5DE5\u4F5C\u7C7B\u578B",
|
|
2126
|
+
"\u91CD\u590D\u89C4\u5219"
|
|
2127
|
+
]
|
|
2128
|
+
},
|
|
2129
|
+
"\u793A\u4F8B": "alpha-classic-cli matter task --id <matterId> --state \u672A\u5B8C\u6210 --limit 20"
|
|
2130
|
+
},
|
|
2131
|
+
{
|
|
2132
|
+
"\u6A21\u5757": "matter",
|
|
2133
|
+
"\u4E2D\u6587\u540D": "\u9879\u76EE",
|
|
2134
|
+
"\u80FD\u529B": "\u67E5\u8BE2\u4EFB\u52A1\u8BE6\u60C5",
|
|
2135
|
+
"\u547D\u4EE4": "alpha-classic-cli matter task-detail",
|
|
2136
|
+
"\u53C2\u6570": {
|
|
2137
|
+
"--id": "\u5FC5\u586B\u3002\u4EFB\u52A1ID\uFF0C\u901A\u5E38\u5148\u901A\u8FC7 matter task \u83B7\u53D6\u3002",
|
|
2138
|
+
"--comments": "\u53EF\u9009\u3002\u6700\u8FD1\u4EFB\u52A1\u52A8\u6001\u548C\u8BC4\u8BBA\u6570\u91CF\uFF0C\u9ED8\u8BA4 10\uFF0C\u6700\u5927 50\uFF1B\u4F20 0 \u53EF\u8DF3\u8FC7\u3002"
|
|
2139
|
+
},
|
|
2140
|
+
"\u8F93\u51FA\u5B57\u6BB5": {
|
|
2141
|
+
"\u4EFB\u52A1\u6982\u89C8": [
|
|
2142
|
+
"\u4EFB\u52A1ID",
|
|
2143
|
+
"\u4EFB\u52A1\u540D\u79F0",
|
|
2144
|
+
"\u9879\u76EEID",
|
|
2145
|
+
"\u9879\u76EE\u540D\u79F0",
|
|
2146
|
+
"\u4EFB\u52A1\u7EC4",
|
|
2147
|
+
"\u72B6\u6001",
|
|
2148
|
+
"\u521B\u5EFA\u4EBA",
|
|
2149
|
+
"\u8D1F\u8D23\u4EBA",
|
|
2150
|
+
"\u53C2\u4E0E\u4EBA",
|
|
2151
|
+
"\u5F00\u59CB\u65F6\u95F4",
|
|
2152
|
+
"\u5230\u671F\u65F6\u95F4",
|
|
2153
|
+
"\u7ED3\u675F\u65F6\u95F4",
|
|
2154
|
+
"\u4EFB\u52A1\u8BE6\u60C5",
|
|
2155
|
+
"\u68C0\u67E5\u9879",
|
|
2156
|
+
"\u5B50\u4EFB\u52A1",
|
|
2157
|
+
"\u8BC4\u8BBA\u6570",
|
|
2158
|
+
"\u52A8\u6001\u6570",
|
|
2159
|
+
"\u9644\u4EF6\u6570",
|
|
2160
|
+
"\u8BA1\u65F6\u603B\u65F6\u957F",
|
|
2161
|
+
"\u5DE5\u4F5C\u7C7B\u578B",
|
|
2162
|
+
"\u91CD\u590D\u89C4\u5219"
|
|
2163
|
+
],
|
|
2164
|
+
"\u68C0\u67E5\u9879": ["\u68C0\u67E5\u9879ID", "\u5185\u5BB9", "\u72B6\u6001", "\u521B\u5EFA\u65F6\u95F4", "\u66F4\u65B0\u65F6\u95F4"],
|
|
2165
|
+
"\u9644\u4EF6": ["\u6587\u4EF6\u540D", "\u5927\u5C0F"],
|
|
2166
|
+
"\u8BA1\u65F6": ["\u8BA1\u65F6\u603B\u65F6\u957F", "\u603B\u6570", "\u8BA1\u65F6\u5217\u8868"],
|
|
2167
|
+
"\u4EFB\u52A1\u52A8\u6001": ["\u603B\u6570", "\u9875\u7801", "\u6BCF\u9875\u6570\u91CF", "\u52A8\u6001\u5217\u8868"]
|
|
2168
|
+
},
|
|
2169
|
+
"\u793A\u4F8B": "alpha-classic-cli matter task-detail --id <taskId> --comments 10"
|
|
2170
|
+
},
|
|
2171
|
+
{
|
|
2172
|
+
"\u6A21\u5757": "appro",
|
|
2173
|
+
"\u4E2D\u6587\u540D": "\u5BA1\u6279",
|
|
2174
|
+
"\u80FD\u529B": "\u67E5\u8BE2\u5BA1\u6279\u5217\u8868",
|
|
2175
|
+
"\u547D\u4EE4": "alpha-classic-cli appro list",
|
|
2176
|
+
"\u53C2\u6570": {
|
|
2177
|
+
"--scope": "\u53EF\u9009\u3002\u652F\u6301 my/\u6211\u5BA1\u6279\u7684\u3001started/\u6211\u53D1\u8D77\u7684\u3001cc/\u6284\u9001\u6211\u7684\u3001all/\u5168\u90E8\u5BA1\u6279\uFF1B\u9ED8\u8BA4 my\u3002",
|
|
2178
|
+
"--keyword": "\u53EF\u9009\u3002\u5BA1\u6279\u91CD\u8981\u4FE1\u606F\u3001\u9879\u76EE\u540D\u79F0\u7B49\u5173\u952E\u8BCD\u3002",
|
|
2179
|
+
"--status": "\u53EF\u9009\u3002\u5BA1\u6279\u72B6\u6001\u7801\u3001\u4E2D\u6587\u72B6\u6001\u540D\u6216 all\uFF0C\u4F8B\u5982 \u5F85\u6211\u5BA1\u6279\u3002",
|
|
2180
|
+
"--status for scope=my": ["all", "\u5F85\u6211\u5BA1\u6279", "\u6211\u5DF2\u901A\u8FC7", "\u6211\u5DF2\u9A73\u56DE", "\u4ED6\u4EBA\u5DF2\u5904\u7406", "\u6211\u8F6C\u7B7E\u7684"],
|
|
2181
|
+
"--status for scope=started|cc|all": [
|
|
2182
|
+
"all",
|
|
2183
|
+
"\u5BA1\u6279\u4E2D",
|
|
2184
|
+
"\u5DF2\u901A\u8FC7",
|
|
2185
|
+
"\u5DF2\u9A73\u56DE",
|
|
2186
|
+
"\u9A73\u56DE\u540E\u91CD\u65B0\u53D1\u8D77",
|
|
2187
|
+
"\u5DF2\u64A4\u56DE",
|
|
2188
|
+
"\u64A4\u56DE\u540E\u91CD\u65B0\u53D1\u8D77",
|
|
2189
|
+
"\u5DF2\u5220\u9664"
|
|
2190
|
+
],
|
|
2191
|
+
"--appro-type": "\u53EF\u9009\u3002\u5BA1\u6279\u7C7B\u578BID\uFF0C\u591A\u4E2A\u7528\u82F1\u6587\u9017\u53F7\u5206\u9694\u3002",
|
|
2192
|
+
"--starter-id": "\u53EF\u9009\u3002\u53D1\u8D77\u4EBA\u7528\u6237ID\uFF1B\u6700\u7EC8\u4F1A\u653E\u5165\u63A5\u53E3 startUserIds\u3002",
|
|
2193
|
+
"--starter-name": "\u53EF\u9009\u3002\u53D1\u8D77\u4EBA\u59D3\u540D\uFF1BCLI \u4F1A\u5148\u67E5\u53D1\u8D77\u4EBA\u5217\u8868\u5E76\u89E3\u6790\u4E3A starter-id\u3002",
|
|
2194
|
+
"--limit": "\u53EF\u9009\u3002\u9ED8\u8BA4 10\uFF0C\u6700\u5927 50\u3002",
|
|
2195
|
+
"--page": "\u53EF\u9009\u3002\u4ECE 1 \u5F00\u59CB\uFF0C\u9ED8\u8BA4 1\u3002",
|
|
2196
|
+
"--count-only": "\u53EF\u9009\u3002\u53EA\u8FD4\u56DE\u5339\u914D\u6570\u91CF\uFF0C\u9002\u5408\u56DE\u7B54\u201C\u6709\u591A\u5C11\u201D\u7C7B\u95EE\u9898\u3002"
|
|
2197
|
+
},
|
|
2198
|
+
"\u8F93\u51FA\u5B57\u6BB5": {
|
|
2199
|
+
"\u603B\u6570": "\u5339\u914D\u5BA1\u6279\u603B\u6570",
|
|
2200
|
+
"\u9875\u7801": "\u5F53\u524D\u9875\u7801",
|
|
2201
|
+
"\u6BCF\u9875\u6570\u91CF": "\u672C\u6B21\u67E5\u8BE2 pageSize",
|
|
2202
|
+
"\u5BA1\u6279\u5217\u8868": [
|
|
2203
|
+
"\u5BA1\u6279ID",
|
|
2204
|
+
"\u5BA1\u6279\u7C7B\u578B",
|
|
2205
|
+
"\u91CD\u8981\u4FE1\u606F",
|
|
2206
|
+
"\u9879\u76EEID",
|
|
2207
|
+
"\u9879\u76EE\u540D\u79F0",
|
|
2208
|
+
"\u9879\u76EE\u7F16\u53F7",
|
|
2209
|
+
"\u5BA2\u6237",
|
|
2210
|
+
"\u53D1\u8D77\u4EBA",
|
|
2211
|
+
"\u72B6\u6001",
|
|
2212
|
+
"\u5F53\u524D\u8282\u70B9",
|
|
2213
|
+
"\u53D1\u8D77\u65F6\u95F4",
|
|
2214
|
+
"\u5230\u8FBE\u5F53\u524D\u8282\u70B9\u65F6\u95F4",
|
|
2215
|
+
"\u6D41\u7A0B\u4EFB\u52A1ID"
|
|
2216
|
+
]
|
|
2217
|
+
},
|
|
2218
|
+
"\u793A\u4F8B": [
|
|
2219
|
+
"alpha-classic-cli appro list --scope my --status \u5F85\u6211\u5BA1\u6279 --count-only",
|
|
2220
|
+
"alpha-classic-cli appro list --scope started --status \u5BA1\u6279\u4E2D --limit 10",
|
|
2221
|
+
"alpha-classic-cli appro list --scope cc --status \u9A73\u56DE\u540E\u91CD\u65B0\u53D1\u8D77 --limit 10",
|
|
2222
|
+
"alpha-classic-cli appro list --scope all --status \u5DF2\u64A4\u56DE --limit 10"
|
|
2223
|
+
]
|
|
2224
|
+
},
|
|
2225
|
+
{
|
|
2226
|
+
"\u6A21\u5757": "appro",
|
|
2227
|
+
"\u4E2D\u6587\u540D": "\u5BA1\u6279",
|
|
2228
|
+
"\u80FD\u529B": "\u67E5\u8BE2\u5BA1\u6279\u53D1\u8D77\u4EBA\u5217\u8868",
|
|
2229
|
+
"\u547D\u4EE4": "alpha-classic-cli appro initiators",
|
|
2230
|
+
"\u53C2\u6570": {
|
|
2231
|
+
"--keyword": "\u53EF\u9009\u3002\u6309\u53D1\u8D77\u4EBA\u59D3\u540D\u8FC7\u6EE4\u3002",
|
|
2232
|
+
"--include-left": "\u53EF\u9009\u3002\u5305\u542B\u975E\u5728\u804C\u7528\u6237\uFF1B\u9ED8\u8BA4\u53EA\u67E5\u5728\u804C\u672A\u5220\u9664\u7528\u6237\u3002",
|
|
2233
|
+
"--limit": "\u53EF\u9009\u3002\u9ED8\u8BA4 50\uFF0C\u6700\u5927 50\u3002"
|
|
2234
|
+
},
|
|
2235
|
+
"\u8F93\u51FA\u5B57\u6BB5": {
|
|
2236
|
+
"\u603B\u6570": "\u5339\u914D\u53D1\u8D77\u4EBA\u6570",
|
|
2237
|
+
"\u53D1\u8D77\u4EBA\u5217\u8868": ["\u53D1\u8D77\u4EBAID", "\u59D3\u540D", "\u624B\u673A\u53F7", "\u90AE\u7BB1", "\u72B6\u6001"]
|
|
2238
|
+
},
|
|
2239
|
+
"\u793A\u4F8B": "alpha-classic-cli appro initiators --keyword \u5F20\u4E09"
|
|
2240
|
+
},
|
|
2241
|
+
{
|
|
2242
|
+
"\u6A21\u5757": "appro",
|
|
2243
|
+
"\u4E2D\u6587\u540D": "\u5BA1\u6279",
|
|
2244
|
+
"\u80FD\u529B": "\u67E5\u8BE2\u5BA1\u6279\u8BE6\u60C5",
|
|
2245
|
+
"\u547D\u4EE4": "alpha-classic-cli appro detail",
|
|
2246
|
+
"\u53C2\u6570": {
|
|
2247
|
+
"--id": "\u5FC5\u586B\u3002\u5BA1\u6279ID\uFF0C\u901A\u5E38\u5148\u901A\u8FC7 appro list \u83B7\u53D6\u3002",
|
|
2248
|
+
"--comments": "\u53EF\u9009\u3002\u6700\u8FD1\u7528\u6237\u8BC4\u8BBA\u548C\u5BA1\u6279\u52A8\u6001\u6570\u91CF\uFF0C\u9ED8\u8BA4 10\uFF0C\u6700\u5927 50\uFF1B\u4F20 0 \u53EF\u8DF3\u8FC7\u3002"
|
|
2249
|
+
},
|
|
2250
|
+
"\u8F93\u51FA\u5B57\u6BB5": {
|
|
2251
|
+
"\u5BA1\u6279\u6982\u89C8": [
|
|
2252
|
+
"\u5BA1\u6279ID",
|
|
2253
|
+
"\u5BA1\u6279\u7C7B\u578B",
|
|
2254
|
+
"\u91CD\u8981\u4FE1\u606F",
|
|
2255
|
+
"\u72B6\u6001",
|
|
2256
|
+
"\u5F53\u524D\u8282\u70B9",
|
|
2257
|
+
"\u53D1\u8D77\u4EBA",
|
|
2258
|
+
"\u53D1\u8D77\u65F6\u95F4",
|
|
2259
|
+
"\u66F4\u65B0\u65F6\u95F4",
|
|
2260
|
+
"\u5BA1\u6279\u7F16\u53F7",
|
|
2261
|
+
"\u8BC4\u8BBA\u548C\u52A8\u6001\u6570\u91CF",
|
|
2262
|
+
"\u6D41\u7A0B\u4EFB\u52A1ID"
|
|
2263
|
+
],
|
|
2264
|
+
"\u9879\u76EE\u4FE1\u606F": ["\u9879\u76EEID", "\u9879\u76EE\u540D\u79F0", "\u9879\u76EE\u7F16\u53F7", "\u9879\u76EE\u7C7B\u578B", "\u9879\u76EE\u72B6\u6001", "\u9879\u76EE\u6240\u5C5E", "\u5BA2\u6237"],
|
|
2265
|
+
"\u5BA1\u6279\u8868\u5355": {
|
|
2266
|
+
"\u8868\u5355\u7C7B\u578B": "\u5BA1\u6279\u7C7B\u578B\u540D\u79F0\uFF0C\u4F8B\u5982 \u7ACB\u9879\u5BA1\u6279\u3001\u5408\u540C\u5BA1\u6279\u3001\u81EA\u5B9A\u4E49\u5BA1\u6279\u3002",
|
|
2267
|
+
"\u4E1A\u52A1\u5206\u7EC4": "\u6309\u524D\u7AEF\u5BA1\u6279\u8BE6\u60C5\u6A21\u677F\u5C55\u793A\u7684\u5206\u7EC4\u540D\u8F93\u51FA\uFF0C\u4F8B\u5982 \u5408\u540C\u4FE1\u606F\u3001\u76D6\u7AE0\u4FE1\u606F\u3001\u9879\u76EE\u57FA\u672C\u4FE1\u606F\u3001\u9879\u76EE\u8865\u5145\u4FE1\u606F\u3001\u5F53\u524D\u7A0B\u5E8F\u4FE1\u606F\u3001\u9879\u76EE\u8BE6\u60C5\u3001\u9879\u76EE\u6210\u5458\u3001\u5173\u8054\u5408\u540C\u4FE1\u606F\u3001\u5173\u8054\u6536\u6B3E\u4FE1\u606F\u3001\u4E13\u7968\u4FE1\u606F\u3001\u8865\u5145\u4FE1\u606F\u3001\u5907\u6CE8\u3002\u81EA\u5B9A\u4E49 fieldsDtos/formFields \u7EDF\u4E00\u5E76\u5165 \u8865\u5145\u4FE1\u606F\u3002"
|
|
2268
|
+
},
|
|
2269
|
+
"\u5BA1\u6279\u6D41\u7A0B": ["\u8282\u70B9ID", "\u8282\u70B9\u540D\u79F0", "\u8282\u70B9\u7C7B\u578B", "\u8282\u70B9\u72B6\u6001", "\u662F\u5426\u5F53\u524D\u8282\u70B9", "\u5BA1\u6279\u65B9\u5F0F", "\u64CD\u4F5C\u65F6\u95F4", "\u5BA1\u6279\u4EBA"],
|
|
2270
|
+
"\u9644\u4EF6": ["\u6587\u4EF6\u540D", "\u5927\u5C0F"],
|
|
2271
|
+
"\u7528\u6237\u8BC4\u8BBA": ["\u603B\u6570", "\u9875\u7801", "\u6BCF\u9875\u6570\u91CF", "\u8BC4\u8BBA\u5217\u8868", "\u8BC4\u8BBAID", "\u7C7B\u578B", "\u8BC4\u8BBA\u4EBA", "\u5185\u5BB9", "\u8BC4\u8BBA\u65F6\u95F4"],
|
|
2272
|
+
"\u5BA1\u6279\u52A8\u6001": ["\u603B\u6570", "\u9875\u7801", "\u6BCF\u9875\u6570\u91CF", "\u52A8\u6001\u5217\u8868", "\u52A8\u6001ID", "\u7C7B\u578B", "\u64CD\u4F5C", "\u64CD\u4F5C\u4EBA", "\u5185\u5BB9", "\u52A8\u6001\u65F6\u95F4"]
|
|
2273
|
+
},
|
|
2274
|
+
"\u793A\u4F8B": "alpha-classic-cli appro detail --id <approId> --comments 10"
|
|
2275
|
+
}
|
|
2276
|
+
],
|
|
2277
|
+
"\u5B89\u5168\u89C4\u5219": [
|
|
2278
|
+
"\u5F53\u524D\u53EA\u652F\u6301\u67E5\u8BE2\uFF0C\u4E0D\u6267\u884C\u5199\u64CD\u4F5C\u3002",
|
|
2279
|
+
"\u4E0D\u8981\u8F93\u51FA token\u3002",
|
|
2280
|
+
"\u4E0D\u8981\u81EA\u884C\u62FC\u63A5\u540E\u7AEF\u63A5\u53E3\uFF0C\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u4F7F\u7528 api \u8C03\u8BD5\u547D\u4EE4\u3002",
|
|
2281
|
+
"\u4F18\u5148\u4F7F\u7528 capabilities \u4E2D\u58F0\u660E\u7684\u7A33\u5B9A\u4E1A\u52A1\u547D\u4EE4\u3002",
|
|
2282
|
+
"\u73AF\u5883\u8FD0\u884C\u65F6\u4E0D\u53EF\u5207\u6362\uFF0C\u907F\u514D\u8BEF\u8FDE dev/prod\u3002"
|
|
2283
|
+
]
|
|
2284
|
+
});
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
// src/install/install.ts
|
|
2288
|
+
import fs2 from "fs/promises";
|
|
2289
|
+
import os2 from "os";
|
|
2290
|
+
import path2 from "path";
|
|
2291
|
+
|
|
2292
|
+
// src/install/templates.ts
|
|
2293
|
+
import { existsSync } from "fs";
|
|
2294
|
+
import fs from "fs/promises";
|
|
2295
|
+
import path from "path";
|
|
2296
|
+
import { fileURLToPath } from "url";
|
|
2297
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
2298
|
+
var SKILL_NAME = "alpha-classic-cli";
|
|
2299
|
+
var SKILL_TEMPLATE_ROOT = resolveAssetPath("alpha-classic-skill");
|
|
2300
|
+
var CLAUDE_GUIDE_TEMPLATE = path.join(
|
|
2301
|
+
resolveAssetPath("claude"),
|
|
2302
|
+
"alpha-classic-cli.md"
|
|
2303
|
+
);
|
|
2304
|
+
function resolveAssetPath(assetDirName) {
|
|
2305
|
+
const candidates = [
|
|
2306
|
+
path.resolve(__dirname, "..", "assets", assetDirName),
|
|
2307
|
+
path.resolve(__dirname, "..", "..", "assets", assetDirName)
|
|
2308
|
+
];
|
|
2309
|
+
const match = candidates.find((candidate) => existsSync(candidate));
|
|
2310
|
+
return match ?? candidates[0];
|
|
2311
|
+
}
|
|
2312
|
+
async function copyDirectory(source, target) {
|
|
2313
|
+
await fs.mkdir(target, { recursive: true });
|
|
2314
|
+
const entries = await fs.readdir(source, { withFileTypes: true });
|
|
2315
|
+
for (const entry of entries) {
|
|
2316
|
+
const sourcePath = path.join(source, entry.name);
|
|
2317
|
+
const targetPath = path.join(target, entry.name);
|
|
2318
|
+
if (entry.isDirectory()) {
|
|
2319
|
+
await copyDirectory(sourcePath, targetPath);
|
|
2320
|
+
continue;
|
|
2321
|
+
}
|
|
2322
|
+
if (entry.isFile()) {
|
|
2323
|
+
await fs.copyFile(sourcePath, targetPath);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
// src/install/install.ts
|
|
2329
|
+
function resolveCodexSkillPath(homeDir = os2.homedir()) {
|
|
2330
|
+
return path2.join(homeDir, ".codex", "skills", SKILL_NAME);
|
|
2331
|
+
}
|
|
2332
|
+
function resolveClaudeGuidePath(homeDir = os2.homedir()) {
|
|
2333
|
+
return path2.join(homeDir, ".claude", "alpha-classic-cli.md");
|
|
2334
|
+
}
|
|
2335
|
+
function resolveClaudeMemoryPath(homeDir = os2.homedir()) {
|
|
2336
|
+
return path2.join(homeDir, ".claude", "CLAUDE.md");
|
|
2337
|
+
}
|
|
2338
|
+
function resolveAlphaClawSkillPath(homeDir = os2.homedir()) {
|
|
2339
|
+
const environment = getDefaultEnvironmentPreset();
|
|
2340
|
+
return path2.join(
|
|
2341
|
+
homeDir,
|
|
2342
|
+
`.openclaw-${environment.name}alphaclaw`,
|
|
2343
|
+
"workspace",
|
|
2344
|
+
"skills",
|
|
2345
|
+
SKILL_NAME
|
|
2346
|
+
);
|
|
2347
|
+
}
|
|
2348
|
+
async function installAgentGuides(options) {
|
|
2349
|
+
const agent = options?.agent ?? "codex";
|
|
2350
|
+
const result = {
|
|
2351
|
+
codexSkillPath: resolveCodexSkillPath(options?.homeDir),
|
|
2352
|
+
codexSkillInstalled: false
|
|
2353
|
+
};
|
|
2354
|
+
if (agent === "codex" || agent === "all") {
|
|
2355
|
+
const codexResult = await installCodexSkill(options);
|
|
2356
|
+
result.codexSkillPath = codexResult.codexSkillPath;
|
|
2357
|
+
result.codexSkillInstalled = codexResult.codexSkillInstalled;
|
|
2358
|
+
}
|
|
2359
|
+
if (agent === "claude" || agent === "all") {
|
|
2360
|
+
const claudeResult = await installClaudeGuide(options);
|
|
2361
|
+
result.claudeGuidePath = claudeResult.claudeGuidePath;
|
|
2362
|
+
result.claudeGuideInstalled = claudeResult.claudeGuideInstalled;
|
|
2363
|
+
result.claudeMemoryPath = claudeResult.claudeMemoryPath;
|
|
2364
|
+
result.claudeMemoryUpdated = claudeResult.claudeMemoryUpdated;
|
|
2365
|
+
}
|
|
2366
|
+
if (agent === "alphaclaw" || agent === "all") {
|
|
2367
|
+
const alphaClawResult = await installAlphaClawSkill(options);
|
|
2368
|
+
result.alphaClawSkillPath = alphaClawResult.alphaClawSkillPath;
|
|
2369
|
+
result.alphaClawSkillInstalled = alphaClawResult.alphaClawSkillInstalled;
|
|
2370
|
+
}
|
|
2371
|
+
return result;
|
|
2372
|
+
}
|
|
2373
|
+
async function uninstallAgentGuides(options) {
|
|
2374
|
+
const agent = options?.agent ?? "codex";
|
|
2375
|
+
const result = {
|
|
2376
|
+
codexSkillPath: resolveCodexSkillPath(options?.homeDir),
|
|
2377
|
+
codexSkillInstalled: false
|
|
2378
|
+
};
|
|
2379
|
+
if (agent === "codex" || agent === "all") {
|
|
2380
|
+
await fs2.rm(resolveCodexSkillPath(options?.homeDir), { recursive: true, force: true });
|
|
2381
|
+
result.codexSkillInstalled = false;
|
|
2382
|
+
}
|
|
2383
|
+
if (agent === "claude" || agent === "all") {
|
|
2384
|
+
const claudeResult = await uninstallClaudeGuide(options);
|
|
2385
|
+
result.claudeGuidePath = claudeResult.claudeGuidePath;
|
|
2386
|
+
result.claudeGuideInstalled = false;
|
|
2387
|
+
result.claudeMemoryPath = claudeResult.claudeMemoryPath;
|
|
2388
|
+
result.claudeMemoryUpdated = claudeResult.claudeMemoryUpdated;
|
|
2389
|
+
}
|
|
2390
|
+
if (agent === "alphaclaw" || agent === "all") {
|
|
2391
|
+
await fs2.rm(resolveAlphaClawSkillPath(options?.homeDir), { recursive: true, force: true });
|
|
2392
|
+
result.alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir);
|
|
2393
|
+
result.alphaClawSkillInstalled = false;
|
|
2394
|
+
}
|
|
2395
|
+
return result;
|
|
2396
|
+
}
|
|
2397
|
+
async function installCodexSkill(options) {
|
|
2398
|
+
const skillPath = resolveCodexSkillPath(options?.homeDir);
|
|
2399
|
+
await fs2.rm(skillPath, { recursive: true, force: true });
|
|
2400
|
+
await copyDirectory(SKILL_TEMPLATE_ROOT, skillPath);
|
|
2401
|
+
return {
|
|
2402
|
+
codexSkillPath: skillPath,
|
|
2403
|
+
codexSkillInstalled: true
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
async function installAlphaClawSkill(options) {
|
|
2407
|
+
const skillPath = resolveAlphaClawSkillPath(options?.homeDir);
|
|
2408
|
+
await fs2.rm(skillPath, { recursive: true, force: true });
|
|
2409
|
+
await copyDirectory(SKILL_TEMPLATE_ROOT, skillPath);
|
|
2410
|
+
return {
|
|
2411
|
+
codexSkillPath: resolveCodexSkillPath(options?.homeDir),
|
|
2412
|
+
codexSkillInstalled: false,
|
|
2413
|
+
alphaClawSkillPath: skillPath,
|
|
2414
|
+
alphaClawSkillInstalled: true
|
|
2415
|
+
};
|
|
2416
|
+
}
|
|
2417
|
+
async function installClaudeGuide(options) {
|
|
2418
|
+
const guidePath = resolveClaudeGuidePath(options?.homeDir);
|
|
2419
|
+
const memoryPath = resolveClaudeMemoryPath(options?.homeDir);
|
|
2420
|
+
const importLine = "@~/.claude/alpha-classic-cli.md";
|
|
2421
|
+
await fs2.mkdir(path2.dirname(guidePath), { recursive: true });
|
|
2422
|
+
await fs2.copyFile(CLAUDE_GUIDE_TEMPLATE, guidePath);
|
|
2423
|
+
const memoryUpdated = await ensureClaudeImport(memoryPath, importLine);
|
|
2424
|
+
return {
|
|
2425
|
+
codexSkillPath: resolveCodexSkillPath(options?.homeDir),
|
|
2426
|
+
codexSkillInstalled: false,
|
|
2427
|
+
claudeGuidePath: guidePath,
|
|
2428
|
+
claudeGuideInstalled: true,
|
|
2429
|
+
claudeMemoryPath: memoryPath,
|
|
2430
|
+
claudeMemoryUpdated: memoryUpdated
|
|
2431
|
+
};
|
|
2432
|
+
}
|
|
2433
|
+
async function uninstallClaudeGuide(options) {
|
|
2434
|
+
const guidePath = resolveClaudeGuidePath(options?.homeDir);
|
|
2435
|
+
const memoryPath = resolveClaudeMemoryPath(options?.homeDir);
|
|
2436
|
+
await fs2.rm(guidePath, { force: true });
|
|
2437
|
+
const memoryUpdated = await removeClaudeImport(memoryPath);
|
|
2438
|
+
return {
|
|
2439
|
+
codexSkillPath: resolveCodexSkillPath(options?.homeDir),
|
|
2440
|
+
codexSkillInstalled: false,
|
|
2441
|
+
claudeGuidePath: guidePath,
|
|
2442
|
+
claudeGuideInstalled: false,
|
|
2443
|
+
claudeMemoryPath: memoryPath,
|
|
2444
|
+
claudeMemoryUpdated: memoryUpdated
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2447
|
+
async function inspectInstallState(options) {
|
|
2448
|
+
const skillPath = resolveCodexSkillPath(options?.homeDir);
|
|
2449
|
+
let installed = false;
|
|
2450
|
+
try {
|
|
2451
|
+
await fs2.access(path2.join(skillPath, "SKILL.md"));
|
|
2452
|
+
installed = true;
|
|
2453
|
+
} catch {
|
|
2454
|
+
installed = false;
|
|
2455
|
+
}
|
|
2456
|
+
const claudeGuidePath = resolveClaudeGuidePath(options?.homeDir);
|
|
2457
|
+
let claudeGuideInstalled = false;
|
|
2458
|
+
try {
|
|
2459
|
+
await fs2.access(claudeGuidePath);
|
|
2460
|
+
claudeGuideInstalled = true;
|
|
2461
|
+
} catch {
|
|
2462
|
+
claudeGuideInstalled = false;
|
|
2463
|
+
}
|
|
2464
|
+
const alphaClawSkillPath = resolveAlphaClawSkillPath(options?.homeDir);
|
|
2465
|
+
let alphaClawSkillInstalled = false;
|
|
2466
|
+
try {
|
|
2467
|
+
await fs2.access(path2.join(alphaClawSkillPath, "SKILL.md"));
|
|
2468
|
+
alphaClawSkillInstalled = true;
|
|
2469
|
+
} catch {
|
|
2470
|
+
alphaClawSkillInstalled = false;
|
|
2471
|
+
}
|
|
2472
|
+
return {
|
|
2473
|
+
codexSkillPath: skillPath,
|
|
2474
|
+
codexSkillInstalled: installed,
|
|
2475
|
+
claudeGuidePath,
|
|
2476
|
+
claudeGuideInstalled,
|
|
2477
|
+
claudeMemoryPath: resolveClaudeMemoryPath(options?.homeDir),
|
|
2478
|
+
alphaClawSkillPath,
|
|
2479
|
+
alphaClawSkillInstalled
|
|
2480
|
+
};
|
|
2481
|
+
}
|
|
2482
|
+
async function ensureClaudeImport(memoryPath, importLine) {
|
|
2483
|
+
let current = "";
|
|
2484
|
+
try {
|
|
2485
|
+
current = await fs2.readFile(memoryPath, "utf8");
|
|
2486
|
+
} catch (error) {
|
|
2487
|
+
const nodeError = error;
|
|
2488
|
+
if (nodeError.code !== "ENOENT") {
|
|
2489
|
+
throw error;
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
if (current.includes(importLine) || current.includes("alpha-classic-cli.md")) {
|
|
2493
|
+
return false;
|
|
2494
|
+
}
|
|
2495
|
+
const prefix = current.trimEnd();
|
|
2496
|
+
const next = `${prefix}${prefix ? "\n\n" : ""}# Alpha Classic CLI
|
|
2497
|
+
|
|
2498
|
+
${importLine}
|
|
2499
|
+
`;
|
|
2500
|
+
await fs2.mkdir(path2.dirname(memoryPath), { recursive: true });
|
|
2501
|
+
await fs2.writeFile(memoryPath, next, "utf8");
|
|
2502
|
+
return true;
|
|
2503
|
+
}
|
|
2504
|
+
async function removeClaudeImport(memoryPath) {
|
|
2505
|
+
let current = "";
|
|
2506
|
+
try {
|
|
2507
|
+
current = await fs2.readFile(memoryPath, "utf8");
|
|
2508
|
+
} catch (error) {
|
|
2509
|
+
const nodeError = error;
|
|
2510
|
+
if (nodeError.code === "ENOENT") {
|
|
2511
|
+
return false;
|
|
2512
|
+
}
|
|
2513
|
+
throw error;
|
|
2514
|
+
}
|
|
2515
|
+
const next = current.replace(
|
|
2516
|
+
/\n{0,2}# Alpha Classic CLI\n\n@~\/\.claude\/alpha-classic-cli\.md\n?/g,
|
|
2517
|
+
"\n"
|
|
2518
|
+
).replace(/\n?@~\/\.claude\/alpha-classic-cli\.md\n?/g, "\n").trimEnd();
|
|
2519
|
+
if (next === current.trimEnd()) {
|
|
2520
|
+
return false;
|
|
2521
|
+
}
|
|
2522
|
+
await fs2.writeFile(memoryPath, next ? `${next}
|
|
2523
|
+
` : "", "utf8");
|
|
2524
|
+
return true;
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
// src/commands/doctor.ts
|
|
2528
|
+
async function runDoctor(sessionStore) {
|
|
2529
|
+
const config = await sessionStore.getConfig();
|
|
2530
|
+
let session = await sessionStore.getSession();
|
|
2531
|
+
const environment = getDefaultEnvironmentPreset();
|
|
2532
|
+
const installState = await inspectInstallState();
|
|
2533
|
+
let apiCheck = {
|
|
2534
|
+
ok: false,
|
|
2535
|
+
message: "\u672A\u767B\u5F55\u3002\u8BF7\u6267\u884C\uFF1Aalpha-classic-cli login"
|
|
2536
|
+
};
|
|
2537
|
+
if (session) {
|
|
2538
|
+
try {
|
|
2539
|
+
const client = new ApiClient({
|
|
2540
|
+
sessionStore,
|
|
2541
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
2542
|
+
timeoutMs: config.timeoutMs
|
|
2543
|
+
});
|
|
2544
|
+
const currentUserResponse = await client.check();
|
|
2545
|
+
const currentUserData = getCurrentUserData2(currentUserResponse);
|
|
2546
|
+
const userName = currentUserData?.name ?? currentUserData?.userName ?? session.userName ?? session.name ?? "\u7528\u6237";
|
|
2547
|
+
if (currentUserResponse.isSuccess !== false && currentUserData) {
|
|
2548
|
+
session = await refreshSessionFromCurrentUser(session, currentUserData);
|
|
2549
|
+
}
|
|
2550
|
+
apiCheck = {
|
|
2551
|
+
ok: currentUserResponse.isSuccess !== false,
|
|
2552
|
+
message: currentUserResponse.isSuccess === false ? currentUserResponse.resultMsg ?? "\u767B\u5F55\u9A8C\u8BC1\u5931\u8D25" : `${userName}\uFF0C\u767B\u5F55\u6210\u529F\uFF01`
|
|
2553
|
+
};
|
|
2554
|
+
} catch (error) {
|
|
2555
|
+
apiCheck = {
|
|
2556
|
+
ok: false,
|
|
2557
|
+
message: error instanceof Error ? error.message : String(error)
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
printSuccess({
|
|
2562
|
+
config: {
|
|
2563
|
+
environment: environment.name,
|
|
2564
|
+
baseUrl: environment.baseUrl,
|
|
2565
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
2566
|
+
locked: true,
|
|
2567
|
+
source: "build",
|
|
2568
|
+
configPath: sessionStore.configPath
|
|
2569
|
+
},
|
|
2570
|
+
session: session ? {
|
|
2571
|
+
present: true,
|
|
2572
|
+
userId: session.userId ?? "(unknown)",
|
|
2573
|
+
userName: session.userName ?? session.name ?? "(unknown)",
|
|
2574
|
+
officeId: session.officeId ?? "(unknown)",
|
|
2575
|
+
officeName: session.officeName ?? "(unknown)",
|
|
2576
|
+
environment: environment.name,
|
|
2577
|
+
tokenExpireTime: session.tokenExpireTime ?? "(unknown)",
|
|
2578
|
+
refreshTokenExpireTime: session.refreshTokenExpireTime ?? "(unknown)",
|
|
2579
|
+
deviceType: session.deviceType ?? "ai",
|
|
2580
|
+
updatedAt: session.updatedAt
|
|
2581
|
+
} : { present: false, hint: "alpha-classic-cli login" },
|
|
2582
|
+
install: installState,
|
|
2583
|
+
apiCheck
|
|
2584
|
+
});
|
|
2585
|
+
async function refreshSessionFromCurrentUser(currentSession, currentUserData) {
|
|
2586
|
+
const jwtClaims = decodeAlphaJwtClaims(currentSession.token);
|
|
2587
|
+
const legacySession = currentSession;
|
|
2588
|
+
const officeId = currentUserData.office_id ?? currentUserData.officeId ?? jwtClaims?.office_id;
|
|
2589
|
+
const officeName = currentUserData.officeName ?? jwtClaims?.office_name ?? legacySession.siteName;
|
|
2590
|
+
const userName = currentUserData.name ?? currentUserData.userName ?? jwtClaims?.user_name;
|
|
2591
|
+
const userId = currentUserData.accid ?? currentUserData.id ?? currentUserData.user_id ?? jwtClaims?.user_id;
|
|
2592
|
+
const { siteId: _siteId, siteName: _siteName, ...currentSessionWithoutLegacySite } = legacySession;
|
|
2593
|
+
const refreshed = {
|
|
2594
|
+
...currentSessionWithoutLegacySite,
|
|
2595
|
+
...userId ? { userId } : {},
|
|
2596
|
+
...officeId ?? legacySession.siteId ? { officeId: officeId ?? legacySession.siteId } : {},
|
|
2597
|
+
...userName ? {
|
|
2598
|
+
name: userName,
|
|
2599
|
+
userName
|
|
2600
|
+
} : {},
|
|
2601
|
+
...officeName ? { officeName } : {},
|
|
2602
|
+
...currentSession.tokenExpireTime ?? jwtClaims?.exp ? { tokenExpireTime: currentSession.tokenExpireTime ?? jwtClaims?.exp } : {},
|
|
2603
|
+
deviceType: currentSession.deviceType ?? "ai",
|
|
2604
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2605
|
+
};
|
|
2606
|
+
await sessionStore.saveSession(refreshed);
|
|
2607
|
+
return refreshed;
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
function getCurrentUserData2(response) {
|
|
2611
|
+
return "data" in response && response.data ? response.data : response;
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
// src/commands/env.ts
|
|
2615
|
+
async function runEnvCommand(action, _name, _sessionStore) {
|
|
2616
|
+
const normalizedAction = action?.trim().toLowerCase() ?? "current";
|
|
2617
|
+
if (normalizedAction === "list") {
|
|
2618
|
+
printSuccess(listEnvironmentPresets(), {
|
|
2619
|
+
count: listEnvironmentPresets().length
|
|
2620
|
+
});
|
|
2621
|
+
return;
|
|
2622
|
+
}
|
|
2623
|
+
if (normalizedAction === "current") {
|
|
2624
|
+
const fallback = getDefaultEnvironmentPreset();
|
|
2625
|
+
printSuccess({
|
|
2626
|
+
environment: fallback.name,
|
|
2627
|
+
label: fallback.label,
|
|
2628
|
+
baseUrl: fallback.baseUrl,
|
|
2629
|
+
apiBaseUrl: fallback.apiBaseUrl,
|
|
2630
|
+
locked: true,
|
|
2631
|
+
source: "build"
|
|
2632
|
+
});
|
|
2633
|
+
return;
|
|
2634
|
+
}
|
|
2635
|
+
if (normalizedAction === "use") {
|
|
2636
|
+
throw new Error(
|
|
2637
|
+
"env use has been removed. This CLI only exposes env list and env current."
|
|
2638
|
+
);
|
|
2639
|
+
}
|
|
2640
|
+
throw new Error(`Unknown env action: ${normalizedAction}`);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
// src/commands/matter.ts
|
|
2644
|
+
async function runMatterSearch(options, sessionStore) {
|
|
2645
|
+
const config = await sessionStore.getConfig();
|
|
2646
|
+
const environment = getDefaultEnvironmentPreset();
|
|
2647
|
+
const client = new ApiClient({
|
|
2648
|
+
sessionStore,
|
|
2649
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
2650
|
+
timeoutMs: config.timeoutMs
|
|
2651
|
+
});
|
|
2652
|
+
const limit = clampLimit2(options.limit ?? 10);
|
|
2653
|
+
const page = Math.max(1, options.page ?? 1);
|
|
2654
|
+
const status = parseMatterSearchStatus(options.status);
|
|
2655
|
+
const scope = parseMatterSearchScope(options.scope);
|
|
2656
|
+
const joinMember = scope === "joined" ? await buildJoinedMatterMemberFilter(client, sessionStore) : void 0;
|
|
2657
|
+
const [selectedFields, response] = await Promise.all([
|
|
2658
|
+
fetchMatterListSelectedFields(client),
|
|
2659
|
+
client.request(
|
|
2660
|
+
"POST",
|
|
2661
|
+
"/matterserver/api/v2/matter/search",
|
|
2662
|
+
{
|
|
2663
|
+
data: buildMatterSearchBody({
|
|
2664
|
+
keyword: options.keyword ?? "",
|
|
2665
|
+
limit,
|
|
2666
|
+
page,
|
|
2667
|
+
status,
|
|
2668
|
+
scope,
|
|
2669
|
+
joinMember
|
|
2670
|
+
})
|
|
2671
|
+
}
|
|
2672
|
+
)
|
|
2673
|
+
]);
|
|
2674
|
+
if (response.isSuccess === false) {
|
|
2675
|
+
throw new Error(response.resultMsg ?? "Matter search failed.");
|
|
2676
|
+
}
|
|
2677
|
+
const responseData = unwrapEnvelopeData2(response);
|
|
2678
|
+
const projects = responseData?.matterSearchElementVOs ?? [];
|
|
2679
|
+
const displayedFields = getMatterListDisplayedFields(selectedFields);
|
|
2680
|
+
printSuccess({
|
|
2681
|
+
"\u9879\u76EE\u72B6\u6001": scope === "followed" ? "\u672A\u4F20\u72B6\u6001\u7B5B\u9009\uFF08\u6211\u5173\u6CE8\u7684\uFF09" : status.label,
|
|
2682
|
+
"\u9879\u76EE\u8303\u56F4": formatMatterSearchScopeLabel(scope),
|
|
2683
|
+
"\u603B\u6570": responseData?.totalCount ?? projects.length,
|
|
2684
|
+
"\u9875\u7801": page,
|
|
2685
|
+
"\u6BCF\u9875\u6570\u91CF": limit,
|
|
2686
|
+
"\u5C55\u793A\u5B57\u6BB5": displayedFields,
|
|
2687
|
+
"\u9879\u76EE\u72B6\u6001\u7EDF\u8BA1": (responseData?.matterStatusItems ?? []).map(toMatterStatusSummary),
|
|
2688
|
+
"\u9879\u76EE\u5217\u8868": projects.map((project) => toMatterSummary(project, selectedFields))
|
|
2689
|
+
});
|
|
2690
|
+
}
|
|
2691
|
+
async function runMatterDetail(options, sessionStore) {
|
|
2692
|
+
const matterId = options.id.trim();
|
|
2693
|
+
if (!matterId) {
|
|
2694
|
+
throw new Error("Missing matter id. Use: alpha-classic-cli matter detail --id <matterId>");
|
|
2695
|
+
}
|
|
2696
|
+
const config = await sessionStore.getConfig();
|
|
2697
|
+
const environment = getDefaultEnvironmentPreset();
|
|
2698
|
+
const client = new ApiClient({
|
|
2699
|
+
sessionStore,
|
|
2700
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
2701
|
+
timeoutMs: config.timeoutMs
|
|
2702
|
+
});
|
|
2703
|
+
const detailResponse = await client.request(
|
|
2704
|
+
"GET",
|
|
2705
|
+
`/matterserver/api/v2/matters/${encodeURIComponent(matterId)}`
|
|
2706
|
+
);
|
|
2707
|
+
if (detailResponse.resultCode && detailResponse.resultCode !== "1") {
|
|
2708
|
+
throw new Error(detailResponse.resultMess ?? "Matter detail request failed.");
|
|
2709
|
+
}
|
|
2710
|
+
const detailData = unwrapEnvelopeData2(detailResponse);
|
|
2711
|
+
const matter = detailData?.[0];
|
|
2712
|
+
if (!matter) {
|
|
2713
|
+
throw new Error("\u9879\u76EE\u4E0D\u5B58\u5728\u6216\u5F53\u524D\u7528\u6237\u65E0\u6743\u67E5\u770B\u3002");
|
|
2714
|
+
}
|
|
2715
|
+
const logLimit = clampLogLimit(options.logs ?? 5);
|
|
2716
|
+
const logs = logLimit ? await fetchMatterLogs(client, matterId, logLimit) : [];
|
|
2717
|
+
printSuccess({
|
|
2718
|
+
"\u9879\u76EE\u6982\u89C8": toMatterDetailSummary(matter),
|
|
2719
|
+
"\u6700\u8FD1\u52A8\u6001": logs.map(toMatterLogSummary)
|
|
2720
|
+
});
|
|
2721
|
+
}
|
|
2722
|
+
async function runMatterTaskList(options, sessionStore) {
|
|
2723
|
+
const matterId = options.matterId.trim();
|
|
2724
|
+
if (!matterId) {
|
|
2725
|
+
throw new Error("Missing matter id. Use: alpha-classic-cli matter task --id <matterId>");
|
|
2726
|
+
}
|
|
2727
|
+
const config = await sessionStore.getConfig();
|
|
2728
|
+
const environment = getDefaultEnvironmentPreset();
|
|
2729
|
+
const client = new ApiClient({
|
|
2730
|
+
sessionStore,
|
|
2731
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
2732
|
+
timeoutMs: config.timeoutMs
|
|
2733
|
+
});
|
|
2734
|
+
const page = clampPage2(options.page ?? 1);
|
|
2735
|
+
const limit = clampLimit2(options.limit ?? 20);
|
|
2736
|
+
const stateType = parseMatterTaskState(options.state);
|
|
2737
|
+
const type = parseMatterTaskType(options.type);
|
|
2738
|
+
const attentionType = parseMatterAttentionType(options.attention);
|
|
2739
|
+
const statusType = toMatterTaskStatusType(stateType);
|
|
2740
|
+
const response = await client.request(
|
|
2741
|
+
"GET",
|
|
2742
|
+
"/taskserver/api/v1/tasks/listTaskByMatter",
|
|
2743
|
+
{
|
|
2744
|
+
params: {
|
|
2745
|
+
matterId,
|
|
2746
|
+
statusType,
|
|
2747
|
+
pageIndex: page,
|
|
2748
|
+
pageSize: limit,
|
|
2749
|
+
searchSub: true
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
);
|
|
2753
|
+
if (response.isSuccess === false) {
|
|
2754
|
+
throw new Error(response.resultMsg ?? response.message ?? "Matter task list request failed.");
|
|
2755
|
+
}
|
|
2756
|
+
const responseData = unwrapEnvelopeData2(response);
|
|
2757
|
+
const pageData = response.result ?? responseData ?? {};
|
|
2758
|
+
const groups = pageData.data ?? [];
|
|
2759
|
+
const tasks = pageData.items ?? flattenMatterTaskGroups(groups);
|
|
2760
|
+
const firstMatter = tasks[0]?.matter;
|
|
2761
|
+
printSuccess({
|
|
2762
|
+
"\u9879\u76EEID": matterId,
|
|
2763
|
+
"\u9879\u76EE\u540D\u79F0": firstMatter?.name ?? tasks[0]?.matterName ?? "",
|
|
2764
|
+
"\u9879\u76EE\u7C7B\u578B": firstMatter?.matterType ?? "",
|
|
2765
|
+
"\u72B6\u6001": formatMatterTaskStateLabel(stateType),
|
|
2766
|
+
"\u5173\u6CE8": formatMatterAttentionLabel(attentionType),
|
|
2767
|
+
"\u7C7B\u578B": formatMatterTaskTypeLabel(type),
|
|
2768
|
+
"\u603B\u6570": pageData.totalCount ?? pageData.count ?? tasks.length,
|
|
2769
|
+
"\u9875\u7801": pageData.pageIndex ?? page,
|
|
2770
|
+
"\u6BCF\u9875\u6570\u91CF": pageData.pageSize ?? limit,
|
|
2771
|
+
"\u4EFB\u52A1\u5217\u8868": type === 1 ? groups.map(toMatterTaskGroupSummary) : tasks.map(toMatterTaskSummary)
|
|
2772
|
+
});
|
|
2773
|
+
}
|
|
2774
|
+
async function runMatterTaskDetail(options, sessionStore) {
|
|
2775
|
+
const taskId = options.id.trim();
|
|
2776
|
+
if (!taskId) {
|
|
2777
|
+
throw new Error("Missing task id. Use: alpha-classic-cli matter task-detail --id <taskId>");
|
|
2778
|
+
}
|
|
2779
|
+
const config = await sessionStore.getConfig();
|
|
2780
|
+
const environment = getDefaultEnvironmentPreset();
|
|
2781
|
+
const client = new ApiClient({
|
|
2782
|
+
sessionStore,
|
|
2783
|
+
apiBaseUrl: environment.apiBaseUrl,
|
|
2784
|
+
timeoutMs: config.timeoutMs
|
|
2785
|
+
});
|
|
2786
|
+
const commentsLimit = clampCommentLimit2(options.comments);
|
|
2787
|
+
const [detailResponse, checkItemResponse, attachmentResponse, timingResponse, commentResponse] = await Promise.all([
|
|
2788
|
+
client.request(
|
|
2789
|
+
"GET",
|
|
2790
|
+
`/taskserver/api/v1/tasks/${encodeURIComponent(taskId)}`
|
|
2791
|
+
),
|
|
2792
|
+
client.request(
|
|
2793
|
+
"GET",
|
|
2794
|
+
`/taskserver/api/v1/checkitem/${encodeURIComponent(taskId)}`
|
|
2795
|
+
),
|
|
2796
|
+
client.request(
|
|
2797
|
+
"GET",
|
|
2798
|
+
`/taskserver/api/v1/tasks/attachment/${encodeURIComponent(taskId)}`,
|
|
2799
|
+
{
|
|
2800
|
+
params: {
|
|
2801
|
+
pageIndex: 1,
|
|
2802
|
+
pageSize: 50
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
),
|
|
2806
|
+
client.request(
|
|
2807
|
+
"GET",
|
|
2808
|
+
`/taskserver/api/v2/timing/timing/task/${encodeURIComponent(taskId)}`,
|
|
2809
|
+
{
|
|
2810
|
+
params: {
|
|
2811
|
+
pageIndex: 1,
|
|
2812
|
+
pageSize: commentsLimit
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
),
|
|
2816
|
+
commentsLimit ? client.request(
|
|
2817
|
+
"GET",
|
|
2818
|
+
"/ilaw/api/v2/comment/queryCommentsAndDynamic",
|
|
2819
|
+
{
|
|
2820
|
+
params: {
|
|
2821
|
+
hostId: taskId,
|
|
2822
|
+
pageIndex: 1,
|
|
2823
|
+
pageSize: commentsLimit
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
) : Promise.resolve({
|
|
2827
|
+
succeed: true,
|
|
2828
|
+
result: { pageIndex: 1, pageSize: 0, totalCount: 0, items: [] }
|
|
2829
|
+
})
|
|
2830
|
+
]);
|
|
2831
|
+
if (detailResponse.isSuccess === false) {
|
|
2832
|
+
throw new Error(detailResponse.resultMsg ?? detailResponse.message ?? "Matter task detail request failed.");
|
|
2833
|
+
}
|
|
2834
|
+
if (checkItemResponse.isSuccess === false) {
|
|
2835
|
+
throw new Error(checkItemResponse.resultMsg ?? "Matter task check items request failed.");
|
|
2836
|
+
}
|
|
2837
|
+
if (attachmentResponse.isSuccess === false) {
|
|
2838
|
+
throw new Error(attachmentResponse.resultMsg ?? "Matter task attachments request failed.");
|
|
2839
|
+
}
|
|
2840
|
+
if (timingResponse.isSuccess === false) {
|
|
2841
|
+
throw new Error(timingResponse.resultMsg ?? "Matter task timing request failed.");
|
|
2842
|
+
}
|
|
2843
|
+
if (commentResponse.succeed === false) {
|
|
2844
|
+
throw new Error(commentResponse.message ?? commentResponse.detail ?? "Matter task comments request failed.");
|
|
2845
|
+
}
|
|
2846
|
+
const task = detailResponse.data;
|
|
2847
|
+
if (!task) {
|
|
2848
|
+
throw new Error("\u4EFB\u52A1\u4E0D\u5B58\u5728\u6216\u5F53\u524D\u7528\u6237\u65E0\u6743\u67E5\u770B\u3002");
|
|
2849
|
+
}
|
|
2850
|
+
const attachmentPage = attachmentResponse.data ?? {};
|
|
2851
|
+
const attachments = attachmentPage.data ?? attachmentPage.items ?? [];
|
|
2852
|
+
const attachmentDetails = await fetchDocumentDetailsForAttachments(client, attachments);
|
|
2853
|
+
const timingPage = timingResponse.data ?? {};
|
|
2854
|
+
const commentPage = commentResponse.result ?? {};
|
|
2855
|
+
printSuccess({
|
|
2856
|
+
"\u4EFB\u52A1\u6982\u89C8": toMatterTaskDetailSummary(task),
|
|
2857
|
+
"\u68C0\u67E5\u9879": (checkItemResponse.data ?? []).map(toMatterTaskCheckItemSummary),
|
|
2858
|
+
"\u9644\u4EF6": attachments.map(
|
|
2859
|
+
(attachment) => toMatterTaskAttachmentSummary(attachment, attachmentDetails.get(getAttachmentDocumentKey(attachment)))
|
|
2860
|
+
),
|
|
2861
|
+
"\u8BA1\u65F6": {
|
|
2862
|
+
"\u8BA1\u65F6\u603B\u65F6\u957F": formatTotalTiming(timingPage.timingSum ?? timingPage.allTimingSum ?? 0),
|
|
2863
|
+
"\u603B\u6570": timingPage.totalCount ?? (timingPage.items ?? timingPage.datas ?? []).length,
|
|
2864
|
+
"\u8BA1\u65F6\u5217\u8868": (timingPage.items ?? timingPage.datas ?? []).map(toMatterTaskTimingSummary)
|
|
2865
|
+
},
|
|
2866
|
+
"\u4EFB\u52A1\u52A8\u6001": {
|
|
2867
|
+
"\u603B\u6570": commentPage.totalCount ?? (commentPage.items ?? []).length,
|
|
2868
|
+
"\u9875\u7801": commentPage.pageIndex ?? 1,
|
|
2869
|
+
"\u6BCF\u9875\u6570\u91CF": commentPage.pageSize ?? commentsLimit,
|
|
2870
|
+
"\u52A8\u6001\u5217\u8868": (commentPage.items ?? []).map(toMatterTaskCommentSummary)
|
|
2871
|
+
}
|
|
2872
|
+
});
|
|
2873
|
+
}
|
|
2874
|
+
function buildMatterSearchBody(options) {
|
|
2875
|
+
const today = formatLocalDate(/* @__PURE__ */ new Date());
|
|
2876
|
+
const emptyRange = createEmptyTimeRange(today);
|
|
2877
|
+
const queryOrderPage = {
|
|
2878
|
+
order: {
|
|
2879
|
+
orderItems: [
|
|
2880
|
+
{ isAsc: false, property: "is_view" },
|
|
2881
|
+
{ isAsc: false, property: "matter_name" }
|
|
2882
|
+
]
|
|
2883
|
+
},
|
|
2884
|
+
page: {
|
|
2885
|
+
pageSize: options.limit,
|
|
2886
|
+
startIndex: options.page
|
|
2887
|
+
}
|
|
2888
|
+
};
|
|
2889
|
+
if (options.scope === "followed") {
|
|
2890
|
+
return {
|
|
2891
|
+
isView: true,
|
|
2892
|
+
matchedName: options.keyword.trim(),
|
|
2893
|
+
queryOrderPage
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
const body = {
|
|
2897
|
+
createUserIds: [],
|
|
2898
|
+
customerIds: [],
|
|
2899
|
+
customerOrAnd: false,
|
|
2900
|
+
departmentIds: [],
|
|
2901
|
+
belongIngOrAnd: false,
|
|
2902
|
+
matchedName: options.keyword.trim(),
|
|
2903
|
+
matterCases: [],
|
|
2904
|
+
matterCasesOrAnd: false,
|
|
2905
|
+
matterLevels: [],
|
|
2906
|
+
matterOwnerIds: [],
|
|
2907
|
+
matterStatusSet: options.status.values,
|
|
2908
|
+
memberOfRoles: [],
|
|
2909
|
+
memberRolesOrAnd: false,
|
|
2910
|
+
nowProcessIds: [],
|
|
2911
|
+
nowProcessOrAnd: false,
|
|
2912
|
+
subMatterTypes: [],
|
|
2913
|
+
serviceStartRangeTime: emptyRange,
|
|
2914
|
+
serviceEndRangeTime: emptyRange,
|
|
2915
|
+
filingDate: emptyRange,
|
|
2916
|
+
startMatterTime: emptyRange,
|
|
2917
|
+
endMatterTime: emptyRange,
|
|
2918
|
+
createTime: emptyRange,
|
|
2919
|
+
rangeOfTargetAmount: { min: null, max: null },
|
|
2920
|
+
dynamicStatus: false,
|
|
2921
|
+
oppositePeopleName: "",
|
|
2922
|
+
attorneyIds: [],
|
|
2923
|
+
attorneyOrAnd: false,
|
|
2924
|
+
undertakeIds: [],
|
|
2925
|
+
startUserIds: [],
|
|
2926
|
+
totalContractAmount: { min: null, max: null },
|
|
2927
|
+
totalContractTargetAmount: { min: null, max: null },
|
|
2928
|
+
undertakeOrAnd: false,
|
|
2929
|
+
itemOrAnd: false,
|
|
2930
|
+
queryOrderPage,
|
|
2931
|
+
matterStageIds: [],
|
|
2932
|
+
expandMatterSearchParamVO: {
|
|
2933
|
+
inputSelect: {},
|
|
2934
|
+
selectBox: {},
|
|
2935
|
+
associateCustomer: {},
|
|
2936
|
+
associateMember: {},
|
|
2937
|
+
associateDepartment: {},
|
|
2938
|
+
associateMatter: {},
|
|
2939
|
+
timeSelect: {}
|
|
2940
|
+
}
|
|
2941
|
+
};
|
|
2942
|
+
if (options.scope === "joined" && options.joinMember) {
|
|
2943
|
+
body.memberOfRoles = [
|
|
2944
|
+
{
|
|
2945
|
+
userId: options.joinMember.userId,
|
|
2946
|
+
roleIds: options.joinMember.roleIds
|
|
2947
|
+
}
|
|
2948
|
+
];
|
|
2949
|
+
}
|
|
2950
|
+
return body;
|
|
2951
|
+
}
|
|
2952
|
+
async function fetchMatterListSelectedFields(client) {
|
|
2953
|
+
const response = await client.request(
|
|
2954
|
+
"GET",
|
|
2955
|
+
"/matterserver/api/v1/customFields/dashboard/MATTER_LIST"
|
|
2956
|
+
);
|
|
2957
|
+
if (response.isSuccess === false) {
|
|
2958
|
+
throw new Error(response.resultMsg ?? "Matter list custom fields request failed.");
|
|
2959
|
+
}
|
|
2960
|
+
const data = unwrapEnvelopeData2(response);
|
|
2961
|
+
return data?.selectedFields ?? [];
|
|
2962
|
+
}
|
|
2963
|
+
function getMatterListDisplayedFields(selectedFields) {
|
|
2964
|
+
return [
|
|
2965
|
+
"\u9879\u76EE\u540D\u79F0",
|
|
2966
|
+
"\u9879\u76EE\u72B6\u6001",
|
|
2967
|
+
"\u9879\u76EE\u5BA2\u6237",
|
|
2968
|
+
"\u9879\u76EE\u7C7B\u578B",
|
|
2969
|
+
...selectedFields.map((field) => formatCustomFieldLabel(field)).filter(Boolean)
|
|
2970
|
+
];
|
|
2971
|
+
}
|
|
2972
|
+
function toMatterSummary(item, selectedFields) {
|
|
2973
|
+
const summary = {
|
|
2974
|
+
"\u9879\u76EEID": item.pkId ?? "",
|
|
2975
|
+
"\u9879\u76EE\u540D\u79F0": item.name ?? "",
|
|
2976
|
+
"\u9879\u76EE\u72B6\u6001": item.statusName || formatMatterStatus(toNumber(item.status)),
|
|
2977
|
+
"\u9879\u76EE\u5BA2\u6237": (item.clients ?? []).map((client) => client.clientName ?? "").filter(Boolean),
|
|
2978
|
+
"\u9879\u76EE\u7C7B\u578B": formatMatterType(item)
|
|
2979
|
+
};
|
|
2980
|
+
for (const field of selectedFields) {
|
|
2981
|
+
const label = formatCustomFieldLabel(field);
|
|
2982
|
+
if (!label || label in summary) {
|
|
2983
|
+
continue;
|
|
2984
|
+
}
|
|
2985
|
+
summary[label] = formatMatterListFieldValue(item, field);
|
|
2986
|
+
}
|
|
2987
|
+
return summary;
|
|
2988
|
+
}
|
|
2989
|
+
function toMatterStatusSummary(item) {
|
|
2990
|
+
return {
|
|
2991
|
+
"\u72B6\u6001": formatMatterStatus(item.matterStatus),
|
|
2992
|
+
"\u72B6\u6001\u7801": item.matterStatus ?? null,
|
|
2993
|
+
"\u6570\u91CF": item.count ?? 0
|
|
2994
|
+
};
|
|
2995
|
+
}
|
|
2996
|
+
function toMatterDetailSummary(item) {
|
|
2997
|
+
const status = typeof item.status === "number" ? item.status : void 0;
|
|
2998
|
+
const level = typeof item.level === "number" ? item.level : void 0;
|
|
2999
|
+
return {
|
|
3000
|
+
"\u9879\u76EEID": item.pkId ?? "",
|
|
3001
|
+
"\u9879\u76EE\u540D\u79F0": item.name ?? "",
|
|
3002
|
+
"\u9879\u76EE\u7F16\u53F7": item.matterNo ?? "",
|
|
3003
|
+
"\u9879\u76EE\u72B6\u6001": item.statusName || formatMatterStatus(status),
|
|
3004
|
+
"\u9879\u76EE\u7C7B\u578B": [item.matterTypeName, item.childMatterTypeName].filter(Boolean).join(" / "),
|
|
3005
|
+
"\u9879\u76EE\u7B49\u7EA7": formatMatterLevel2(level),
|
|
3006
|
+
"\u5BA2\u6237": formatContacts(item.clients),
|
|
3007
|
+
"\u5176\u4ED6\u5F53\u4E8B\u4EBA": formatContacts([...item.litigants ?? [], ...item.relevants ?? []]),
|
|
3008
|
+
"\u6240\u5C5E": formatMatterBelong(item),
|
|
3009
|
+
"\u6848\u6E90\u5F8B\u5E08": formatAttorneys(item.attorneys ?? item.originatingAttorneys),
|
|
3010
|
+
"\u627F\u529E\u5F8B\u5E08": formatAttorneys(item.undertakeAttorneys),
|
|
3011
|
+
"\u4E3B\u529E\u5F8B\u5E08": formatAttorneys(item.responsibleAttorneys),
|
|
3012
|
+
"\u534F\u529E\u5F8B\u5E08": formatAttorneys(item.assistAttorneys),
|
|
3013
|
+
"\u9879\u76EE\u6210\u5458": formatMembers(item.members),
|
|
3014
|
+
"\u6848\u7531": item.matterCaseName ?? "",
|
|
3015
|
+
"\u4EE3\u7406\u5BA1\u7EA7": item.caseProcessName ?? "",
|
|
3016
|
+
"\u670D\u52A1\u5185\u5BB9": item.lawFieldName ?? "",
|
|
3017
|
+
"\u5F00\u59CB\u65E5\u671F": item.beginDate ?? "",
|
|
3018
|
+
"\u7ED3\u675F\u65E5\u671F": item.endDate ?? "",
|
|
3019
|
+
"\u7ACB\u9879\u65F6\u95F4": item.startMatterTime ?? item.openDate ?? "",
|
|
3020
|
+
"\u7ED3\u9879\u65F6\u95F4": item.endMatterTime ?? item.closeDate ?? "",
|
|
3021
|
+
"\u5F52\u6863\u65E5\u671F": item.filingDate ?? "",
|
|
3022
|
+
"\u5F52\u6863\u7F16\u53F7": item.filingNo ?? "",
|
|
3023
|
+
"\u9879\u76EE\u8BE6\u60C5": item.remark ?? ""
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
async function fetchMatterLogs(client, matterId, limit) {
|
|
3027
|
+
const response = await client.request(
|
|
3028
|
+
"GET",
|
|
3029
|
+
`/notice/v1/dynamics/matters/${encodeURIComponent(matterId)}`
|
|
3030
|
+
);
|
|
3031
|
+
if (response.isSuccess === false) {
|
|
3032
|
+
throw new Error(response.resultMsg ?? "Matter logs request failed.");
|
|
3033
|
+
}
|
|
3034
|
+
const data = unwrapEnvelopeData2(response);
|
|
3035
|
+
return (data ?? []).slice(0, limit);
|
|
3036
|
+
}
|
|
3037
|
+
async function fetchDocumentDetailsForAttachments(client, attachments) {
|
|
3038
|
+
const directories = /* @__PURE__ */ new Map();
|
|
3039
|
+
for (const attachment of attachments) {
|
|
3040
|
+
const repoId = getAttachmentRepoId(attachment);
|
|
3041
|
+
const filePath = getAttachmentPath(attachment);
|
|
3042
|
+
if (!repoId || !filePath) {
|
|
3043
|
+
continue;
|
|
3044
|
+
}
|
|
3045
|
+
const directoryPath = getDirectoryPath(filePath);
|
|
3046
|
+
directories.set(`${repoId}|${directoryPath}`, { repoId, path: directoryPath });
|
|
3047
|
+
}
|
|
3048
|
+
const filesByDirectory = await Promise.all(
|
|
3049
|
+
[...directories.values()].map(async (directory) => {
|
|
3050
|
+
const response = await client.request(
|
|
3051
|
+
"GET",
|
|
3052
|
+
"/document-engine/api/v1/dir/list",
|
|
3053
|
+
{
|
|
3054
|
+
params: {
|
|
3055
|
+
repoId: directory.repoId,
|
|
3056
|
+
p: directory.path
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
);
|
|
3060
|
+
if (response.isSuccess === false) {
|
|
3061
|
+
throw new Error(response.resultMsg ?? "Document file detail request failed.");
|
|
3062
|
+
}
|
|
3063
|
+
const data = unwrapEnvelopeData2(response);
|
|
3064
|
+
return { directory, files: data ?? [] };
|
|
3065
|
+
})
|
|
3066
|
+
);
|
|
3067
|
+
const details = /* @__PURE__ */ new Map();
|
|
3068
|
+
for (const attachment of attachments) {
|
|
3069
|
+
const repoId = getAttachmentRepoId(attachment);
|
|
3070
|
+
const filePath = getAttachmentPath(attachment);
|
|
3071
|
+
if (!repoId || !filePath) {
|
|
3072
|
+
continue;
|
|
3073
|
+
}
|
|
3074
|
+
const directoryPath = getDirectoryPath(filePath);
|
|
3075
|
+
const directoryFiles = filesByDirectory.find(
|
|
3076
|
+
(item) => item.directory.repoId === repoId && item.directory.path === directoryPath
|
|
3077
|
+
)?.files ?? [];
|
|
3078
|
+
const fileId = getAttachmentFileId(attachment);
|
|
3079
|
+
const fileName = getFileNameFromPath(filePath);
|
|
3080
|
+
const match = directoryFiles.find((file) => fileId ? file.id === fileId : file.name === fileName);
|
|
3081
|
+
if (match) {
|
|
3082
|
+
details.set(getAttachmentDocumentKey(attachment), match);
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
return details;
|
|
3086
|
+
}
|
|
3087
|
+
function toMatterLogSummary(item) {
|
|
3088
|
+
const content = parseLogContent(item.content);
|
|
3089
|
+
return {
|
|
3090
|
+
"\u52A8\u6001ID": item.id ?? "",
|
|
3091
|
+
"\u7C7B\u578B": item.type ?? "",
|
|
3092
|
+
"\u65F6\u95F4": item.create_time ?? item.createTime ?? "",
|
|
3093
|
+
"\u5185\u5BB9": content
|
|
3094
|
+
};
|
|
3095
|
+
}
|
|
3096
|
+
function flattenMatterTaskGroups(groups) {
|
|
3097
|
+
return groups.flatMap(
|
|
3098
|
+
(group) => (group.tasks ?? []).map((task) => ({
|
|
3099
|
+
...task,
|
|
3100
|
+
parentName: task.parentName ?? group.name,
|
|
3101
|
+
taskGroupName: task.taskGroupName ?? group.name
|
|
3102
|
+
}))
|
|
3103
|
+
);
|
|
3104
|
+
}
|
|
3105
|
+
function toMatterTaskGroupSummary(group) {
|
|
3106
|
+
return {
|
|
3107
|
+
"\u4EFB\u52A1ID": group.id ?? "",
|
|
3108
|
+
"\u4EFB\u52A1\u540D\u79F0": group.name ?? "",
|
|
3109
|
+
"\u4EFB\u52A1\u7EC4": "",
|
|
3110
|
+
"\u72B6\u6001": group.state === 1 ? "\u5DF2\u5B8C\u6210" : "\u672A\u5B8C\u6210",
|
|
3111
|
+
"\u8D1F\u8D23\u4EBA": [],
|
|
3112
|
+
"\u53C2\u4E0E\u4EBA": [],
|
|
3113
|
+
"\u5230\u671F\u65F6\u95F4": "",
|
|
3114
|
+
"\u5F00\u59CB\u65F6\u95F4": "",
|
|
3115
|
+
"\u7ED3\u675F\u65F6\u95F4": "",
|
|
3116
|
+
"\u8BA1\u65F6\u603B\u65F6\u957F": "",
|
|
3117
|
+
"\u68C0\u67E5\u9879": {
|
|
3118
|
+
"\u603B\u6570": 0,
|
|
3119
|
+
"\u5DF2\u5B8C\u6210": 0
|
|
3120
|
+
},
|
|
3121
|
+
"\u8BC4\u8BBA\u6570": 0,
|
|
3122
|
+
"\u9644\u4EF6\u6570": 0,
|
|
3123
|
+
"\u662F\u5426\u5173\u6CE8": false,
|
|
3124
|
+
"\u65F6\u95F4\u7C7B\u578B": "",
|
|
3125
|
+
"\u5168\u5929\u7C7B\u578B": "",
|
|
3126
|
+
"\u5DE5\u4F5C\u7C7B\u578B": "",
|
|
3127
|
+
"\u91CD\u590D\u89C4\u5219": "",
|
|
3128
|
+
"\u4EFB\u52A1\u7EDF\u8BA1": {
|
|
3129
|
+
"\u672A\u5B8C\u6210": group.unfinishedTaskCount ?? 0,
|
|
3130
|
+
"\u5DF2\u5B8C\u6210": group.finishedTaskCount ?? 0,
|
|
3131
|
+
"\u5DF2\u5220\u9664": group.deletedTaskCount ?? 0
|
|
3132
|
+
}
|
|
3133
|
+
};
|
|
3134
|
+
}
|
|
3135
|
+
function toMatterTaskSummary(item) {
|
|
3136
|
+
return {
|
|
3137
|
+
"\u4EFB\u52A1ID": item.id ?? "",
|
|
3138
|
+
"\u4EFB\u52A1\u540D\u79F0": item.name ?? "",
|
|
3139
|
+
"\u4EFB\u52A1\u7EC4": item.parentName ?? item.taskGroupName ?? "",
|
|
3140
|
+
"\u72B6\u6001": item.state === true || item.state === 1 ? "\u5DF2\u5B8C\u6210" : "\u672A\u5B8C\u6210",
|
|
3141
|
+
"\u8D1F\u8D23\u4EBA": formatTaskUsers(item.assignUser ? [item.assignUser] : []),
|
|
3142
|
+
"\u53C2\u4E0E\u4EBA": formatTaskUsers(item.attendeeUsers ?? item.attendees),
|
|
3143
|
+
"\u5230\u671F\u65F6\u95F4": formatDateTime2(item.dueTime),
|
|
3144
|
+
"\u5F00\u59CB\u65F6\u95F4": formatDateTime2(item.startTime),
|
|
3145
|
+
"\u7ED3\u675F\u65F6\u95F4": formatDateTime2(item.endTime),
|
|
3146
|
+
"\u8BA1\u65F6\u603B\u65F6\u957F": formatTotalTiming(item.timingSum),
|
|
3147
|
+
"\u68C0\u67E5\u9879": {
|
|
3148
|
+
"\u603B\u6570": item.itemCount ?? 0,
|
|
3149
|
+
"\u5DF2\u5B8C\u6210": item.doneItemCount ?? item.completedItemCount ?? 0
|
|
3150
|
+
},
|
|
3151
|
+
"\u8BC4\u8BBA\u6570": item.commentCount ?? 0,
|
|
3152
|
+
"\u9644\u4EF6\u6570": item.attachmentCount ?? 0,
|
|
3153
|
+
"\u662F\u5426\u5173\u6CE8": item.attentioned === 1 || item.favorite === true || item.favorite === 1,
|
|
3154
|
+
"\u65F6\u95F4\u7C7B\u578B": formatMatterTaskTimeType(item.timeType),
|
|
3155
|
+
"\u5168\u5929\u7C7B\u578B": formatMatterTaskDayType(item.dayType),
|
|
3156
|
+
"\u5DE5\u4F5C\u7C7B\u578B": formatTaskWorkType(item.workType),
|
|
3157
|
+
"\u91CD\u590D\u89C4\u5219": formatTaskRepeatSetting(item.repeatSetting)
|
|
3158
|
+
};
|
|
3159
|
+
}
|
|
3160
|
+
function toMatterTaskDetailSummary(item) {
|
|
3161
|
+
return {
|
|
3162
|
+
"\u4EFB\u52A1ID": item.id ?? "",
|
|
3163
|
+
"\u4EFB\u52A1\u540D\u79F0": item.name ?? "",
|
|
3164
|
+
"\u9879\u76EEID": item.matterId ?? "",
|
|
3165
|
+
"\u9879\u76EE\u540D\u79F0": item.matterName ?? item.matter?.name ?? "",
|
|
3166
|
+
"\u4EFB\u52A1\u7EC4": item.taskGroupName ?? item.parentName ?? "",
|
|
3167
|
+
"\u72B6\u6001": item.state === true || item.state === 1 ? "\u5DF2\u5B8C\u6210" : "\u672A\u5B8C\u6210",
|
|
3168
|
+
"\u662F\u5426\u6709\u6548": item.valid === true || item.valid === 1,
|
|
3169
|
+
"\u521B\u5EFA\u4EBA": formatTaskUser(item.createUser),
|
|
3170
|
+
"\u8D1F\u8D23\u4EBA": formatTaskUsers(item.assignUser ? [item.assignUser] : []),
|
|
3171
|
+
"\u53C2\u4E0E\u4EBA": formatTaskUsers(item.attendeeUsers ?? item.attendees),
|
|
3172
|
+
"\u5F00\u59CB\u65F6\u95F4": formatDateTime2(item.startTime),
|
|
3173
|
+
"\u5230\u671F\u65F6\u95F4": formatDateTime2(item.dueTime),
|
|
3174
|
+
"\u7ED3\u675F\u65F6\u95F4": formatDateTime2(item.endTime),
|
|
3175
|
+
"\u5B8C\u6210\u65F6\u95F4": formatDateTime2(item.finishTime),
|
|
3176
|
+
"\u4EFB\u52A1\u8BE6\u60C5": item.detail ?? "",
|
|
3177
|
+
"\u68C0\u67E5\u9879": {
|
|
3178
|
+
"\u603B\u6570": item.itemCount ?? 0,
|
|
3179
|
+
"\u5DF2\u5B8C\u6210": item.doneItemCount ?? item.completedItemCount ?? 0
|
|
3180
|
+
},
|
|
3181
|
+
"\u5B50\u4EFB\u52A1": {
|
|
3182
|
+
"\u603B\u6570": item.subtaskCount ?? 0,
|
|
3183
|
+
"\u5DF2\u5B8C\u6210": item.completedSubtaskCount ?? 0,
|
|
3184
|
+
"\u5DF2\u5220\u9664": item.deletedSubtaskCount ?? 0
|
|
3185
|
+
},
|
|
3186
|
+
"\u8BC4\u8BBA\u6570": item.commentCount ?? 0,
|
|
3187
|
+
"\u52A8\u6001\u6570": item.dynamicCount ?? 0,
|
|
3188
|
+
"\u9644\u4EF6\u6570": item.attachmentCount ?? 0,
|
|
3189
|
+
"\u4FDD\u9669\u7BB1\u6587\u4EF6\u6570": item.safeBoxFileCount ?? 0,
|
|
3190
|
+
"\u8BA1\u65F6\u603B\u65F6\u957F": formatTotalTiming(item.timingSum),
|
|
3191
|
+
"\u662F\u5426\u5173\u6CE8": item.attentioned === 1 || item.favorite === true || item.favorite === 1,
|
|
3192
|
+
"\u65F6\u95F4\u7C7B\u578B": formatMatterTaskTimeType(item.timeType),
|
|
3193
|
+
"\u5168\u5929\u7C7B\u578B": formatMatterTaskDayType(item.dayType),
|
|
3194
|
+
"\u5DE5\u4F5C\u7C7B\u578B": formatTaskWorkType(item.workType),
|
|
3195
|
+
"\u91CD\u590D\u89C4\u5219": formatTaskRepeatSetting(item.repeatSetting)
|
|
3196
|
+
};
|
|
3197
|
+
}
|
|
3198
|
+
function toMatterTaskCheckItemSummary(item) {
|
|
3199
|
+
return {
|
|
3200
|
+
"\u68C0\u67E5\u9879ID": item.id ?? "",
|
|
3201
|
+
"\u5185\u5BB9": item.name ?? item.content ?? "",
|
|
3202
|
+
"\u72B6\u6001": item.state === true || item.state === 1 || item.completed ? "\u5DF2\u5B8C\u6210" : "\u672A\u5B8C\u6210",
|
|
3203
|
+
"\u521B\u5EFA\u65F6\u95F4": formatDateTime2(item.gmtCreate),
|
|
3204
|
+
"\u66F4\u65B0\u65F6\u95F4": formatDateTime2(item.gmtModified)
|
|
3205
|
+
};
|
|
3206
|
+
}
|
|
3207
|
+
function toMatterTaskAttachmentSummary(item, detail) {
|
|
3208
|
+
const path4 = getAttachmentPath(item);
|
|
3209
|
+
return {
|
|
3210
|
+
"\u6587\u4EF6\u540D": detail?.name ?? item.fileName ?? item.name ?? getFileNameFromPath(path4),
|
|
3211
|
+
"\u5927\u5C0F": detail?.size ?? item.fileSize ?? item.size ?? ""
|
|
3212
|
+
};
|
|
3213
|
+
}
|
|
3214
|
+
function toMatterTaskTimingSummary(item) {
|
|
3215
|
+
return {
|
|
3216
|
+
"\u8BA1\u65F6ID": item.id ?? "",
|
|
3217
|
+
"\u8BA1\u65F6\u4EBA": item.userName ?? item.user?.userName ?? item.user?.name ?? "",
|
|
3218
|
+
"\u5F00\u59CB\u65F6\u95F4": formatDateTime2(item.startTime),
|
|
3219
|
+
"\u7ED3\u675F\u65F6\u95F4": formatDateTime2(item.endTime),
|
|
3220
|
+
"\u8BA1\u65F6\u65F6\u957F": formatTotalTiming(item.timingSum),
|
|
3221
|
+
"\u5DE5\u4F5C\u7C7B\u578B": item.workType?.name ?? ""
|
|
3222
|
+
};
|
|
3223
|
+
}
|
|
3224
|
+
function toMatterTaskCommentSummary(item) {
|
|
3225
|
+
return {
|
|
3226
|
+
"\u52A8\u6001ID": item.id ?? "",
|
|
3227
|
+
"\u7C7B\u578B": formatTaskCommentType(item.concreteType),
|
|
3228
|
+
"\u64CD\u4F5C\u4EBA": item.createUser?.userName ?? item.createUser?.name ?? "",
|
|
3229
|
+
"\u5185\u5BB9": item.content ?? item.comment ?? "",
|
|
3230
|
+
"\u65F6\u95F4": formatDateTime2(item.createTime),
|
|
3231
|
+
"\u76F8\u5BF9\u65F6\u95F4": item.createTimeFormat ?? ""
|
|
3232
|
+
};
|
|
3233
|
+
}
|
|
3234
|
+
function parseLogContent(content) {
|
|
3235
|
+
if (!content) {
|
|
3236
|
+
return "";
|
|
3237
|
+
}
|
|
3238
|
+
try {
|
|
3239
|
+
const parsed = JSON.parse(content);
|
|
3240
|
+
if (parsed && typeof parsed === "object" && "content" in parsed) {
|
|
3241
|
+
const inner = parsed.content;
|
|
3242
|
+
if (typeof inner === "string") {
|
|
3243
|
+
try {
|
|
3244
|
+
return JSON.parse(inner);
|
|
3245
|
+
} catch {
|
|
3246
|
+
return inner;
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
return parsed;
|
|
3251
|
+
} catch {
|
|
3252
|
+
return content;
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
function formatContacts(contacts) {
|
|
3256
|
+
return (contacts ?? []).map((contact) => {
|
|
3257
|
+
const name = contact.contactName ?? "";
|
|
3258
|
+
const deleted = contact.isDeleted ? "\uFF08\u5DF2\u5220\u9664\uFF09" : "";
|
|
3259
|
+
const position = "customerPositionName" in contact && contact.customerPositionName ? `\uFF08${contact.customerPositionName}\uFF09` : "";
|
|
3260
|
+
return `${name}${position}${deleted}`;
|
|
3261
|
+
}).filter(Boolean);
|
|
3262
|
+
}
|
|
3263
|
+
function formatAttorneys(attorneys) {
|
|
3264
|
+
return (attorneys ?? []).map((attorney) => attorney.attorneyName ?? "").filter(Boolean);
|
|
3265
|
+
}
|
|
3266
|
+
function formatMembers(members) {
|
|
3267
|
+
return (members ?? []).map((member) => {
|
|
3268
|
+
const role = member.roleName ? `\uFF08${member.roleName}\uFF09` : "";
|
|
3269
|
+
return `${member.userName ?? ""}${role}`;
|
|
3270
|
+
}).filter(Boolean);
|
|
3271
|
+
}
|
|
3272
|
+
function formatMatterBelong(item) {
|
|
3273
|
+
if (item.matterOwnerName) {
|
|
3274
|
+
return `${item.matterOwnerName}\uFF08\u4E2A\u4EBA\u9879\u76EE\uFF09`;
|
|
3275
|
+
}
|
|
3276
|
+
return (item.groups ?? []).map((group) => group.name ?? "").filter(Boolean).join("\uFF0C");
|
|
3277
|
+
}
|
|
3278
|
+
function formatMatterStatus(status) {
|
|
3279
|
+
switch (status) {
|
|
3280
|
+
case 0:
|
|
3281
|
+
return "\u9884\u7ACB\u9879";
|
|
3282
|
+
case 2:
|
|
3283
|
+
return "\u8FDB\u884C\u4E2D";
|
|
3284
|
+
case 4:
|
|
3285
|
+
return "\u5DF2\u5B8C\u7ED3";
|
|
3286
|
+
case 6:
|
|
3287
|
+
return "\u5DF2\u5F52\u6863";
|
|
3288
|
+
case 7:
|
|
3289
|
+
return "\u5DF2\u6401\u7F6E";
|
|
3290
|
+
default:
|
|
3291
|
+
return status === void 0 ? "" : `\u672A\u77E5\u72B6\u6001(${status})`;
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
function formatMatterType(item) {
|
|
3295
|
+
return [item.matterTypeName, item.childrenMatterTypeName].filter(Boolean).join(" / ");
|
|
3296
|
+
}
|
|
3297
|
+
function formatCustomFieldLabel(field) {
|
|
3298
|
+
return field.customFieldValue || field.customFieldName || field.customFieldKey || "";
|
|
3299
|
+
}
|
|
3300
|
+
function formatMatterListFieldValue(item, field) {
|
|
3301
|
+
if (String(field.showType) === "4") {
|
|
3302
|
+
return formatFallbackValue(item.expandMatters?.[formatCustomFieldLabel(field)]);
|
|
3303
|
+
}
|
|
3304
|
+
switch (field.customFieldKey) {
|
|
3305
|
+
case "matterDynamicContent":
|
|
3306
|
+
return formatLatestDynamic(item);
|
|
3307
|
+
case "matterNo":
|
|
3308
|
+
return item.matterNo ?? "";
|
|
3309
|
+
case "sealCount":
|
|
3310
|
+
return item.sealCount ?? "";
|
|
3311
|
+
case "startMatterTime":
|
|
3312
|
+
return formatDateOnly(item.startMatterTime);
|
|
3313
|
+
case "totalTiming":
|
|
3314
|
+
return formatTotalTiming(item.sumTime);
|
|
3315
|
+
case "task":
|
|
3316
|
+
return `${(item.allTask ?? 0) - (item.unfinishTask ?? 0)} / ${item.allTask ?? 0}`;
|
|
3317
|
+
case "matterLevel":
|
|
3318
|
+
return formatMatterLevel2(item.matterLevel);
|
|
3319
|
+
case "endMatterTime":
|
|
3320
|
+
return formatDateOnly(item.endMatterTime);
|
|
3321
|
+
case "filingDate":
|
|
3322
|
+
return formatDateOnly(item.filingDate);
|
|
3323
|
+
case "serviceStartRangeTime":
|
|
3324
|
+
return formatDateOnly(item.serviceStartRangeTime);
|
|
3325
|
+
case "serviceEndRangeTime":
|
|
3326
|
+
return formatDateOnly(item.serviceEndRangeTime);
|
|
3327
|
+
case "matterOwner":
|
|
3328
|
+
return formatNamedItems(item.matterOwners, "ownerName");
|
|
3329
|
+
case "matterSourceLawyer":
|
|
3330
|
+
return formatNamedItems(item.matterSourceLawyer, "userName");
|
|
3331
|
+
case "matterReasonMessage":
|
|
3332
|
+
return item.matterReasonMessage?.length ? item.matterReasonMessage.join("\uFF0C") : "";
|
|
3333
|
+
case "startUserName":
|
|
3334
|
+
return item.startUserName ?? "";
|
|
3335
|
+
case "courtTime":
|
|
3336
|
+
return formatNamedItems(item.processEsEntities, "courtTime");
|
|
3337
|
+
case "nowProcessName":
|
|
3338
|
+
return [item.legalTypeName, item.caseProcessName].filter(Boolean).join(" ");
|
|
3339
|
+
case "matterMembers":
|
|
3340
|
+
return formatNamedItems(item.members, "userName");
|
|
3341
|
+
case "undertakeLaywer":
|
|
3342
|
+
return formatNamedItems(item.undertakeLaywer, "userName");
|
|
3343
|
+
case "otherParty":
|
|
3344
|
+
return formatNamedItems(item.otherParty, "userName");
|
|
3345
|
+
case "contractTargetAmount":
|
|
3346
|
+
return formatFallbackValue(item.financeDTO?.contractTargetAmount);
|
|
3347
|
+
case "contractTotal":
|
|
3348
|
+
return formatFallbackValue(item.financeDTO?.contractTotal);
|
|
3349
|
+
case "matterRemark":
|
|
3350
|
+
return item.matterRemark ?? "";
|
|
3351
|
+
case "billTotal":
|
|
3352
|
+
return formatFallbackValue(item.financeDTO?.billTotal);
|
|
3353
|
+
case "residueIncomeTotal":
|
|
3354
|
+
return formatFallbackValue(item.financeDTO?.residueIncomeTotal);
|
|
3355
|
+
case "spendTotal":
|
|
3356
|
+
return formatFallbackValue(item.financeDTO?.spendTotal);
|
|
3357
|
+
case "invoiceTotal":
|
|
3358
|
+
return formatFallbackValue(item.financeDTO?.invoiceTotal);
|
|
3359
|
+
case "incomeTotal":
|
|
3360
|
+
return formatFallbackValue(item.financeDTO?.incomeTotal);
|
|
3361
|
+
case "invoiceNo":
|
|
3362
|
+
return formatFallbackValue(item.financeDTO?.invoiceNo);
|
|
3363
|
+
case "hasRiskCharge":
|
|
3364
|
+
return formatFallbackValue(item.financeDTO?.hasRiskCharge);
|
|
3365
|
+
case "filingNo":
|
|
3366
|
+
return item.filingNo ?? "";
|
|
3367
|
+
case "process":
|
|
3368
|
+
return formatNamedItems(item.processEsEntities, "processName");
|
|
3369
|
+
case "processCourse":
|
|
3370
|
+
return formatNamedItems(item.processEsEntities, "court");
|
|
3371
|
+
default:
|
|
3372
|
+
return formatFallbackValue(field.customFieldKey ? item[field.customFieldKey] : void 0);
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
function formatLatestDynamic(item) {
|
|
3376
|
+
const dynamic = item.matterDynamicContent;
|
|
3377
|
+
const dynamicText = [dynamic?.content, dynamic?.taskName, dynamic?.actionTime].filter(Boolean).join(" ");
|
|
3378
|
+
return dynamicText || dynamic?.description || dynamic?.title || "\u4E00\u4E2A\u6708\u5185\u65E0\u52A8\u6001";
|
|
3379
|
+
}
|
|
3380
|
+
function formatNamedItems(items, key) {
|
|
3381
|
+
return (items ?? []).map((item) => item[key]).filter((value) => value !== void 0 && value !== null && value !== "").map(String).join("\uFF0C");
|
|
3382
|
+
}
|
|
3383
|
+
function formatFallbackValue(value) {
|
|
3384
|
+
if (value === void 0 || value === null) {
|
|
3385
|
+
return "";
|
|
3386
|
+
}
|
|
3387
|
+
if (Array.isArray(value)) {
|
|
3388
|
+
return value.map((item) => {
|
|
3389
|
+
if (item && typeof item === "object") {
|
|
3390
|
+
const record = item;
|
|
3391
|
+
return record.name ?? record.userName ?? record.ownerName ?? record.clientName ?? record.contactName ?? "";
|
|
3392
|
+
}
|
|
3393
|
+
return item;
|
|
3394
|
+
}).filter((item) => item !== "").join("\uFF0C");
|
|
3395
|
+
}
|
|
3396
|
+
return value;
|
|
3397
|
+
}
|
|
3398
|
+
function formatDateOnly(value) {
|
|
3399
|
+
const formatted = formatDateTime2(value);
|
|
3400
|
+
return formatted ? formatted.slice(0, 10) : "";
|
|
3401
|
+
}
|
|
3402
|
+
function formatTotalTiming(milliseconds) {
|
|
3403
|
+
if (!milliseconds || milliseconds <= 0) {
|
|
3404
|
+
return "0\u5C0F\u65F6";
|
|
3405
|
+
}
|
|
3406
|
+
const hours = milliseconds / 36e5;
|
|
3407
|
+
return `${Number(hours.toFixed(2))}\u5C0F\u65F6`;
|
|
3408
|
+
}
|
|
3409
|
+
function formatDateTime2(value) {
|
|
3410
|
+
if (value === void 0 || value === null || value === "") {
|
|
3411
|
+
return "";
|
|
3412
|
+
}
|
|
3413
|
+
const date = parseDateTime2(value);
|
|
3414
|
+
if (!date) {
|
|
3415
|
+
return String(value);
|
|
3416
|
+
}
|
|
3417
|
+
const year = date.getFullYear();
|
|
3418
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
3419
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
3420
|
+
const hour = String(date.getHours()).padStart(2, "0");
|
|
3421
|
+
const minute = String(date.getMinutes()).padStart(2, "0");
|
|
3422
|
+
const second = String(date.getSeconds()).padStart(2, "0");
|
|
3423
|
+
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
|
3424
|
+
}
|
|
3425
|
+
function toNumber(value) {
|
|
3426
|
+
if (typeof value === "number") {
|
|
3427
|
+
return value;
|
|
3428
|
+
}
|
|
3429
|
+
if (typeof value === "string" && value.trim()) {
|
|
3430
|
+
const parsed = Number.parseInt(value, 10);
|
|
3431
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
3432
|
+
}
|
|
3433
|
+
return void 0;
|
|
3434
|
+
}
|
|
3435
|
+
function formatMatterLevel2(level) {
|
|
3436
|
+
switch (level) {
|
|
3437
|
+
case 1:
|
|
3438
|
+
return "\u65E0\u7B49\u7EA7";
|
|
3439
|
+
case 2:
|
|
3440
|
+
return "\u4F4E";
|
|
3441
|
+
case 3:
|
|
3442
|
+
return "\u4E2D";
|
|
3443
|
+
case 4:
|
|
3444
|
+
return "\u9AD8";
|
|
3445
|
+
default:
|
|
3446
|
+
return "";
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
function parseMatterTaskState(value) {
|
|
3450
|
+
const raw = (value ?? "\u672A\u5B8C\u6210").trim().toLowerCase();
|
|
3451
|
+
if (!raw || raw === "all" || raw === "\u5168\u90E8" || raw === "\u5168\u90E8\u4EFB\u52A1") {
|
|
3452
|
+
return -1;
|
|
3453
|
+
}
|
|
3454
|
+
const aliases = {
|
|
3455
|
+
unfinished: 0,
|
|
3456
|
+
"\u672A\u5B8C\u6210": 0,
|
|
3457
|
+
done: 1,
|
|
3458
|
+
finished: 1,
|
|
3459
|
+
"\u5DF2\u5B8C\u6210": 1,
|
|
3460
|
+
all: -1,
|
|
3461
|
+
"\u5168\u90E8": -1,
|
|
3462
|
+
"\u5168\u90E8\u4EFB\u52A1": -1
|
|
3463
|
+
};
|
|
3464
|
+
if (raw in aliases) {
|
|
3465
|
+
return aliases[raw];
|
|
3466
|
+
}
|
|
3467
|
+
const parsed = Number.parseInt(raw, 10);
|
|
3468
|
+
if (Number.isNaN(parsed) || ![-1, 0, 1].includes(parsed)) {
|
|
3469
|
+
throw new Error("Invalid task state. Use all, \u672A\u5B8C\u6210, or \u5DF2\u5B8C\u6210.");
|
|
3470
|
+
}
|
|
3471
|
+
return parsed;
|
|
3472
|
+
}
|
|
3473
|
+
function parseMatterSearchStatus(value) {
|
|
3474
|
+
const raw = (value ?? "\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879").trim().toLowerCase();
|
|
3475
|
+
const aliases = {
|
|
3476
|
+
"\u9884\u7ACB\u9879": { label: "\u9884\u7ACB\u9879", values: [0] },
|
|
3477
|
+
pending: { label: "\u9884\u7ACB\u9879", values: [0] },
|
|
3478
|
+
"\u8FDB\u884C\u4E2D": { label: "\u8FDB\u884C\u4E2D", values: [2] },
|
|
3479
|
+
open: { label: "\u8FDB\u884C\u4E2D", values: [2] },
|
|
3480
|
+
active: { label: "\u8FDB\u884C\u4E2D", values: [2] },
|
|
3481
|
+
"\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879": { label: "\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879", values: [2, 0] },
|
|
3482
|
+
"\u9884\u7ACB\u9879+\u8FDB\u884C\u4E2D": { label: "\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879", values: [2, 0] },
|
|
3483
|
+
current: { label: "\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879", values: [2, 0] },
|
|
3484
|
+
default: { label: "\u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879", values: [2, 0] },
|
|
3485
|
+
"\u5DF2\u5B8C\u7ED3": { label: "\u5DF2\u5B8C\u7ED3", values: [4] },
|
|
3486
|
+
closed: { label: "\u5DF2\u5B8C\u7ED3", values: [4] },
|
|
3487
|
+
"\u5DF2\u6401\u7F6E": { label: "\u5DF2\u6401\u7F6E", values: [7] },
|
|
3488
|
+
suspended: { label: "\u5DF2\u6401\u7F6E", values: [7] },
|
|
3489
|
+
paused: { label: "\u5DF2\u6401\u7F6E", values: [7] },
|
|
3490
|
+
"\u5DF2\u5F52\u6863": { label: "\u5DF2\u5F52\u6863", values: [6] },
|
|
3491
|
+
filed: { label: "\u5DF2\u5F52\u6863", values: [6] },
|
|
3492
|
+
archived: { label: "\u5DF2\u5F52\u6863", values: [6] },
|
|
3493
|
+
"\u5168\u90E8": { label: "\u5168\u90E8", values: [0, 2, 4, 6, 7] },
|
|
3494
|
+
all: { label: "\u5168\u90E8", values: [0, 2, 4, 6, 7] }
|
|
3495
|
+
};
|
|
3496
|
+
const match = aliases[raw];
|
|
3497
|
+
if (match) {
|
|
3498
|
+
return match;
|
|
3499
|
+
}
|
|
3500
|
+
throw new Error(
|
|
3501
|
+
"Invalid matter status. Use \u9884\u7ACB\u9879, \u8FDB\u884C\u4E2D, \u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879, \u5DF2\u5B8C\u7ED3, \u5DF2\u6401\u7F6E, \u5DF2\u5F52\u6863, or \u5168\u90E8."
|
|
3502
|
+
);
|
|
3503
|
+
}
|
|
3504
|
+
function parseMatterSearchScope(value) {
|
|
3505
|
+
const raw = (value ?? "\u6240\u6709\u9879\u76EE").trim().toLowerCase();
|
|
3506
|
+
const aliases = {
|
|
3507
|
+
"\u6240\u6709\u9879\u76EE": "all",
|
|
3508
|
+
"\u5168\u90E8\u9879\u76EE": "all",
|
|
3509
|
+
all: "all",
|
|
3510
|
+
"\u6211\u5173\u6CE8\u7684": "followed",
|
|
3511
|
+
followed: "followed",
|
|
3512
|
+
favorite: "followed",
|
|
3513
|
+
starred: "followed",
|
|
3514
|
+
"\u5DF2\u52A0\u5165\u7684": "joined",
|
|
3515
|
+
joined: "joined",
|
|
3516
|
+
"\u6211\u52A0\u5165\u7684": "joined"
|
|
3517
|
+
};
|
|
3518
|
+
const match = aliases[raw];
|
|
3519
|
+
if (match) {
|
|
3520
|
+
return match;
|
|
3521
|
+
}
|
|
3522
|
+
throw new Error("Invalid matter scope. Use \u6240\u6709\u9879\u76EE, \u6211\u5173\u6CE8\u7684, or \u5DF2\u52A0\u5165\u7684.");
|
|
3523
|
+
}
|
|
3524
|
+
function formatMatterSearchScopeLabel(scope) {
|
|
3525
|
+
switch (scope) {
|
|
3526
|
+
case "followed":
|
|
3527
|
+
return "\u6211\u5173\u6CE8\u7684";
|
|
3528
|
+
case "joined":
|
|
3529
|
+
return "\u5DF2\u52A0\u5165\u7684";
|
|
3530
|
+
case "all":
|
|
3531
|
+
default:
|
|
3532
|
+
return "\u6240\u6709\u9879\u76EE";
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
async function buildJoinedMatterMemberFilter(client, sessionStore) {
|
|
3536
|
+
const session = await sessionStore.getSession();
|
|
3537
|
+
if (!session?.userId) {
|
|
3538
|
+
throw new Error("Missing current user id. Run alpha-classic-cli doctor or login again.");
|
|
3539
|
+
}
|
|
3540
|
+
const response = await client.request(
|
|
3541
|
+
"GET",
|
|
3542
|
+
"/matterserver/api/v2/matter/roles",
|
|
3543
|
+
{
|
|
3544
|
+
params: {
|
|
3545
|
+
subjectid: 0,
|
|
3546
|
+
subjecttype: "MAT"
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
);
|
|
3550
|
+
const data = unwrapEnvelopeData2(response);
|
|
3551
|
+
const roleIds = (data ?? []).map((role) => role.id).filter((id) => id !== void 0 && id !== null).map(String);
|
|
3552
|
+
if (!roleIds.length) {
|
|
3553
|
+
throw new Error("Cannot resolve matter role ids for joined matter search.");
|
|
3554
|
+
}
|
|
3555
|
+
return {
|
|
3556
|
+
userId: session.userId,
|
|
3557
|
+
roleIds
|
|
3558
|
+
};
|
|
3559
|
+
}
|
|
3560
|
+
function unwrapEnvelopeData2(response) {
|
|
3561
|
+
if (response && typeof response === "object" && "data" in response && ("isSuccess" in response || "resultMsg" in response)) {
|
|
3562
|
+
return response.data;
|
|
3563
|
+
}
|
|
3564
|
+
return response;
|
|
3565
|
+
}
|
|
3566
|
+
function parseMatterTaskType(value) {
|
|
3567
|
+
const raw = (value ?? "task").trim().toLowerCase();
|
|
3568
|
+
const aliases = {
|
|
3569
|
+
task: 0,
|
|
3570
|
+
tasks: 0,
|
|
3571
|
+
\u4EFB\u52A1: 0,
|
|
3572
|
+
group: 1,
|
|
3573
|
+
groups: 1,
|
|
3574
|
+
\u4EFB\u52A1\u7EC4: 1
|
|
3575
|
+
};
|
|
3576
|
+
if (raw in aliases) {
|
|
3577
|
+
return aliases[raw];
|
|
3578
|
+
}
|
|
3579
|
+
const parsed = Number.parseInt(raw, 10);
|
|
3580
|
+
if (Number.isNaN(parsed) || ![0, 1].includes(parsed)) {
|
|
3581
|
+
throw new Error("Invalid task type. Use task or group.");
|
|
3582
|
+
}
|
|
3583
|
+
return parsed;
|
|
3584
|
+
}
|
|
3585
|
+
function parseMatterAttentionType(value) {
|
|
3586
|
+
const raw = (value ?? "all").trim().toLowerCase();
|
|
3587
|
+
const aliases = {
|
|
3588
|
+
all: 0,
|
|
3589
|
+
\u5168\u90E8: 0,
|
|
3590
|
+
"\u6211\u5173\u6CE8\u7684": 1,
|
|
3591
|
+
attention: 1,
|
|
3592
|
+
followed: 1,
|
|
3593
|
+
follow: 1
|
|
3594
|
+
};
|
|
3595
|
+
if (raw in aliases) {
|
|
3596
|
+
return aliases[raw];
|
|
3597
|
+
}
|
|
3598
|
+
const parsed = Number.parseInt(raw, 10);
|
|
3599
|
+
if (Number.isNaN(parsed)) {
|
|
3600
|
+
throw new Error("Invalid attention type. Use all, \u6211\u5173\u6CE8\u7684, or a numeric value.");
|
|
3601
|
+
}
|
|
3602
|
+
return parsed;
|
|
3603
|
+
}
|
|
3604
|
+
function formatMatterTaskStateLabel(stateType) {
|
|
3605
|
+
switch (stateType) {
|
|
3606
|
+
case -1:
|
|
3607
|
+
return "\u5168\u90E8\u4EFB\u52A1";
|
|
3608
|
+
case 0:
|
|
3609
|
+
return "\u672A\u5B8C\u6210";
|
|
3610
|
+
case 1:
|
|
3611
|
+
return "\u5DF2\u5B8C\u6210";
|
|
3612
|
+
default:
|
|
3613
|
+
return `\u72B6\u6001(${stateType})`;
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3616
|
+
function toMatterTaskStatusType(stateType) {
|
|
3617
|
+
switch (stateType) {
|
|
3618
|
+
case -1:
|
|
3619
|
+
return 4;
|
|
3620
|
+
case 1:
|
|
3621
|
+
return 2;
|
|
3622
|
+
case 0:
|
|
3623
|
+
default:
|
|
3624
|
+
return 1;
|
|
3625
|
+
}
|
|
3626
|
+
}
|
|
3627
|
+
function formatMatterTaskTypeLabel(type) {
|
|
3628
|
+
switch (type) {
|
|
3629
|
+
case 0:
|
|
3630
|
+
return "\u4EFB\u52A1";
|
|
3631
|
+
case 1:
|
|
3632
|
+
return "\u4EFB\u52A1\u7EC4";
|
|
3633
|
+
default:
|
|
3634
|
+
return `\u7C7B\u578B(${type})`;
|
|
3635
|
+
}
|
|
3636
|
+
}
|
|
3637
|
+
function formatMatterAttentionLabel(attentionType) {
|
|
3638
|
+
switch (attentionType) {
|
|
3639
|
+
case 0:
|
|
3640
|
+
return "\u5168\u90E8";
|
|
3641
|
+
case 1:
|
|
3642
|
+
return "\u6211\u5173\u6CE8\u7684";
|
|
3643
|
+
default:
|
|
3644
|
+
return `\u5173\u6CE8\u7C7B\u578B(${attentionType})`;
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
function formatTaskUsers(users) {
|
|
3648
|
+
return (users ?? []).map((user) => user.userName ?? user.name ?? "").filter(Boolean);
|
|
3649
|
+
}
|
|
3650
|
+
function formatTaskUser(user) {
|
|
3651
|
+
return user?.userName ?? user?.name ?? "";
|
|
3652
|
+
}
|
|
3653
|
+
function formatTaskCommentType(type) {
|
|
3654
|
+
switch (type) {
|
|
3655
|
+
case 100:
|
|
3656
|
+
return "\u8BC4\u8BBA";
|
|
3657
|
+
case 400:
|
|
3658
|
+
return "\u52A8\u6001";
|
|
3659
|
+
default:
|
|
3660
|
+
return type === void 0 ? "" : `\u7C7B\u578B(${type})`;
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3663
|
+
function getFileNameFromPath(path4) {
|
|
3664
|
+
if (!path4) {
|
|
3665
|
+
return "";
|
|
3666
|
+
}
|
|
3667
|
+
return path4.split("/").filter(Boolean).pop() ?? path4;
|
|
3668
|
+
}
|
|
3669
|
+
function getAttachmentDocumentKey(item) {
|
|
3670
|
+
const repoId = getAttachmentRepoId(item);
|
|
3671
|
+
const fileId = getAttachmentFileId(item);
|
|
3672
|
+
const path4 = getAttachmentPath(item);
|
|
3673
|
+
return `${repoId}|${fileId || path4}`;
|
|
3674
|
+
}
|
|
3675
|
+
function getAttachmentRepoId(item) {
|
|
3676
|
+
return item.pathInfoVo?.repoId ?? "";
|
|
3677
|
+
}
|
|
3678
|
+
function getAttachmentFileId(item) {
|
|
3679
|
+
return item.fileId ?? item.pathInfoVo?.fileId ?? item.id ?? "";
|
|
3680
|
+
}
|
|
3681
|
+
function getAttachmentPath(item) {
|
|
3682
|
+
return item.filePath ?? item.path ?? item.pathInfoVo?.filePath ?? "";
|
|
3683
|
+
}
|
|
3684
|
+
function getDirectoryPath(path4) {
|
|
3685
|
+
const normalized = path4.startsWith("/") ? path4 : `/${path4}`;
|
|
3686
|
+
const lastSlashIndex = normalized.lastIndexOf("/");
|
|
3687
|
+
if (lastSlashIndex <= 0) {
|
|
3688
|
+
return "/";
|
|
3689
|
+
}
|
|
3690
|
+
return normalized.slice(0, lastSlashIndex);
|
|
3691
|
+
}
|
|
3692
|
+
function formatTaskWorkType(workType) {
|
|
3693
|
+
if (!workType) {
|
|
3694
|
+
return "";
|
|
3695
|
+
}
|
|
3696
|
+
return {
|
|
3697
|
+
"\u5DE5\u4F5C\u7C7B\u578BID": workType.id ?? "",
|
|
3698
|
+
"\u5DE5\u4F5C\u7C7B\u578B\u540D\u79F0": workType.name ?? ""
|
|
3699
|
+
};
|
|
3700
|
+
}
|
|
3701
|
+
function formatTaskRepeatSetting(repeatSetting) {
|
|
3702
|
+
if (!repeatSetting) {
|
|
3703
|
+
return "";
|
|
3704
|
+
}
|
|
3705
|
+
return {
|
|
3706
|
+
"\u89C4\u5219ID": repeatSetting.id ?? "",
|
|
3707
|
+
"\u91CD\u590D\u89C4\u5219": repeatSetting.repeatRule ?? "",
|
|
3708
|
+
"\u81EA\u5B9A\u4E49\u89C4\u5219": repeatSetting.customRepeatRule ?? "",
|
|
3709
|
+
"\u65E5\u671F\u7D22\u5F15": repeatSetting.dayIndexList ?? [],
|
|
3710
|
+
"\u7ED3\u675F\u7C7B\u578B": repeatSetting.endType ?? "",
|
|
3711
|
+
"\u7ED3\u675F\u65E5\u671F": formatDateTime2(repeatSetting.endByDate),
|
|
3712
|
+
"\u7ED3\u675F\u6B21\u6570": repeatSetting.endByTimes ?? ""
|
|
3713
|
+
};
|
|
3714
|
+
}
|
|
3715
|
+
function formatMatterTaskTimeType(value) {
|
|
3716
|
+
switch (value) {
|
|
3717
|
+
case 1:
|
|
3718
|
+
return "\u5230\u671F\u65F6\u95F4";
|
|
3719
|
+
case 2:
|
|
3720
|
+
return "\u5F00\u59CB\u7ED3\u675F\u65F6\u95F4";
|
|
3721
|
+
default:
|
|
3722
|
+
return value === void 0 || value === null ? "" : String(value);
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
function formatMatterTaskDayType(value) {
|
|
3726
|
+
switch (value) {
|
|
3727
|
+
case 1:
|
|
3728
|
+
return "\u5168\u5929\u4EFB\u52A1";
|
|
3729
|
+
case 2:
|
|
3730
|
+
return "\u975E\u5168\u5929\u4EFB\u52A1";
|
|
3731
|
+
default:
|
|
3732
|
+
return value === void 0 || value === null ? "" : String(value);
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
function createEmptyTimeRange(siftMaxTime) {
|
|
3736
|
+
return {
|
|
3737
|
+
startTime: "",
|
|
3738
|
+
endTime: "",
|
|
3739
|
+
siftMaxTime
|
|
3740
|
+
};
|
|
3741
|
+
}
|
|
3742
|
+
function clampLimit2(limit) {
|
|
3743
|
+
if (!Number.isFinite(limit) || limit < 1) {
|
|
3744
|
+
return 10;
|
|
3745
|
+
}
|
|
3746
|
+
return Math.min(Math.floor(limit), 50);
|
|
3747
|
+
}
|
|
3748
|
+
function clampPage2(page) {
|
|
3749
|
+
if (!Number.isFinite(page) || page < 1) {
|
|
3750
|
+
return 1;
|
|
3751
|
+
}
|
|
3752
|
+
return Math.floor(page);
|
|
3753
|
+
}
|
|
3754
|
+
function clampLogLimit(limit) {
|
|
3755
|
+
if (!Number.isFinite(limit) || limit < 0) {
|
|
3756
|
+
return 5;
|
|
3757
|
+
}
|
|
3758
|
+
return Math.min(Math.floor(limit), 20);
|
|
3759
|
+
}
|
|
3760
|
+
function clampCommentLimit2(limit) {
|
|
3761
|
+
if (limit === void 0) {
|
|
3762
|
+
return 10;
|
|
3763
|
+
}
|
|
3764
|
+
if (!Number.isFinite(limit) || limit < 0) {
|
|
3765
|
+
return 10;
|
|
3766
|
+
}
|
|
3767
|
+
return Math.min(Math.floor(limit), 50);
|
|
3768
|
+
}
|
|
3769
|
+
function formatLocalDate(date) {
|
|
3770
|
+
const year = date.getFullYear();
|
|
3771
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
3772
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
3773
|
+
return `${year}-${month}-${day}`;
|
|
3774
|
+
}
|
|
3775
|
+
function parseDateTime2(value) {
|
|
3776
|
+
if (typeof value === "number") {
|
|
3777
|
+
return dateFromTimestamp2(value);
|
|
3778
|
+
}
|
|
3779
|
+
const trimmed = value.trim();
|
|
3780
|
+
if (!trimmed) {
|
|
3781
|
+
return null;
|
|
3782
|
+
}
|
|
3783
|
+
if (/^\d+$/.test(trimmed)) {
|
|
3784
|
+
return dateFromTimestamp2(Number.parseInt(trimmed, 10));
|
|
3785
|
+
}
|
|
3786
|
+
const parsed = new Date(trimmed);
|
|
3787
|
+
return Number.isNaN(parsed.getTime()) ? null : parsed;
|
|
3788
|
+
}
|
|
3789
|
+
function dateFromTimestamp2(timestamp) {
|
|
3790
|
+
if (!Number.isFinite(timestamp)) {
|
|
3791
|
+
return null;
|
|
3792
|
+
}
|
|
3793
|
+
const milliseconds = Math.abs(timestamp) < 1e10 ? timestamp * 1e3 : timestamp;
|
|
3794
|
+
const date = new Date(milliseconds);
|
|
3795
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3798
|
+
// src/commands/version.ts
|
|
3799
|
+
function runVersion(info) {
|
|
3800
|
+
const environment = getDefaultEnvironmentPreset();
|
|
3801
|
+
printSuccess({
|
|
3802
|
+
"\u540D\u79F0": info.name,
|
|
3803
|
+
"\u7248\u672C": info.version,
|
|
3804
|
+
"\u6240\u5C5E\u7CFB\u7EDF": "Alpha \u5F8B\u6240\u7BA1\u7406\u7CFB\u7EDF",
|
|
3805
|
+
"\u73AF\u5883": environment.name,
|
|
3806
|
+
"baseUrl": environment.baseUrl,
|
|
3807
|
+
"apiBaseUrl": environment.apiBaseUrl,
|
|
3808
|
+
"\u73AF\u5883\u662F\u5426\u6784\u5EFA\u65F6\u9501\u5B9A": true
|
|
3809
|
+
});
|
|
3810
|
+
}
|
|
3811
|
+
|
|
3812
|
+
// src/session/store.ts
|
|
3813
|
+
import fs3 from "fs/promises";
|
|
3814
|
+
import os3 from "os";
|
|
3815
|
+
import path3 from "path";
|
|
3816
|
+
function defaultConfigDir() {
|
|
3817
|
+
return process.env.ALPHA_CLI_CONFIG_DIR ?? path3.join(os3.homedir(), ".config", "alpha-classic-cli");
|
|
3818
|
+
}
|
|
3819
|
+
var SessionStore = class {
|
|
3820
|
+
configDir;
|
|
3821
|
+
configPath;
|
|
3822
|
+
sessionPath;
|
|
3823
|
+
constructor(options) {
|
|
3824
|
+
this.configDir = options?.configDir ?? defaultConfigDir();
|
|
3825
|
+
this.configPath = path3.join(this.configDir, "config.json");
|
|
3826
|
+
this.sessionPath = path3.join(this.configDir, "session.json");
|
|
3827
|
+
}
|
|
3828
|
+
async getConfig() {
|
|
3829
|
+
return readJsonFile(this.configPath, {});
|
|
3830
|
+
}
|
|
3831
|
+
async saveConfig(patch) {
|
|
3832
|
+
const current = await this.getConfig();
|
|
3833
|
+
const next = { ...current, ...patch };
|
|
3834
|
+
await writePrivateJsonFile(this.configPath, next);
|
|
3835
|
+
return next;
|
|
3836
|
+
}
|
|
3837
|
+
async getSession() {
|
|
3838
|
+
return readJsonFile(this.sessionPath, null);
|
|
3839
|
+
}
|
|
3840
|
+
async saveSession(session) {
|
|
3841
|
+
await writePrivateJsonFile(this.sessionPath, session);
|
|
3842
|
+
}
|
|
3843
|
+
async clearSession() {
|
|
3844
|
+
await fs3.rm(this.sessionPath, { force: true });
|
|
3845
|
+
}
|
|
3846
|
+
async clearAuthState() {
|
|
3847
|
+
await this.clearSession();
|
|
3848
|
+
const current = await this.getConfig();
|
|
3849
|
+
const {
|
|
3850
|
+
defaultOfficeId: _defaultOfficeId,
|
|
3851
|
+
...next
|
|
3852
|
+
} = current;
|
|
3853
|
+
await writePrivateJsonFile(this.configPath, next);
|
|
3854
|
+
return next;
|
|
3855
|
+
}
|
|
3856
|
+
};
|
|
3857
|
+
async function readJsonFile(filePath, fallback) {
|
|
3858
|
+
try {
|
|
3859
|
+
const content = await fs3.readFile(filePath, "utf8");
|
|
3860
|
+
return JSON.parse(content);
|
|
3861
|
+
} catch (error) {
|
|
3862
|
+
const nodeError = error;
|
|
3863
|
+
if (nodeError.code === "ENOENT") {
|
|
3864
|
+
return fallback;
|
|
3865
|
+
}
|
|
3866
|
+
throw error;
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
async function writePrivateJsonFile(filePath, value) {
|
|
3870
|
+
await fs3.mkdir(path3.dirname(filePath), { recursive: true });
|
|
3871
|
+
await fs3.writeFile(filePath, JSON.stringify(value, null, 2), {
|
|
3872
|
+
encoding: "utf8",
|
|
3873
|
+
mode: 384
|
|
3874
|
+
});
|
|
3875
|
+
}
|
|
3876
|
+
|
|
3877
|
+
// src/index.ts
|
|
3878
|
+
var require3 = createRequire2(import.meta.url);
|
|
3879
|
+
var packageJson = require3("../package.json");
|
|
3880
|
+
function parseInteger(value) {
|
|
3881
|
+
const parsed = Number.parseInt(value, 10);
|
|
3882
|
+
if (Number.isNaN(parsed)) {
|
|
3883
|
+
throw new Error(`Invalid number: ${value}`);
|
|
3884
|
+
}
|
|
3885
|
+
return parsed;
|
|
3886
|
+
}
|
|
3887
|
+
async function main() {
|
|
3888
|
+
const sessionStore = new SessionStore();
|
|
3889
|
+
const program = new Command();
|
|
3890
|
+
program.name("alpha-classic-cli").description("Alpha Classic AI-friendly CLI for Alpha web app").version(packageJson.version ?? "0.0.0");
|
|
3891
|
+
program.command("install").description("Install agent guides for Codex, Claude Code, Alpha-claw, or all supported agents").option("--agent <agent>", "Agent target: codex, claude, alphaclaw, all", "codex").action(async (options) => {
|
|
3892
|
+
const agent = parseAgentInstallTarget(options.agent);
|
|
3893
|
+
const result = await installAgentGuides({ agent });
|
|
3894
|
+
printSuccess(result);
|
|
3895
|
+
});
|
|
3896
|
+
program.command("uninstall").description("Uninstall agent guides for Codex, Claude Code, Alpha-claw, or all supported agents").option("--agent <agent>", "Agent target: codex, claude, alphaclaw, all", "codex").action(async (options) => {
|
|
3897
|
+
const agent = parseAgentInstallTarget(options.agent);
|
|
3898
|
+
const result = await uninstallAgentGuides({ agent });
|
|
3899
|
+
printSuccess(result);
|
|
3900
|
+
});
|
|
3901
|
+
program.command("capabilities").description("Print machine-readable CLI capabilities for agents").action(() => {
|
|
3902
|
+
runCapabilities(packageJson.version ?? "0.0.0");
|
|
3903
|
+
});
|
|
3904
|
+
program.command("version").description("Print machine-readable CLI version").action(() => {
|
|
3905
|
+
runVersion({
|
|
3906
|
+
name: packageJson.name ?? "alpha-classic-cli",
|
|
3907
|
+
version: packageJson.version ?? "0.0.0"
|
|
3908
|
+
});
|
|
3909
|
+
});
|
|
3910
|
+
program.command("login").description("Start Alpha CLI device authorization login").option("--token <token>", "Debug fallback token").option("--user-id <id>", "Current user id").option("--office-id <id>", "Current office id").option("--name <name>", "Current user name").option("--no-wait", "Create device authorization and print JSON only").option("--json", "Print final result as JSON envelope").option("--device-code <deviceCode>", "Poll an existing device code").option("--timeout-ms <ms>", "Device authorization wait timeout", parseInteger).option("--no-open-browser", "Do not open browser when token is missing").action(
|
|
3911
|
+
async (options) => {
|
|
3912
|
+
const progress = (message) => {
|
|
3913
|
+
console.error(message);
|
|
3914
|
+
};
|
|
3915
|
+
if (options.noWait || options.wait === false) {
|
|
3916
|
+
const result = await createLoginDeviceAuthorization(
|
|
3917
|
+
{
|
|
3918
|
+
timeoutMs: options.timeoutMs,
|
|
3919
|
+
onProgress: progress
|
|
3920
|
+
},
|
|
3921
|
+
sessionStore
|
|
3922
|
+
);
|
|
3923
|
+
printSuccess({
|
|
3924
|
+
verification_url: result.auth.verificationUriComplete,
|
|
3925
|
+
verification_uri: result.auth.verificationUri,
|
|
3926
|
+
user_code: result.auth.userCode,
|
|
3927
|
+
device_code: result.auth.deviceCode,
|
|
3928
|
+
expires_in: result.auth.expiresIn,
|
|
3929
|
+
interval: result.auth.interval,
|
|
3930
|
+
hint: `\u8BF7\u5C06 verification_url \u539F\u6837\u4EA4\u7ED9\u7528\u6237\u6253\u5F00\u786E\u8BA4\uFF1B\u786E\u8BA4\u540E\u6267\u884C\uFF1Aalpha-classic-cli login --device-code ${result.auth.deviceCode}`
|
|
3931
|
+
});
|
|
3932
|
+
return;
|
|
3933
|
+
}
|
|
3934
|
+
const session = options.deviceCode ? await pollLoginDeviceAuthorization(
|
|
3935
|
+
{
|
|
3936
|
+
timeoutMs: options.timeoutMs,
|
|
3937
|
+
onProgress: progress
|
|
3938
|
+
},
|
|
3939
|
+
sessionStore,
|
|
3940
|
+
options.deviceCode
|
|
3941
|
+
) : await runLogin(
|
|
3942
|
+
{
|
|
3943
|
+
token: options.token,
|
|
3944
|
+
userId: options.userId,
|
|
3945
|
+
officeId: options.officeId,
|
|
3946
|
+
name: options.name,
|
|
3947
|
+
timeoutMs: options.timeoutMs,
|
|
3948
|
+
openBrowser: options.openBrowser,
|
|
3949
|
+
onProgress: progress
|
|
3950
|
+
},
|
|
3951
|
+
sessionStore
|
|
3952
|
+
);
|
|
3953
|
+
printSuccess({
|
|
3954
|
+
event: "login_success",
|
|
3955
|
+
userId: session.userId,
|
|
3956
|
+
userName: session.userName ?? session.name,
|
|
3957
|
+
officeId: session.officeId,
|
|
3958
|
+
officeName: session.officeName,
|
|
3959
|
+
deviceType: session.deviceType ?? "ai",
|
|
3960
|
+
updatedAt: session.updatedAt
|
|
3961
|
+
});
|
|
3962
|
+
}
|
|
3963
|
+
);
|
|
3964
|
+
program.command("logout").description("Clear local session and identity cache").action(async () => {
|
|
3965
|
+
await sessionStore.clearAuthState();
|
|
3966
|
+
printSuccess({ session: "cleared", identityCache: "cleared" });
|
|
3967
|
+
});
|
|
3968
|
+
program.command("doctor").description("Inspect config, session, skill install, and API health").action(async () => {
|
|
3969
|
+
await runDoctor(sessionStore);
|
|
3970
|
+
});
|
|
3971
|
+
program.command("env").description("Inspect the build-time environment").argument("[action]", "Action: list, current").argument("[name]", "Environment name for list/current only").action(async (action, name) => {
|
|
3972
|
+
await runEnvCommand(action, name, sessionStore);
|
|
3973
|
+
});
|
|
3974
|
+
program.command("api").description("Call a raw API endpoint").argument("<method>", "HTTP method").argument("<path>", "API path").option("--params <json>", "Query params JSON object").option("--data <json>", "Request body JSON").action(
|
|
3975
|
+
async (method, apiPath, options) => {
|
|
3976
|
+
await runApiCommand(method, apiPath, options, sessionStore);
|
|
3977
|
+
}
|
|
3978
|
+
);
|
|
3979
|
+
const matter = program.command("matter").alias("project").description("Matter/project commands");
|
|
3980
|
+
matter.command("search").description("Search matters by keyword").option("--keyword <keyword>", "Matter keyword").option("--status <status>", "Matter status: \u9884\u7ACB\u9879, \u8FDB\u884C\u4E2D, \u8FDB\u884C\u4E2D+\u9884\u7ACB\u9879, \u5DF2\u5B8C\u7ED3, \u5DF2\u6401\u7F6E, \u5DF2\u5F52\u6863, \u5168\u90E8").option("--scope <scope>", "Matter scope: \u6240\u6709\u9879\u76EE, \u6211\u5173\u6CE8\u7684, \u5DF2\u52A0\u5165\u7684").option("--limit <number>", "Max results", parseInteger).option("--page <number>", "Page index, starts from 1", parseInteger).action(async (options) => {
|
|
3981
|
+
await runMatterSearch(options, sessionStore);
|
|
3982
|
+
});
|
|
3983
|
+
matter.command("detail").description("Show matter overview details").requiredOption("--id <matterId>", "Matter id").option("--logs <number>", "Recent dynamic count, 0 to skip", parseInteger).action(async (options) => {
|
|
3984
|
+
await runMatterDetail(options, sessionStore);
|
|
3985
|
+
});
|
|
3986
|
+
matter.command("task").description("List tasks for a matter/project").requiredOption("--id <matterId>", "Matter id").option("--state <state>", "Task state: all, \u672A\u5B8C\u6210, \u5DF2\u5B8C\u6210").option("--page <number>", "Page index, starts from 1", parseInteger).option("--limit <number>", "Max results", parseInteger).option("--type <type>", "Task type: task or group").option("--attention <type>", "Attention filter: all, \u6211\u5173\u6CE8\u7684").action(
|
|
3987
|
+
async (options) => {
|
|
3988
|
+
await runMatterTaskList(
|
|
3989
|
+
{
|
|
3990
|
+
matterId: options.id,
|
|
3991
|
+
state: options.state,
|
|
3992
|
+
page: options.page,
|
|
3993
|
+
limit: options.limit,
|
|
3994
|
+
type: options.type,
|
|
3995
|
+
attention: options.attention
|
|
3996
|
+
},
|
|
3997
|
+
sessionStore
|
|
3998
|
+
);
|
|
3999
|
+
}
|
|
4000
|
+
);
|
|
4001
|
+
matter.command("task-detail").description("Show task details for a matter/project task").requiredOption("--id <taskId>", "Task id").option("--comments <number>", "Recent task dynamic/comment count, 0 to skip", parseInteger).action(async (options) => {
|
|
4002
|
+
await runMatterTaskDetail(
|
|
4003
|
+
{
|
|
4004
|
+
id: options.id,
|
|
4005
|
+
comments: options.comments
|
|
4006
|
+
},
|
|
4007
|
+
sessionStore
|
|
4008
|
+
);
|
|
4009
|
+
});
|
|
4010
|
+
const appro = program.command("appro").description("Approval commands");
|
|
4011
|
+
appro.command("list").description("List approvals").option(
|
|
4012
|
+
"--scope <scope>",
|
|
4013
|
+
"Approval scope: my, started, cc, all, \u6211\u5BA1\u6279\u7684, \u6211\u53D1\u8D77\u7684, \u6284\u9001\u6211\u7684, \u5168\u90E8\u5BA1\u6279",
|
|
4014
|
+
"my"
|
|
4015
|
+
).option("--keyword <keyword>", "Approval keyword").option("--status <status>", "Approval status code, Chinese status name, or all").option("--appro-type <ids>", "Approval type ids, comma-separated").option("--starter-id <id>", "Approval starter user id").option("--starter-name <name>", "Approval starter name; resolved through appro initiators").option("--limit <number>", "Max results", parseInteger).option("--page <number>", "Page index, starts from 1", parseInteger).option("--count-only", "Only print the matched approval count").action(
|
|
4016
|
+
async (options) => {
|
|
4017
|
+
await runApproList(options, sessionStore);
|
|
4018
|
+
}
|
|
4019
|
+
);
|
|
4020
|
+
appro.command("initiators").description("List approval initiators").option("--keyword <keyword>", "Initiator name keyword").option("--include-left", "Include inactive/left users").option("--limit <number>", "Max results", parseInteger).action(
|
|
4021
|
+
async (options) => {
|
|
4022
|
+
await runApproInitiators(options, sessionStore);
|
|
4023
|
+
}
|
|
4024
|
+
);
|
|
4025
|
+
appro.command("detail").description("Show approval details").requiredOption("--id <approId>", "Approval id").option("--comments <number>", "Recent comment count, 0 to skip", parseInteger).action(async (options) => {
|
|
4026
|
+
await runApproDetail(options, sessionStore);
|
|
4027
|
+
});
|
|
4028
|
+
await program.parseAsync(process.argv);
|
|
4029
|
+
}
|
|
4030
|
+
function parseAgentInstallTarget(value) {
|
|
4031
|
+
const target = (value ?? "codex").trim().toLowerCase();
|
|
4032
|
+
if (target === "codex" || target === "claude" || target === "alphaclaw" || target === "all") {
|
|
4033
|
+
return target;
|
|
4034
|
+
}
|
|
4035
|
+
throw new Error(`Invalid agent target: ${value}. Supported: codex, claude, alphaclaw, all`);
|
|
4036
|
+
}
|
|
4037
|
+
main().catch((error) => {
|
|
4038
|
+
printError("runtime", error instanceof Error ? error.message : String(error));
|
|
4039
|
+
process.exitCode = 1;
|
|
4040
|
+
});
|
|
4041
|
+
//# sourceMappingURL=index.js.map
|