weaver-work-cli 0.1.40 → 0.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{archive-JHTONRST.js → archive-J4I6MCKF.js} +2 -2
- package/dist/chunks/{archive-oa-FCHLCPHC.js → archive-oa-BRZKKTO4.js} +2 -2
- package/dist/chunks/{asset-RLIHC7DB.js → asset-L7D4FAOZ.js} +2 -2
- package/dist/chunks/{asset-idle-KVOFTLCP.js → asset-idle-DADLLV75.js} +2 -2
- package/dist/chunks/{attachment-content-RZYDB3MB.js → attachment-content-K4C7VLWQ.js} +3 -3
- package/dist/chunks/{blog-42OZTJNP.js → blog-BVGQ7NZL.js} +2 -2
- package/dist/chunks/{caizhilian-KRK547K5.js → caizhilian-SAADNFD6.js} +2 -2
- package/dist/chunks/{calendar-RTWAMKHD.js → calendar-Q7NQY5Z2.js} +61 -23
- package/dist/chunks/{chunk-LFMSDBZN.js → chunk-3KTFS4IA.js} +308 -153
- package/dist/chunks/{chunk-G2JSIUWF.js → chunk-4PD5NWAX.js} +89 -0
- package/dist/chunks/{chunk-T6EGVBKU.js → chunk-4RAE6JXP.js} +1 -1
- package/dist/chunks/{chunk-7BRU4EFH.js → chunk-72CKAUAG.js} +29 -2
- package/dist/chunks/{chunk-NETCCARD.js → chunk-APVFJUQH.js} +2 -2
- package/dist/chunks/{chunk-CAQNBBQA.js → chunk-BBKDXQEC.js} +2 -2
- package/dist/chunks/{chunk-57IECMWX.js → chunk-BIPYLLVS.js} +26 -12
- package/dist/chunks/{chunk-LN447PY2.js → chunk-EKWAQSLU.js} +3 -2
- package/dist/chunks/{chunk-4TEDNCON.js → chunk-FOAA27U5.js} +338 -52
- package/dist/chunks/{chunk-7U577Q7U.js → chunk-G4UR6NXN.js} +2 -2
- package/dist/chunks/{chunk-NJKREDA3.js → chunk-GEWYMQME.js} +1 -1
- package/dist/chunks/{chunk-I566ZYNF.js → chunk-GHXCDPTM.js} +1 -1
- package/dist/chunks/{chunk-4CTESSKI.js → chunk-IZ7S7QUS.js} +4 -4
- package/dist/chunks/{chunk-VNBU55SL.js → chunk-JPRO6ER2.js} +57 -2432
- package/dist/chunks/{chunk-IZSSVYAG.js → chunk-LADPYOWC.js} +2 -2
- package/dist/chunks/chunk-LDZQPUIA.js +1238 -0
- package/dist/chunks/chunk-NKZRQXST.js +2546 -0
- package/dist/chunks/{chunk-JWRZM2H2.js → chunk-QKNKR4RH.js} +3 -3
- package/dist/chunks/{chunk-FLS4DPGP.js → chunk-R4CHUSKC.js} +28 -15
- package/dist/chunks/{chunk-WFFNM65B.js → chunk-SA6VBIHY.js} +73 -19
- package/dist/chunks/{chunk-SPRHHSVC.js → chunk-TTPJJJC4.js} +2 -2
- package/dist/chunks/{chunk-7E6MUOEK.js → chunk-W7BEHOSR.js} +2 -2
- package/dist/chunks/{chunk-CXRQWOZ5.js → chunk-YRSZQUD2.js} +2 -2
- package/dist/chunks/{conflict-VR55AOOO.js → conflict-F2OMZRTO.js} +2 -2
- package/dist/chunks/{contract-HI4FNPYE.js → contract-5BETHRSG.js} +2 -2
- package/dist/chunks/{cowork-HJLI353D.js → cowork-3MN6EQQO.js} +22 -12
- package/dist/chunks/create-flow-5FQNNMVO.js +55 -0
- package/dist/chunks/{ebuilder-form-HTGI63UU.js → ebuilder-form-SBHOYBUD.js} +3 -3
- package/dist/chunks/{ehr-GYXIYH3A.js → ehr-KMOJULKG.js} +432 -1234
- package/dist/chunks/{env-DW3G4HUO.js → env-LB7NBL2O.js} +2 -2
- package/dist/chunks/{esb-I5INCEFE.js → esb-W2PJCFCX.js} +4 -4
- package/dist/chunks/{factory-TKXGXS6L.js → factory-6ZFQXQ46.js} +1 -1
- package/dist/chunks/{fna-K2MHTQ24.js → fna-ZQPCUV4R.js} +2 -2
- package/dist/chunks/{group-chat-VYBNMJLG.js → group-chat-2HHAJN46.js} +5 -3
- package/dist/chunks/{host-ZUQTJYYK.js → host-4CBHGOHT.js} +3 -3
- package/dist/chunks/{host-D5SERMAJ.js → host-ATKVNZAT.js} +3 -3
- package/dist/chunks/{host-JM4YVHFM.js → host-BQH22NTQ.js} +3 -3
- package/dist/chunks/{host-L3VLITMT.js → host-X2CSLFM6.js} +3 -3
- package/dist/chunks/{host-256GVCAH.js → host-YTODKMSL.js} +3 -3
- package/dist/chunks/{hrm-VLRBKTZB.js → hrm-FFM4UJFS.js} +4 -4
- package/dist/chunks/{im-QK3VTLXK.js → im-VEHKDQPB.js} +7 -7
- package/dist/chunks/{invoice-T5JTA32H.js → invoice-LVIKSIIF.js} +3 -3
- package/dist/chunks/{jiuchuanhui-P2FNEQVZ.js → jiuchuanhui-X6DINO5P.js} +2 -2
- package/dist/chunks/{lazy-dispatch-XRRI46M6.js → lazy-dispatch-KSWTN5L6.js} +4 -4
- package/dist/chunks/{mail-3Y7MJ6PS.js → mail-VDKRGUD3.js} +2 -2
- package/dist/chunks/{meeting-M7LTXGJE.js → meeting-CLC6HP3Z.js} +12 -11
- package/dist/chunks/{okr-OBC6S67L.js → okr-CHG4OO3U.js} +2 -2
- package/dist/chunks/{plan-5H6I53SK.js → plan-XWR75667.js} +2 -2
- package/dist/chunks/{project-L75QZV4S.js → project-5BXOOKMG.js} +40 -23
- package/dist/chunks/recruit-stage-DGMFNNDE.js +4507 -0
- package/dist/chunks/{registry-RXPN6BBT.js → registry-7FFOXIAW.js} +4 -4
- package/dist/chunks/{registry-KMHCPAAD.js → registry-BKBZPBAJ.js} +10 -9
- package/dist/chunks/{registry-QGHFNUWS.js → registry-OZSMDVPP.js} +2 -2
- package/dist/chunks/{registry-UGRBCBHO.js → registry-RHMW6ANW.js} +2 -2
- package/dist/chunks/{registry-NYPYMZXG.js → registry-Z43434VG.js} +1 -1
- package/dist/chunks/{room-recommend-A3UDC3CA.js → room-recommend-62H7ZQQ6.js} +4 -4
- package/dist/chunks/{schedule-5GCACCK7.js → schedule-FNXKH3DQ.js} +4 -4
- package/dist/chunks/{workflow-M5ZJ7DWF.js → workflow-ADHKCAJK.js} +6 -6
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/commands.js +1 -0
- package/dist/internal/e10/auth/messages.js +6 -0
- package/dist/internal/e10/auth/session.js +17 -0
- package/dist/internal/e10/auth/xiaoe.js +286 -44
- package/dist/internal/e10/auth-recovery.js +36 -5
- package/dist/internal/e10/context.js +56 -12
- package/dist/internal/e10/index.js +1 -1
- package/dist/internal/e10/network-error.js +93 -0
- package/dist/internal/e10/request-runtime.js +6 -0
- package/dist/shortcuts/calendar/operations/read.js +31 -22
- package/dist/shortcuts/calendar/operations/write.js +45 -1
- package/dist/shortcuts/cowork/operations/discuss-write.js +5 -1
- package/dist/shortcuts/cowork/operations/item-write.js +1 -7
- package/dist/shortcuts/cowork/operations/member-write.js +3 -1
- package/dist/shortcuts/cowork/operations/permission-write.js +5 -1
- package/dist/shortcuts/cowork/operations/shared.js +7 -0
- package/dist/shortcuts/ehr/operations/attend-write.js +43 -1
- package/dist/shortcuts/ehr/operations/hr-contact.js +7 -4
- package/dist/shortcuts/ehr/operations/hr-report.js +13 -7
- package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +134 -59
- package/dist/shortcuts/ehr/operations/recruit-write.js +262 -17
- package/dist/shortcuts/ehr/operations/recruit.js +10 -4
- package/dist/shortcuts/ehr/operations/shared.js +47 -0
- package/dist/shortcuts/hrm/operations/org.js +118 -0
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +4 -1
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +85 -28
- package/dist/shortcuts/meeting/operations/eb/factory.js +33 -0
- package/dist/shortcuts/meeting/operations/eb/group-chat.js +25 -3
- package/dist/shortcuts/meeting/operations/eb/person-cache.js +96 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +33 -11
- package/dist/shortcuts/project/operations/read.js +6 -25
- package/dist/shortcuts/project/operations/shared.js +22 -0
- package/dist/shortcuts/project/operations/write.js +28 -2
- package/dist/shortcuts/recruit-stage/context.js +119 -0
- package/dist/shortcuts/recruit-stage/continuation.js +73 -0
- package/dist/shortcuts/recruit-stage/errors.js +65 -0
- package/dist/shortcuts/recruit-stage/host.js +109 -0
- package/dist/shortcuts/recruit-stage/index.js +115 -0
- package/dist/shortcuts/recruit-stage/manifest.js +29 -0
- package/dist/shortcuts/recruit-stage/operations/interview-arrange.js +722 -0
- package/dist/shortcuts/recruit-stage/operations/interview-feedback.js +269 -0
- package/dist/shortcuts/recruit-stage/operations/jd-create.js +630 -0
- package/dist/shortcuts/recruit-stage/operations/list.js +431 -0
- package/dist/shortcuts/recruit-stage/operations/registry.js +38 -0
- package/dist/shortcuts/recruit-stage/operations/resume-import.js +1198 -0
- package/dist/shortcuts/recruit-stage/operations/search.js +158 -0
- package/dist/shortcuts/recruit-stage/operations/types.js +25 -0
- package/dist/shortcuts/recruit-stage/school-tiers.json +318 -0
- package/dist/shortcuts/recruit-stage/shared.js +608 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +13 -6
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +17 -24
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +14 -9
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +50 -8
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +2 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +17 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +7 -39
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +3 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +51 -15
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +16 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +151 -63
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.subGroup.js +56 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +39 -14
- package/docs/e10-auth.md +7 -1
- package/docs/operation-manual.md +8 -0
- package/package.json +1 -1
- package/scripts/install-skill-to-xiaoe.mjs +105 -0
- package/scripts/package-skill.mjs +4 -2
- package/skill-template/business-info.json +24 -0
- package/skill-template/domains/recruit-stage.md +29 -0
- package/skills/weaver-e10-calendar/SKILL.md +2 -1
- package/skills/weaver-e10-calendar/references/calendar-write.md +54 -0
- package/skills/weaver-e10-cowork/SKILL.md +1 -1
- package/skills/weaver-e10-cowork/references/cowork-write.md +3 -1
- package/skills/weaver-e10-jucailin/SKILL.md +1 -1
- package/skills/weaver-e10-jucailin/references/attend-write.md +8 -0
- package/skills/weaver-e10-jucailin/references/hr-contact.md +8 -0
- package/skills/weaver-e10-jucailin/references/hr-report.md +8 -0
- package/skills/weaver-e10-jucailin/references/recruit-create.md +2 -2
- package/skills/weaver-e10-jucailin/references/recruit-read.md +1 -1
- package/skills/weaver-e10-jucailin/references/recruit-write.md +4 -3
- package/skills/weaver-e10-mail/SKILL.md +1 -1
- package/skills/weaver-e10-meeting/SKILL.md +32 -2
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-recruit-stage/SKILL.md +226 -0
- package/skills/weaver-e10-recruit-stage/agents/openai.yaml +119 -0
- package/skills/weaver-e10-recruit-stage/lib/recruit-xiaoe-file.mjs +188 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-arrange-interview.md +322 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-capability-check.md +127 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-check-install.md +65 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-detail-process.md +63 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-edit-interview-feedback.md +142 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-jd-create.md +73 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-jd-template.md +56 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-list-candidate.md +101 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-list-interview.md +148 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-match-candidates.md +77 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-output-links.md +59 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resolve-creator.md +69 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resolve-metadata.md +241 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resume-import.md +438 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resume-parse.md +128 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-search-candidate.md +146 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-urge-feedback.md +69 -0
- package/skills/weaver-e10-shared/SKILL.md +1 -1
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -2
- package/skills/weaver-e10-shijingran/SKILL.md +3 -2
- package/skills/weaver-e10-shijingran/references/operations.md +3 -1
- package/skills/weaver-e10-shijingran/references/source-manifest.json +41 -40
- package/skills/weaver-e10-shijingran/references/write-operations.md +2 -0
- package/skills/weaver-e10-workflow/SKILL.md +4 -2
- package/skills/weaver-e10-workflow/aigroup/default.json +11 -9
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +23 -13
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +62 -20
- package/skills/weaver-e10-yepiaotong/SKILL.md +9 -10
- package/skills/weaver-e10-yepiaotong/references/invoice-agent-entry.md +6 -3
- package/dist/chunks/{chunk-E7OK5WD5.js → chunk-2LV74IWP.js} +5 -5
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 网络错误的统一识别。
|
|
3
|
+
*
|
|
4
|
+
* Node/undici 的 `fetch` 只抛 `TypeError: fetch failed`,真实原因(拒绝连接、
|
|
5
|
+
* DNS 失败、TLS 失败、连接/响应超时)放在 `error.cause.code` 上。丢掉这条 code,
|
|
6
|
+
* 「连不上 E10」就会被误报成「登录态不可用」,把用户引导去重新登录。
|
|
7
|
+
*/
|
|
8
|
+
/** 明确属于「网络层没打通」的系统错误码(Node 常见 errno + undici 内部码)。 */
|
|
9
|
+
const NETWORK_ERROR_CODES = new Set([
|
|
10
|
+
'ECONNREFUSED',
|
|
11
|
+
'ECONNRESET',
|
|
12
|
+
'ECONNABORTED',
|
|
13
|
+
'EHOSTUNREACH',
|
|
14
|
+
'EHOSTDOWN',
|
|
15
|
+
'ENETUNREACH',
|
|
16
|
+
'ENETDOWN',
|
|
17
|
+
'ENETRESET',
|
|
18
|
+
'ENOTFOUND',
|
|
19
|
+
'EAI_AGAIN',
|
|
20
|
+
'EPIPE',
|
|
21
|
+
'ETIMEDOUT',
|
|
22
|
+
'ESOCKETTIMEDOUT',
|
|
23
|
+
'ERR_SOCKET_CONNECTION_TIMEOUT',
|
|
24
|
+
'UND_ERR_CONNECT_TIMEOUT',
|
|
25
|
+
'UND_ERR_HEADERS_TIMEOUT',
|
|
26
|
+
'UND_ERR_BODY_TIMEOUT',
|
|
27
|
+
'UND_ERR_SOCKET',
|
|
28
|
+
'UND_ERR_CLOSED',
|
|
29
|
+
'UND_ERR_ABORTED',
|
|
30
|
+
'CERT_HAS_EXPIRED',
|
|
31
|
+
'DEPTH_ZERO_SELF_SIGNED_CERT',
|
|
32
|
+
'SELF_SIGNED_CERT_IN_CHAIN',
|
|
33
|
+
'UNABLE_TO_VERIFY_LEAF_SIGNATURE',
|
|
34
|
+
'ERR_TLS_CERT_ALTNAME_INVALID',
|
|
35
|
+
'ERR_SSL_WRONG_VERSION_NUMBER',
|
|
36
|
+
]);
|
|
37
|
+
/** `AbortController.abort()` 抛出的 DOMException 没有 errno,统一用这个码表示「超时」。 */
|
|
38
|
+
export const ABORT_ERROR_CODE = 'ABORT_ERR';
|
|
39
|
+
function asRecord(value) {
|
|
40
|
+
return value && typeof value === 'object' ? value : null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 取错误链上最内层的系统错误码(`error.cause.code`);`AbortError` 归一化成
|
|
44
|
+
* `ABORT_ERR`。用 `seen` 防环:Node 的 cause 链偶尔会指回上层。
|
|
45
|
+
*/
|
|
46
|
+
export function readErrorCauseCode(error, maxDepth = 5) {
|
|
47
|
+
let current = error;
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
for (let depth = 0; depth < maxDepth; depth += 1) {
|
|
50
|
+
if (current === undefined || current === null || seen.has(current))
|
|
51
|
+
return undefined;
|
|
52
|
+
seen.add(current);
|
|
53
|
+
if (current instanceof Error && current.name === 'AbortError')
|
|
54
|
+
return ABORT_ERROR_CODE;
|
|
55
|
+
const record = asRecord(current);
|
|
56
|
+
if (!record)
|
|
57
|
+
return undefined;
|
|
58
|
+
if (record.name === 'AbortError')
|
|
59
|
+
return ABORT_ERROR_CODE;
|
|
60
|
+
const code = record.code;
|
|
61
|
+
if (typeof code === 'string' && code)
|
|
62
|
+
return code;
|
|
63
|
+
const errno = record.errno;
|
|
64
|
+
if (typeof errno === 'string' && errno)
|
|
65
|
+
return errno;
|
|
66
|
+
if (typeof errno === 'number')
|
|
67
|
+
return String(errno);
|
|
68
|
+
current = record.cause;
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
export function isAbortError(error) {
|
|
73
|
+
if (error instanceof Error && error.name === 'AbortError')
|
|
74
|
+
return true;
|
|
75
|
+
return asRecord(error)?.name === 'AbortError';
|
|
76
|
+
}
|
|
77
|
+
export function isNetworkErrorCode(code) {
|
|
78
|
+
return typeof code === 'string' && NETWORK_ERROR_CODES.has(code.toUpperCase());
|
|
79
|
+
}
|
|
80
|
+
/** undici 把底层原因藏起来时只剩这句话,但语义已经很明确了。 */
|
|
81
|
+
const TRANSPORT_MESSAGE_PATTERN = /fetch failed|socket hang up|other side closed|network|connection (?:refused|reset|closed)|timed? ?out|timeout|certificate|getaddrinfo|dns lookup/i;
|
|
82
|
+
export function looksLikeTransportMessage(message) {
|
|
83
|
+
return TRANSPORT_MESSAGE_PATTERN.test(message);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 给一次 fetch(含读响应体)套上超时。调用方必须在 `finally` 里 `clear()`,
|
|
87
|
+
* 否则进程会被这一个定时器拖住。
|
|
88
|
+
*/
|
|
89
|
+
export function createTimeoutSignal(timeoutMs) {
|
|
90
|
+
const controller = new AbortController();
|
|
91
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
92
|
+
return { signal: controller.signal, clear: () => clearTimeout(timer) };
|
|
93
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
2
|
import { classifyE10Redirect, isE10AuthenticationRequired, recoverXiaoEAuthSession, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
3
3
|
import { startFetchTiming } from './fetch-timing.js';
|
|
4
|
+
import { readErrorCauseCode } from './network-error.js';
|
|
4
5
|
import { E10_XIAOE_RECOVERY_FAILED_MESSAGE } from './auth/messages.js';
|
|
5
6
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
6
7
|
const DEFAULT_BIG_INT_STRINGS = true;
|
|
@@ -314,12 +315,17 @@ export class E10RequestRuntime {
|
|
|
314
315
|
throw new E10ApiError('network', 'timeout', `请求超时(${timeoutMs}ms)`, {
|
|
315
316
|
retryable: false,
|
|
316
317
|
exitCode: ExitCode.NetworkError,
|
|
318
|
+
details: { timeoutMs },
|
|
317
319
|
});
|
|
318
320
|
}
|
|
319
321
|
const message = error instanceof Error ? error.message : String(error);
|
|
322
|
+
// Node 的 `fetch failed` 不带原因,真正的 errno(ECONNREFUSED/ENOTFOUND…)
|
|
323
|
+
// 在 `error.cause.code` 上:保留下来才能区分「断网」与「服务端报错」。
|
|
324
|
+
const causeCode = readErrorCauseCode(error);
|
|
320
325
|
throw new E10ApiError('network', 'transport', `请求失败:${message}`, {
|
|
321
326
|
retryable: true,
|
|
322
327
|
exitCode: ExitCode.NetworkError,
|
|
328
|
+
...(causeCode ? { details: { causeCode } } : {}),
|
|
323
329
|
});
|
|
324
330
|
}
|
|
325
331
|
finally {
|
|
@@ -184,6 +184,36 @@ function firstId(value) {
|
|
|
184
184
|
return String(value);
|
|
185
185
|
return undefined;
|
|
186
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* 取「日程」应用 appId 与日程表单 formId(用于详情卡片页链接)。
|
|
189
|
+
* 偶发空返回时 getObjsByTag 原样重试最多 3 次。任一获取失败返回 null。
|
|
190
|
+
* 创建日程后需用 formId 拼卡片页链接,故抽为可复用函数。
|
|
191
|
+
*/
|
|
192
|
+
export async function fetchAgendaAppAndForm(host) {
|
|
193
|
+
const appIdsResponse = await host.request({
|
|
194
|
+
method: 'GET',
|
|
195
|
+
path: '/api/bs/ebuilder/app/tags/getAppIds',
|
|
196
|
+
operation: 'calendar.app.check',
|
|
197
|
+
query: { tag: AGENDA_APP_TAG },
|
|
198
|
+
}).catch(() => undefined);
|
|
199
|
+
const appId = firstId(appIdsResponse?.data);
|
|
200
|
+
let formId;
|
|
201
|
+
if (appId) {
|
|
202
|
+
for (let attempt = 0; attempt < 3 && !formId; attempt++) {
|
|
203
|
+
const formResponse = await host.request({
|
|
204
|
+
method: 'GET',
|
|
205
|
+
path: '/api/ebuilder/form/obj/getObjsByTag',
|
|
206
|
+
operation: 'calendar.app.check',
|
|
207
|
+
query: { tag: AGENDA_FORM_TAG, appId },
|
|
208
|
+
}).catch(() => undefined);
|
|
209
|
+
formId = firstId(formResponse?.data);
|
|
210
|
+
if (!formId && attempt < 2) {
|
|
211
|
+
await new Promise((resolve) => setTimeout(resolve, 800));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return { appId: appId ?? null, formId: formId ?? null };
|
|
216
|
+
}
|
|
187
217
|
const calendarAppCheck = {
|
|
188
218
|
name: 'calendar.app.check',
|
|
189
219
|
resource: 'calendar',
|
|
@@ -194,14 +224,7 @@ const calendarAppCheck = {
|
|
|
194
224
|
risk: 'read',
|
|
195
225
|
inputSchema: schemaOf({}),
|
|
196
226
|
handler: async (_args, { host }) => {
|
|
197
|
-
|
|
198
|
-
const appIdsResponse = await host.request({
|
|
199
|
-
method: 'GET',
|
|
200
|
-
path: '/api/bs/ebuilder/app/tags/getAppIds',
|
|
201
|
-
operation: 'calendar.app.check',
|
|
202
|
-
query: { tag: AGENDA_APP_TAG },
|
|
203
|
-
}).catch(() => undefined);
|
|
204
|
-
const appId = firstId(appIdsResponse?.data);
|
|
227
|
+
const { appId, formId } = await fetchAgendaAppAndForm(host);
|
|
205
228
|
if (!appId) {
|
|
206
229
|
return calendarSuccess('calendar.app.check', {
|
|
207
230
|
installed: false,
|
|
@@ -217,20 +240,6 @@ const calendarAppCheck = {
|
|
|
217
240
|
query: { appId },
|
|
218
241
|
}).catch(() => undefined);
|
|
219
242
|
const commitVersion = versionResponse?.data?.commitVersion ?? versionResponse?.commitVersion;
|
|
220
|
-
// 3. 查询日程表单 ID(偶发空返回,参数原样重试最多 3 次)
|
|
221
|
-
let formId;
|
|
222
|
-
for (let attempt = 0; attempt < 3 && !formId; attempt++) {
|
|
223
|
-
const formResponse = await host.request({
|
|
224
|
-
method: 'GET',
|
|
225
|
-
path: '/api/ebuilder/form/obj/getObjsByTag',
|
|
226
|
-
operation: 'calendar.app.check',
|
|
227
|
-
query: { tag: AGENDA_FORM_TAG, appId },
|
|
228
|
-
}).catch(() => undefined);
|
|
229
|
-
formId = firstId(formResponse?.data);
|
|
230
|
-
if (!formId && attempt < 2) {
|
|
231
|
-
await new Promise((resolve) => setTimeout(resolve, 800));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
243
|
const hasVersion = typeof commitVersion === 'string' && commitVersion.trim() !== '';
|
|
235
244
|
const installed = hasVersion && commitVersion !== null && commitVersion !== undefined;
|
|
236
245
|
const versionOk = installed && compareVersion(commitVersion, MIN_APP_VERSION) >= 0;
|
|
@@ -2,6 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { calendarConfirmationError, calendarPartialError, calendarValidationError, CalendarCliError } from '../errors.js';
|
|
3
3
|
import { calendarSuccess, schemaOf, SCHEMA_ID, SCHEMA_DATETIME_MINUTE, SCHEMA_SWITCH, SCHEMA_DATE } from './types.js';
|
|
4
4
|
import { assertDateTimeMinute, defaultEndTime, optionId, participantIds, pickDefined, } from './shared.js';
|
|
5
|
+
import { fetchAgendaAppAndForm } from './read.js';
|
|
5
6
|
const CONTINUATION_TTL_SECONDS = 600;
|
|
6
7
|
// 日程 mainTable 可选业务字段(创建/更新共用)
|
|
7
8
|
const OPTIONAL_FIELDS = [
|
|
@@ -81,6 +82,37 @@ async function verifyLease(args, action, env) {
|
|
|
81
82
|
function isNetworkError(error) {
|
|
82
83
|
return error instanceof CalendarCliError && error.type === 'network';
|
|
83
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* 从 saveFormData/createAgenda 返回体提取新建日程 ID。
|
|
87
|
+
* 兼容两种后端形态:
|
|
88
|
+
* - 顶层 `datajson.dataIds`(字符串数组)
|
|
89
|
+
* - `datajson.datas[].mainTable.dataIds` / `datajson.datas[].mainTable.id`
|
|
90
|
+
*/
|
|
91
|
+
function extractCreatedIds(response) {
|
|
92
|
+
const datajson = response?.datajson;
|
|
93
|
+
if (!datajson || typeof datajson !== 'object')
|
|
94
|
+
return [];
|
|
95
|
+
if (Array.isArray(datajson.dataIds)) {
|
|
96
|
+
return datajson.dataIds.map((v) => String(v)).filter(Boolean);
|
|
97
|
+
}
|
|
98
|
+
const datas = Array.isArray(datajson.datas) ? datajson.datas : [];
|
|
99
|
+
const ids = [];
|
|
100
|
+
for (const d of datas) {
|
|
101
|
+
const mt = d?.mainTable;
|
|
102
|
+
if (!mt)
|
|
103
|
+
continue;
|
|
104
|
+
if (Array.isArray(mt.dataIds))
|
|
105
|
+
ids.push(...mt.dataIds.map((v) => String(v)));
|
|
106
|
+
else if (mt.id !== undefined && mt.id !== null && mt.id !== '')
|
|
107
|
+
ids.push(String(mt.id));
|
|
108
|
+
}
|
|
109
|
+
return ids;
|
|
110
|
+
}
|
|
111
|
+
/** 拼日程详情卡片页链接(baseUrl 可能带协议头,统一归一成 https://host/...)。 */
|
|
112
|
+
function buildCardUrl(baseUrl, formId, id) {
|
|
113
|
+
const hostPart = String(baseUrl || '').replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
114
|
+
return `https://${hostPart}/sp/ebdfpage/card/0/${formId}/${id}`;
|
|
115
|
+
}
|
|
84
116
|
/** 构造写入接口 datajson 请求体(datas[].mainTable 结构)。 */
|
|
85
117
|
async function buildWriteDatajson(host, mainTableList) {
|
|
86
118
|
const session = await host.getSession();
|
|
@@ -195,9 +227,21 @@ const calendarCreateApply = {
|
|
|
195
227
|
}
|
|
196
228
|
throw error;
|
|
197
229
|
}
|
|
230
|
+
const createdIds = extractCreatedIds(response);
|
|
231
|
+
const createdId = createdIds[0];
|
|
232
|
+
const session = await env.host.getSession();
|
|
233
|
+
let accessUrl = null;
|
|
234
|
+
if (createdId) {
|
|
235
|
+
const { formId } = await fetchAgendaAppAndForm(env.host);
|
|
236
|
+
if (formId) {
|
|
237
|
+
accessUrl = buildCardUrl(session.baseUrl, formId, createdId);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
198
240
|
return calendarSuccess('calendar.create.apply', {
|
|
199
241
|
status: 'COMPLETE',
|
|
200
|
-
|
|
242
|
+
createdId: createdId ?? null,
|
|
243
|
+
createdIds,
|
|
244
|
+
accessUrl,
|
|
201
245
|
});
|
|
202
246
|
},
|
|
203
247
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoworkCliError, coworkNotFoundError, coworkPartialError, coworkValidationError } from '../errors.js';
|
|
2
2
|
import { READ_BEFORE_WRITE, WRITE, SCHEMA_ID, coworkSuccess, schemaOf, } from './types.js';
|
|
3
|
-
import { assertEnum, assertString, compact, normalizeList, requireConfirm, toBase64Html, toId, toPositiveInt, unwrapData, verifyLease, } from './shared.js';
|
|
3
|
+
import { assertEnum, assertString, compact, coworkViewUrl, normalizeList, requireConfirm, toBase64Html, toId, toPositiveInt, unwrapData, verifyLease, } from './shared.js';
|
|
4
4
|
function isNetworkError(error) {
|
|
5
5
|
return error instanceof CoworkCliError && error.type === 'network';
|
|
6
6
|
}
|
|
@@ -132,6 +132,8 @@ const discussPublishApply = {
|
|
|
132
132
|
coworkId,
|
|
133
133
|
sectionId,
|
|
134
134
|
status: data.status ?? root?.status ?? null,
|
|
135
|
+
viewUrl: coworkViewUrl(lease.baseUrl, coworkId),
|
|
136
|
+
mobileViewUrl: coworkViewUrl(lease.baseUrl, coworkId, true),
|
|
135
137
|
});
|
|
136
138
|
},
|
|
137
139
|
};
|
|
@@ -266,6 +268,8 @@ const discussActionApply = {
|
|
|
266
268
|
coworkId,
|
|
267
269
|
discussId,
|
|
268
270
|
result: unwrapData(response) ?? null,
|
|
271
|
+
viewUrl: coworkViewUrl(lease.baseUrl, coworkId),
|
|
272
|
+
mobileViewUrl: coworkViewUrl(lease.baseUrl, coworkId, true),
|
|
269
273
|
});
|
|
270
274
|
},
|
|
271
275
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoworkCliError, coworkNotFoundError, coworkPartialError, coworkValidationError } from '../errors.js';
|
|
2
2
|
import { READ_BEFORE_WRITE, WRITE, SCHEMA_ID, SCHEMA_DATETIME, coworkSuccess, schemaOf, } from './types.js';
|
|
3
|
-
import { assertEnum, assertString, requireConfirm, toBase64Html, toId, unwrapData, verifyLease, } from './shared.js';
|
|
3
|
+
import { assertEnum, assertString, coworkViewUrl, requireConfirm, toBase64Html, toId, unwrapData, verifyLease, } from './shared.js';
|
|
4
4
|
function isNetworkError(error) {
|
|
5
5
|
return error instanceof CoworkCliError && error.type === 'network';
|
|
6
6
|
}
|
|
@@ -114,12 +114,6 @@ function hashCode(text) {
|
|
|
114
114
|
}
|
|
115
115
|
return String(hash >>> 0);
|
|
116
116
|
}
|
|
117
|
-
function coworkViewUrl(baseUrl, id, mobile = false) {
|
|
118
|
-
if (!id)
|
|
119
|
-
return null;
|
|
120
|
-
const base = String(baseUrl || '').replace(/\/+$/, '');
|
|
121
|
-
return `${base}/${mobile ? 'mobile' : 'sp'}/cowork/view/${id}`;
|
|
122
|
-
}
|
|
123
117
|
function defaultEndTime() {
|
|
124
118
|
const target = new Date(Date.now() + 7 * 24 * 3600 * 1000);
|
|
125
119
|
const pad = (n) => String(n).padStart(2, '0');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoworkCliError, coworkNotFoundError, coworkPartialError, coworkValidationError } from '../errors.js';
|
|
2
2
|
import { READ_BEFORE_WRITE, WRITE, SCHEMA_ID, coworkSuccess, schemaOf, } from './types.js';
|
|
3
|
-
import { assertEnum, compact, normalizeList, requireConfirm, toId, toIdList, toPositiveInt, unwrapData, verifyLease, } from './shared.js';
|
|
3
|
+
import { assertEnum, compact, coworkViewUrl, normalizeList, requireConfirm, toId, toIdList, toPositiveInt, unwrapData, verifyLease, } from './shared.js';
|
|
4
4
|
function isNetworkError(error) {
|
|
5
5
|
return error instanceof CoworkCliError && error.type === 'network';
|
|
6
6
|
}
|
|
@@ -153,6 +153,8 @@ const memberActionApply = {
|
|
|
153
153
|
coworkId,
|
|
154
154
|
userIds: action === 'join' ? undefined : String(form.ids).split(','),
|
|
155
155
|
result: unwrapData(response) ?? null,
|
|
156
|
+
viewUrl: coworkViewUrl(lease.baseUrl, coworkId),
|
|
157
|
+
mobileViewUrl: coworkViewUrl(lease.baseUrl, coworkId, true),
|
|
156
158
|
});
|
|
157
159
|
},
|
|
158
160
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoworkCliError, coworkNotFoundError, coworkPartialError, coworkValidationError } from '../errors.js';
|
|
2
2
|
import { READ_BEFORE_WRITE, WRITE, SCHEMA_ID, coworkSuccess, schemaOf, } from './types.js';
|
|
3
|
-
import { normalizeList, requireConfirm, toId, unwrapData, verifyLease, } from './shared.js';
|
|
3
|
+
import { coworkViewUrl, normalizeList, requireConfirm, toId, unwrapData, verifyLease, } from './shared.js';
|
|
4
4
|
function isNetworkError(error) {
|
|
5
5
|
return error instanceof CoworkCliError && error.type === 'network';
|
|
6
6
|
}
|
|
@@ -163,6 +163,8 @@ const permAddApply = {
|
|
|
163
163
|
userId,
|
|
164
164
|
userName,
|
|
165
165
|
result: unwrapData(response) ?? null,
|
|
166
|
+
viewUrl: coworkViewUrl(lease.baseUrl, coworkId),
|
|
167
|
+
mobileViewUrl: coworkViewUrl(lease.baseUrl, coworkId, true),
|
|
166
168
|
});
|
|
167
169
|
},
|
|
168
170
|
};
|
|
@@ -275,6 +277,8 @@ const permRemoveApply = {
|
|
|
275
277
|
removed: stillThere === false ? true : undefined,
|
|
276
278
|
verified: stillThere !== null,
|
|
277
279
|
result: unwrapData(response) ?? null,
|
|
280
|
+
viewUrl: coworkViewUrl(lease.baseUrl, coworkId),
|
|
281
|
+
mobileViewUrl: coworkViewUrl(lease.baseUrl, coworkId, true),
|
|
278
282
|
});
|
|
279
283
|
},
|
|
280
284
|
};
|
|
@@ -88,6 +88,13 @@ export function unwrapData(response) {
|
|
|
88
88
|
return response;
|
|
89
89
|
return response.data;
|
|
90
90
|
}
|
|
91
|
+
/** 协作查看页地址:PC `/sp/cowork/view/{id}`、移动端 `/mobile/cowork/view/{id}`(真实环境取证形态,禁止改拼)。 */
|
|
92
|
+
export function coworkViewUrl(baseUrl, id, mobile = false) {
|
|
93
|
+
if (!id)
|
|
94
|
+
return null;
|
|
95
|
+
const base = String(baseUrl || '').replace(/\/+$/, '');
|
|
96
|
+
return `${base}/${mobile ? 'mobile' : 'sp'}/cowork/view/${id}`;
|
|
97
|
+
}
|
|
91
98
|
/** 协作列表的 data 形如 { pageSize, total, current, pageUid, columns[], data[] }。 */
|
|
92
99
|
export function normalizePaged(response) {
|
|
93
100
|
const data = unwrapData(response);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { ehrConfirmationError, ehrPartialError, ehrValidationError, EhrCliError } from '../errors.js';
|
|
3
3
|
import { READ, SCHEMA_DATE, SCHEMA_ID, ehrSuccess, schemaOf, WRITE, } from './types.js';
|
|
4
|
-
import { assertEnum, assertEnumArray, compact, pickDefined, toIdList } from './shared.js';
|
|
4
|
+
import { assertEnum, assertEnumArray, compact, pickDefined, toIdList, EHR_PAGES, ehrPageUrl, addDays } from './shared.js';
|
|
5
5
|
const CONTINUATION_TTL_SECONDS = 600;
|
|
6
6
|
const CARD_TYPES = ['CHECKIN', 'CHECKOUT', 'LEAVE', 'RETURN', 'CHECKIN_AND_RETURN', 'CHECKOUT_AND_LEAVE'];
|
|
7
7
|
const APPEAL_TYPES = [
|
|
@@ -316,9 +316,51 @@ const ehrAttendAppealSaveApply = {
|
|
|
316
316
|
}
|
|
317
317
|
throw error;
|
|
318
318
|
}
|
|
319
|
+
// 回执(按 references/attend-appeal-save.md 契约,2026-11-04):
|
|
320
|
+
// ① 回查申诉列表定位本次新建记录(日期前后各放宽 1 天,防跨天/时区边界漏查);
|
|
321
|
+
// ② 返回 appealListUrl(考勤异常/申诉页面,已取证路由)。
|
|
322
|
+
// 回查失败不阻塞提交结果(提交已成功),以 locateWarning 如实提示。
|
|
323
|
+
const session = await env.host.getSession();
|
|
324
|
+
const appealListUrl = ehrPageUrl(session.baseUrl, EHR_PAGES.attendAbnormal);
|
|
325
|
+
let appeal = null;
|
|
326
|
+
let locateWarning;
|
|
327
|
+
try {
|
|
328
|
+
const listResp = await env.host.request({
|
|
329
|
+
method: 'POST',
|
|
330
|
+
path: '/api/attend/web/appeal/getAppealList',
|
|
331
|
+
body: {
|
|
332
|
+
beginDate: addDays(String(args.attendDay), -1),
|
|
333
|
+
endDate: addDays(String(args.attendDay), 1),
|
|
334
|
+
current: 1,
|
|
335
|
+
pageSize: 50,
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
const payload = listResp?.data;
|
|
339
|
+
const rows = Array.isArray(payload?.data) ? payload.data
|
|
340
|
+
: Array.isArray(payload?.rows) ? payload.rows
|
|
341
|
+
: Array.isArray(payload) ? payload
|
|
342
|
+
: [];
|
|
343
|
+
const day = String(args.attendDay);
|
|
344
|
+
const desc = String(args.appealDesc ?? '');
|
|
345
|
+
const pick = rows.find((r) => String(r?.attendDay ?? r?.attend_date ?? r?.attendDate ?? '').startsWith(day))
|
|
346
|
+
|| (desc ? rows.find((r) => String(r?.appealDesc ?? r?.appeal_desc ?? '').includes(desc)) : null)
|
|
347
|
+
|| null;
|
|
348
|
+
if (pick)
|
|
349
|
+
appeal = pick;
|
|
350
|
+
else
|
|
351
|
+
locateWarning = '未在申诉列表中定位到本次记录(可能刚提交尚在同步),请稍后用 ehr.attend.appeal.list 复核';
|
|
352
|
+
}
|
|
353
|
+
catch (e) {
|
|
354
|
+
locateWarning = '申诉列表回查失败:' + (e?.message || '未知原因') + ';请稍后用 ehr.attend.appeal.list 复核';
|
|
355
|
+
}
|
|
319
356
|
return ehrSuccess('ehr.attend.appeal.save.apply', {
|
|
320
357
|
status: 'COMPLETE',
|
|
321
358
|
result: response?.data,
|
|
359
|
+
/** 定位到的新建申诉记录(含申诉 ID 等,处理申诉时用其 id) */
|
|
360
|
+
appeal,
|
|
361
|
+
/** 考勤异常/申诉页面地址(已取证路由,禁止改拼) */
|
|
362
|
+
appealListUrl,
|
|
363
|
+
...(locateWarning ? { locateWarning } : {}),
|
|
322
364
|
verifyHint: '可通过 ehr.attend.appeal.list 回查申诉是否已生成',
|
|
323
365
|
});
|
|
324
366
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ehrValidationError } from '../errors.js';
|
|
2
2
|
import { READ, SCHEMA_DATE, SCHEMA_ID, SCHEMA_ID_LIST, ehrSuccess, schemaOf, } from './types.js';
|
|
3
|
-
import { assertDateRange, assertEnum, compact, normalizePaged, pickDefined, toIdList, toNumber, toPositiveInt, } from './shared.js';
|
|
3
|
+
import { assertDateRange, assertEnum, compact, normalizePaged, pickDefined, toIdList, toNumber, toPositiveInt, EHR_PAGES, ehrPageUrl, } from './shared.js';
|
|
4
4
|
const BROWSER_TYPES = ['department', 'subcompany', 'position', 'resource', 'jobsetid', 'grade'];
|
|
5
5
|
const USERNAME_OPERATORS = ['in', 'notIn', 'eq', 'notEq'];
|
|
6
6
|
const PERSONNEL_STATUS = ['all', 'normal', '1', '2', '3', '4', '5', '6', '7', '9', '10'];
|
|
@@ -139,7 +139,8 @@ const contactSearch = {
|
|
|
139
139
|
body: compact(body),
|
|
140
140
|
});
|
|
141
141
|
const { data, page } = normalizePaged(response);
|
|
142
|
-
|
|
142
|
+
const hrSession = await host.getSession();
|
|
143
|
+
return ehrSuccess('ehr.hr.contact.search', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrEmployeeManager), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
143
144
|
},
|
|
144
145
|
};
|
|
145
146
|
const contactCount = {
|
|
@@ -268,7 +269,8 @@ const birthdayList = {
|
|
|
268
269
|
body,
|
|
269
270
|
});
|
|
270
271
|
const { data, page } = normalizePaged(response);
|
|
271
|
-
|
|
272
|
+
const hrSession = await host.getSession();
|
|
273
|
+
return ehrSuccess('ehr.hr.birthday.list', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrBirthdayList), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
272
274
|
},
|
|
273
275
|
};
|
|
274
276
|
const empchangeConditions = {
|
|
@@ -347,7 +349,8 @@ const empchangeList = {
|
|
|
347
349
|
body: compact(body),
|
|
348
350
|
});
|
|
349
351
|
const { data, page } = normalizePaged(response);
|
|
350
|
-
|
|
352
|
+
const hrSession = await host.getSession();
|
|
353
|
+
return ehrSuccess('ehr.hr.empchange.list', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrPersonalStateChange), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
351
354
|
},
|
|
352
355
|
};
|
|
353
356
|
export const hrContactOperations = [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ehrValidationError } from '../errors.js';
|
|
2
2
|
import { READ, SCHEMA_DATE, SCHEMA_ID, SCHEMA_ID_LIST, SCHEMA_STRING_LIST, ehrSuccess, schemaOf, } from './types.js';
|
|
3
|
-
import { assertEnum, compact, normalizePaged, toIdList, toNumber, toPositiveInt } from './shared.js';
|
|
3
|
+
import { assertEnum, compact, normalizePaged, toIdList, toNumber, toPositiveInt, EHR_PAGES, ehrPageUrl } from './shared.js';
|
|
4
4
|
const EST_DATA_TYPES = [
|
|
5
5
|
'numberingCount',
|
|
6
6
|
'numberingCountWithSub',
|
|
@@ -74,7 +74,8 @@ const reportDeptTable = {
|
|
|
74
74
|
body: buildPersonReport(args, 'departmentName'),
|
|
75
75
|
});
|
|
76
76
|
const { data, page } = normalizePaged(response);
|
|
77
|
-
|
|
77
|
+
const hrSession = await host.getSession();
|
|
78
|
+
return ehrSuccess('ehr.hr.report.dept.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrReportDeptPerson), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
78
79
|
},
|
|
79
80
|
};
|
|
80
81
|
const reportPosiTable = {
|
|
@@ -93,7 +94,8 @@ const reportPosiTable = {
|
|
|
93
94
|
body: buildPersonReport(args, 'positionName'),
|
|
94
95
|
});
|
|
95
96
|
const { data, page } = normalizePaged(response);
|
|
96
|
-
|
|
97
|
+
const hrSession = await host.getSession();
|
|
98
|
+
return ehrSuccess('ehr.hr.report.posi.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrReportPosiPerson), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
97
99
|
},
|
|
98
100
|
};
|
|
99
101
|
const reportJobTable = {
|
|
@@ -112,7 +114,8 @@ const reportJobTable = {
|
|
|
112
114
|
body: buildPersonReport(args, 'jobName'),
|
|
113
115
|
});
|
|
114
116
|
const { data, page } = normalizePaged(response);
|
|
115
|
-
|
|
117
|
+
const hrSession = await host.getSession();
|
|
118
|
+
return ehrSuccess('ehr.hr.report.job.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrReportJobPerson), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
116
119
|
},
|
|
117
120
|
};
|
|
118
121
|
const reportJobTypeTable = {
|
|
@@ -214,7 +217,8 @@ const estEmpTable = {
|
|
|
214
217
|
},
|
|
215
218
|
});
|
|
216
219
|
const { data, page } = normalizePaged(response);
|
|
217
|
-
|
|
220
|
+
const hrSession = await host.getSession();
|
|
221
|
+
return ehrSuccess('ehr.hr.est.emp.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrTpReportTp), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
218
222
|
},
|
|
219
223
|
};
|
|
220
224
|
const estDcEmpTable = {
|
|
@@ -258,7 +262,8 @@ const estDcEmpTable = {
|
|
|
258
262
|
},
|
|
259
263
|
});
|
|
260
264
|
const { data, page } = normalizePaged(response);
|
|
261
|
-
|
|
265
|
+
const hrSession = await host.getSession();
|
|
266
|
+
return ehrSuccess('ehr.hr.est.dc.emp.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrTpReportHw), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
262
267
|
},
|
|
263
268
|
};
|
|
264
269
|
const turnEmpTable = {
|
|
@@ -305,7 +310,8 @@ const turnEmpTable = {
|
|
|
305
310
|
body,
|
|
306
311
|
});
|
|
307
312
|
const { data, page } = normalizePaged(response);
|
|
308
|
-
|
|
313
|
+
const hrSession = await host.getSession();
|
|
314
|
+
return ehrSuccess('ehr.hr.turn.emp.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrTpReportTurn), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
|
|
309
315
|
},
|
|
310
316
|
};
|
|
311
317
|
const propsSa = {
|