weaver-work-cli 0.1.29 → 0.1.32
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-UMGX72K6.js +2537 -0
- package/dist/chunks/archive-oa-N2IYBLF3.js +1317 -0
- package/dist/chunks/asset-GLEGKFG5.js +2109 -0
- package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
- package/dist/chunks/blog-E44OTVDA.js +2157 -0
- package/dist/chunks/caizhilian-DQUFZXZL.js +10087 -0
- package/dist/chunks/calendar-JKPIRKFD.js +1195 -0
- package/dist/chunks/chunk-2GA5ZIQL.js +1615 -0
- package/dist/chunks/chunk-4YC43QQ4.js +403 -0
- package/dist/chunks/chunk-6EFWDL7Y.js +161 -0
- package/dist/chunks/chunk-6RKD4DRZ.js +5556 -0
- package/dist/chunks/chunk-AJ62BGAW.js +29 -0
- package/dist/chunks/chunk-BUSC6UAE.js +43 -0
- package/dist/chunks/chunk-C6R3B2ML.js +358 -0
- package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
- package/dist/chunks/chunk-DW6AUUKS.js +508 -0
- package/dist/chunks/chunk-E4Z23GHM.js +6962 -0
- package/dist/chunks/chunk-EG6ZU444.js +654 -0
- package/dist/chunks/chunk-EZALDOQH.js +383 -0
- package/dist/chunks/chunk-FMPJJYYI.js +106 -0
- package/dist/chunks/chunk-G2JSIUWF.js +769 -0
- package/dist/chunks/chunk-G3QJULO2.js +387 -0
- package/dist/chunks/chunk-GCG2NMWR.js +703 -0
- package/dist/chunks/chunk-GPMFD4RD.js +75 -0
- package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
- package/dist/chunks/chunk-H7J4DC5R.js +464 -0
- package/dist/chunks/chunk-IURUFGZK.js +477 -0
- package/dist/chunks/chunk-LUSPKZKY.js +53 -0
- package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
- package/dist/chunks/chunk-NOODWMCL.js +584 -0
- package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
- package/dist/chunks/chunk-P26ZWSKU.js +73 -0
- package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
- package/dist/chunks/chunk-WKI2FBIQ.js +15606 -0
- package/dist/chunks/chunk-WSKBSQ2U.js +231 -0
- package/dist/chunks/chunk-YLCYX7LE.js +371 -0
- package/dist/chunks/chunk-YRVDW4WN.js +205 -0
- package/dist/chunks/chunk-ZEDWSH32.js +68 -0
- package/dist/chunks/continuation-2CKSBLA6.js +11 -0
- package/dist/chunks/continuation-HZIZRZBX.js +13 -0
- package/dist/chunks/continuation-NLECEJPX.js +11 -0
- package/dist/chunks/ebuilder-form-V5FG2EHC.js +2276 -0
- package/dist/chunks/ehr-HMFY6VIL.js +5241 -0
- package/dist/chunks/employee-SAK2QYXX.js +11 -0
- package/dist/chunks/esb-ZYSVB7SG.js +141 -0
- package/dist/chunks/fna-B7RKPAZD.js +1444 -0
- package/dist/chunks/host-45WED2KK.js +21 -0
- package/dist/chunks/host-I4Z6BFYX.js +23 -0
- package/dist/chunks/host-KNZ52LJZ.js +17 -0
- package/dist/chunks/host-OCH2BCCV.js +19 -0
- package/dist/chunks/hrm-2KAZGUHI.js +244 -0
- package/dist/chunks/im-ACJJWH4U.js +252 -0
- package/dist/chunks/invoice-ZK3WCX2U.js +5179 -0
- package/dist/chunks/jiuchuanhui-5PQD3IL2.js +1940 -0
- package/dist/chunks/lazy-dispatch-JQXBW3GM.js +28 -0
- package/dist/chunks/mail-S2HDDXO2.js +2695 -0
- package/dist/chunks/meeting-QVN3I37L.js +504 -0
- package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
- package/dist/chunks/okr-QNG4VC2Q.js +2482 -0
- package/dist/chunks/plan-A25EMW6U.js +2025 -0
- package/dist/chunks/project-G6XV66DZ.js +1361 -0
- package/dist/chunks/registry-2VLUAESA.js +14 -0
- package/dist/chunks/registry-7C5UMIPL.js +19 -0
- package/dist/chunks/registry-DC6KR3NH.js +18 -0
- package/dist/chunks/registry-NYPYMZXG.js +16 -0
- package/dist/chunks/registry-TI3CIUXF.js +19 -0
- package/dist/chunks/room-recommend-WRTHO6Y2.js +20 -0
- package/dist/chunks/schedule-KFIITGSK.js +24 -0
- package/dist/chunks/state-Y2XBP6YE.js +15 -0
- package/dist/chunks/workflow-DJ7SYWAF.js +245 -0
- package/dist/cmd/argv.js +45 -0
- package/dist/cmd/docs/index.js +3 -3
- package/dist/cmd/lazy-dispatch.js +20 -0
- package/dist/cmd/root.js +2 -4
- package/dist/cmd/setup/index.js +2 -2
- package/dist/cmd/skills/index.js +2 -2
- package/dist/core/package-paths.js +61 -0
- package/dist/index.js +163 -7
- package/dist/internal/e10/auth/xiaoe.js +3 -3
- package/dist/internal/e10/request-runtime.js +18 -62
- package/dist/internal/skills/detector.js +2 -2
- package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
- package/dist/shortcuts/contract/host.js +91 -35
- package/dist/shortcuts/contract/index.js +213 -0
- package/dist/shortcuts/contract/manifest.js +928 -0
- package/dist/shortcuts/contract/ooxml/docx.js +295 -0
- package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
- package/dist/shortcuts/contract/ooxml/zip.js +158 -0
- package/dist/shortcuts/contract/operations/assistant.js +1156 -0
- package/dist/shortcuts/contract/operations/clause-library.js +522 -0
- package/dist/shortcuts/contract/operations/compare.js +193 -0
- package/dist/shortcuts/contract/operations/credit-page.js +34 -0
- package/dist/shortcuts/contract/operations/flow.js +98 -0
- package/dist/shortcuts/contract/operations/page.js +66 -0
- package/dist/shortcuts/contract/operations/performance.js +733 -0
- package/dist/shortcuts/contract/operations/quote.js +557 -0
- package/dist/shortcuts/contract/operations/recommend.js +78 -0
- package/dist/shortcuts/contract/operations/registry.js +18 -0
- package/dist/shortcuts/contract/operations/review.js +83 -0
- package/dist/shortcuts/contract/operations/shared.js +37 -0
- package/dist/shortcuts/contract/operations/upload.js +108 -0
- package/dist/shortcuts/contract/operations/write.js +3 -2
- package/dist/shortcuts/index.js +140 -40
- package/dist/shortcuts/invoice/manifest.js +34 -11
- package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
- package/dist/shortcuts/invoice/operations/reim.js +81 -5
- package/dist/shortcuts/invoice/operations/shared.js +12 -5
- package/dist/shortcuts/meeting/host.js +45 -3
- package/dist/shortcuts/meeting/invitation/docx.js +442 -0
- package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
- package/dist/shortcuts/meeting/operations/attachment.js +442 -0
- package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
- package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
- package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
- package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
- package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
- package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
- package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
- package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
- package/dist/shortcuts/meeting/operations/invitation.js +458 -0
- package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
- package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
- package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
- package/dist/shortcuts/meeting/operations/receipts.js +1 -1
- package/dist/shortcuts/meeting/operations/registry.js +18 -0
- package/dist/shortcuts/meeting/operations/summary.js +276 -0
- package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
- package/dist/shortcuts/meeting/operations.js +42 -1
- package/dist/shortcuts/meeting/qr/encoder.js +427 -0
- package/dist/shortcuts/meeting/qr/render.js +103 -0
- package/dist/shortcuts/workflow/operations/form.js +17 -5
- package/docs/contract.md +39 -4
- package/docs/invoice.md +5 -5
- package/package.json +3 -2
- package/scripts/bundle.mjs +63 -0
- package/skill-template/business-info.json +25 -4
- package/skill-template/domains/jinchengda.md +16 -3
- package/skill-template/domains/yepiaotong.md +1 -1
- package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
- package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
- package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
- package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
- package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
- package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
- package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
- package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
- package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
- package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
- package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
- package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
- package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
- package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
- package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
- package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
- package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
- package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
- package/skills/weaver-e10-meeting/SKILL.md +493 -17
- package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
- package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
- package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
- package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
- package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-yepiaotong/SKILL.md +9 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +6 -0
- package/templates/meeting/invitation.docx +0 -0
|
@@ -0,0 +1,769 @@
|
|
|
1
|
+
import { createRequire as __esbuildCreateRequire } from 'node:module';
|
|
2
|
+
const require = __esbuildCreateRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
READ,
|
|
5
|
+
SCHEMA_ID,
|
|
6
|
+
SCHEMA_PAGE,
|
|
7
|
+
browserBaseBody,
|
|
8
|
+
hrmEmployeeOperations,
|
|
9
|
+
hrmSuccess,
|
|
10
|
+
orgLink,
|
|
11
|
+
pickDefined,
|
|
12
|
+
positionLink,
|
|
13
|
+
schemaOf,
|
|
14
|
+
toNumber,
|
|
15
|
+
toPositiveInt,
|
|
16
|
+
toStringIdList
|
|
17
|
+
} from "./chunk-NOODWMCL.js";
|
|
18
|
+
import {
|
|
19
|
+
hrmValidationError
|
|
20
|
+
} from "./chunk-OOUTBLZ4.js";
|
|
21
|
+
|
|
22
|
+
// src/shortcuts/hrm/operations/org.ts
|
|
23
|
+
var ORG_TYPES = ["subcompany", "department"];
|
|
24
|
+
var orgQuery = {
|
|
25
|
+
name: "hrm.org.query",
|
|
26
|
+
resource: "org",
|
|
27
|
+
method: "org.query",
|
|
28
|
+
action: "hrm.org.query",
|
|
29
|
+
summary: "\u6309\u540D\u79F0/\u7F16\u53F7/\u4E0A\u7EA7\u7EC4\u7EC7\u67E5\u8BE2\u5206\u90E8\u6216\u90E8\u95E8\uFF08type \u533A\u5206\uFF1B\u4E0D\u4F20 type \u65F6\u9ED8\u8BA4\u90E8\u95E8\uFF0C\u53EF\u7528 type \u5207\u5206\u90E8\u5206\u90E8\uFF09",
|
|
30
|
+
risk: READ,
|
|
31
|
+
inputSchema: schemaOf({
|
|
32
|
+
type: { type: "string", enum: [...ORG_TYPES], description: "subcompany \u5206\u90E8 / department \u90E8\u95E8\uFF1B\u4E0D\u4F20\u9ED8\u8BA4 department" },
|
|
33
|
+
name: { type: "string", description: "\u540D\u79F0\uFF08\u6A21\u7CCA\u5305\u542B\u5339\u914D\uFF09" },
|
|
34
|
+
code: { type: "string", description: "\u7F16\u53F7\uFF08\u6A21\u7CCA\u5305\u542B\u5339\u914D\uFF09" },
|
|
35
|
+
parent: { type: "array", items: SCHEMA_ID, description: "\u4E0A\u7EA7\u90E8\u95E8 id \u6570\u7EC4\uFF08\u90E8\u95E8\u6302\u5728\u90E8\u95E8\u4E0B\uFF0Cdepartment\uFF09" },
|
|
36
|
+
subcompany: { type: "array", items: SCHEMA_ID, description: "\u4E0A\u7EA7\u5206\u90E8 id \u6570\u7EC4\uFF08\u90E8\u95E8\u6302\u5728\u5206\u90E8\u4E0B\uFF0Cdepartment\uFF09" },
|
|
37
|
+
supSubDepartment: { type: "array", items: SCHEMA_ID, description: "\u4E0A\u7EA7\u5206\u90E8 id \u6570\u7EC4\uFF08\u5206\u90E8\u6302\u5728\u5206\u90E8\u4E0B\uFF0Csubcompany\uFF09" },
|
|
38
|
+
...SCHEMA_PAGE
|
|
39
|
+
}),
|
|
40
|
+
handler: async (args, { host }) => {
|
|
41
|
+
const type = args.type === void 0 ? "department" : String(args.type);
|
|
42
|
+
if (!ORG_TYPES.includes(type)) {
|
|
43
|
+
throw hrmValidationError("enum_invalid", `type \u53D6\u503C\u5FC5\u987B\u662F ${ORG_TYPES.join(" / ")} \u4E4B\u4E00`);
|
|
44
|
+
}
|
|
45
|
+
const name = args.name === void 0 ? "" : String(args.name).trim();
|
|
46
|
+
const code = args.code === void 0 ? "" : String(args.code).trim();
|
|
47
|
+
const parentIds = toStringIdList(args.parent, "parent");
|
|
48
|
+
const subcompanyIds = toStringIdList(args.subcompany, "subcompany");
|
|
49
|
+
const supSubDepartmentIds = toStringIdList(args.supSubDepartment, "supSubDepartment");
|
|
50
|
+
const hasText = name !== "" || code !== "";
|
|
51
|
+
const hasOrg = Boolean(parentIds?.length || subcompanyIds?.length || supSubDepartmentIds?.length);
|
|
52
|
+
if (!hasText && !hasOrg) {
|
|
53
|
+
throw hrmValidationError("empty_condition", "\u7EC4\u7EC7\u67E5\u8BE2\u5FC5\u987B\u643A\u5E26\u81F3\u5C11\u4E00\u4E2A\u6536\u655B\u6761\u4EF6\uFF1Aname / code / parent / subcompany / supSubDepartment");
|
|
54
|
+
}
|
|
55
|
+
const formDatas = {};
|
|
56
|
+
if (name) formDatas.name = [{ nameCondition: { id: "in", content: "\u5305\u542B", disabled: false }, name }];
|
|
57
|
+
if (code) formDatas.code = [{ codeCondition: { id: "in", content: "\u5305\u542B", disabled: false }, code }];
|
|
58
|
+
if (parentIds?.length) {
|
|
59
|
+
formDatas.parent = [{ parentCondition: { id: "eq", content: "\u7B49\u4E8E", disabled: false }, parent: parentIds.map((id) => ({ id })) }];
|
|
60
|
+
}
|
|
61
|
+
if (subcompanyIds?.length) {
|
|
62
|
+
formDatas.subcompany = [{ subcompanyCondition: { id: "eq", content: "\u7B49\u4E8E", disabled: false }, subcompany: subcompanyIds.map((id) => ({ id })) }];
|
|
63
|
+
}
|
|
64
|
+
if (supSubDepartmentIds?.length) {
|
|
65
|
+
formDatas.supSubDepartment = [{ supSubDepartmentCondition: { id: "eq", content: "\u7B49\u4E8E", disabled: false }, supSubDepartment: supSubDepartmentIds.map((id) => ({ id })) }];
|
|
66
|
+
}
|
|
67
|
+
const body = {
|
|
68
|
+
...browserBaseBody(),
|
|
69
|
+
virtualType: "ALL",
|
|
70
|
+
cmd: "list",
|
|
71
|
+
formDatas,
|
|
72
|
+
quickSearchDatas: {},
|
|
73
|
+
type: "and",
|
|
74
|
+
stopDepartment: false
|
|
75
|
+
};
|
|
76
|
+
const current = toPositiveInt(args.current, "current") ?? 1;
|
|
77
|
+
const pageSize = toNumber(args.pageSize, "pageSize") ?? 200;
|
|
78
|
+
body.current = current;
|
|
79
|
+
body.pageSize = pageSize;
|
|
80
|
+
const path = type === "subcompany" ? "/api/hrm/common/browser/data/subcompany" : "/api/hrm/common/browser/data/department";
|
|
81
|
+
const resp = await host.request({ method: "POST", path, body });
|
|
82
|
+
const d = resp?.data ?? {};
|
|
83
|
+
const rawRows = Array.isArray(d.data) ? d.data : [];
|
|
84
|
+
const session = await host.getSession();
|
|
85
|
+
const baseUrl = session.baseUrl.replace(/\/+$/, "");
|
|
86
|
+
const rows = rawRows.map((r) => ({ ...r, link: orgLink(baseUrl, r.id) }));
|
|
87
|
+
return hrmSuccess("hrm.org.query", { rows, total: Number(d.total ?? rows.length), type }, { current, pageSize });
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var orgDetail = {
|
|
91
|
+
name: "hrm.org.detail",
|
|
92
|
+
resource: "org",
|
|
93
|
+
method: "org.detail",
|
|
94
|
+
action: "hrm.org.detail",
|
|
95
|
+
summary: "\u6309\u7EC4\u7EC7\u8282\u70B9 id \u53D6\u90E8\u95E8/\u5206\u90E8\u8BE6\u60C5\u8868\u5355\uFF08\u7C7B\u578B\u7531\u670D\u52A1\u7AEF\u6309\u8BB0\u5F55\u81EA\u52A8\u5224\u65AD\uFF1B\u542B\u5168\u8DEF\u5F84 fullPath \u4E0E\u4EBA\u5458\u7EDF\u8BA1\uFF09",
|
|
96
|
+
risk: READ,
|
|
97
|
+
inputSchema: schemaOf(
|
|
98
|
+
{ id: SCHEMA_ID },
|
|
99
|
+
{ required: ["id"] }
|
|
100
|
+
),
|
|
101
|
+
handler: async (args, { host }) => {
|
|
102
|
+
const id = String(args.id).trim();
|
|
103
|
+
if (!id) throw hrmValidationError("id_required", "id \u5FC5\u586B");
|
|
104
|
+
const session = await host.getSession();
|
|
105
|
+
const baseUrl = session.baseUrl.replace(/\/+$/, "");
|
|
106
|
+
const resp = await host.request({
|
|
107
|
+
method: "GET",
|
|
108
|
+
path: "/api/bs/hrm/organization/getForm",
|
|
109
|
+
query: { id, readOnly: true, includeSub: true, quote: true, isMobile: false },
|
|
110
|
+
headers: { Referer: `${baseUrl}/sp/hrm/orgCard/${id}` }
|
|
111
|
+
});
|
|
112
|
+
const raw = resp?.data?.data ?? {};
|
|
113
|
+
const parentName = Array.isArray(raw.parent) && raw.parent[0]?.name ? String(raw.parent[0].name) : "";
|
|
114
|
+
const subcompanyName = Array.isArray(raw.subcompany) && raw.subcompany[0]?.name ? String(raw.subcompany[0].name) : "";
|
|
115
|
+
return hrmSuccess("hrm.org.detail", {
|
|
116
|
+
id,
|
|
117
|
+
name: raw.name,
|
|
118
|
+
type: raw.type,
|
|
119
|
+
code: raw.code,
|
|
120
|
+
fullPath: raw.fullPath,
|
|
121
|
+
status: raw.status,
|
|
122
|
+
...parentName ? { parentName } : {},
|
|
123
|
+
...subcompanyName ? { subcompanyName } : {},
|
|
124
|
+
...pickDefined(raw, ["description", "remark"]),
|
|
125
|
+
link: orgLink(baseUrl, id)
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var hrmOrgOperations = [
|
|
130
|
+
orgQuery,
|
|
131
|
+
orgDetail
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
// src/shortcuts/hrm/operations/position.ts
|
|
135
|
+
function positionFormDatas() {
|
|
136
|
+
const d = {};
|
|
137
|
+
for (const f of ["name", "full_name", "code", "parent", "department", "jobsetid", "grade_id"]) {
|
|
138
|
+
d[f] = [{ [`${f}Opt`]: { id: "in", content: "\u5305\u542B", disabled: false } }];
|
|
139
|
+
}
|
|
140
|
+
return d;
|
|
141
|
+
}
|
|
142
|
+
function formatPosRow(r, baseUrl) {
|
|
143
|
+
return {
|
|
144
|
+
id: r.id,
|
|
145
|
+
name: r.name || r.content || "",
|
|
146
|
+
code: r.code || "",
|
|
147
|
+
title: r.title || "",
|
|
148
|
+
leaf: r.leaf !== false,
|
|
149
|
+
link: positionLink(baseUrl, r.id)
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function formatPosListItem(r, baseUrl) {
|
|
153
|
+
return {
|
|
154
|
+
id: r.id,
|
|
155
|
+
name: r.name,
|
|
156
|
+
fullName: r.fullName || "",
|
|
157
|
+
code: r.code || "",
|
|
158
|
+
parent: r.parent || "",
|
|
159
|
+
parentId: r.parentId || "",
|
|
160
|
+
department: r.department || "",
|
|
161
|
+
userCount: r.userCount || "0",
|
|
162
|
+
partTimeCount: r.partTimeCount || "0",
|
|
163
|
+
cancelStatus: r.cancelStatus,
|
|
164
|
+
jobsetid: r.jobsetid || "",
|
|
165
|
+
link: positionLink(baseUrl, r.id)
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
var positionQuery = {
|
|
169
|
+
name: "hrm.position.query",
|
|
170
|
+
resource: "position",
|
|
171
|
+
method: "position.query",
|
|
172
|
+
action: "hrm.position.query",
|
|
173
|
+
summary: "\u6309\u540D\u79F0/\u7F16\u53F7\u67E5\u5C97\u4F4D\uFF08\u5FEB\u6377\u641C\u7D22\u540D\u79F0\u7F16\u53F7\u5408\u4E00\uFF1B\u663E\u5F0F name/code \u8D70\u9AD8\u7EA7\u6761\u4EF6\uFF09",
|
|
174
|
+
risk: READ,
|
|
175
|
+
inputSchema: schemaOf({
|
|
176
|
+
keyword: { type: "string", description: "\u5FEB\u6377\u641C\u7D22\u5173\u952E\u8BCD\uFF0C\u540D\u79F0\u4E0E\u7F16\u53F7\u5408\u4E00\u5339\u914D" },
|
|
177
|
+
name: { type: "string", description: "\u5C97\u4F4D\u540D\u79F0\uFF08\u5305\u542B\u5339\u914D\uFF09" },
|
|
178
|
+
code: { type: "string", description: "\u5C97\u4F4D\u7F16\u53F7\uFF08\u7CBE\u786E\u5339\u914D\uFF09" }
|
|
179
|
+
}),
|
|
180
|
+
handler: async (args, { host }) => {
|
|
181
|
+
const name = args.name === void 0 ? "" : String(args.name).trim();
|
|
182
|
+
const code = args.code === void 0 ? "" : String(args.code).trim();
|
|
183
|
+
const keyword = args.keyword === void 0 ? "" : String(args.keyword).trim();
|
|
184
|
+
if (!name && !code && !keyword) {
|
|
185
|
+
throw hrmValidationError("empty_condition", "\u5C97\u4F4D\u67E5\u8BE2\u5FC5\u987B\u643A\u5E26\u81F3\u5C11\u4E00\u4E2A\u6536\u655B\u6761\u4EF6\uFF1Akeyword \u6216 name / code");
|
|
186
|
+
}
|
|
187
|
+
const formDatas = positionFormDatas();
|
|
188
|
+
const quickSearchDatas = {};
|
|
189
|
+
if (name) {
|
|
190
|
+
formDatas.name = [{ nameOpt: { id: "in", content: "\u5305\u542B", disabled: false } }, { nameInput: name }];
|
|
191
|
+
} else if (code) {
|
|
192
|
+
formDatas.code = [{ codeOpt: { id: "eq", content: "\u7B49\u4E8E", disabled: false } }, { codeInput: code }];
|
|
193
|
+
} else {
|
|
194
|
+
quickSearchDatas.name = keyword;
|
|
195
|
+
}
|
|
196
|
+
const resp = await host.request({
|
|
197
|
+
method: "POST",
|
|
198
|
+
path: "/api/app/hrm/common/browser/data/position",
|
|
199
|
+
body: { cmd: "list", current: 1, pageSize: 200, formDatas, quickSearchDatas, type: "and" }
|
|
200
|
+
});
|
|
201
|
+
const d = resp?.data ?? {};
|
|
202
|
+
const rawRows = Array.isArray(d.data) ? d.data : [];
|
|
203
|
+
const session = await host.getSession();
|
|
204
|
+
const baseUrl = session.baseUrl.replace(/\/+$/, "");
|
|
205
|
+
const rows = rawRows.map((r) => formatPosRow(r, baseUrl));
|
|
206
|
+
return hrmSuccess("hrm.position.query", { rows, total: Number(d.total ?? rows.length) });
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
var positionDetail = {
|
|
210
|
+
name: "hrm.position.detail",
|
|
211
|
+
resource: "position",
|
|
212
|
+
method: "position.detail",
|
|
213
|
+
action: "hrm.position.detail",
|
|
214
|
+
summary: "\u6309\u5C97\u4F4D id \u53D6\u5C97\u4F4D\u8BE6\u60C5\u8868\u5355\uFF08\u53EA\u8BFB type=info\uFF0C\u542B\u804C\u52A1/\u804C\u7EA7\u540D\u79F0\uFF09",
|
|
215
|
+
risk: READ,
|
|
216
|
+
inputSchema: schemaOf(
|
|
217
|
+
{ id: SCHEMA_ID },
|
|
218
|
+
{ required: ["id"] }
|
|
219
|
+
),
|
|
220
|
+
handler: async (args, { host }) => {
|
|
221
|
+
const id = String(args.id).trim();
|
|
222
|
+
if (!id) throw hrmValidationError("id_required", "id \u5FC5\u586B");
|
|
223
|
+
const session = await host.getSession();
|
|
224
|
+
const baseUrl = session.baseUrl.replace(/\/+$/, "");
|
|
225
|
+
const resp = await host.request({
|
|
226
|
+
method: "GET",
|
|
227
|
+
path: "/api/bs/hrm/post/getEditOrAddPostForm",
|
|
228
|
+
query: { id, type: "info" },
|
|
229
|
+
headers: { Referer: `${baseUrl}/sp/hrm/positionCard/${id}` }
|
|
230
|
+
});
|
|
231
|
+
const raw = resp?.data?.data ?? {};
|
|
232
|
+
const parentName = Array.isArray(raw.parent) && raw.parent[0]?.name ? String(raw.parent[0].name) : "";
|
|
233
|
+
const jobsetName = Array.isArray(raw.jobsetid) && raw.jobsetid[0]?.name ? String(raw.jobsetid[0].name) : "";
|
|
234
|
+
const jobsetTypeName = Array.isArray(raw.jobset_type_id) && raw.jobset_type_id[0]?.name ? String(raw.jobset_type_id[0].name) : "";
|
|
235
|
+
const grade = Array.isArray(raw.grade) ? raw.grade.map((g) => g && typeof g === "object" ? g.name ?? g : g) : raw.grade;
|
|
236
|
+
return hrmSuccess("hrm.position.detail", {
|
|
237
|
+
id,
|
|
238
|
+
name: raw.name,
|
|
239
|
+
code: raw.code,
|
|
240
|
+
...parentName ? { parentName } : {},
|
|
241
|
+
...jobsetName ? { jobsetName } : {},
|
|
242
|
+
...jobsetTypeName ? { jobsetTypeName } : {},
|
|
243
|
+
...grade !== void 0 ? { grade } : {},
|
|
244
|
+
link: positionLink(baseUrl, id)
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
var positionList = {
|
|
249
|
+
name: "hrm.position.list",
|
|
250
|
+
resource: "position",
|
|
251
|
+
method: "position.list",
|
|
252
|
+
action: "hrm.position.list",
|
|
253
|
+
summary: "\u6309\u7EC4\u7EC7/\u540D\u79F0/\u7F16\u53F7\u6279\u91CF\u67E5\u8BE2\u5C97\u4F4D\uFF08\u5C97\u4F4D\u5730\u5740\u7C3F\uFF0C\u4E00\u6B21\u6027 + \u81EA\u52A8\u7FFB\u9875\uFF1B\u65E0\u8FC7\u6EE4\u9700\u663E\u5F0F all=true\uFF09",
|
|
254
|
+
risk: READ,
|
|
255
|
+
inputSchema: schemaOf({
|
|
256
|
+
org: SCHEMA_ID,
|
|
257
|
+
name: { type: "string", description: "\u5C97\u4F4D\u540D\u79F0\u8FC7\u6EE4\uFF08\u4E0E code \u4E8C\u9009\u4E00\uFF09" },
|
|
258
|
+
code: { type: "string", description: "\u5C97\u4F4D\u7F16\u53F7\u8FC7\u6EE4\uFF08\u4E0E name \u4E8C\u9009\u4E00\uFF09" },
|
|
259
|
+
all: { type: "boolean", description: "\u663E\u5F0F\u786E\u8BA4\u5168\u91CF\u62C9\u53D6\uFF08\u65E0 org/name/code \u8FC7\u6EE4\u65F6\u5FC5\u586B true\uFF09" },
|
|
260
|
+
pageSize: SCHEMA_ID
|
|
261
|
+
}),
|
|
262
|
+
handler: async (args, { host }) => {
|
|
263
|
+
const hasFilter = args.org !== void 0 || args.name !== void 0 || args.code !== void 0;
|
|
264
|
+
if (!hasFilter && args.all !== true) {
|
|
265
|
+
throw hrmValidationError("full_pull_blocked", "\u7981\u6B62\u65E0\u6761\u4EF6\u5168\u91CF\u62C9\u53D6\u5C97\u4F4D\uFF08\u5F53\u524D\u73AF\u5883\u5C97\u4F4D\u53EF\u8FBE\u6570\u5343\u6761\uFF09\u3002\u8BF7\u63D0\u4F9B org\uFF08\u7EC4\u7EC7 id\uFF09\u6216 name / code \u8FC7\u6EE4\uFF1B\u786E\u9700\u5168\u91CF\u8BF7\u663E\u5F0F\u4F20 all=true");
|
|
266
|
+
}
|
|
267
|
+
const body = {
|
|
268
|
+
moduleType: "positionAddressBook",
|
|
269
|
+
leftOrgId: args.org !== void 0 ? String(args.org) : "",
|
|
270
|
+
tableType: "none",
|
|
271
|
+
isContainBlock: "0",
|
|
272
|
+
includeSub: true,
|
|
273
|
+
saCondition: {
|
|
274
|
+
name: [{ name_condition: "in" }],
|
|
275
|
+
fullName: [{ fullName_condition: "in" }],
|
|
276
|
+
code: [{ code_condition: "in" }],
|
|
277
|
+
department: [{ department_condition: "in" }]
|
|
278
|
+
},
|
|
279
|
+
saMatchType: "and"
|
|
280
|
+
};
|
|
281
|
+
if (args.name !== void 0 || args.code !== void 0) {
|
|
282
|
+
body.keyword = String(args.name ?? args.code);
|
|
283
|
+
body.keywordMatchFieldList = args.name !== void 0 ? ["name"] : ["code"];
|
|
284
|
+
} else {
|
|
285
|
+
body.keyword = "";
|
|
286
|
+
body.keywordMatchFieldList = [];
|
|
287
|
+
}
|
|
288
|
+
const pageSize = toNumber(args.pageSize, "pageSize") ?? 100;
|
|
289
|
+
const collected = [];
|
|
290
|
+
let total = 0;
|
|
291
|
+
const maxPages = 500;
|
|
292
|
+
for (let current = 1; current <= maxPages; current++) {
|
|
293
|
+
const resp = await host.request({
|
|
294
|
+
method: "POST",
|
|
295
|
+
path: "/api/bs/hrm/position/queryListByOrgTree",
|
|
296
|
+
body: { ...body, current, pageSize }
|
|
297
|
+
});
|
|
298
|
+
const d = resp?.data ?? {};
|
|
299
|
+
const rows = Array.isArray(d.data) ? d.data : [];
|
|
300
|
+
collected.push(...rows);
|
|
301
|
+
total = Number(d.total ?? total);
|
|
302
|
+
if (!rows.length || collected.length >= total) break;
|
|
303
|
+
}
|
|
304
|
+
const session = await host.getSession();
|
|
305
|
+
const baseUrl = session.baseUrl.replace(/\/+$/, "");
|
|
306
|
+
const list = collected.map((r) => formatPosListItem(r, baseUrl));
|
|
307
|
+
return hrmSuccess("hrm.position.list", { rows: list, total: total || list.length }, { pageSize });
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
var hrmPositionOperations = [
|
|
311
|
+
positionQuery,
|
|
312
|
+
positionDetail,
|
|
313
|
+
positionList
|
|
314
|
+
];
|
|
315
|
+
|
|
316
|
+
// src/shortcuts/hrm/operations/resolve.ts
|
|
317
|
+
var VIRTUAL_PATH = "/api/bs/hrm/companyVirtual/listCompanyVirtual";
|
|
318
|
+
var ORG_DETAIL_PATH = "/api/bs/hrm/organization/getForm";
|
|
319
|
+
var ORG_TYPES2 = ["department", "subcompany"];
|
|
320
|
+
var DEFAULT_MAX_CANDIDATES = 20;
|
|
321
|
+
var MAX_CANDIDATES = 200;
|
|
322
|
+
var MAX_SUGGESTIONS = 5;
|
|
323
|
+
function text(value) {
|
|
324
|
+
return value === void 0 || value === null ? "" : String(value).trim();
|
|
325
|
+
}
|
|
326
|
+
function normalizedName(value) {
|
|
327
|
+
return text(value).normalize("NFKC").replace(/\s+/gu, "").toLocaleLowerCase();
|
|
328
|
+
}
|
|
329
|
+
function normalizePath(value) {
|
|
330
|
+
return text(value).split(/[|/]+/u).map((part) => part.trim()).filter(Boolean).join("/");
|
|
331
|
+
}
|
|
332
|
+
function idValue(value, field) {
|
|
333
|
+
const valueText = text(value);
|
|
334
|
+
if (!/^\d+$/u.test(valueText)) {
|
|
335
|
+
throw hrmValidationError("id_invalid", `${field} \u5FC5\u987B\u662F\u6570\u5B57 ID`);
|
|
336
|
+
}
|
|
337
|
+
return valueText;
|
|
338
|
+
}
|
|
339
|
+
function maxCandidatesValue(value) {
|
|
340
|
+
if (value === void 0 || value === null || value === "") return DEFAULT_MAX_CANDIDATES;
|
|
341
|
+
const numeric = Number(value);
|
|
342
|
+
if (!Number.isInteger(numeric) || numeric < 1 || numeric > MAX_CANDIDATES) {
|
|
343
|
+
throw hrmValidationError("number_invalid", `maxCandidates \u5FC5\u987B\u662F 1~${MAX_CANDIDATES} \u7684\u6574\u6570`);
|
|
344
|
+
}
|
|
345
|
+
return numeric;
|
|
346
|
+
}
|
|
347
|
+
function uniqueById(items) {
|
|
348
|
+
const seen = /* @__PURE__ */ new Set();
|
|
349
|
+
return items.filter((item) => {
|
|
350
|
+
if (!item.id || seen.has(item.id)) return false;
|
|
351
|
+
seen.add(item.id);
|
|
352
|
+
return true;
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
function readVirtuals(response) {
|
|
356
|
+
const root = response?.data;
|
|
357
|
+
const rows = Array.isArray(root) ? root : Array.isArray(root?.data) ? root.data : [];
|
|
358
|
+
return uniqueById(rows.map((row) => ({
|
|
359
|
+
id: text(row?.id ?? row?.value),
|
|
360
|
+
name: text(row?.content ?? row?.name ?? row?.label)
|
|
361
|
+
})).filter((item) => item.id && item.name));
|
|
362
|
+
}
|
|
363
|
+
function levenshtein(left, right) {
|
|
364
|
+
const a = [...left];
|
|
365
|
+
const b = [...right];
|
|
366
|
+
let previous = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
367
|
+
for (let row = 1; row <= a.length; row += 1) {
|
|
368
|
+
const current = [row];
|
|
369
|
+
for (let column = 1; column <= b.length; column += 1) {
|
|
370
|
+
current[column] = Math.min(
|
|
371
|
+
current[column - 1] + 1,
|
|
372
|
+
previous[column] + 1,
|
|
373
|
+
previous[column - 1] + (a[row - 1] === b[column - 1] ? 0 : 1)
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
previous = current;
|
|
377
|
+
}
|
|
378
|
+
return previous[b.length];
|
|
379
|
+
}
|
|
380
|
+
function similarity(left, right) {
|
|
381
|
+
const a = normalizedName(left);
|
|
382
|
+
const b = normalizedName(right);
|
|
383
|
+
const longest = Math.max([...a].length, [...b].length);
|
|
384
|
+
return longest === 0 ? 1 : 1 - levenshtein(a, b) / longest;
|
|
385
|
+
}
|
|
386
|
+
function nearVirtuals(keyword, virtuals) {
|
|
387
|
+
return virtuals.map((item) => ({ item, score: similarity(keyword, item.name) })).filter(({ score }) => score >= 0.6 && score < 1).sort((left, right) => right.score - left.score).map(({ item }) => item).slice(0, MAX_SUGGESTIONS);
|
|
388
|
+
}
|
|
389
|
+
function orgPath(row, type) {
|
|
390
|
+
const direct = type === "department" ? row.supDepartment : row.supSubDepartment;
|
|
391
|
+
if (text(direct)) return normalizePath(direct);
|
|
392
|
+
const title = text(row.title);
|
|
393
|
+
const name = text(row.name);
|
|
394
|
+
if (title && name && title.startsWith(`${name}|`)) {
|
|
395
|
+
return normalizePath(title.slice(name.length + 1));
|
|
396
|
+
}
|
|
397
|
+
return "";
|
|
398
|
+
}
|
|
399
|
+
function fullOrg(row, type, baseUrl, virtual) {
|
|
400
|
+
const id = text(row.id);
|
|
401
|
+
const name = text(row.name);
|
|
402
|
+
const parentPath = orgPath(row, type);
|
|
403
|
+
const rawFullPath = normalizePath(row.fullPath);
|
|
404
|
+
const fullPath = rawFullPath || (parentPath ? `${parentPath}/${name}` : name);
|
|
405
|
+
const virtualName = parentPath.split("/")[0] || virtual.name;
|
|
406
|
+
const parentId = text(row.parent?.id ?? row.parent);
|
|
407
|
+
const subcompanyId = text(row.subcompanyid ?? row.subcompanyId);
|
|
408
|
+
const virtualId = text(row.virtualid ?? row.virtualId) || virtual.id;
|
|
409
|
+
return {
|
|
410
|
+
id,
|
|
411
|
+
name,
|
|
412
|
+
type: text(row.type) || type,
|
|
413
|
+
...text(row.code) ? { code: text(row.code) } : {},
|
|
414
|
+
fullPath,
|
|
415
|
+
...parentPath ? { parentPath } : {},
|
|
416
|
+
...parentId ? { parentId } : {},
|
|
417
|
+
...subcompanyId ? { subcompanyId } : {},
|
|
418
|
+
virtualId,
|
|
419
|
+
virtualName,
|
|
420
|
+
...row.status !== void 0 ? { status: row.status } : {},
|
|
421
|
+
link: orgLink(baseUrl, id)
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
function orgCandidate(row, type, baseUrl, virtual) {
|
|
425
|
+
const item = fullOrg(row, type, baseUrl, virtual);
|
|
426
|
+
return {
|
|
427
|
+
id: item.id,
|
|
428
|
+
name: item.name,
|
|
429
|
+
type: item.type,
|
|
430
|
+
fullPath: item.fullPath,
|
|
431
|
+
...item.code ? { code: item.code } : {},
|
|
432
|
+
link: item.link
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
function browsePath(type) {
|
|
436
|
+
return type === "department" ? "/api/hrm/common/browser/data/department" : "/api/hrm/common/browser/data/subcompany";
|
|
437
|
+
}
|
|
438
|
+
async function browseOrg(host, type, virtualId, keyword, condition, pageSize) {
|
|
439
|
+
const response = await host.request({
|
|
440
|
+
method: "POST",
|
|
441
|
+
path: browsePath(type),
|
|
442
|
+
body: {
|
|
443
|
+
...browserBaseBody(),
|
|
444
|
+
virtualType: "ALL",
|
|
445
|
+
cmd: "list",
|
|
446
|
+
current: 1,
|
|
447
|
+
pageSize,
|
|
448
|
+
companyId: virtualId,
|
|
449
|
+
formDatas: {
|
|
450
|
+
name: [{
|
|
451
|
+
nameCondition: {
|
|
452
|
+
id: condition,
|
|
453
|
+
content: condition === "eq" ? "\u7B49\u4E8E" : "\u5305\u542B",
|
|
454
|
+
disabled: false
|
|
455
|
+
},
|
|
456
|
+
name: keyword
|
|
457
|
+
}]
|
|
458
|
+
},
|
|
459
|
+
quickSearchDatas: {},
|
|
460
|
+
type: "and",
|
|
461
|
+
stopDepartment: false
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
const data = response?.data ?? {};
|
|
465
|
+
const rows = Array.isArray(data.data) ? data.data : [];
|
|
466
|
+
const reportedTotal = Number(data.total);
|
|
467
|
+
return {
|
|
468
|
+
type,
|
|
469
|
+
rows,
|
|
470
|
+
total: Number.isFinite(reportedTotal) ? reportedTotal : rows.length
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
async function browseTypes(host, types, virtualId, keyword, condition, pageSize) {
|
|
474
|
+
return Promise.all(types.map((type) => browseOrg(host, type, virtualId, keyword, condition, pageSize)));
|
|
475
|
+
}
|
|
476
|
+
function exactRows(results, keyword) {
|
|
477
|
+
const normalized = normalizedName(keyword);
|
|
478
|
+
return results.map((result) => {
|
|
479
|
+
const rows = result.rows.filter((row) => normalizedName(row.name) === normalized);
|
|
480
|
+
return { ...result, rows, total: rows.length };
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
function totalMatches(results) {
|
|
484
|
+
return results.reduce((sum, result) => sum + Math.max(result.total, result.rows.length), 0);
|
|
485
|
+
}
|
|
486
|
+
function allRows(results) {
|
|
487
|
+
return results.flatMap((result) => result.rows.map((row) => ({ type: result.type, row })));
|
|
488
|
+
}
|
|
489
|
+
function resolvedFromMatches(results, explicitType) {
|
|
490
|
+
if (explicitType) {
|
|
491
|
+
const result = results[0];
|
|
492
|
+
const count = Math.max(result.total, result.rows.length);
|
|
493
|
+
return {
|
|
494
|
+
selected: count === 1 && result.rows[0] ? { type: result.type, row: result.rows[0] } : void 0,
|
|
495
|
+
alternatives: [],
|
|
496
|
+
ambiguous: count > 1
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
const department = results.find((result) => result.type === "department");
|
|
500
|
+
const subcompany = results.find((result) => result.type === "subcompany");
|
|
501
|
+
const departmentCount = department ? Math.max(department.total, department.rows.length) : 0;
|
|
502
|
+
const subcompanyCount = subcompany ? Math.max(subcompany.total, subcompany.rows.length) : 0;
|
|
503
|
+
if (departmentCount === 1 && department?.rows[0]) {
|
|
504
|
+
return {
|
|
505
|
+
selected: { type: "department", row: department.rows[0] },
|
|
506
|
+
alternatives: (subcompany?.rows ?? []).map((row) => ({ type: "subcompany", row })),
|
|
507
|
+
ambiguous: false
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
if (departmentCount > 1) return { alternatives: [], ambiguous: true };
|
|
511
|
+
if (subcompanyCount === 1 && subcompany?.rows[0]) {
|
|
512
|
+
return { selected: { type: "subcompany", row: subcompany.rows[0] }, alternatives: [], ambiguous: false };
|
|
513
|
+
}
|
|
514
|
+
return { alternatives: [], ambiguous: subcompanyCount > 1 };
|
|
515
|
+
}
|
|
516
|
+
function truncatedCandidates(results, maxCandidates, baseUrl, virtual) {
|
|
517
|
+
const candidateTotal = totalMatches(results);
|
|
518
|
+
const candidates = allRows(results).slice(0, maxCandidates).map(({ type, row }) => orgCandidate(row, type, baseUrl, virtual));
|
|
519
|
+
return {
|
|
520
|
+
candidates,
|
|
521
|
+
candidateTotal,
|
|
522
|
+
truncated: candidateTotal > candidates.length
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
async function resolveOrgId(host, orgId, baseUrl, virtual) {
|
|
526
|
+
const response = await host.request({
|
|
527
|
+
method: "GET",
|
|
528
|
+
path: ORG_DETAIL_PATH,
|
|
529
|
+
query: { id: orgId, readOnly: true, includeSub: true, quote: true, isMobile: false },
|
|
530
|
+
headers: { Referer: `${baseUrl}/sp/hrm/orgCard/${orgId}` }
|
|
531
|
+
});
|
|
532
|
+
const raw = response?.data?.data ?? {};
|
|
533
|
+
const type = raw.type === "subcompany" ? "subcompany" : "department";
|
|
534
|
+
const parentName = Array.isArray(raw.parent) ? text(raw.parent[0]?.name) : "";
|
|
535
|
+
const subcompanyName = Array.isArray(raw.subcompany) ? text(raw.subcompany[0]?.name) : "";
|
|
536
|
+
const fullPath = normalizePath(raw.fullPath);
|
|
537
|
+
const pathParts = fullPath.split("/").filter(Boolean);
|
|
538
|
+
return {
|
|
539
|
+
id: text(raw.id) || orgId,
|
|
540
|
+
name: text(raw.name),
|
|
541
|
+
type,
|
|
542
|
+
...text(raw.code) ? { code: text(raw.code) } : {},
|
|
543
|
+
...fullPath ? { fullPath } : {},
|
|
544
|
+
...pathParts.length > 1 ? { parentPath: pathParts.slice(0, -1).join("/") } : {},
|
|
545
|
+
...parentName ? { parentName } : {},
|
|
546
|
+
...subcompanyName ? { subcompanyName } : {},
|
|
547
|
+
virtualId: virtual.id,
|
|
548
|
+
virtualName: virtual.name,
|
|
549
|
+
...raw.status !== void 0 ? { status: raw.status } : {},
|
|
550
|
+
link: orgLink(baseUrl, orgId)
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
function relaxedKeywords(name) {
|
|
554
|
+
const characters = [...text(name)];
|
|
555
|
+
if (characters.length <= 2) return [characters.join("")].filter(Boolean);
|
|
556
|
+
const suffix = characters.slice(-2).join("");
|
|
557
|
+
const prefix = characters.slice(0, 2).join("");
|
|
558
|
+
return suffix === prefix ? [suffix] : [suffix, prefix];
|
|
559
|
+
}
|
|
560
|
+
async function nearOrgSuggestions(host, type, virtual, name, pageSize, baseUrl) {
|
|
561
|
+
const results = [];
|
|
562
|
+
const seen = /* @__PURE__ */ new Set();
|
|
563
|
+
for (const keyword of relaxedKeywords(name)) {
|
|
564
|
+
const result = await browseOrg(host, type, virtual.id, keyword, "in", pageSize);
|
|
565
|
+
for (const row of result.rows) {
|
|
566
|
+
const id = text(row.id);
|
|
567
|
+
if (!id || seen.has(id)) continue;
|
|
568
|
+
seen.add(id);
|
|
569
|
+
results.push(orgCandidate(row, type, baseUrl, virtual));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return results;
|
|
573
|
+
}
|
|
574
|
+
var orgResolve = {
|
|
575
|
+
name: "hrm.org.resolve",
|
|
576
|
+
resource: "org",
|
|
577
|
+
method: "org.resolve",
|
|
578
|
+
action: "hrm.org.resolve",
|
|
579
|
+
summary: "\u6309\u591A\u7EF4\u540D\u79F0\u4E0E\u7EC4\u7EC7\u540D\u79F0\u89E3\u6790\u552F\u4E00\u90E8\u95E8/\u5206\u90E8\uFF1B\u6B67\u4E49\u6216\u8FD1\u4F3C\u540D\u79F0\u53EA\u8FD4\u56DE\u5019\u9009\uFF0C\u4E0D\u4EE3\u66FF\u7528\u6237\u9009\u62E9",
|
|
580
|
+
risk: READ,
|
|
581
|
+
inputSchema: schemaOf({
|
|
582
|
+
virtual: { type: "string", minLength: 1, description: "\u591A\u7EF4\u540D\u79F0\uFF1B\u4E0E virtualId \u81F3\u5C11\u4F20\u4E00\u4E2A" },
|
|
583
|
+
virtualId: SCHEMA_ID,
|
|
584
|
+
name: { type: "string", minLength: 1, description: "\u7EC4\u7EC7\u540D\u79F0\uFF1B\u4E0E orgId \u81F3\u5C11\u4F20\u4E00\u4E2A" },
|
|
585
|
+
orgId: SCHEMA_ID,
|
|
586
|
+
type: { type: "string", enum: [...ORG_TYPES2] },
|
|
587
|
+
maxCandidates: { type: "integer", minimum: 1, maximum: MAX_CANDIDATES, default: DEFAULT_MAX_CANDIDATES }
|
|
588
|
+
}),
|
|
589
|
+
handler: async (args, { host }) => {
|
|
590
|
+
const virtualKeyword = text(args.virtual);
|
|
591
|
+
const name = text(args.name);
|
|
592
|
+
const virtualId = args.virtualId === void 0 ? "" : idValue(args.virtualId, "virtualId");
|
|
593
|
+
const orgId = args.orgId === void 0 ? "" : idValue(args.orgId, "orgId");
|
|
594
|
+
if (!virtualKeyword && !virtualId) {
|
|
595
|
+
throw hrmValidationError("virtual_required", "virtual \u6216 virtualId \u81F3\u5C11\u4F20\u4E00\u4E2A");
|
|
596
|
+
}
|
|
597
|
+
if (!name && !orgId) {
|
|
598
|
+
throw hrmValidationError("name_required", "name \u6216 orgId \u81F3\u5C11\u4F20\u4E00\u4E2A");
|
|
599
|
+
}
|
|
600
|
+
const explicitType = args.type !== void 0;
|
|
601
|
+
const requestedType = explicitType ? text(args.type) : "";
|
|
602
|
+
if (explicitType && !ORG_TYPES2.includes(requestedType)) {
|
|
603
|
+
throw hrmValidationError("enum_invalid", `type \u53D6\u503C\u5FC5\u987B\u662F ${ORG_TYPES2.join(" / ")} \u4E4B\u4E00`);
|
|
604
|
+
}
|
|
605
|
+
const types = explicitType ? [requestedType] : ["department", "subcompany"];
|
|
606
|
+
const maxCandidates = maxCandidatesValue(args.maxCandidates);
|
|
607
|
+
const pageSize = Math.max(100, maxCandidates);
|
|
608
|
+
const virtualResponse = await host.request({ method: "GET", path: VIRTUAL_PATH });
|
|
609
|
+
const virtuals = readVirtuals(virtualResponse);
|
|
610
|
+
let virtual;
|
|
611
|
+
let virtualMatchType = "exact";
|
|
612
|
+
if (virtualId) {
|
|
613
|
+
virtual = virtuals.find((item) => item.id === virtualId);
|
|
614
|
+
virtualMatchType = "id";
|
|
615
|
+
} else {
|
|
616
|
+
const keyword = normalizedName(virtualKeyword);
|
|
617
|
+
const exact = virtuals.filter((item) => normalizedName(item.name) === keyword);
|
|
618
|
+
const matches2 = exact.length > 0 ? exact : virtuals.filter((item) => normalizedName(item.name).includes(keyword));
|
|
619
|
+
virtualMatchType = exact.length > 0 ? "exact" : "fuzzy";
|
|
620
|
+
if (matches2.length > 1) {
|
|
621
|
+
const candidates = matches2.slice(0, maxCandidates);
|
|
622
|
+
return hrmSuccess("hrm.org.resolve", {
|
|
623
|
+
status: "ambiguous",
|
|
624
|
+
stage: "virtual",
|
|
625
|
+
virtual: null,
|
|
626
|
+
matchType: virtualMatchType,
|
|
627
|
+
candidates,
|
|
628
|
+
candidateTotal: matches2.length,
|
|
629
|
+
truncated: matches2.length > candidates.length,
|
|
630
|
+
message: `\u591A\u7EF4\u300C${virtualKeyword}\u300D\u5339\u914D\u5230 ${matches2.length} \u4E2A\u5019\u9009\uFF0C\u8BF7\u786E\u8BA4\u540E\u628A\u5019\u9009 id \u4F5C\u4E3A virtualId \u590D\u8C03\u3002`
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
virtual = matches2[0];
|
|
634
|
+
}
|
|
635
|
+
if (!virtual) {
|
|
636
|
+
const suggestions2 = virtualKeyword ? nearVirtuals(virtualKeyword, virtuals) : [];
|
|
637
|
+
const available = virtuals.map((item) => item.name).join("\u3001");
|
|
638
|
+
const target = virtualId ? `ID ${virtualId}` : `\u300C${virtualKeyword}\u300D`;
|
|
639
|
+
const suggestionText = suggestions2.length > 0 ? `\uFF1B\u8FD1\u4F3C\u540D\u79F0\uFF1A${suggestions2.map((item) => item.name).join("\u3001")}\u3002\u4E0D\u8981\u81EA\u884C\u66FF\u6362\u540D\u79F0\uFF0C\u8BF7\u5148\u8BA9\u7528\u6237\u786E\u8BA4` : "";
|
|
640
|
+
return hrmSuccess("hrm.org.resolve", {
|
|
641
|
+
status: "not_found",
|
|
642
|
+
stage: "virtual",
|
|
643
|
+
virtual: null,
|
|
644
|
+
matchType: "none",
|
|
645
|
+
candidates: [],
|
|
646
|
+
candidateTotal: 0,
|
|
647
|
+
suggestions: suggestions2,
|
|
648
|
+
suggestionTotal: suggestions2.length,
|
|
649
|
+
availableVirtuals: virtuals,
|
|
650
|
+
message: `\u591A\u7EF4${target}\u4E0D\u5B58\u5728${suggestionText}\u3002\u5F53\u524D\u53EF\u7528\u591A\u7EF4\uFF1A${available || "\u65E0"}\u3002`
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
const virtualResult = {
|
|
654
|
+
id: virtual.id,
|
|
655
|
+
name: virtual.name,
|
|
656
|
+
keyword: virtualKeyword,
|
|
657
|
+
matchType: virtualMatchType
|
|
658
|
+
};
|
|
659
|
+
const session = await host.getSession();
|
|
660
|
+
const baseUrl = session.baseUrl.replace(/\/+$/u, "");
|
|
661
|
+
if (orgId) {
|
|
662
|
+
const org = await resolveOrgId(host, orgId, baseUrl, virtual);
|
|
663
|
+
return hrmSuccess("hrm.org.resolve", {
|
|
664
|
+
status: "resolved",
|
|
665
|
+
stage: "org",
|
|
666
|
+
matchType: "id",
|
|
667
|
+
type: org.type,
|
|
668
|
+
virtual: virtualResult,
|
|
669
|
+
org,
|
|
670
|
+
message: `\u5DF2\u6309 orgId \u5B9A\u4F4D\u7EC4\u7EC7\u300C${String(org.name || orgId)}\u300D\u3002`
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
let matchType = "exact";
|
|
674
|
+
let matches = await browseTypes(host, types, virtual.id, name, "eq", pageSize);
|
|
675
|
+
let choice = resolvedFromMatches(matches, explicitType);
|
|
676
|
+
if (!choice.selected && !choice.ambiguous) {
|
|
677
|
+
const fuzzyResults = await browseTypes(host, types, virtual.id, name, "in", pageSize);
|
|
678
|
+
const normalizedExact = exactRows(fuzzyResults, name);
|
|
679
|
+
if (totalMatches(normalizedExact) > 0) {
|
|
680
|
+
matches = normalizedExact;
|
|
681
|
+
matchType = "exact";
|
|
682
|
+
} else {
|
|
683
|
+
matches = fuzzyResults;
|
|
684
|
+
matchType = "fuzzy";
|
|
685
|
+
}
|
|
686
|
+
choice = resolvedFromMatches(matches, explicitType);
|
|
687
|
+
}
|
|
688
|
+
if (choice.selected) {
|
|
689
|
+
const org = fullOrg(choice.selected.row, choice.selected.type, baseUrl, virtual);
|
|
690
|
+
const alsoMatched = choice.alternatives.map(({ type, row }) => orgCandidate(row, type, baseUrl, virtual));
|
|
691
|
+
const fuzzyMessage = matchType === "fuzzy" ? "\uFF08\u6A21\u7CCA\u5339\u914D\uFF09" : "";
|
|
692
|
+
const alternativeMessage = alsoMatched.length > 0 ? `\uFF1B\u53E6\u6709\u540C\u540D\u8282\u70B9 ${alsoMatched.length} \u4E2A\uFF0C\u8BF7\u4E00\u5E76\u544A\u77E5\u7528\u6237` : "";
|
|
693
|
+
return hrmSuccess("hrm.org.resolve", {
|
|
694
|
+
status: "resolved",
|
|
695
|
+
stage: "org",
|
|
696
|
+
matchType,
|
|
697
|
+
type: choice.selected.type,
|
|
698
|
+
virtual: virtualResult,
|
|
699
|
+
org,
|
|
700
|
+
...alsoMatched.length > 0 ? { alsoMatched } : {},
|
|
701
|
+
message: `\u5DF2${fuzzyMessage}\u5B9A\u4F4D${choice.selected.type === "department" ? "\u90E8\u95E8" : "\u5206\u90E8"}\u300C${name}\u300D${alternativeMessage}\u3002`
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
if (choice.ambiguous) {
|
|
705
|
+
const candidateData = truncatedCandidates(matches, maxCandidates, baseUrl, virtual);
|
|
706
|
+
const truncatedMessage = candidateData.truncated ? `\uFF0C\u4EC5\u5217\u51FA\u524D ${maxCandidates} \u4E2A` : "";
|
|
707
|
+
return hrmSuccess("hrm.org.resolve", {
|
|
708
|
+
status: "ambiguous",
|
|
709
|
+
stage: "org",
|
|
710
|
+
matchType,
|
|
711
|
+
virtual: virtualResult,
|
|
712
|
+
...candidateData,
|
|
713
|
+
message: `\u7EC4\u7EC7\u300C${name}\u300D\u5339\u914D\u5230 ${candidateData.candidateTotal} \u4E2A\u5019\u9009${truncatedMessage}\uFF0C\u8BF7\u786E\u8BA4\u540E\u628A\u5019\u9009 id \u4F5C\u4E3A orgId \u590D\u8C03\u3002`
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
const suggestionType = requestedType || "department";
|
|
717
|
+
const allSuggestions = await nearOrgSuggestions(host, suggestionType, virtual, name, pageSize, baseUrl);
|
|
718
|
+
const suggestions = allSuggestions.slice(0, MAX_SUGGESTIONS);
|
|
719
|
+
const suggestionMessage = suggestions.length > 0 ? `\uFF1B\u627E\u5230\u8FD1\u4F3C\u540D\u79F0 ${suggestions.map((item) => item.name).join("\u3001")}\uFF0C\u4E0D\u8981\u81EA\u884C\u66FF\u6362\u540D\u79F0\uFF0C\u8BF7\u5148\u8BA9\u7528\u6237\u786E\u8BA4` : "";
|
|
720
|
+
return hrmSuccess("hrm.org.resolve", {
|
|
721
|
+
status: "not_found",
|
|
722
|
+
stage: "org",
|
|
723
|
+
matchType: "none",
|
|
724
|
+
virtual: virtualResult,
|
|
725
|
+
suggestions,
|
|
726
|
+
suggestionTotal: allSuggestions.length,
|
|
727
|
+
message: `\u5728\u591A\u7EF4\u300C${virtual.name}\u300D\u4E2D\u672A\u627E\u5230\u7EC4\u7EC7\u300C${name}\u300D${suggestionMessage}\u3002`
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
var hrmResolveOperations = [orgResolve];
|
|
732
|
+
|
|
733
|
+
// src/shortcuts/hrm/operations/registry.ts
|
|
734
|
+
function buildRegistry() {
|
|
735
|
+
const registry = /* @__PURE__ */ new Map();
|
|
736
|
+
const definitions = [
|
|
737
|
+
...hrmEmployeeOperations,
|
|
738
|
+
...hrmOrgOperations,
|
|
739
|
+
...hrmResolveOperations,
|
|
740
|
+
...hrmPositionOperations
|
|
741
|
+
];
|
|
742
|
+
for (const definition of definitions) {
|
|
743
|
+
if (registry.has(definition.name)) {
|
|
744
|
+
throw new Error(`duplicate hrm operation: ${definition.name}`);
|
|
745
|
+
}
|
|
746
|
+
registry.set(definition.name, definition);
|
|
747
|
+
}
|
|
748
|
+
return registry;
|
|
749
|
+
}
|
|
750
|
+
var hrmOperationRegistry = buildRegistry();
|
|
751
|
+
function hrmOperationDefinitions() {
|
|
752
|
+
return [...hrmOperationRegistry.values()];
|
|
753
|
+
}
|
|
754
|
+
function getHrmOperation(operation) {
|
|
755
|
+
const definition = hrmOperationRegistry.get(operation);
|
|
756
|
+
if (!definition) {
|
|
757
|
+
throw hrmValidationError("operation_unknown", `\u7EC4\u7EC7\u7BA1\u7406\u4E0D\u652F\u6301\u64CD\u4F5C\uFF1A${operation}`);
|
|
758
|
+
}
|
|
759
|
+
return definition;
|
|
760
|
+
}
|
|
761
|
+
function hasHrmOperation(operation) {
|
|
762
|
+
return hrmOperationRegistry.has(operation);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
export {
|
|
766
|
+
hrmOperationDefinitions,
|
|
767
|
+
getHrmOperation,
|
|
768
|
+
hasHrmOperation
|
|
769
|
+
};
|