weaver-work-cli 0.1.39 → 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/README.md +4 -2
- package/dist/chunks/{archive-ENZYBBME.js → archive-J4I6MCKF.js} +2 -2
- package/dist/chunks/{archive-oa-YWLEC5V4.js → archive-oa-BRZKKTO4.js} +2 -2
- package/dist/chunks/{asset-OOV6DWPA.js → asset-L7D4FAOZ.js} +2 -2
- package/dist/chunks/{asset-idle-RE632MY5.js → asset-idle-DADLLV75.js} +2 -2
- package/dist/chunks/{attachment-content-RWN2FCLL.js → attachment-content-K4C7VLWQ.js} +3 -3
- package/dist/chunks/{blog-PEPOJAL7.js → blog-BVGQ7NZL.js} +2 -2
- package/dist/chunks/{caizhilian-WYIQDVPJ.js → caizhilian-SAADNFD6.js} +2 -2
- package/dist/chunks/{calendar-CIARBAOX.js → calendar-Q7NQY5Z2.js} +61 -23
- package/dist/chunks/{chunk-F2EQXUEE.js → chunk-3KTFS4IA.js} +397 -159
- package/dist/chunks/{chunk-G2JSIUWF.js → chunk-4PD5NWAX.js} +89 -0
- package/dist/chunks/{chunk-HJYVHXUQ.js → chunk-4RAE6JXP.js} +1 -1
- package/dist/chunks/{chunk-CQHGNCK2.js → chunk-72CKAUAG.js} +41 -8
- package/dist/chunks/{chunk-K3RUEEOL.js → chunk-APVFJUQH.js} +2 -2
- package/dist/chunks/{chunk-BJGXMFGD.js → chunk-BBKDXQEC.js} +2 -2
- package/dist/chunks/chunk-BIPYLLVS.js +501 -0
- package/dist/chunks/{chunk-GVPJZXJ2.js → chunk-EKWAQSLU.js} +92 -50
- package/dist/chunks/{chunk-XXJOSZTQ.js → chunk-FOAA27U5.js} +381 -57
- package/dist/chunks/{chunk-I2HB737U.js → chunk-G4UR6NXN.js} +2 -2
- package/dist/chunks/{chunk-YS5DPN4T.js → chunk-GEWYMQME.js} +1 -1
- package/dist/chunks/{chunk-P2DAISYW.js → chunk-GHXCDPTM.js} +1 -1
- package/dist/chunks/{chunk-L4N7B7ZD.js → chunk-IZ7S7QUS.js} +4 -4
- package/dist/chunks/{chunk-NLK2RZKG.js → chunk-JPRO6ER2.js} +122 -2214
- package/dist/chunks/{chunk-36DIFZAH.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-EINRJHQ3.js → chunk-QKNKR4RH.js} +3 -3
- package/dist/chunks/{chunk-T7JDJJ7H.js → chunk-R4CHUSKC.js} +126 -19
- package/dist/chunks/{chunk-EZGFHJFW.js → chunk-SA6VBIHY.js} +88 -15
- package/dist/chunks/{chunk-ZXRNHZTE.js → chunk-TTPJJJC4.js} +2 -2
- package/dist/chunks/{chunk-KTCB5R5H.js → chunk-W7BEHOSR.js} +2 -2
- package/dist/chunks/{chunk-MUQUHKPG.js → chunk-YRSZQUD2.js} +2 -2
- package/dist/chunks/{conflict-DRMDOL56.js → conflict-F2OMZRTO.js} +2 -2
- package/dist/chunks/{contract-73MERZWN.js → contract-5BETHRSG.js} +2 -2
- package/dist/chunks/{cowork-HNGBPD7A.js → cowork-3MN6EQQO.js} +27 -10
- package/dist/chunks/create-flow-5FQNNMVO.js +55 -0
- package/dist/chunks/{ebuilder-form-OY6DVNRK.js → ebuilder-form-SBHOYBUD.js} +3 -3
- package/dist/chunks/{ehr-RAQNEQO7.js → ehr-KMOJULKG.js} +432 -1234
- package/dist/chunks/env-LB7NBL2O.js +19 -0
- package/dist/chunks/{esb-6XV7C7YV.js → esb-W2PJCFCX.js} +4 -4
- package/dist/chunks/factory-6ZFQXQ46.js +30 -0
- package/dist/chunks/{fna-XTSRB7G7.js → fna-ZQPCUV4R.js} +2 -2
- package/dist/chunks/group-chat-2HHAJN46.js +20 -0
- package/dist/chunks/{host-YMBXWFWX.js → host-4CBHGOHT.js} +3 -3
- package/dist/chunks/{host-A7J6GDUP.js → host-ATKVNZAT.js} +3 -3
- package/dist/chunks/{host-3F5UM5GN.js → host-BQH22NTQ.js} +3 -3
- package/dist/chunks/{host-YAQAPYNP.js → host-X2CSLFM6.js} +3 -3
- package/dist/chunks/{host-VGPVP7YF.js → host-YTODKMSL.js} +3 -3
- package/dist/chunks/{hrm-TLHKC545.js → hrm-FFM4UJFS.js} +4 -4
- package/dist/chunks/{im-YOUCFMUK.js → im-VEHKDQPB.js} +8 -8
- package/dist/chunks/{invoice-WNBS2B4C.js → invoice-LVIKSIIF.js} +3 -3
- package/dist/chunks/{jiuchuanhui-XABWS5RN.js → jiuchuanhui-X6DINO5P.js} +2 -2
- package/dist/chunks/{lazy-dispatch-NLZ5UQQI.js → lazy-dispatch-KSWTN5L6.js} +4 -4
- package/dist/chunks/{mail-LRYMBFNL.js → mail-VDKRGUD3.js} +9 -4
- package/dist/chunks/{meeting-ESXL6MFI.js → meeting-CLC6HP3Z.js} +12 -10
- package/dist/chunks/{okr-EOV65SSF.js → okr-CHG4OO3U.js} +2 -2
- package/dist/chunks/{plan-YFPVKW6Y.js → plan-XWR75667.js} +2 -2
- package/dist/chunks/{project-MDVZUYQW.js → project-5BXOOKMG.js} +40 -23
- package/dist/chunks/recruit-stage-DGMFNNDE.js +4507 -0
- package/dist/chunks/{registry-VT5Y2HLA.js → registry-7FFOXIAW.js} +4 -4
- package/dist/chunks/{registry-QCLZEDAP.js → registry-BKBZPBAJ.js} +10 -8
- package/dist/chunks/{registry-YX4CSEMD.js → registry-RHMW6ANW.js} +2 -2
- package/dist/chunks/{registry-NYPYMZXG.js → registry-Z43434VG.js} +1 -1
- package/dist/chunks/{room-recommend-L3MWH4JW.js → room-recommend-62H7ZQQ6.js} +4 -4
- package/dist/chunks/{schedule-UASAVDVD.js → schedule-FNXKH3DQ.js} +4 -4
- package/dist/chunks/{workflow-KDGIUCNW.js → workflow-ADHKCAJK.js} +4 -4
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/commands.js +110 -56
- package/dist/internal/e10/auth/messages.js +6 -0
- package/dist/internal/e10/auth/session.js +28 -1
- package/dist/internal/e10/auth/xiaoe.js +315 -48
- package/dist/internal/e10/auth-recovery.js +36 -5
- package/dist/internal/e10/client.js +13 -0
- package/dist/internal/e10/context.js +61 -9
- package/dist/internal/e10/index.js +1 -1
- package/dist/internal/e10/network-error.js +93 -0
- package/dist/internal/e10/request-runtime.js +15 -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 +5 -3
- 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/mail/operations/mail-send.js +8 -2
- package/dist/shortcuts/meeting/operations/eb/catalog.js +9 -2
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +461 -127
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +87 -5
- package/dist/shortcuts/meeting/operations/eb/factory.js +33 -0
- package/dist/shortcuts/meeting/operations/eb/flow-memory.js +49 -0
- package/dist/shortcuts/meeting/operations/eb/group-chat.js +605 -0
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/person-cache.js +96 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +44 -6
- package/dist/shortcuts/meeting/operations/eb/room-summary.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/usage-cache.js +99 -0
- package/dist/shortcuts/meeting/operations/from-group-chat.js +35 -12
- package/dist/shortcuts/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/form.js +21 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +52 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +19 -11
- 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 +78 -10
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +3 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +17 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +16 -40
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +3 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +52 -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 +53 -16
- package/docs/e10-auth.md +22 -1
- package/docs/operation-manual.md +8 -0
- package/package.json +1 -1
- package/scripts/install-skill-to-xiaoe.mjs +105 -0
- package/scripts/mcp-meeting.mjs +234 -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-mail/references/mail-send.md +2 -0
- package/skills/weaver-e10-meeting/SKILL.md +119 -26
- package/skills/weaver-e10-meeting/references/meeting-minute-file.md +25 -11
- 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 +2 -2
- 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 +7 -1
- package/skills/weaver-e10-workflow/aigroup/default.json +23 -9
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +37 -21
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +135 -43
- package/skills/weaver-e10-yepiaotong/SKILL.md +9 -10
- package/skills/weaver-e10-yepiaotong/references/invoice-agent-entry.md +6 -3
|
@@ -0,0 +1,1238 @@
|
|
|
1
|
+
import { createRequire as __esbuildCreateRequire } from 'node:module';
|
|
2
|
+
const require = __esbuildCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
CliError
|
|
5
|
+
} from "./chunk-LUSPKZKY.js";
|
|
6
|
+
|
|
7
|
+
// src/shortcuts/ehr/errors.ts
|
|
8
|
+
var EhrCliError = class extends CliError {
|
|
9
|
+
type;
|
|
10
|
+
subtype;
|
|
11
|
+
code;
|
|
12
|
+
retryable;
|
|
13
|
+
stage;
|
|
14
|
+
details;
|
|
15
|
+
partialData;
|
|
16
|
+
constructor(type, subtype, message, options = {}) {
|
|
17
|
+
super(message, options.exitCode ?? 5 /* InternalError */);
|
|
18
|
+
this.name = "EhrCliError";
|
|
19
|
+
this.type = type;
|
|
20
|
+
this.subtype = subtype;
|
|
21
|
+
this.code = options.code;
|
|
22
|
+
this.retryable = options.retryable ?? false;
|
|
23
|
+
this.stage = options.stage;
|
|
24
|
+
this.details = options.details;
|
|
25
|
+
this.partialData = options.partialData;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
function ehrValidationError(subtype, message, details) {
|
|
29
|
+
return new EhrCliError("validation", subtype, message, {
|
|
30
|
+
details,
|
|
31
|
+
exitCode: 2 /* UsageError */
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function ehrAuthError(subtype, message, details) {
|
|
35
|
+
return new EhrCliError("authentication", subtype, message, {
|
|
36
|
+
details,
|
|
37
|
+
exitCode: 3 /* AuthError */
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function ehrNetworkError(subtype, message, options = {}) {
|
|
41
|
+
return new EhrCliError("network", subtype, message, {
|
|
42
|
+
...options,
|
|
43
|
+
retryable: options.retryable ?? true,
|
|
44
|
+
exitCode: 4 /* NetworkError */
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function ehrConfirmationError(action, details) {
|
|
48
|
+
return new EhrCliError("confirmation", "required", "\u8BE5\u64CD\u4F5C\u9700\u8981\u660E\u786E\u786E\u8BA4", {
|
|
49
|
+
details: { action, ...details },
|
|
50
|
+
exitCode: 10 /* ConfirmationRequired */
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function ehrPartialError(message, partialData, details) {
|
|
54
|
+
return new EhrCliError("partial", "write_uncertain", message, {
|
|
55
|
+
details,
|
|
56
|
+
partialData,
|
|
57
|
+
exitCode: 11 /* Partial */
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/shortcuts/ehr/operations/shared.ts
|
|
62
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
63
|
+
function asObject(value) {
|
|
64
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
65
|
+
throw ehrValidationError("input_not_object", "\u8F93\u5165\u5FC5\u987B\u662F JSON \u5BF9\u8C61");
|
|
66
|
+
}
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
function assertNoForbiddenKeys(input) {
|
|
70
|
+
for (const key of Object.keys(input)) {
|
|
71
|
+
if (FORBIDDEN_KEYS.has(key)) {
|
|
72
|
+
throw ehrValidationError("forbidden_key", `\u8F93\u5165\u5305\u542B\u975E\u6CD5\u5B57\u6BB5\uFF1A${key}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
var DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
77
|
+
var MONTH_PATTERN = /^\d{4}-\d{2}$/;
|
|
78
|
+
function isDate(value) {
|
|
79
|
+
return typeof value === "string" && DATE_PATTERN.test(value);
|
|
80
|
+
}
|
|
81
|
+
function isMonth(value) {
|
|
82
|
+
return typeof value === "string" && MONTH_PATTERN.test(value);
|
|
83
|
+
}
|
|
84
|
+
function isRealDate(value) {
|
|
85
|
+
const [year, month, day] = value.split("-").map(Number);
|
|
86
|
+
if (month < 1 || month > 12) return false;
|
|
87
|
+
const daysInMonth = new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
88
|
+
return day >= 1 && day <= daysInMonth;
|
|
89
|
+
}
|
|
90
|
+
function assertDate(value, field) {
|
|
91
|
+
if (!isDate(value)) throw ehrValidationError("date_invalid", `${field} \u5FC5\u987B\u662F YYYY-MM-DD \u683C\u5F0F`);
|
|
92
|
+
const text = value;
|
|
93
|
+
if (!isRealDate(text)) {
|
|
94
|
+
throw ehrValidationError("date_invalid", `${field} \u4E0D\u662F\u5408\u6CD5\u65E5\u671F\uFF08\u6708\u4EFD\u9700 01-12\uFF0C\u65E5\u671F\u9700\u5728\u8BE5\u6708\u6709\u6548\u8303\u56F4\u5185\uFF09\uFF1A${text}`);
|
|
95
|
+
}
|
|
96
|
+
return text;
|
|
97
|
+
}
|
|
98
|
+
function assertMonth(value, field) {
|
|
99
|
+
if (!isMonth(value)) throw ehrValidationError("month_invalid", `${field} \u5FC5\u987B\u662F YYYY-MM \u683C\u5F0F`);
|
|
100
|
+
const text = value;
|
|
101
|
+
const month = Number(text.slice(5));
|
|
102
|
+
if (month < 1 || month > 12) {
|
|
103
|
+
throw ehrValidationError("month_invalid", `${field} \u7684\u6708\u4EFD\u5FC5\u987B\u5728 01-12\uFF1A${text}`);
|
|
104
|
+
}
|
|
105
|
+
return text;
|
|
106
|
+
}
|
|
107
|
+
function toNumber(value, field) {
|
|
108
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
109
|
+
const numeric = Number(value);
|
|
110
|
+
if (!Number.isFinite(numeric)) {
|
|
111
|
+
throw ehrValidationError("number_invalid", `${field} \u5FC5\u987B\u662F\u6570\u5B57`);
|
|
112
|
+
}
|
|
113
|
+
return numeric;
|
|
114
|
+
}
|
|
115
|
+
function toPositiveInt(value, field) {
|
|
116
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
117
|
+
const numeric = Number(value);
|
|
118
|
+
if (!Number.isFinite(numeric)) {
|
|
119
|
+
throw ehrValidationError("number_invalid", `${field} \u5FC5\u987B\u662F\u6570\u5B57`);
|
|
120
|
+
}
|
|
121
|
+
const truncated = Math.trunc(numeric);
|
|
122
|
+
if (truncated !== numeric || truncated <= 0) {
|
|
123
|
+
throw ehrValidationError("number_invalid", `${field} \u5FC5\u987B\u662F\u6B63\u6574\u6570`);
|
|
124
|
+
}
|
|
125
|
+
return truncated;
|
|
126
|
+
}
|
|
127
|
+
function toIdList(value, field) {
|
|
128
|
+
if (value === void 0 || value === null) return void 0;
|
|
129
|
+
if (!Array.isArray(value)) throw ehrValidationError("id_list_invalid", `${field} \u5FC5\u987B\u662F ID \u6570\u7EC4`);
|
|
130
|
+
return value.map((item, index) => {
|
|
131
|
+
if (item === void 0 || item === null || item === "") {
|
|
132
|
+
throw ehrValidationError("id_list_invalid", `${field}[${index}] \u4E0D\u80FD\u4E3A\u7A7A`);
|
|
133
|
+
}
|
|
134
|
+
const numeric = Number(item);
|
|
135
|
+
if (!Number.isFinite(numeric)) {
|
|
136
|
+
throw ehrValidationError("id_list_invalid", `${field}[${index}] \u5FC5\u987B\u662F\u6570\u5B57 ID`);
|
|
137
|
+
}
|
|
138
|
+
return numeric;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function pickDefined(value, keys) {
|
|
142
|
+
const result = {};
|
|
143
|
+
for (const key of keys) {
|
|
144
|
+
if (value[key] !== void 0) result[key] = value[key];
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
function compact(body) {
|
|
149
|
+
for (const key of Object.keys(body)) {
|
|
150
|
+
if (body[key] === void 0) delete body[key];
|
|
151
|
+
}
|
|
152
|
+
return body;
|
|
153
|
+
}
|
|
154
|
+
function assertDateRange(args, startField, endField) {
|
|
155
|
+
const start = args[startField];
|
|
156
|
+
const end = args[endField];
|
|
157
|
+
if ((start === void 0 || start === null) !== (end === void 0 || end === null)) {
|
|
158
|
+
throw ehrValidationError("date_range_incomplete", `${startField} \u4E0E ${endField} \u5FC5\u987B\u6210\u5BF9\u63D0\u4F9B`);
|
|
159
|
+
}
|
|
160
|
+
if (start === void 0 || start === null) return {};
|
|
161
|
+
const startDate = assertDate(start, startField);
|
|
162
|
+
const endDate = assertDate(end, endField);
|
|
163
|
+
if (startDate > endDate) {
|
|
164
|
+
throw ehrValidationError("date_range_invalid", `${startField} \u4E0D\u5F97\u665A\u4E8E ${endField}`);
|
|
165
|
+
}
|
|
166
|
+
return { start: startDate, end: endDate };
|
|
167
|
+
}
|
|
168
|
+
function requireDateRange(args, startField = "beginDate", endField = "endDate") {
|
|
169
|
+
const start = args[startField];
|
|
170
|
+
const end = args[endField];
|
|
171
|
+
if (start === void 0 || start === null || start === "" || end === void 0 || end === null || end === "") {
|
|
172
|
+
throw ehrValidationError("date_range_required", `${startField} \u4E0E ${endField} \u5FC5\u586B\uFF0C\u683C\u5F0F YYYY-MM-DD`);
|
|
173
|
+
}
|
|
174
|
+
const range = assertDateRange(args, startField, endField);
|
|
175
|
+
return { beginDate: range.start, endDate: range.end };
|
|
176
|
+
}
|
|
177
|
+
function unwrapData(response) {
|
|
178
|
+
if (!response || typeof response !== "object") return response;
|
|
179
|
+
return response.data;
|
|
180
|
+
}
|
|
181
|
+
function normalizePaged(response) {
|
|
182
|
+
const data = unwrapData(response);
|
|
183
|
+
const page = {};
|
|
184
|
+
const candidates = [data?.page, response?.page, data, response];
|
|
185
|
+
for (const source of candidates) {
|
|
186
|
+
if (!source || typeof source !== "object") continue;
|
|
187
|
+
for (const key of ["pageNo", "current", "pageSize", "total", "totalCount", "totalPage", "tableId"]) {
|
|
188
|
+
if (source[key] !== void 0 && page[key] === void 0) page[key] = source[key];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return { data, page };
|
|
192
|
+
}
|
|
193
|
+
function toPageQuery(args) {
|
|
194
|
+
const page = {};
|
|
195
|
+
const current = toPositiveInt(args?.current, "current");
|
|
196
|
+
const pageSize = toNumber(args?.pageSize, "pageSize");
|
|
197
|
+
const pageNo = toNumber(args?.pageNo, "pageNo");
|
|
198
|
+
if (current !== void 0) page.current = current;
|
|
199
|
+
if (pageSize !== void 0) page.pageSize = pageSize;
|
|
200
|
+
if (pageNo !== void 0) page.pageNo = pageNo;
|
|
201
|
+
return page;
|
|
202
|
+
}
|
|
203
|
+
var SECOND_AUTH_TOKEN_DEFAULT = "DONT_NEED";
|
|
204
|
+
function resolveSecondAuthToken(value) {
|
|
205
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
206
|
+
return SECOND_AUTH_TOKEN_DEFAULT;
|
|
207
|
+
}
|
|
208
|
+
function assertEnum(value, allowed, field) {
|
|
209
|
+
const text = typeof value === "string" ? value : String(value);
|
|
210
|
+
if (!allowed.includes(text)) {
|
|
211
|
+
throw ehrValidationError("enum_invalid", `${field} \u53D6\u503C\u5FC5\u987B\u662F ${allowed.join(" / ")} \u4E4B\u4E00`);
|
|
212
|
+
}
|
|
213
|
+
return text;
|
|
214
|
+
}
|
|
215
|
+
var EHR_PAGES = {
|
|
216
|
+
/** 考勤异常/申诉页面(创建的申诉在此可查) */
|
|
217
|
+
attendAbnormal: "/sp/attend/abnormal",
|
|
218
|
+
/** 在职员工名册(原通讯录) */
|
|
219
|
+
hrEmployeeManager: "/sp/hrm/hr/employeeManager",
|
|
220
|
+
/** 生日名单 */
|
|
221
|
+
hrBirthdayList: "/sp/hrm/hr/birthday/list",
|
|
222
|
+
/** 人员状态变更记录 */
|
|
223
|
+
hrPersonalStateChange: "/sp/hrm/hr/personalStateChange/record",
|
|
224
|
+
/** 时点员工名册 */
|
|
225
|
+
hrTpReportTp: "/sp/hrm/hr/tpReport/tp",
|
|
226
|
+
/** 历史曾在职名册 */
|
|
227
|
+
hrTpReportHw: "/sp/hrm/hr/tpReport/hw",
|
|
228
|
+
/** 离职员工名册 */
|
|
229
|
+
hrTpReportDismiss: "/sp/hrm/hr/tpReport/dismiss",
|
|
230
|
+
/** 人员流动分析表 */
|
|
231
|
+
hrTpReportTurn: "/sp/hrm/hr/tpReport/turn",
|
|
232
|
+
/** 基本状况分析 */
|
|
233
|
+
hrReportBasePerson: "/sp/hrm/hr/reportForm/basePerson",
|
|
234
|
+
/** 部门人数统计 */
|
|
235
|
+
hrReportDeptPerson: "/sp/hrm/hr/reportForm/deptPerson",
|
|
236
|
+
/** 岗位人数统计 */
|
|
237
|
+
hrReportPosiPerson: "/sp/hrm/hr/reportForm/posiPerson",
|
|
238
|
+
/** 职务状况统计 */
|
|
239
|
+
hrReportJobPerson: "/sp/hrm/hr/reportForm/jobPerson"
|
|
240
|
+
};
|
|
241
|
+
function ehrPageUrl(baseUrl, path) {
|
|
242
|
+
return String(baseUrl || "").replace(/\/+$/, "") + path;
|
|
243
|
+
}
|
|
244
|
+
function addDays(date, delta) {
|
|
245
|
+
const [y, m, d] = String(date).split("-").map(Number);
|
|
246
|
+
const t = new Date(Date.UTC(y, m - 1, d + delta));
|
|
247
|
+
const f = (n) => String(n).padStart(2, "0");
|
|
248
|
+
return `${t.getUTCFullYear()}-${f(t.getUTCMonth() + 1)}-${f(t.getUTCDate())}`;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/shortcuts/ehr/operations/recruit.ts
|
|
252
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
253
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
254
|
+
import { homedir } from "node:os";
|
|
255
|
+
import { join, resolve } from "node:path";
|
|
256
|
+
|
|
257
|
+
// src/shortcuts/ehr/operations/types.ts
|
|
258
|
+
var READ = "read";
|
|
259
|
+
var WRITE = "write";
|
|
260
|
+
function ehrSuccess(action, data, meta) {
|
|
261
|
+
const payload = { ok: true, action, data };
|
|
262
|
+
if (meta && Object.keys(meta).length > 0) payload.meta = meta;
|
|
263
|
+
return payload;
|
|
264
|
+
}
|
|
265
|
+
function schemaOf(properties, options = {}) {
|
|
266
|
+
return {
|
|
267
|
+
type: "object",
|
|
268
|
+
additionalProperties: false,
|
|
269
|
+
properties,
|
|
270
|
+
...options.required?.length ? { required: options.required } : {},
|
|
271
|
+
...options.description ? { description: options.description } : {}
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
var SCHEMA_DATE = { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$" };
|
|
275
|
+
var SCHEMA_MONTH = { type: "string", pattern: "^\\d{4}-\\d{2}$" };
|
|
276
|
+
var SCHEMA_ID = { oneOf: [{ type: "integer" }, { type: "string", pattern: "^\\d+$" }] };
|
|
277
|
+
var SCHEMA_ID_LIST = { type: "array", items: SCHEMA_ID };
|
|
278
|
+
var SCHEMA_STRING_LIST = { type: "array", items: { type: "string" } };
|
|
279
|
+
|
|
280
|
+
// src/shortcuts/ehr/operations/recruit.ts
|
|
281
|
+
var RECRUIT_APP_TAG = "weaver-recruit-service";
|
|
282
|
+
var RECRUIT_CACHE_VERSION = 1;
|
|
283
|
+
var RECRUIT_TAGS = {
|
|
284
|
+
talent_pool: "uf_rcrt_talent_pool",
|
|
285
|
+
interview_plan: "uf_rcrt_interview_plan",
|
|
286
|
+
interview_detail: "uf_rcrt_interview_detail",
|
|
287
|
+
demand_manage: "uf_rcrt_demand_manage",
|
|
288
|
+
position_manage: "uf_rcrt_position_manage",
|
|
289
|
+
entry_manage: "uf_rcrt_entry_manage",
|
|
290
|
+
offer: "uf_rcrt_offer",
|
|
291
|
+
offer_sending: "uf_rcrt_offer_sending",
|
|
292
|
+
candidate_manage: "uf_rcrt_candidate_manage",
|
|
293
|
+
entry_transact: "uf_rcrt_entry_transact",
|
|
294
|
+
entry_cancel: "uf_rcrt_entry_cancel",
|
|
295
|
+
entry_change: "uf_rcrt_entry_change",
|
|
296
|
+
dictionary: "uf_rcrt_dictionary",
|
|
297
|
+
biz_config: "uf_rcrt_biz_config_mapper"
|
|
298
|
+
};
|
|
299
|
+
var LIST_KEYWORDS = {
|
|
300
|
+
talent: ["\u4EBA\u624D\u5E93", "\u4EBA\u624D\u7BA1\u7406"],
|
|
301
|
+
demand: ["\u62DB\u8058\u9700\u6C42", "\u9700\u6C42"],
|
|
302
|
+
position: ["\u62DB\u8058\u804C\u4F4D", "\u804C\u4F4D\u5217\u8868", "\u804C\u4F4D\u7BA1\u7406"],
|
|
303
|
+
entry: ["\u5165\u804C\u7BA1\u7406"],
|
|
304
|
+
offer: ["\u5F55\u7528\u7BA1\u7406", "offer\u7BA1\u7406", "offer"],
|
|
305
|
+
interview: ["\u9762\u8BD5\u7BA1\u7406", "\u9762\u8BD5\u5B89\u6392\u5217\u8868", "\u9762\u8BD5\u5B89\u6392"],
|
|
306
|
+
candidate: ["\u5E94\u8058\u8005", "\u5019\u9009\u4EBA", "\u5E94\u8058\u6279\u6B21", "\u5E94\u8058\u7BA1\u7406"],
|
|
307
|
+
biz_config: ["\u4E1A\u52A1\u914D\u7F6E\u6620\u5C04\u8868"]
|
|
308
|
+
};
|
|
309
|
+
var LIST_TYPES = {
|
|
310
|
+
demand: { listKey: "demand", formType: "demand_manage", title: "\u62DB\u8058\u9700\u6C42" },
|
|
311
|
+
position: { listKey: "position", formType: "position_manage", title: "\u62DB\u8058\u804C\u4F4D" },
|
|
312
|
+
entry: { listKey: "entry", formType: "entry_manage", title: "\u5165\u804C\u7BA1\u7406" },
|
|
313
|
+
offer: { listKey: "offer", formType: "offer", title: "\u5F55\u7528\u7BA1\u7406" },
|
|
314
|
+
interview: { listKey: "interview", formType: "interview_plan", title: "\u9762\u8BD5\u7BA1\u7406" },
|
|
315
|
+
candidate: { listKey: "candidate", formType: "candidate_manage", title: "\u5E94\u8058\u8005" }
|
|
316
|
+
};
|
|
317
|
+
var INTERNAL_KEYS = /* @__PURE__ */ new Set([
|
|
318
|
+
"id",
|
|
319
|
+
"form_data_id",
|
|
320
|
+
"form_table_id",
|
|
321
|
+
"rowKey",
|
|
322
|
+
"ebrecord_rowkey",
|
|
323
|
+
"isFollow",
|
|
324
|
+
"is_flow",
|
|
325
|
+
"data_status",
|
|
326
|
+
"data_status_value",
|
|
327
|
+
"update_time",
|
|
328
|
+
"formDataId",
|
|
329
|
+
"isFollowSearch",
|
|
330
|
+
"isShareToMe"
|
|
331
|
+
]);
|
|
332
|
+
var DISPLAY_UI_KEYS = /* @__PURE__ */ new Set([
|
|
333
|
+
...INTERNAL_KEYS,
|
|
334
|
+
"operate",
|
|
335
|
+
"isToDo",
|
|
336
|
+
"todoPropSpan",
|
|
337
|
+
"flow_status"
|
|
338
|
+
]);
|
|
339
|
+
function randHex32() {
|
|
340
|
+
return randomUUID().replace(/-/g, "");
|
|
341
|
+
}
|
|
342
|
+
function randHex6() {
|
|
343
|
+
return randomBytes(3).toString("hex");
|
|
344
|
+
}
|
|
345
|
+
function cacheDirFor(baseUrl) {
|
|
346
|
+
const url = new URL(baseUrl);
|
|
347
|
+
const host = url.hostname + (url.port ? `_${url.port}` : "");
|
|
348
|
+
const envRoot = process.env.E10_SKILL_CACHE_DIR;
|
|
349
|
+
if (envRoot) return join(envRoot, host);
|
|
350
|
+
const home = process.env.WEAVER_WORK_CLI_HOME || process.env.WORK_CLI_HOME || resolve(homedir(), ".weaver-work-cli");
|
|
351
|
+
return join(home, "env-cache", "recruit-ops", host);
|
|
352
|
+
}
|
|
353
|
+
function namesOf(field) {
|
|
354
|
+
if (!field) return null;
|
|
355
|
+
let arr;
|
|
356
|
+
if (Array.isArray(field)) arr = field;
|
|
357
|
+
else if (typeof field === "object") arr = [field];
|
|
358
|
+
else if (typeof field === "string") {
|
|
359
|
+
const text = field.trim();
|
|
360
|
+
if (!text.startsWith("[") && !text.startsWith("{")) return text || null;
|
|
361
|
+
try {
|
|
362
|
+
arr = JSON.parse(text);
|
|
363
|
+
} catch {
|
|
364
|
+
return text || null;
|
|
365
|
+
}
|
|
366
|
+
if (!Array.isArray(arr)) arr = [arr];
|
|
367
|
+
} else return null;
|
|
368
|
+
const names = arr.map((item) => item && typeof item === "object" ? item.name || item.username || item.text || item.title : null).filter(Boolean);
|
|
369
|
+
return names.length ? names.join("\u3001") : null;
|
|
370
|
+
}
|
|
371
|
+
function isPlainId(value) {
|
|
372
|
+
return value != null && /^\d+$/.test(String(value).trim());
|
|
373
|
+
}
|
|
374
|
+
var RecruitContextError = class extends Error {
|
|
375
|
+
subtype;
|
|
376
|
+
constructor(subtype, message) {
|
|
377
|
+
super(message);
|
|
378
|
+
this.subtype = subtype;
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
async function fetchFormFields(host, appId, objId) {
|
|
382
|
+
const form = new FormData();
|
|
383
|
+
form.set("groupId", appId);
|
|
384
|
+
form.set("sourceId", objId);
|
|
385
|
+
form.set("sourceType", "FORM");
|
|
386
|
+
form.set("detailFieldsGroup", "true");
|
|
387
|
+
form.set("enableMerge", "true");
|
|
388
|
+
form.set("customParam", '{"terminal":""}');
|
|
389
|
+
form.set("params", "[]");
|
|
390
|
+
const response = await host.request({
|
|
391
|
+
method: "POST",
|
|
392
|
+
path: "/api/ebuilder/common/ds/fields",
|
|
393
|
+
multipart: form
|
|
394
|
+
});
|
|
395
|
+
const fmap = {};
|
|
396
|
+
const omap = {};
|
|
397
|
+
for (const group of response?.data || []) {
|
|
398
|
+
for (const field of group?.fields || []) {
|
|
399
|
+
const config = field?.config || {};
|
|
400
|
+
const dataKey = config.dataKey || "";
|
|
401
|
+
const fieldId = String(field?.id || "");
|
|
402
|
+
if (dataKey && fieldId) fmap[dataKey] = fieldId;
|
|
403
|
+
if (fieldId && Array.isArray(config.options) && config.options.length) {
|
|
404
|
+
const map = {};
|
|
405
|
+
for (const option of config.options) {
|
|
406
|
+
if (!option || typeof option !== "object") continue;
|
|
407
|
+
const name = option.name;
|
|
408
|
+
let selectionId = option.selectionId;
|
|
409
|
+
if (!selectionId && typeof option.extra === "string") {
|
|
410
|
+
try {
|
|
411
|
+
const extra = JSON.parse(option.extra);
|
|
412
|
+
selectionId = extra.selectionId || extra.id;
|
|
413
|
+
} catch {
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
if (!selectionId) selectionId = option.value || option.valueKey || option.id;
|
|
417
|
+
if (selectionId && name) map[String(selectionId)] = name;
|
|
418
|
+
}
|
|
419
|
+
if (Object.keys(map).length) omap[fieldId] = map;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return { fmap, omap };
|
|
424
|
+
}
|
|
425
|
+
async function resolveRecruitEnv(host, appId) {
|
|
426
|
+
const forms = {};
|
|
427
|
+
let tenantKey = "";
|
|
428
|
+
for (const [logic, tag] of Object.entries(RECRUIT_TAGS)) {
|
|
429
|
+
const response = await host.request({
|
|
430
|
+
path: "/api/ebuilder/form/obj/getObjsByTag",
|
|
431
|
+
query: { appId, tag }
|
|
432
|
+
});
|
|
433
|
+
const entry = Array.isArray(response?.data) && response.data.length ? response.data[0] : null;
|
|
434
|
+
forms[logic] = {
|
|
435
|
+
objId: String(entry?.id || ""),
|
|
436
|
+
formId: String(entry?.formId || ""),
|
|
437
|
+
objName: entry?.objName || ""
|
|
438
|
+
};
|
|
439
|
+
if (!tenantKey && entry?.tenantKey) tenantKey = String(entry.tenantKey);
|
|
440
|
+
}
|
|
441
|
+
const menuResponse = await host.request({
|
|
442
|
+
path: "/api/cusapp/app/allMenus",
|
|
443
|
+
query: { isFront: 1, appId, terminalType: "PC" }
|
|
444
|
+
});
|
|
445
|
+
const flat = [];
|
|
446
|
+
const walk = (nodes) => {
|
|
447
|
+
for (const node of nodes || []) {
|
|
448
|
+
if (node && typeof node === "object") {
|
|
449
|
+
flat.push(node);
|
|
450
|
+
walk(node.children || node.childs);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
const menuData = menuResponse?.data;
|
|
455
|
+
walk(typeof menuData === "object" && menuData ? menuData.cusAppMenus || menuData : menuData);
|
|
456
|
+
const searchMenus = [];
|
|
457
|
+
const pages = [];
|
|
458
|
+
for (const node of flat) {
|
|
459
|
+
if (node.pageType === "SEARCH") {
|
|
460
|
+
searchMenus.push({ menuName: node.menuName, listId: String(node.pageId || ""), cusMenuId: String(node.id || "") });
|
|
461
|
+
} else if (node.pageType === "PAGE") {
|
|
462
|
+
pages.push({ menuName: node.menuName, pageId: String(node.pageId || "") });
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
const fields = {};
|
|
466
|
+
const fieldOptions = {};
|
|
467
|
+
const resolvedForms = Object.entries(forms).filter(([, v]) => v.objId);
|
|
468
|
+
await Promise.all(resolvedForms.map(async ([logic, entry]) => {
|
|
469
|
+
const { fmap, omap } = await fetchFormFields(host, appId, entry.objId);
|
|
470
|
+
if (Object.keys(fmap).length) fields[entry.objId] = fmap;
|
|
471
|
+
if (Object.keys(omap).length) fieldOptions[entry.objId] = omap;
|
|
472
|
+
void logic;
|
|
473
|
+
}));
|
|
474
|
+
const dictByName = {};
|
|
475
|
+
const dictRaw = [];
|
|
476
|
+
const dictMenu = searchMenus.find((m) => (m.menuName || "").trim() === "\u6570\u636E\u5B57\u5178") || null;
|
|
477
|
+
const dictObjId = forms.dictionary?.objId || "";
|
|
478
|
+
if (dictObjId && dictMenu) {
|
|
479
|
+
const size = 500;
|
|
480
|
+
let current = 1;
|
|
481
|
+
for (; ; ) {
|
|
482
|
+
const response = await host.request({
|
|
483
|
+
path: `/api/ebuilder/form/list/getListDatas?passid=${dictObjId}&cid=${dictObjId}`,
|
|
484
|
+
body: {
|
|
485
|
+
current,
|
|
486
|
+
pageSize: size,
|
|
487
|
+
tableuid: randHex32(),
|
|
488
|
+
listId: dictMenu.listId,
|
|
489
|
+
searchParamData: { searchType: "3", type: "and" },
|
|
490
|
+
terminal: "PC",
|
|
491
|
+
browser: "Chrome",
|
|
492
|
+
requiredMatch: 1,
|
|
493
|
+
mapResult: 1,
|
|
494
|
+
recheckQuery: 1,
|
|
495
|
+
isFollow: 0,
|
|
496
|
+
isShareToMe: 0,
|
|
497
|
+
filterCondition: {},
|
|
498
|
+
cusMenuId: dictMenu.cusMenuId,
|
|
499
|
+
urlPageTitle: "\u6570\u636E\u5B57\u5178",
|
|
500
|
+
menuName: "\u6570\u636E\u5B57\u5178"
|
|
501
|
+
},
|
|
502
|
+
headers: { ebBusinessId: dictMenu.listId }
|
|
503
|
+
});
|
|
504
|
+
const rows = response?.data?.data || [];
|
|
505
|
+
for (const row of rows) {
|
|
506
|
+
const name = row.selection_name;
|
|
507
|
+
const optionId = row.form_data_id;
|
|
508
|
+
if (name && optionId) {
|
|
509
|
+
(dictByName[String(name)] ||= []).push(String(optionId));
|
|
510
|
+
dictRaw.push({ selection_name: String(name), option_id: String(optionId), dict_type: row.dict_type, browser_key: row.browser_key });
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
if (rows.length < size) break;
|
|
514
|
+
current += 1;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
let ebdDetailPageId = "";
|
|
518
|
+
let selfUse = "0";
|
|
519
|
+
const bizConfig = forms.biz_config || { objId: "", formId: "", objName: "" };
|
|
520
|
+
const bizConfigMenu = searchMenus.find((m) => (m.menuName || "").trim() === "\u4E1A\u52A1\u914D\u7F6E\u6620\u5C04\u8868") || null;
|
|
521
|
+
if (bizConfig.objId && bizConfigMenu) {
|
|
522
|
+
try {
|
|
523
|
+
const { fmap } = await fetchFormFields(host, appId, bizConfig.objId);
|
|
524
|
+
const keyField = fmap.config_key || "";
|
|
525
|
+
const valueField = fmap.config || "";
|
|
526
|
+
if (keyField && valueField) {
|
|
527
|
+
let current = 1;
|
|
528
|
+
for (; ; ) {
|
|
529
|
+
const response = await host.request({
|
|
530
|
+
path: `/api/ebuilder/form/list/getListDatas?passid=${bizConfig.objId}&cid=${bizConfig.objId}`,
|
|
531
|
+
body: {
|
|
532
|
+
current,
|
|
533
|
+
pageSize: 100,
|
|
534
|
+
tableuid: randHex32(),
|
|
535
|
+
listId: bizConfigMenu.listId,
|
|
536
|
+
searchParamData: { searchType: "3", type: "and" },
|
|
537
|
+
terminal: "PC",
|
|
538
|
+
browser: "Chrome",
|
|
539
|
+
requiredMatch: 1,
|
|
540
|
+
mapResult: 1,
|
|
541
|
+
recheckQuery: 1,
|
|
542
|
+
isFollow: 0,
|
|
543
|
+
isShareToMe: 0,
|
|
544
|
+
filterCondition: {},
|
|
545
|
+
cusMenuId: bizConfigMenu.cusMenuId,
|
|
546
|
+
urlPageTitle: "\u4E1A\u52A1\u914D\u7F6E\u6620\u5C04\u8868",
|
|
547
|
+
menuName: "\u4E1A\u52A1\u914D\u7F6E\u6620\u5C04\u8868"
|
|
548
|
+
},
|
|
549
|
+
headers: { ebBusinessId: bizConfigMenu.listId }
|
|
550
|
+
});
|
|
551
|
+
const rows = response?.data?.data || [];
|
|
552
|
+
if (!rows.length) break;
|
|
553
|
+
for (const row of rows) {
|
|
554
|
+
if (String(row.config_key || "") === "28" && row.config) {
|
|
555
|
+
const match = String(row.config).match(/\/sp\/ebdpage\/view\/(\d+)/);
|
|
556
|
+
if (match) ebdDetailPageId = match[1];
|
|
557
|
+
}
|
|
558
|
+
if (String(row.config_key || "") === "-9999" && String(row.config) === "1") selfUse = "1";
|
|
559
|
+
}
|
|
560
|
+
if (rows.length < 100) break;
|
|
561
|
+
current += 1;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
} catch {
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (!ebdDetailPageId) {
|
|
568
|
+
try {
|
|
569
|
+
const response = await host.request({
|
|
570
|
+
path: "/api/bs/ebuilder/page/list",
|
|
571
|
+
query: { appid: appId }
|
|
572
|
+
});
|
|
573
|
+
for (const page of Array.isArray(response?.data) ? response.data : []) {
|
|
574
|
+
if ((page?.name || "") === "\u4EBA\u624D\u5361\u7247" && page?.type === "PAGE" && page?.id) {
|
|
575
|
+
ebdDetailPageId = String(page.id);
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
} catch {
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
const options = {};
|
|
583
|
+
for (const [dataKey, logic] of [["recruit_status", "talent_pool"], ["channel", "talent_pool"]]) {
|
|
584
|
+
const entry = forms[logic] || { objId: "", formId: "", objName: "" };
|
|
585
|
+
const fieldId = (fields[entry.objId] || {})[dataKey] || "";
|
|
586
|
+
if (fieldId && entry.objId) {
|
|
587
|
+
const response = await host.request({
|
|
588
|
+
path: "/api/ebuilder/common/ds/options",
|
|
589
|
+
query: { fieldName: fieldId, objId: entry.objId, sourceType: "FORM", groupId: appId }
|
|
590
|
+
});
|
|
591
|
+
if (Array.isArray(response?.data)) {
|
|
592
|
+
options[dataKey] = {};
|
|
593
|
+
for (const option of response.data) {
|
|
594
|
+
if (option?.id) options[dataKey][String(option.id)] = option.name;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
const lists = {
|
|
600
|
+
talent: null,
|
|
601
|
+
demand: null,
|
|
602
|
+
position: null,
|
|
603
|
+
entry: null,
|
|
604
|
+
offer: null,
|
|
605
|
+
interview: null,
|
|
606
|
+
candidate: null,
|
|
607
|
+
dict: dictMenu,
|
|
608
|
+
biz_config: bizConfigMenu,
|
|
609
|
+
all_search: searchMenus,
|
|
610
|
+
pages
|
|
611
|
+
};
|
|
612
|
+
for (const [biz, keywords] of Object.entries(LIST_KEYWORDS)) {
|
|
613
|
+
for (const menu of searchMenus) {
|
|
614
|
+
if (keywords.some((keyword) => (menu.menuName || "").includes(keyword))) {
|
|
615
|
+
lists[biz] = menu;
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return {
|
|
621
|
+
appId,
|
|
622
|
+
tenantKey,
|
|
623
|
+
forms,
|
|
624
|
+
lists,
|
|
625
|
+
fields,
|
|
626
|
+
field_options: fieldOptions,
|
|
627
|
+
options,
|
|
628
|
+
dict: { by_name: dictByName, raw: dictRaw },
|
|
629
|
+
ebdDetailPageId,
|
|
630
|
+
selfUse
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
function createRecruitContextLoader() {
|
|
634
|
+
const memo = /* @__PURE__ */ new Map();
|
|
635
|
+
async function load(host) {
|
|
636
|
+
const session = await host.getSession();
|
|
637
|
+
const baseUrl = session.baseUrl.replace(/\/+$/, "");
|
|
638
|
+
const memoKey = baseUrl;
|
|
639
|
+
let cached = memo.get(memoKey);
|
|
640
|
+
if (cached) return cached;
|
|
641
|
+
let appId = "";
|
|
642
|
+
let diskCache = null;
|
|
643
|
+
try {
|
|
644
|
+
const dir = cacheDirFor(baseUrl);
|
|
645
|
+
if (existsSync(dir)) {
|
|
646
|
+
const files = readdirSync(dir).filter((file) => file.endsWith(".json"));
|
|
647
|
+
if (files.length === 1) {
|
|
648
|
+
appId = files[0].replace(/\.json$/, "");
|
|
649
|
+
diskCache = JSON.parse(readFileSync(join(dir, files[0]), "utf8"));
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
} catch {
|
|
653
|
+
}
|
|
654
|
+
if (diskCache && diskCache.cacheVersion === RECRUIT_CACHE_VERSION) {
|
|
655
|
+
memo.set(memoKey, diskCache);
|
|
656
|
+
return diskCache;
|
|
657
|
+
}
|
|
658
|
+
const gate = await host.request({
|
|
659
|
+
path: "/api/bs/ebuilder/app/tags/getAppIds",
|
|
660
|
+
query: { tag: RECRUIT_APP_TAG }
|
|
661
|
+
});
|
|
662
|
+
const appIds = gate?.data;
|
|
663
|
+
if (!Array.isArray(appIds) || !appIds.length) {
|
|
664
|
+
throw new RecruitContextError(
|
|
665
|
+
"recruit_service_not_installed",
|
|
666
|
+
"\u5F53\u524D\u79DF\u6237\u672A\u5B89\u88C5\u62DB\u8058\u670D\u52A1\uFF08weaver-recruit-service\uFF09\uFF0C\u65E0\u6CD5\u4F7F\u7528\u62DB\u8058\u80FD\u529B\u3002\u8BF7\u5148\u5728 E10 \u5E94\u7528\u5E02\u573A\u5B89\u88C5\u300C\u62DB\u8058\u300D\u5E94\u7528\u3002"
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
appId = String(appIds[0]);
|
|
670
|
+
const resolved = await resolveRecruitEnv(host, appId);
|
|
671
|
+
try {
|
|
672
|
+
const dir = cacheDirFor(baseUrl);
|
|
673
|
+
mkdirSync(dir, { recursive: true });
|
|
674
|
+
writeFileSync(
|
|
675
|
+
join(dir, `${appId}.json`),
|
|
676
|
+
JSON.stringify({
|
|
677
|
+
__meta__: {
|
|
678
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19),
|
|
679
|
+
note: "recruit-ops \u73AF\u5883\u53C2\u6570\u7F13\u5B58\uFF08weaver-work-cli \u8FD0\u884C\u65F6\u89E3\u6790\u4EA7\u7269\uFF0C\u4E0D\u542B\u8BA4\u8BC1\u5B57\u6BB5\uFF09"
|
|
680
|
+
},
|
|
681
|
+
envKey: `${dir.split(/[\\/]/).pop()}|${appId}`,
|
|
682
|
+
cacheVersion: RECRUIT_CACHE_VERSION,
|
|
683
|
+
...resolved
|
|
684
|
+
}, null, 2),
|
|
685
|
+
"utf8"
|
|
686
|
+
);
|
|
687
|
+
} catch {
|
|
688
|
+
}
|
|
689
|
+
memo.set(memoKey, resolved);
|
|
690
|
+
return resolved;
|
|
691
|
+
}
|
|
692
|
+
return { load };
|
|
693
|
+
}
|
|
694
|
+
function buildListBody(params) {
|
|
695
|
+
return {
|
|
696
|
+
current: params.current ?? 1,
|
|
697
|
+
pageSize: params.pageSize ?? 10,
|
|
698
|
+
tableuid: randHex32(),
|
|
699
|
+
listId: params.listId,
|
|
700
|
+
searchParamData: {
|
|
701
|
+
searchType: "3",
|
|
702
|
+
type: "and",
|
|
703
|
+
...params.conditions && Object.keys(params.conditions).length ? { commonSearchFields: params.conditions } : {}
|
|
704
|
+
},
|
|
705
|
+
terminal: "PC",
|
|
706
|
+
browser: "Chrome",
|
|
707
|
+
requiredMatch: 1,
|
|
708
|
+
mapResult: 1,
|
|
709
|
+
recheckQuery: 1,
|
|
710
|
+
isFollow: 0,
|
|
711
|
+
isShareToMe: 0,
|
|
712
|
+
filterCondition: {},
|
|
713
|
+
cusMenuId: params.cusMenuId,
|
|
714
|
+
urlPageTitle: params.title,
|
|
715
|
+
menuName: params.menuName
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
async function fetchListRows(host, objId, listId, body) {
|
|
719
|
+
const countBody = { ...body };
|
|
720
|
+
delete countBody.current;
|
|
721
|
+
delete countBody.pageSize;
|
|
722
|
+
const [listResponse, countResponse] = await Promise.all([
|
|
723
|
+
host.request({
|
|
724
|
+
path: `/api/ebuilder/form/list/getListDatas?passid=${objId}&cid=${objId}`,
|
|
725
|
+
body,
|
|
726
|
+
headers: { ebBusinessId: listId }
|
|
727
|
+
}),
|
|
728
|
+
host.request({
|
|
729
|
+
path: `/api/ebuilder/form/list/getListDataCount?passid=${objId}&cid=${objId}`,
|
|
730
|
+
body: countBody,
|
|
731
|
+
headers: { ebBusinessId: listId }
|
|
732
|
+
}).catch(() => null)
|
|
733
|
+
]);
|
|
734
|
+
const data = normalizePaged(listResponse).data;
|
|
735
|
+
const rawRows = data?.data || [];
|
|
736
|
+
const displayRows = data?.displayData;
|
|
737
|
+
const hasDisplay = Array.isArray(displayRows) && displayRows.length > 0;
|
|
738
|
+
const rows = hasDisplay ? displayRows : rawRows;
|
|
739
|
+
const countData = countResponse ? normalizePaged(countResponse).data : null;
|
|
740
|
+
const pageSize = typeof body.pageSize === "number" ? body.pageSize : typeof body.pageSize === "string" ? Number(body.pageSize) || rows.length : rows.length;
|
|
741
|
+
const countUsable = countData !== null && typeof countData.total === "number";
|
|
742
|
+
let total;
|
|
743
|
+
let totalExact;
|
|
744
|
+
let totalNote;
|
|
745
|
+
if (countUsable) {
|
|
746
|
+
total = countData.total;
|
|
747
|
+
totalExact = true;
|
|
748
|
+
} else if (rows.length < pageSize) {
|
|
749
|
+
total = rows.length;
|
|
750
|
+
totalExact = true;
|
|
751
|
+
totalNote = "\u8BA1\u6570\u63A5\u53E3\u4E0D\u53EF\u7528\uFF0C\u672C\u9875\u672A\u6EE1\uFF08\u5DF2\u5230\u672B\u9875\uFF09\uFF0C\u603B\u6570\u6309\u5DF2\u53D6\u56DE\u884C\u6570\u5F97\u51FA";
|
|
752
|
+
} else {
|
|
753
|
+
total = null;
|
|
754
|
+
totalExact = false;
|
|
755
|
+
totalNote = "\u8BA1\u6570\u63A5\u53E3\u4E0D\u53EF\u7528\u4E14\u672C\u9875\u5DF2\u6EE1\uFF0C\u603B\u6570\u4E0D\u53EF\u77E5\uFF08\u53EF\u8C03\u5927 pageSize \u53D6\u56DE\u5168\u90E8\u884C\u6570\uFF09";
|
|
756
|
+
}
|
|
757
|
+
return { rows, displayRows: hasDisplay ? displayRows : null, total, totalExact, totalNote };
|
|
758
|
+
}
|
|
759
|
+
var contextResolve = {
|
|
760
|
+
name: "ehr.recruit.context.resolve",
|
|
761
|
+
resource: "recruit",
|
|
762
|
+
method: "context.resolve",
|
|
763
|
+
action: "ehr.recruit.context.resolve",
|
|
764
|
+
summary: "\u89E3\u6790\u62DB\u8058\u6A21\u5757\u8FD0\u884C\u65F6\u53C2\u6570\uFF08appId/\u8868\u5355 objId/\u5217\u8868 listId+cusMenuId/\u5B57\u6BB5\u6620\u5C04\uFF09\uFF0C\u4E3B\u8981\u4F9B\u8C03\u8BD5\u4E0E\u515C\u5E95\uFF1B\u4E1A\u52A1 operation \u4F1A\u9690\u5F0F\u81EA\u52A8\u89E3\u6790",
|
|
765
|
+
capability: "recruit",
|
|
766
|
+
risk: READ,
|
|
767
|
+
inputSchema: schemaOf({}),
|
|
768
|
+
handler: async (_args, env) => {
|
|
769
|
+
if (!env.recruitContext) {
|
|
770
|
+
throw ehrValidationError("recruit_context_unavailable", "\u62DB\u8058\u4E0A\u4E0B\u6587\u52A0\u8F7D\u5668\u672A\u521D\u59CB\u5316");
|
|
771
|
+
}
|
|
772
|
+
const cache = await env.recruitContext.load(env.host);
|
|
773
|
+
return ehrSuccess("ehr.recruit.context.resolve", {
|
|
774
|
+
appId: cache.appId,
|
|
775
|
+
tenantKey: cache.tenantKey || null,
|
|
776
|
+
forms: cache.forms,
|
|
777
|
+
lists: cache.lists,
|
|
778
|
+
ebdDetailPageId: cache.ebdDetailPageId || null,
|
|
779
|
+
selfUse: cache.selfUse
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
var candidateSearch = {
|
|
784
|
+
name: "ehr.recruit.candidate.search",
|
|
785
|
+
resource: "recruit",
|
|
786
|
+
method: "candidate.search",
|
|
787
|
+
action: "ehr.recruit.candidate.search",
|
|
788
|
+
summary: "\u6309\u59D3\u540D/\u624B\u673A\u53F7\u6A21\u7CCA\u641C\u7D22\u4EBA\u624D\u5E93\u4EBA\u624D\uFF1B\u65E0\u7B5B\u9009\u6761\u4EF6\u65F6\u5217\u51FA\u5168\u90E8\u4EBA\u624D\u7528\u4E8E\u6D4F\u89C8\u3002\u8FD4\u56DE\u767D\u540D\u5355\u5C55\u793A\u5B57\u6BB5",
|
|
789
|
+
capability: "recruit",
|
|
790
|
+
risk: READ,
|
|
791
|
+
inputSchema: schemaOf({
|
|
792
|
+
name: { type: "string", description: "\u59D3\u540D\u6A21\u7CCA\u5339\u914D" },
|
|
793
|
+
mobile: { type: "string", description: "\u624B\u673A\u53F7\u6A21\u7CCA\u5339\u914D" },
|
|
794
|
+
current: SCHEMA_ID,
|
|
795
|
+
pageSize: SCHEMA_ID
|
|
796
|
+
}),
|
|
797
|
+
handler: async (args, env) => {
|
|
798
|
+
if (!env.recruitContext) {
|
|
799
|
+
throw ehrValidationError("recruit_context_unavailable", "\u62DB\u8058\u4E0A\u4E0B\u6587\u52A0\u8F7D\u5668\u672A\u521D\u59CB\u5316");
|
|
800
|
+
}
|
|
801
|
+
const cache = await env.recruitContext.load(env.host);
|
|
802
|
+
const talentList = cache.lists.talent;
|
|
803
|
+
const talentObjId = cache.forms.talent_pool?.objId;
|
|
804
|
+
if (!talentList?.listId || !talentObjId) {
|
|
805
|
+
throw new RecruitContextError("recruit_context_missing", "\u5F53\u524D\u73AF\u5883\u672A\u89E3\u6790\u5230\u300C\u4EBA\u624D\u5E93\u300D\u83DC\u5355\u6216\u4EBA\u624D\u5E93\u8868\u5355\uFF0C\u65E0\u6CD5\u641C\u7D22\u4EBA\u624D\u3002\u8BF7\u5148\u8FD0\u884C ehr.recruit.context.resolve \u68C0\u67E5\u73AF\u5883\u3002");
|
|
806
|
+
}
|
|
807
|
+
const fields = cache.fields[talentObjId] || {};
|
|
808
|
+
const nameField = "field_" + (fields.candidate_name || fields.name);
|
|
809
|
+
const mobileField = "field_" + fields.telephone;
|
|
810
|
+
const conditions = {};
|
|
811
|
+
if (args.name) conditions[nameField] = [{ [nameField]: args.name, [`${nameField}_condition_type`]: "like" }];
|
|
812
|
+
if (args.mobile) conditions[mobileField] = [{ [mobileField]: args.mobile, [`${mobileField}_condition_type`]: "like" }];
|
|
813
|
+
const body = buildListBody({
|
|
814
|
+
listId: talentList.listId,
|
|
815
|
+
cusMenuId: talentList.cusMenuId,
|
|
816
|
+
menuName: talentList.menuName || "\u4EBA\u624D\u7BA1\u7406",
|
|
817
|
+
title: "\u4EBA\u624D\u5E93",
|
|
818
|
+
current: toPositiveInt(args.current, "current") ?? 1,
|
|
819
|
+
pageSize: toNumber(args.pageSize, "pageSize") ?? 10,
|
|
820
|
+
conditions
|
|
821
|
+
});
|
|
822
|
+
const { rows, displayRows, total, totalExact, totalNote } = await fetchListRows(env.host, talentObjId, talentList.listId, body);
|
|
823
|
+
let creatorNameMap = {};
|
|
824
|
+
if (!displayRows) {
|
|
825
|
+
const pureIds = [...new Set(rows.map((row) => row?.creator).filter(isPlainId).map((value) => String(value).trim()))];
|
|
826
|
+
if (pureIds.length) {
|
|
827
|
+
creatorNameMap = {};
|
|
828
|
+
for (let index = 0; index < pureIds.length; index += 100) {
|
|
829
|
+
const batch = pureIds.slice(index, index + 100);
|
|
830
|
+
try {
|
|
831
|
+
const response = await env.host.request({
|
|
832
|
+
path: "/api/hrm/common/getEmployeeByIds",
|
|
833
|
+
body: { userIdList: batch, externalIdList: [] },
|
|
834
|
+
headers: { devtype: "5" }
|
|
835
|
+
});
|
|
836
|
+
for (const user of response?.data?.userList || []) {
|
|
837
|
+
if (user?.id != null) creatorNameMap[String(user.id)] = user.name || null;
|
|
838
|
+
}
|
|
839
|
+
} catch {
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
const statusMap = cache.options?.recruit_status || {};
|
|
845
|
+
const dictNameMap = {};
|
|
846
|
+
for (const item of cache.dict?.raw || []) {
|
|
847
|
+
if (item.option_id && item.selection_name) dictNameMap[item.option_id] = item.selection_name;
|
|
848
|
+
}
|
|
849
|
+
const dataRows = rows.map((row) => {
|
|
850
|
+
let creator = null;
|
|
851
|
+
if (displayRows) {
|
|
852
|
+
creator = namesOf(row?.creator);
|
|
853
|
+
} else if (row?.creator != null) {
|
|
854
|
+
const raw = String(row.creator).trim();
|
|
855
|
+
creator = isPlainId(raw) ? creatorNameMap[raw] || raw : namesOf(raw) || raw;
|
|
856
|
+
}
|
|
857
|
+
return {
|
|
858
|
+
talentId: row?.form_data_id || row?.id || null,
|
|
859
|
+
name: row?.candidate_name || row?.name || null,
|
|
860
|
+
mobile: row?.telephone || null,
|
|
861
|
+
channel: dictNameMap[row?.channel] || row?.channel || null,
|
|
862
|
+
status: statusMap[row?.recruit_status] || row?.recruit_status || null,
|
|
863
|
+
creator,
|
|
864
|
+
createTime: row?.create_time || null
|
|
865
|
+
};
|
|
866
|
+
});
|
|
867
|
+
return ehrSuccess("ehr.recruit.candidate.search", { total, totalExact, ...totalNote ? { totalNote } : {}, rows: dataRows });
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
var candidateList = {
|
|
871
|
+
name: "ehr.recruit.candidate.list",
|
|
872
|
+
resource: "recruit",
|
|
873
|
+
method: "candidate.list",
|
|
874
|
+
action: "ehr.recruit.candidate.list",
|
|
875
|
+
summary: "\u67E5\u8BE2\u62DB\u8058\u4E1A\u52A1\u5217\u8868\uFF08demand \u62DB\u8058\u9700\u6C42 / position \u62DB\u8058\u804C\u4F4D / entry \u5165\u804C\u7BA1\u7406 / offer \u5F55\u7528\u7BA1\u7406\uFF09\uFF0CdisplayData \u663E\u793A\u5C42\u96F6\u7FFB\u8BD1\u8F93\u51FA",
|
|
876
|
+
capability: "recruit",
|
|
877
|
+
risk: READ,
|
|
878
|
+
inputSchema: schemaOf({
|
|
879
|
+
type: { type: "string", enum: ["demand", "position", "entry", "offer", "interview", "candidate"], description: "\u5217\u8868\u7C7B\u578B" },
|
|
880
|
+
current: SCHEMA_ID,
|
|
881
|
+
pageSize: SCHEMA_ID
|
|
882
|
+
}, { required: ["type"] }),
|
|
883
|
+
handler: async (args, env) => {
|
|
884
|
+
const type = typeof args.type === "string" ? args.type : "";
|
|
885
|
+
const listType = LIST_TYPES[type];
|
|
886
|
+
if (!listType) {
|
|
887
|
+
throw ehrValidationError("enum_invalid", `type \u53D6\u503C\u5FC5\u987B\u662F ${Object.keys(LIST_TYPES).join(" / ")} \u4E4B\u4E00`);
|
|
888
|
+
}
|
|
889
|
+
if (!env.recruitContext) {
|
|
890
|
+
throw ehrValidationError("recruit_context_unavailable", "\u62DB\u8058\u4E0A\u4E0B\u6587\u52A0\u8F7D\u5668\u672A\u521D\u59CB\u5316");
|
|
891
|
+
}
|
|
892
|
+
const cache = await env.recruitContext.load(env.host);
|
|
893
|
+
const listParam = cache.lists[listType.listKey];
|
|
894
|
+
if (!listParam?.listId) {
|
|
895
|
+
throw new RecruitContextError(
|
|
896
|
+
"recruit_list_unavailable",
|
|
897
|
+
`\u5F53\u524D\u73AF\u5883\u672A\u542F\u7528\u300C${listType.title}\u300D\u529F\u80FD\uFF08\u672A\u627E\u5230\u5BF9\u5E94\u83DC\u5355/\u5217\u8868\u53C2\u6570\uFF0C\u6309\u80FD\u529B\u63A2\u6D4B\u62E6\u622A\uFF09\u3002`
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
const formObjId = cache.forms[listType.formType]?.objId;
|
|
901
|
+
if (!formObjId) {
|
|
902
|
+
throw new RecruitContextError("recruit_context_missing", `\u672A\u89E3\u6790\u5230\u300C${listType.title}\u300D\u5BF9\u5E94\u8868\u5355\uFF0C\u65E0\u6CD5\u67E5\u8BE2\u3002`);
|
|
903
|
+
}
|
|
904
|
+
const body = buildListBody({
|
|
905
|
+
listId: listParam.listId,
|
|
906
|
+
cusMenuId: listParam.cusMenuId,
|
|
907
|
+
menuName: listParam.menuName || listType.title,
|
|
908
|
+
title: listType.title,
|
|
909
|
+
current: toPositiveInt(args.current, "current") ?? 1,
|
|
910
|
+
pageSize: toNumber(args.pageSize, "pageSize") ?? 10
|
|
911
|
+
});
|
|
912
|
+
const { rows, displayRows, total, totalExact, totalNote } = await fetchListRows(env.host, formObjId, listParam.listId, body);
|
|
913
|
+
const outRows = rows.map((row) => {
|
|
914
|
+
const cleaned = { form_data_id: row?.form_data_id || row?.id };
|
|
915
|
+
for (const [key, value] of Object.entries(row || {})) {
|
|
916
|
+
if (displayRows) {
|
|
917
|
+
if (DISPLAY_UI_KEYS.has(key) || key === "form_data_id") continue;
|
|
918
|
+
if (key.endsWith("Span") || key.endsWith("Action")) continue;
|
|
919
|
+
const text2 = String(value ?? "");
|
|
920
|
+
if (!text2) continue;
|
|
921
|
+
if (typeof value === "object" || typeof value === "string" && text2.trimStart().startsWith("[")) {
|
|
922
|
+
const names2 = namesOf(value);
|
|
923
|
+
cleaned[key] = names2 != null ? names2 : text2;
|
|
924
|
+
continue;
|
|
925
|
+
}
|
|
926
|
+
cleaned[key] = text2;
|
|
927
|
+
continue;
|
|
928
|
+
}
|
|
929
|
+
if (INTERNAL_KEYS.has(key)) continue;
|
|
930
|
+
const text = String(value ?? "");
|
|
931
|
+
if (!text) continue;
|
|
932
|
+
if (/^\d{16,}$/.test(text)) continue;
|
|
933
|
+
const names = typeof value === "object" || typeof value === "string" && text.trimStart().startsWith("[") ? namesOf(value) : null;
|
|
934
|
+
cleaned[key] = names != null ? names : text;
|
|
935
|
+
}
|
|
936
|
+
return cleaned;
|
|
937
|
+
});
|
|
938
|
+
return ehrSuccess("ehr.recruit.candidate.list", {
|
|
939
|
+
type,
|
|
940
|
+
total,
|
|
941
|
+
totalExact,
|
|
942
|
+
...totalNote ? { totalNote } : {},
|
|
943
|
+
current: body.current,
|
|
944
|
+
pageSize: body.pageSize,
|
|
945
|
+
rows: outRows
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
};
|
|
949
|
+
function personNames(value) {
|
|
950
|
+
const text = String(value ?? "").trim();
|
|
951
|
+
if (!text) return "";
|
|
952
|
+
if (text.startsWith("[")) {
|
|
953
|
+
try {
|
|
954
|
+
const arr = JSON.parse(text);
|
|
955
|
+
if (Array.isArray(arr)) {
|
|
956
|
+
const names = arr.map((item) => typeof item === "string" ? item : item?.name ?? item?.username ?? "").filter(Boolean);
|
|
957
|
+
if (names.length) return names.join("\u3001");
|
|
958
|
+
}
|
|
959
|
+
} catch {
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
return text;
|
|
963
|
+
}
|
|
964
|
+
function nameLike(value) {
|
|
965
|
+
const text = String(value ?? "").trim();
|
|
966
|
+
if (!text || /^\d{16,}$/.test(text)) return null;
|
|
967
|
+
return text;
|
|
968
|
+
}
|
|
969
|
+
async function resolveCurrentUserName(host) {
|
|
970
|
+
try {
|
|
971
|
+
const session = await host.getSession();
|
|
972
|
+
const baseUrl = String(session?.baseUrl || "");
|
|
973
|
+
if (!baseUrl) return "";
|
|
974
|
+
const resp = await fetch(
|
|
975
|
+
`${baseUrl}/api/baseserver/layout/teamsCheck?clientType=not_xinchuang&client=WEB&domainName=${encodeURIComponent(baseUrl)}`,
|
|
976
|
+
{
|
|
977
|
+
method: "POST",
|
|
978
|
+
headers: {
|
|
979
|
+
accept: "application/json",
|
|
980
|
+
"content-type": "application/json",
|
|
981
|
+
eteamsid: String(session?.eteamsId || ""),
|
|
982
|
+
cookie: typeof session?.cookieHeader === "function" ? session.cookieHeader() : "",
|
|
983
|
+
"user-agent": typeof session?.uaHeader === "function" ? session.uaHeader() : "weaver-work-cli",
|
|
984
|
+
origin: baseUrl
|
|
985
|
+
},
|
|
986
|
+
redirect: "manual"
|
|
987
|
+
}
|
|
988
|
+
);
|
|
989
|
+
const data = await resp.json().catch(() => ({}));
|
|
990
|
+
const cu = data.currentUser ?? data.data?.currentUser ?? null;
|
|
991
|
+
return cu ? String(cu.username ?? cu.id ?? "") : "";
|
|
992
|
+
} catch {
|
|
993
|
+
return "";
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
var interviewFeedbackTodo = {
|
|
997
|
+
name: "ehr.recruit.interview.feedbackTodo",
|
|
998
|
+
resource: "recruit",
|
|
999
|
+
method: "interview.feedbackTodo",
|
|
1000
|
+
action: "ehr.recruit.interview.feedbackTodo",
|
|
1001
|
+
summary: "\u9762\u8BD5\u5F85\u529E\uFF1A**\u53EA\u8FD4\u56DE\u6211\u4F5C\u4E3A\u9762\u8BD5\u5B98\u7684 AI \u9762\u8BD5\u5F85\u53CD\u9988\u6E05\u5355**\uFF08\u5019\u9009\u4EBA\u5DF2\u7B54\u5B8C\u3001\u5DF2\u6709\u5F55\u50CF\u3001\u6211\u8FD8\u6CA1\u586B\u610F\u89C1\uFF09\uFF1B\u6309\u9700\u7FFB\u9875 + \u5BA2\u6237\u7AEF\u7B5B\u9009\uFF0C\u4E0D\u8FD4\u56DE\u5168\u91CF\u9762\u8BD5",
|
|
1002
|
+
capability: "recruit",
|
|
1003
|
+
risk: READ,
|
|
1004
|
+
inputSchema: schemaOf({
|
|
1005
|
+
maxPages: { type: "integer", minimum: 1, maximum: 50, description: "\u6700\u591A\u7FFB\u9875\u6570\uFF08\u9ED8\u8BA4 5\uFF09" },
|
|
1006
|
+
pageSize: { type: "integer", minimum: 1, maximum: 200, description: "\u5355\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 200\uFF0C\u5B9E\u6D4B\u670D\u52A1\u7AEF\u4E0A\u9650 200\uFF09" }
|
|
1007
|
+
}),
|
|
1008
|
+
handler: async (args, env) => {
|
|
1009
|
+
if (!env.recruitContext) throw ehrValidationError("recruit_context_unavailable", "\u62DB\u8058\u4E0A\u4E0B\u6587\u52A0\u8F7D\u5668\u672A\u521D\u59CB\u5316");
|
|
1010
|
+
const cache = await env.recruitContext.load(env.host);
|
|
1011
|
+
const listParam = cache.lists.interview;
|
|
1012
|
+
const form = cache.forms.interview_plan;
|
|
1013
|
+
if (!listParam?.listId || !form?.objId) {
|
|
1014
|
+
throw new RecruitContextError(
|
|
1015
|
+
"recruit_list_unavailable",
|
|
1016
|
+
"\u5F53\u524D\u73AF\u5883\u672A\u542F\u7528\u300C\u9762\u8BD5\u7BA1\u7406\u300D\u529F\u80FD\uFF08\u672A\u627E\u5230\u9762\u8BD5\u5217\u8868/\u8868\u5355\u53C2\u6570\uFF0C\u6309\u80FD\u529B\u63A2\u6D4B\u62E6\u622A\uFF09\u3002"
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
const pageSize = toNumber(args.pageSize, "pageSize") ?? 200;
|
|
1020
|
+
const maxPages = toNumber(args.maxPages, "maxPages") ?? 5;
|
|
1021
|
+
const me = await resolveCurrentUserName(env.host);
|
|
1022
|
+
const fields = cache.fields[form.objId] || {};
|
|
1023
|
+
const fieldOpts = cache.field_options[form.objId] || {};
|
|
1024
|
+
const statusOpts = fieldOpts[fields.union_status] || {};
|
|
1025
|
+
const typeOpts = fieldOpts[fields.interview_type] || {};
|
|
1026
|
+
const toCn = (map, raw) => {
|
|
1027
|
+
const text = String(raw ?? "");
|
|
1028
|
+
return map[text] ?? text;
|
|
1029
|
+
};
|
|
1030
|
+
const statusOf = (row) => toCn(statusOpts, row?.union_status_key ?? row?.union_status);
|
|
1031
|
+
const typeOf = (row) => toCn(typeOpts, row?.interview_type_key ?? row?.interview_type);
|
|
1032
|
+
const interviewerOf = (row) => personNames(row?.interviewer);
|
|
1033
|
+
const scanned = [];
|
|
1034
|
+
let lastPageCount = 0;
|
|
1035
|
+
for (let i = 0; i < maxPages; i++) {
|
|
1036
|
+
const body = buildListBody({
|
|
1037
|
+
listId: listParam.listId,
|
|
1038
|
+
cusMenuId: listParam.cusMenuId,
|
|
1039
|
+
menuName: listParam.menuName || "\u9762\u8BD5\u7BA1\u7406",
|
|
1040
|
+
title: "\u9762\u8BD5\u7BA1\u7406",
|
|
1041
|
+
current: i + 1,
|
|
1042
|
+
pageSize
|
|
1043
|
+
});
|
|
1044
|
+
const page = await fetchListRows(env.host, form.objId, listParam.listId, body);
|
|
1045
|
+
const use = page.displayRows && page.displayRows.length ? page.displayRows : page.rows;
|
|
1046
|
+
scanned.push(...use);
|
|
1047
|
+
lastPageCount = use.length;
|
|
1048
|
+
if (use.length < pageSize) break;
|
|
1049
|
+
}
|
|
1050
|
+
const pending = scanned.filter((row) => /待反馈/.test(statusOf(row)));
|
|
1051
|
+
const mineAll = me ? pending.filter((row) => interviewerOf(row).includes(me)) : [];
|
|
1052
|
+
const mineAi = mineAll.filter((row) => /AI\s*面试/i.test(typeOf(row)));
|
|
1053
|
+
const slim = (row) => ({
|
|
1054
|
+
form_data_id: row?.form_data_id ?? row?.id ?? null,
|
|
1055
|
+
candidate_name: nameLike(row?.candidate_name) ?? nameLike(row?.talent_id) ?? nameLike(row?.name),
|
|
1056
|
+
position_name: nameLike(row?.position_name) ?? nameLike(row?.position_manage_id),
|
|
1057
|
+
start_time: row?.start_time ?? null,
|
|
1058
|
+
interview_type_key: typeOf(row) || null,
|
|
1059
|
+
interview_session: row?.interview_session ?? null,
|
|
1060
|
+
interviewer: interviewerOf(row) || null,
|
|
1061
|
+
union_status_key: statusOf(row) || null,
|
|
1062
|
+
subject: row?.subject ?? null,
|
|
1063
|
+
talent_id: row?.talent_id ?? null,
|
|
1064
|
+
position_manage_id: row?.position_manage_id ?? null
|
|
1065
|
+
});
|
|
1066
|
+
const notes = [];
|
|
1067
|
+
if (!me) notes.push("\u672A\u80FD\u89E3\u6790\u5F53\u524D\u767B\u5F55\u4EBA\u59D3\u540D\uFF08teamsCheck \u5931\u8D25\uFF09\uFF0C\u65E0\u6CD5\u6309\u9762\u8BD5\u5B98\u8FC7\u6EE4");
|
|
1068
|
+
if (lastPageCount >= pageSize && scanned.length >= pageSize * maxPages) {
|
|
1069
|
+
notes.push(`\u5DF2\u626B\u63CF ${scanned.length} \u6761\uFF08\u8FBE maxPages=${maxPages} \u4E0A\u9650\uFF09\uFF0C\u5982\u6000\u7591\u9057\u6F0F\u53EF\u52A0\u5927 maxPages`);
|
|
1070
|
+
}
|
|
1071
|
+
return ehrSuccess("ehr.recruit.interview.feedbackTodo", {
|
|
1072
|
+
currentUser: me || null,
|
|
1073
|
+
scanned: scanned.length,
|
|
1074
|
+
myAiPendingFeedback: { count: mineAi.length, rows: mineAi.map(slim) },
|
|
1075
|
+
myOtherPendingFeedback: {
|
|
1076
|
+
count: mineAll.length - mineAi.length,
|
|
1077
|
+
rows: mineAll.filter((row) => !/AI\s*面试/i.test(typeOf(row))).map(slim)
|
|
1078
|
+
},
|
|
1079
|
+
...notes.length ? { note: notes.join("\uFF1B") } : {}
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
var candidateCard = {
|
|
1084
|
+
name: "ehr.recruit.candidate.card",
|
|
1085
|
+
resource: "recruit",
|
|
1086
|
+
method: "candidate.card",
|
|
1087
|
+
action: "ehr.recruit.candidate.card",
|
|
1088
|
+
summary: "\u67E5\u770B\u4EBA\u624D\u8BE6\u60C5\u5361\u7247\uFF1A\u6743\u9650\u6821\u9A8C + \u56DB\u5F20\u5361\u7247\uFF08\u57FA\u672C\u4FE1\u606F/\u5E94\u8058\u8FDB\u5C55/\u9762\u8BD5\u5B89\u6392/\u6C9F\u901A\u5907\u6CE8\uFF09\u5E76\u884C\u62C9\u53D6\uFF0C\u59D3\u540D\u4E0E\u5B57\u5178\u5168\u90E8\u5185\u8054\u89E3\u6790",
|
|
1089
|
+
capability: "recruit",
|
|
1090
|
+
risk: READ,
|
|
1091
|
+
inputSchema: schemaOf(
|
|
1092
|
+
{ talentId: { oneOf: [{ type: "integer" }, { type: "string", pattern: "^\\d+$" }], description: "\u4EBA\u624D ID\uFF0C\u6765\u81EA candidate.search \u7684 talentId" } },
|
|
1093
|
+
{ required: ["talentId"] }
|
|
1094
|
+
),
|
|
1095
|
+
handler: async (args, env) => {
|
|
1096
|
+
const talentId = args.talentId;
|
|
1097
|
+
if (talentId === void 0 || talentId === null || talentId === "") {
|
|
1098
|
+
throw ehrValidationError("talent_id_required", "talentId \u5FC5\u586B");
|
|
1099
|
+
}
|
|
1100
|
+
if (!/^\d+$/.test(String(talentId).trim())) {
|
|
1101
|
+
throw ehrValidationError("talent_id_invalid", "talentId \u5FC5\u987B\u662F\u6570\u5B57 ID");
|
|
1102
|
+
}
|
|
1103
|
+
const id = String(talentId).trim();
|
|
1104
|
+
if (!env.recruitContext) {
|
|
1105
|
+
throw ehrValidationError("recruit_context_unavailable", "\u62DB\u8058\u4E0A\u4E0B\u6587\u52A0\u8F7D\u5668\u672A\u521D\u59CB\u5316");
|
|
1106
|
+
}
|
|
1107
|
+
const cache = await env.recruitContext.load(env.host);
|
|
1108
|
+
const talentListId = cache.lists.talent?.listId || "";
|
|
1109
|
+
const extra = talentListId ? { ebBusinessId: talentListId } : {};
|
|
1110
|
+
const rk1 = randHex6();
|
|
1111
|
+
const [rightsResponse, prepareResponse] = await Promise.all([
|
|
1112
|
+
env.host.request({
|
|
1113
|
+
path: `/api/recruit/talent/hasRights?formDataId=${id}`,
|
|
1114
|
+
method: "POST",
|
|
1115
|
+
headers: extra
|
|
1116
|
+
}),
|
|
1117
|
+
env.host.request({
|
|
1118
|
+
path: `/api/recruit/candidate/getCandidateCardPrepareQuery?talentId=${id}&randomkey_${rk1}=${rk1}`,
|
|
1119
|
+
headers: extra
|
|
1120
|
+
})
|
|
1121
|
+
]);
|
|
1122
|
+
const rights = rightsResponse?.data || [];
|
|
1123
|
+
if (!rights.includes("READ")) {
|
|
1124
|
+
throw ehrValidationError("recruit_rights_denied", "\u5F53\u524D\u8D26\u53F7\u65E0\u8BE5\u4EBA\u624D\u8BE6\u60C5\u7684 READ \u6743\u9650\uFF0C\u65E0\u6CD5\u67E5\u770B\u3002");
|
|
1125
|
+
}
|
|
1126
|
+
const batchId = prepareResponse?.data?.batchId;
|
|
1127
|
+
if (!batchId) {
|
|
1128
|
+
throw new RecruitContextError("recruit_batch_id_missing", "\u672A\u53D6\u5230 batchId\uFF08prepareQuery \u8FD4\u56DE\u5F02\u5E38\uFF09\uFF0C\u65E0\u6CD5\u67E5\u770B\u8BE6\u60C5\u5361\u7247\u3002");
|
|
1129
|
+
}
|
|
1130
|
+
const rk2 = randHex6();
|
|
1131
|
+
const v = randHex6();
|
|
1132
|
+
const query = `talentId=${id}&batchId=${batchId}&v=${v}&randomkey_${rk2}=${rk2}`;
|
|
1133
|
+
const cardBody = { talentId: id, batchId, current: 1, pageSize: 100 };
|
|
1134
|
+
const [base, other, interview, remark] = await Promise.all([
|
|
1135
|
+
env.host.request({ path: `/api/recruit/candidate/getCandidateCardBaseInfo?${query}`, headers: extra }),
|
|
1136
|
+
env.host.request({ path: `/api/recruit/candidate/getCandidateCardOtherInfo?${query}`, headers: extra }),
|
|
1137
|
+
env.host.request({ path: "/api/recruit/candidate/getCandidateCardInterviewInfo", body: cardBody, headers: extra }),
|
|
1138
|
+
env.host.request({ path: "/api/recruit/candidate/getCandidateCardRemark", body: cardBody, headers: extra })
|
|
1139
|
+
]);
|
|
1140
|
+
const statusMap = cache.options?.recruit_status || {};
|
|
1141
|
+
const talent = base?.data?.talent || {};
|
|
1142
|
+
const currentBatch = other?.data?.currentCandidateBatch || {};
|
|
1143
|
+
const interviewList = interview?.data?.list || [];
|
|
1144
|
+
const remarkList = remark?.data?.list || [];
|
|
1145
|
+
const baseUrl = (await env.host.getSession()).baseUrl.replace(/\/+$/, "");
|
|
1146
|
+
return ehrSuccess("ehr.recruit.candidate.card", {
|
|
1147
|
+
talentId: id,
|
|
1148
|
+
cardLink: cache.ebdDetailPageId ? `${baseUrl}/sp/ebdpage/view/${cache.ebdDetailPageId}?talentId=${id}${String(cache.selfUse ?? "") === "1" ? "&recruitType=useSelf" : ""}` : null,
|
|
1149
|
+
baseInfo: {
|
|
1150
|
+
name: talent?.hrm?.name,
|
|
1151
|
+
mobile: talent?.telephone,
|
|
1152
|
+
channel: talent?.channel,
|
|
1153
|
+
status: statusMap[base?.data?.recruitStatus] || base?.data?.recruitStatus || null,
|
|
1154
|
+
createTime: talent?.createTime
|
|
1155
|
+
},
|
|
1156
|
+
position: {
|
|
1157
|
+
position: currentBatch?.position?.name,
|
|
1158
|
+
stage: currentBatch?.currentStageName,
|
|
1159
|
+
stages: (currentBatch?.allStage || []).map((stage) => stage?.stageName).filter(Boolean),
|
|
1160
|
+
archiveStatus: currentBatch?.archiveStatus?.name,
|
|
1161
|
+
employManager: namesOf(currentBatch?.employManager),
|
|
1162
|
+
channel: currentBatch?.channel,
|
|
1163
|
+
candidateManageId: currentBatch?.id || currentBatch?.candidateManageId || null,
|
|
1164
|
+
batchId: currentBatch?.batchId || batchId,
|
|
1165
|
+
positionId: currentBatch?.position?.id || null
|
|
1166
|
+
},
|
|
1167
|
+
interviews: interviewList.map((item) => ({
|
|
1168
|
+
subject: item?.subject,
|
|
1169
|
+
startTime: item?.startTime || null,
|
|
1170
|
+
endTime: item?.endTime || null,
|
|
1171
|
+
status: namesOf(item?.unionStatus),
|
|
1172
|
+
type: namesOf(item?.interviewType),
|
|
1173
|
+
round: namesOf(item?.interviewSession),
|
|
1174
|
+
interviewer: namesOf(item?.interviewer),
|
|
1175
|
+
arranger: namesOf(item?.creator),
|
|
1176
|
+
updater: namesOf(item?.updater),
|
|
1177
|
+
position: namesOf(item?.positionManageId),
|
|
1178
|
+
feedbacks: (item?.interviewFeedBack || []).map((feedback) => ({
|
|
1179
|
+
result: feedback?.result?.[0]?.name || null,
|
|
1180
|
+
comment: feedback?.judgement ? feedback.judgement.replace(/<[^>]+>/g, "").trim() : null,
|
|
1181
|
+
feedbacker: namesOf(feedback?.updater),
|
|
1182
|
+
createTime: feedback?.createTime
|
|
1183
|
+
}))
|
|
1184
|
+
})),
|
|
1185
|
+
remarks: remarkList.map((item) => ({
|
|
1186
|
+
time: item?.contactTime || item?.createTime,
|
|
1187
|
+
creator: item?.creator?.username || item?.creator?.name || null,
|
|
1188
|
+
content: item?.remark
|
|
1189
|
+
}))
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
var recruitOperations = [
|
|
1194
|
+
contextResolve,
|
|
1195
|
+
candidateSearch,
|
|
1196
|
+
candidateList,
|
|
1197
|
+
candidateCard,
|
|
1198
|
+
interviewFeedbackTodo
|
|
1199
|
+
];
|
|
1200
|
+
|
|
1201
|
+
export {
|
|
1202
|
+
EhrCliError,
|
|
1203
|
+
ehrValidationError,
|
|
1204
|
+
ehrAuthError,
|
|
1205
|
+
ehrNetworkError,
|
|
1206
|
+
ehrConfirmationError,
|
|
1207
|
+
ehrPartialError,
|
|
1208
|
+
READ,
|
|
1209
|
+
WRITE,
|
|
1210
|
+
ehrSuccess,
|
|
1211
|
+
schemaOf,
|
|
1212
|
+
SCHEMA_DATE,
|
|
1213
|
+
SCHEMA_MONTH,
|
|
1214
|
+
SCHEMA_ID,
|
|
1215
|
+
SCHEMA_ID_LIST,
|
|
1216
|
+
SCHEMA_STRING_LIST,
|
|
1217
|
+
asObject,
|
|
1218
|
+
assertNoForbiddenKeys,
|
|
1219
|
+
assertMonth,
|
|
1220
|
+
toNumber,
|
|
1221
|
+
toPositiveInt,
|
|
1222
|
+
toIdList,
|
|
1223
|
+
pickDefined,
|
|
1224
|
+
compact,
|
|
1225
|
+
assertDateRange,
|
|
1226
|
+
requireDateRange,
|
|
1227
|
+
normalizePaged,
|
|
1228
|
+
toPageQuery,
|
|
1229
|
+
resolveSecondAuthToken,
|
|
1230
|
+
assertEnum,
|
|
1231
|
+
EHR_PAGES,
|
|
1232
|
+
ehrPageUrl,
|
|
1233
|
+
addDays,
|
|
1234
|
+
createRecruitContextLoader,
|
|
1235
|
+
buildListBody,
|
|
1236
|
+
fetchListRows,
|
|
1237
|
+
recruitOperations
|
|
1238
|
+
};
|