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.
Files changed (197) hide show
  1. package/README.md +4 -2
  2. package/dist/chunks/{archive-ENZYBBME.js → archive-J4I6MCKF.js} +2 -2
  3. package/dist/chunks/{archive-oa-YWLEC5V4.js → archive-oa-BRZKKTO4.js} +2 -2
  4. package/dist/chunks/{asset-OOV6DWPA.js → asset-L7D4FAOZ.js} +2 -2
  5. package/dist/chunks/{asset-idle-RE632MY5.js → asset-idle-DADLLV75.js} +2 -2
  6. package/dist/chunks/{attachment-content-RWN2FCLL.js → attachment-content-K4C7VLWQ.js} +3 -3
  7. package/dist/chunks/{blog-PEPOJAL7.js → blog-BVGQ7NZL.js} +2 -2
  8. package/dist/chunks/{caizhilian-WYIQDVPJ.js → caizhilian-SAADNFD6.js} +2 -2
  9. package/dist/chunks/{calendar-CIARBAOX.js → calendar-Q7NQY5Z2.js} +61 -23
  10. package/dist/chunks/{chunk-F2EQXUEE.js → chunk-3KTFS4IA.js} +397 -159
  11. package/dist/chunks/{chunk-G2JSIUWF.js → chunk-4PD5NWAX.js} +89 -0
  12. package/dist/chunks/{chunk-HJYVHXUQ.js → chunk-4RAE6JXP.js} +1 -1
  13. package/dist/chunks/{chunk-CQHGNCK2.js → chunk-72CKAUAG.js} +41 -8
  14. package/dist/chunks/{chunk-K3RUEEOL.js → chunk-APVFJUQH.js} +2 -2
  15. package/dist/chunks/{chunk-BJGXMFGD.js → chunk-BBKDXQEC.js} +2 -2
  16. package/dist/chunks/chunk-BIPYLLVS.js +501 -0
  17. package/dist/chunks/{chunk-GVPJZXJ2.js → chunk-EKWAQSLU.js} +92 -50
  18. package/dist/chunks/{chunk-XXJOSZTQ.js → chunk-FOAA27U5.js} +381 -57
  19. package/dist/chunks/{chunk-I2HB737U.js → chunk-G4UR6NXN.js} +2 -2
  20. package/dist/chunks/{chunk-YS5DPN4T.js → chunk-GEWYMQME.js} +1 -1
  21. package/dist/chunks/{chunk-P2DAISYW.js → chunk-GHXCDPTM.js} +1 -1
  22. package/dist/chunks/{chunk-L4N7B7ZD.js → chunk-IZ7S7QUS.js} +4 -4
  23. package/dist/chunks/{chunk-NLK2RZKG.js → chunk-JPRO6ER2.js} +122 -2214
  24. package/dist/chunks/{chunk-36DIFZAH.js → chunk-LADPYOWC.js} +2 -2
  25. package/dist/chunks/chunk-LDZQPUIA.js +1238 -0
  26. package/dist/chunks/chunk-NKZRQXST.js +2546 -0
  27. package/dist/chunks/{chunk-EINRJHQ3.js → chunk-QKNKR4RH.js} +3 -3
  28. package/dist/chunks/{chunk-T7JDJJ7H.js → chunk-R4CHUSKC.js} +126 -19
  29. package/dist/chunks/{chunk-EZGFHJFW.js → chunk-SA6VBIHY.js} +88 -15
  30. package/dist/chunks/{chunk-ZXRNHZTE.js → chunk-TTPJJJC4.js} +2 -2
  31. package/dist/chunks/{chunk-KTCB5R5H.js → chunk-W7BEHOSR.js} +2 -2
  32. package/dist/chunks/{chunk-MUQUHKPG.js → chunk-YRSZQUD2.js} +2 -2
  33. package/dist/chunks/{conflict-DRMDOL56.js → conflict-F2OMZRTO.js} +2 -2
  34. package/dist/chunks/{contract-73MERZWN.js → contract-5BETHRSG.js} +2 -2
  35. package/dist/chunks/{cowork-HNGBPD7A.js → cowork-3MN6EQQO.js} +27 -10
  36. package/dist/chunks/create-flow-5FQNNMVO.js +55 -0
  37. package/dist/chunks/{ebuilder-form-OY6DVNRK.js → ebuilder-form-SBHOYBUD.js} +3 -3
  38. package/dist/chunks/{ehr-RAQNEQO7.js → ehr-KMOJULKG.js} +432 -1234
  39. package/dist/chunks/env-LB7NBL2O.js +19 -0
  40. package/dist/chunks/{esb-6XV7C7YV.js → esb-W2PJCFCX.js} +4 -4
  41. package/dist/chunks/factory-6ZFQXQ46.js +30 -0
  42. package/dist/chunks/{fna-XTSRB7G7.js → fna-ZQPCUV4R.js} +2 -2
  43. package/dist/chunks/group-chat-2HHAJN46.js +20 -0
  44. package/dist/chunks/{host-YMBXWFWX.js → host-4CBHGOHT.js} +3 -3
  45. package/dist/chunks/{host-A7J6GDUP.js → host-ATKVNZAT.js} +3 -3
  46. package/dist/chunks/{host-3F5UM5GN.js → host-BQH22NTQ.js} +3 -3
  47. package/dist/chunks/{host-YAQAPYNP.js → host-X2CSLFM6.js} +3 -3
  48. package/dist/chunks/{host-VGPVP7YF.js → host-YTODKMSL.js} +3 -3
  49. package/dist/chunks/{hrm-TLHKC545.js → hrm-FFM4UJFS.js} +4 -4
  50. package/dist/chunks/{im-YOUCFMUK.js → im-VEHKDQPB.js} +8 -8
  51. package/dist/chunks/{invoice-WNBS2B4C.js → invoice-LVIKSIIF.js} +3 -3
  52. package/dist/chunks/{jiuchuanhui-XABWS5RN.js → jiuchuanhui-X6DINO5P.js} +2 -2
  53. package/dist/chunks/{lazy-dispatch-NLZ5UQQI.js → lazy-dispatch-KSWTN5L6.js} +4 -4
  54. package/dist/chunks/{mail-LRYMBFNL.js → mail-VDKRGUD3.js} +9 -4
  55. package/dist/chunks/{meeting-ESXL6MFI.js → meeting-CLC6HP3Z.js} +12 -10
  56. package/dist/chunks/{okr-EOV65SSF.js → okr-CHG4OO3U.js} +2 -2
  57. package/dist/chunks/{plan-YFPVKW6Y.js → plan-XWR75667.js} +2 -2
  58. package/dist/chunks/{project-MDVZUYQW.js → project-5BXOOKMG.js} +40 -23
  59. package/dist/chunks/recruit-stage-DGMFNNDE.js +4507 -0
  60. package/dist/chunks/{registry-VT5Y2HLA.js → registry-7FFOXIAW.js} +4 -4
  61. package/dist/chunks/{registry-QCLZEDAP.js → registry-BKBZPBAJ.js} +10 -8
  62. package/dist/chunks/{registry-YX4CSEMD.js → registry-RHMW6ANW.js} +2 -2
  63. package/dist/chunks/{registry-NYPYMZXG.js → registry-Z43434VG.js} +1 -1
  64. package/dist/chunks/{room-recommend-L3MWH4JW.js → room-recommend-62H7ZQQ6.js} +4 -4
  65. package/dist/chunks/{schedule-UASAVDVD.js → schedule-FNXKH3DQ.js} +4 -4
  66. package/dist/chunks/{workflow-KDGIUCNW.js → workflow-ADHKCAJK.js} +4 -4
  67. package/dist/index.js +33 -28
  68. package/dist/internal/e10/auth/commands.js +110 -56
  69. package/dist/internal/e10/auth/messages.js +6 -0
  70. package/dist/internal/e10/auth/session.js +28 -1
  71. package/dist/internal/e10/auth/xiaoe.js +315 -48
  72. package/dist/internal/e10/auth-recovery.js +36 -5
  73. package/dist/internal/e10/client.js +13 -0
  74. package/dist/internal/e10/context.js +61 -9
  75. package/dist/internal/e10/index.js +1 -1
  76. package/dist/internal/e10/network-error.js +93 -0
  77. package/dist/internal/e10/request-runtime.js +15 -0
  78. package/dist/shortcuts/calendar/operations/read.js +31 -22
  79. package/dist/shortcuts/calendar/operations/write.js +45 -1
  80. package/dist/shortcuts/cowork/operations/discuss-write.js +5 -1
  81. package/dist/shortcuts/cowork/operations/item-write.js +5 -3
  82. package/dist/shortcuts/cowork/operations/member-write.js +3 -1
  83. package/dist/shortcuts/cowork/operations/permission-write.js +5 -1
  84. package/dist/shortcuts/cowork/operations/shared.js +7 -0
  85. package/dist/shortcuts/ehr/operations/attend-write.js +43 -1
  86. package/dist/shortcuts/ehr/operations/hr-contact.js +7 -4
  87. package/dist/shortcuts/ehr/operations/hr-report.js +13 -7
  88. package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +134 -59
  89. package/dist/shortcuts/ehr/operations/recruit-write.js +262 -17
  90. package/dist/shortcuts/ehr/operations/recruit.js +10 -4
  91. package/dist/shortcuts/ehr/operations/shared.js +47 -0
  92. package/dist/shortcuts/hrm/operations/org.js +118 -0
  93. package/dist/shortcuts/index.js +5 -0
  94. package/dist/shortcuts/mail/operations/mail-send.js +8 -2
  95. package/dist/shortcuts/meeting/operations/eb/catalog.js +9 -2
  96. package/dist/shortcuts/meeting/operations/eb/create-flow.js +461 -127
  97. package/dist/shortcuts/meeting/operations/eb/crm-search.js +87 -5
  98. package/dist/shortcuts/meeting/operations/eb/factory.js +33 -0
  99. package/dist/shortcuts/meeting/operations/eb/flow-memory.js +49 -0
  100. package/dist/shortcuts/meeting/operations/eb/group-chat.js +605 -0
  101. package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
  102. package/dist/shortcuts/meeting/operations/eb/person-cache.js +96 -0
  103. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +44 -6
  104. package/dist/shortcuts/meeting/operations/eb/room-summary.js +2 -0
  105. package/dist/shortcuts/meeting/operations/eb/usage-cache.js +99 -0
  106. package/dist/shortcuts/meeting/operations/from-group-chat.js +35 -12
  107. package/dist/shortcuts/project/operations/read.js +6 -25
  108. package/dist/shortcuts/project/operations/shared.js +22 -0
  109. package/dist/shortcuts/project/operations/write.js +28 -2
  110. package/dist/shortcuts/recruit-stage/context.js +119 -0
  111. package/dist/shortcuts/recruit-stage/continuation.js +73 -0
  112. package/dist/shortcuts/recruit-stage/errors.js +65 -0
  113. package/dist/shortcuts/recruit-stage/host.js +109 -0
  114. package/dist/shortcuts/recruit-stage/index.js +115 -0
  115. package/dist/shortcuts/recruit-stage/manifest.js +29 -0
  116. package/dist/shortcuts/recruit-stage/operations/interview-arrange.js +722 -0
  117. package/dist/shortcuts/recruit-stage/operations/interview-feedback.js +269 -0
  118. package/dist/shortcuts/recruit-stage/operations/jd-create.js +630 -0
  119. package/dist/shortcuts/recruit-stage/operations/list.js +431 -0
  120. package/dist/shortcuts/recruit-stage/operations/registry.js +38 -0
  121. package/dist/shortcuts/recruit-stage/operations/resume-import.js +1198 -0
  122. package/dist/shortcuts/recruit-stage/operations/search.js +158 -0
  123. package/dist/shortcuts/recruit-stage/operations/types.js +25 -0
  124. package/dist/shortcuts/recruit-stage/school-tiers.json +318 -0
  125. package/dist/shortcuts/recruit-stage/shared.js +608 -0
  126. package/dist/shortcuts/workflow/operations/form.js +21 -2
  127. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +52 -1
  128. package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +4 -2
  129. package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +19 -11
  130. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +17 -24
  131. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +14 -9
  132. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +78 -10
  133. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +3 -1
  134. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +17 -11
  135. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +16 -40
  136. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +3 -2
  137. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +52 -15
  138. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +16 -1
  139. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +151 -63
  140. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.subGroup.js +56 -0
  141. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +53 -16
  142. package/docs/e10-auth.md +22 -1
  143. package/docs/operation-manual.md +8 -0
  144. package/package.json +1 -1
  145. package/scripts/install-skill-to-xiaoe.mjs +105 -0
  146. package/scripts/mcp-meeting.mjs +234 -0
  147. package/scripts/package-skill.mjs +4 -2
  148. package/skill-template/business-info.json +24 -0
  149. package/skill-template/domains/recruit-stage.md +29 -0
  150. package/skills/weaver-e10-calendar/SKILL.md +2 -1
  151. package/skills/weaver-e10-calendar/references/calendar-write.md +54 -0
  152. package/skills/weaver-e10-cowork/SKILL.md +1 -1
  153. package/skills/weaver-e10-cowork/references/cowork-write.md +3 -1
  154. package/skills/weaver-e10-jucailin/SKILL.md +1 -1
  155. package/skills/weaver-e10-jucailin/references/attend-write.md +8 -0
  156. package/skills/weaver-e10-jucailin/references/hr-contact.md +8 -0
  157. package/skills/weaver-e10-jucailin/references/hr-report.md +8 -0
  158. package/skills/weaver-e10-jucailin/references/recruit-create.md +2 -2
  159. package/skills/weaver-e10-jucailin/references/recruit-read.md +1 -1
  160. package/skills/weaver-e10-jucailin/references/recruit-write.md +4 -3
  161. package/skills/weaver-e10-mail/SKILL.md +1 -1
  162. package/skills/weaver-e10-mail/references/mail-send.md +2 -0
  163. package/skills/weaver-e10-meeting/SKILL.md +119 -26
  164. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +25 -11
  165. package/skills/weaver-e10-meeting.zip +0 -0
  166. package/skills/weaver-e10-recruit-stage/SKILL.md +226 -0
  167. package/skills/weaver-e10-recruit-stage/agents/openai.yaml +119 -0
  168. package/skills/weaver-e10-recruit-stage/lib/recruit-xiaoe-file.mjs +188 -0
  169. package/skills/weaver-e10-recruit-stage/references/recruit-arrange-interview.md +322 -0
  170. package/skills/weaver-e10-recruit-stage/references/recruit-capability-check.md +127 -0
  171. package/skills/weaver-e10-recruit-stage/references/recruit-check-install.md +65 -0
  172. package/skills/weaver-e10-recruit-stage/references/recruit-detail-process.md +63 -0
  173. package/skills/weaver-e10-recruit-stage/references/recruit-edit-interview-feedback.md +142 -0
  174. package/skills/weaver-e10-recruit-stage/references/recruit-jd-create.md +73 -0
  175. package/skills/weaver-e10-recruit-stage/references/recruit-jd-template.md +56 -0
  176. package/skills/weaver-e10-recruit-stage/references/recruit-list-candidate.md +101 -0
  177. package/skills/weaver-e10-recruit-stage/references/recruit-list-interview.md +148 -0
  178. package/skills/weaver-e10-recruit-stage/references/recruit-match-candidates.md +77 -0
  179. package/skills/weaver-e10-recruit-stage/references/recruit-output-links.md +59 -0
  180. package/skills/weaver-e10-recruit-stage/references/recruit-resolve-creator.md +69 -0
  181. package/skills/weaver-e10-recruit-stage/references/recruit-resolve-metadata.md +241 -0
  182. package/skills/weaver-e10-recruit-stage/references/recruit-resume-import.md +438 -0
  183. package/skills/weaver-e10-recruit-stage/references/recruit-resume-parse.md +128 -0
  184. package/skills/weaver-e10-recruit-stage/references/recruit-search-candidate.md +146 -0
  185. package/skills/weaver-e10-recruit-stage/references/recruit-urge-feedback.md +69 -0
  186. package/skills/weaver-e10-shared/SKILL.md +2 -2
  187. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -2
  188. package/skills/weaver-e10-shijingran/SKILL.md +3 -2
  189. package/skills/weaver-e10-shijingran/references/operations.md +3 -1
  190. package/skills/weaver-e10-shijingran/references/source-manifest.json +41 -40
  191. package/skills/weaver-e10-shijingran/references/write-operations.md +2 -0
  192. package/skills/weaver-e10-workflow/SKILL.md +7 -1
  193. package/skills/weaver-e10-workflow/aigroup/default.json +23 -9
  194. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +37 -21
  195. package/skills/weaver-e10-workflow/tools/todo-summary.cjs +135 -43
  196. package/skills/weaver-e10-yepiaotong/SKILL.md +9 -10
  197. package/skills/weaver-e10-yepiaotong/references/invoice-agent-entry.md +6 -3
@@ -1,6 +1,6 @@
1
1
  import { ehrValidationError } from '../errors.js';
2
2
  import { READ, SCHEMA_DATE, SCHEMA_ID, SCHEMA_ID_LIST, ehrSuccess, schemaOf, } from './types.js';
3
- import { assertDateRange, assertEnum, compact, normalizePaged, pickDefined, toIdList, toNumber, toPositiveInt, } from './shared.js';
3
+ import { assertDateRange, assertEnum, compact, normalizePaged, pickDefined, toIdList, toNumber, toPositiveInt, EHR_PAGES, ehrPageUrl, } from './shared.js';
4
4
  const BROWSER_TYPES = ['department', 'subcompany', 'position', 'resource', 'jobsetid', 'grade'];
5
5
  const USERNAME_OPERATORS = ['in', 'notIn', 'eq', 'notEq'];
6
6
  const PERSONNEL_STATUS = ['all', 'normal', '1', '2', '3', '4', '5', '6', '7', '9', '10'];
@@ -139,7 +139,8 @@ const contactSearch = {
139
139
  body: compact(body),
140
140
  });
141
141
  const { data, page } = normalizePaged(response);
142
- return ehrSuccess('ehr.hr.contact.search', data, { page });
142
+ const hrSession = await host.getSession();
143
+ return ehrSuccess('ehr.hr.contact.search', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrEmployeeManager), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
143
144
  },
144
145
  };
145
146
  const contactCount = {
@@ -268,7 +269,8 @@ const birthdayList = {
268
269
  body,
269
270
  });
270
271
  const { data, page } = normalizePaged(response);
271
- return ehrSuccess('ehr.hr.birthday.list', data, { page });
272
+ const hrSession = await host.getSession();
273
+ return ehrSuccess('ehr.hr.birthday.list', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrBirthdayList), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
272
274
  },
273
275
  };
274
276
  const empchangeConditions = {
@@ -347,7 +349,8 @@ const empchangeList = {
347
349
  body: compact(body),
348
350
  });
349
351
  const { data, page } = normalizePaged(response);
350
- return ehrSuccess('ehr.hr.empchange.list', data, { page });
352
+ const hrSession = await host.getSession();
353
+ return ehrSuccess('ehr.hr.empchange.list', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrPersonalStateChange), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
351
354
  },
352
355
  };
353
356
  export const hrContactOperations = [
@@ -1,6 +1,6 @@
1
1
  import { ehrValidationError } from '../errors.js';
2
2
  import { READ, SCHEMA_DATE, SCHEMA_ID, SCHEMA_ID_LIST, SCHEMA_STRING_LIST, ehrSuccess, schemaOf, } from './types.js';
3
- import { assertEnum, compact, normalizePaged, toIdList, toNumber, toPositiveInt } from './shared.js';
3
+ import { assertEnum, compact, normalizePaged, toIdList, toNumber, toPositiveInt, EHR_PAGES, ehrPageUrl } from './shared.js';
4
4
  const EST_DATA_TYPES = [
5
5
  'numberingCount',
6
6
  'numberingCountWithSub',
@@ -74,7 +74,8 @@ const reportDeptTable = {
74
74
  body: buildPersonReport(args, 'departmentName'),
75
75
  });
76
76
  const { data, page } = normalizePaged(response);
77
- return ehrSuccess('ehr.hr.report.dept.table', data, { page });
77
+ const hrSession = await host.getSession();
78
+ return ehrSuccess('ehr.hr.report.dept.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrReportDeptPerson), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
78
79
  },
79
80
  };
80
81
  const reportPosiTable = {
@@ -93,7 +94,8 @@ const reportPosiTable = {
93
94
  body: buildPersonReport(args, 'positionName'),
94
95
  });
95
96
  const { data, page } = normalizePaged(response);
96
- return ehrSuccess('ehr.hr.report.posi.table', data, { page });
97
+ const hrSession = await host.getSession();
98
+ return ehrSuccess('ehr.hr.report.posi.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrReportPosiPerson), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
97
99
  },
98
100
  };
99
101
  const reportJobTable = {
@@ -112,7 +114,8 @@ const reportJobTable = {
112
114
  body: buildPersonReport(args, 'jobName'),
113
115
  });
114
116
  const { data, page } = normalizePaged(response);
115
- return ehrSuccess('ehr.hr.report.job.table', data, { page });
117
+ const hrSession = await host.getSession();
118
+ return ehrSuccess('ehr.hr.report.job.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrReportJobPerson), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
116
119
  },
117
120
  };
118
121
  const reportJobTypeTable = {
@@ -214,7 +217,8 @@ const estEmpTable = {
214
217
  },
215
218
  });
216
219
  const { data, page } = normalizePaged(response);
217
- return ehrSuccess('ehr.hr.est.emp.table', data, { page });
220
+ const hrSession = await host.getSession();
221
+ return ehrSuccess('ehr.hr.est.emp.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrTpReportTp), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
218
222
  },
219
223
  };
220
224
  const estDcEmpTable = {
@@ -258,7 +262,8 @@ const estDcEmpTable = {
258
262
  },
259
263
  });
260
264
  const { data, page } = normalizePaged(response);
261
- return ehrSuccess('ehr.hr.est.dc.emp.table', data, { page });
265
+ const hrSession = await host.getSession();
266
+ return ehrSuccess('ehr.hr.est.dc.emp.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrTpReportHw), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
262
267
  },
263
268
  };
264
269
  const turnEmpTable = {
@@ -305,7 +310,8 @@ const turnEmpTable = {
305
310
  body,
306
311
  });
307
312
  const { data, page } = normalizePaged(response);
308
- return ehrSuccess('ehr.hr.turn.emp.table', data, { page });
313
+ const hrSession = await host.getSession();
314
+ return ehrSuccess('ehr.hr.turn.emp.table', data, { page, viewUrl: ehrPageUrl(hrSession.baseUrl, EHR_PAGES.hrTpReportTurn), profileUrlTemplate: ehrPageUrl(hrSession.baseUrl, '/sp/hrm/profileInfo/{人员id}') });
309
315
  },
310
316
  };
311
317
  const propsSa = {
@@ -335,45 +335,122 @@ async function uploadResumeFile(env, filePath, fieldId, formId) {
335
335
  }
336
336
  return { fileid: String(fileid), name, size };
337
337
  }
338
- /** 平台标签:按名称在本环境标签清单里解析 id(同名优先公共),不自动创建。 */
339
- async function applyPlatformTags(env, talentId, tagNames) {
340
- if (!tagNames.length)
341
- return { applied: [], skipped: [] };
342
- const list = (await env.host.request({
338
+ /** 按名查标签(并行 type=0 公共 / type=1 个人)。服务端若忽略 name 会返回满页 → filtered=false,由调用方回退全量。
339
+ * 🔴 2026-11-04 修:原实现只取第 1 页 500 条,环境标签超 500 时后续标签永远匹配不到(静默跳过)。 */
340
+ async function queryTagByName(env, name) {
341
+ const pageSize = 100;
342
+ const bodyOf = (type) => ({ type, name, order: 8, pageSize, pageNo: 1, search: 1, tagGroup: 0, tagModules: ['ebuilderform'] });
343
+ const rs = await Promise.all([0, 1].map((type) => env.host
344
+ .request({
343
345
  path: '/api/my/tag/query',
344
346
  method: 'POST',
345
- body: { tagModules: ['ebuilderform'], current: 1, pageSize: 500 },
347
+ body: bodyOf(type),
346
348
  operation: 'ehr.recruit.candidate.import.apply',
347
- }));
348
- const rows = list?.data?.data || list?.data?.list || [];
349
+ })
350
+ .catch(() => null)));
351
+ const items = [];
352
+ let filtered = true;
353
+ for (const r of rs) {
354
+ const d = r?.data || {};
355
+ const list = Array.isArray(d.data) ? d.data : [];
356
+ const total = Number(d.total || 0);
357
+ if (list.length >= pageSize && total >= pageSize)
358
+ filtered = false;
359
+ items.push(...list);
360
+ }
361
+ return { items, filtered };
362
+ }
363
+ /** 单类型的全量标签(首轮取 total 后并发翻页,限并发 5、上限 40 页)——仅在按名查询不可用时回退 */
364
+ async function fetchTagsOfType(env, type) {
365
+ const pageSize = 100;
366
+ const bodyOf = (pageNo) => ({ type, name: '', order: 8, pageSize, pageNo, search: 1, tagGroup: 0, tagModules: ['ebuilderform'] });
367
+ const requestPage = (pageNo) => env.host
368
+ .request({
369
+ path: '/api/my/tag/query',
370
+ method: 'POST',
371
+ body: bodyOf(pageNo),
372
+ operation: 'ehr.recruit.candidate.import.apply',
373
+ })
374
+ .catch(() => null);
375
+ const first = (await requestPage(1));
376
+ const d = first?.data || {};
377
+ const rows = Array.isArray(d.data) ? [...d.data] : [];
378
+ const total = Number(d.total || 0);
379
+ const pages = Math.min(40, Math.max(1, Math.ceil(total / pageSize)));
380
+ if (pages > 1 && rows.length) {
381
+ const rest = Array.from({ length: pages - 1 }, (_, i) => i + 2);
382
+ for (let i = 0; i < rest.length; i += 5) {
383
+ const batch = rest.slice(i, i + 5);
384
+ const rs = await Promise.all(batch.map((p) => requestPage(p)));
385
+ for (const r of rs) {
386
+ const list = r?.data?.data;
387
+ if (Array.isArray(list))
388
+ rows.push(...list);
389
+ }
390
+ }
391
+ }
392
+ return rows;
393
+ }
394
+ /** 解析标签名 → id(同名优先公共),不创建标签。
395
+ * ① 按名精确查询(N 个名字 → 1 轮请求);② 服务端未按名过滤时才回退全量(不落盘、不缓存)。 */
396
+ async function resolveTagIds(env, tagNames) {
397
+ const norm = (s) => String(s == null ? '' : s).trim().toLowerCase();
398
+ const uniqNames = [...new Set(tagNames.map((n) => String(n)).filter(Boolean))];
349
399
  const byName = new Map();
350
- for (const row of rows) {
351
- const name = String(row.name ?? row.tagName ?? '').trim();
352
- const id = row.tagId ?? row.id;
353
- if (name && id !== undefined && !byName.has(name))
354
- byName.set(name, { id: String(id), name });
400
+ const absorb = (row) => {
401
+ const name = String(row?.name ?? row?.tagName ?? '').trim();
402
+ const id = row?.tagId ?? row?.id;
403
+ if (!name || id === undefined)
404
+ return;
405
+ const key = norm(name);
406
+ const prev = byName.get(key);
407
+ if (!prev)
408
+ byName.set(key, { id: String(id), name });
409
+ else if ((row?.type ?? 0) === 0)
410
+ byName.set(key, { id: String(id), name });
411
+ };
412
+ const probes = await Promise.all(uniqNames.map((n) => queryTagByName(env, n)));
413
+ const nameQueryUsable = probes.every((p) => p.filtered);
414
+ if (nameQueryUsable) {
415
+ for (const p of probes)
416
+ for (const item of p.items)
417
+ absorb(item);
355
418
  }
356
- const tags = [];
357
- const applied = [];
419
+ else {
420
+ for (const type of [0, 1]) {
421
+ const rows = await fetchTagsOfType(env, type).catch(() => []);
422
+ for (const item of rows)
423
+ absorb(item);
424
+ }
425
+ }
426
+ const resolved = [];
427
+ const found = [];
358
428
  const skipped = [];
359
429
  for (const name of tagNames) {
360
- const hit = byName.get(name);
430
+ const hit = byName.get(norm(name));
361
431
  if (!hit) {
362
432
  skipped.push(name);
363
433
  continue;
364
434
  }
365
- tags.push({ id: hit.id, name: hit.name, type: 0 });
366
- applied.push(name);
435
+ resolved.push({ id: hit.id, name: hit.name, type: 0 });
436
+ found.push(name);
367
437
  }
368
- if (tags.length) {
438
+ return { resolved, found, skipped };
439
+ }
440
+ /** 写入平台标签(解析 + batchAddEntityTag)。解析结果不存在时静默跳过,不自动创建标签。 */
441
+ async function applyPlatformTags(env, talentId, tagNames) {
442
+ if (!tagNames.length)
443
+ return { applied: [], skipped: [] };
444
+ const r = await resolveTagIds(env, tagNames);
445
+ if (r.resolved.length) {
369
446
  await env.host.request({
370
447
  path: '/api/my/tag/common/batchAddEntityTag',
371
448
  method: 'POST',
372
- body: { tags, batchDatas: [{ entityId: talentId, module: 'ebuilderform' }] },
449
+ body: { tags: r.resolved, batchDatas: [{ entityId: talentId, module: 'ebuilderform' }] },
373
450
  operation: 'ehr.recruit.candidate.import.apply',
374
451
  });
375
452
  }
376
- return { applied, skipped };
453
+ return { applied: r.found, skipped: r.skipped };
377
454
  }
378
455
  async function requireCache(env) {
379
456
  if (!env.recruitContext)
@@ -582,7 +659,16 @@ const candidateImportPrepare = {
582
659
  handler: async (args, env) => {
583
660
  const cache = await requireCache(env);
584
661
  const plan = await buildImportPlan(env, cache, args);
585
- const dup = await checkDuplicateByMobile(env, cache, plan.mobile);
662
+ // 标签预检(只读)+ 查重并行:让用户在确认摘要里就能看到哪些标签在本环境不存在(apply 会跳过它们)
663
+ const tagNames = Array.isArray(args.tags) ? args.tags.map(String).filter(Boolean) : [];
664
+ const [dup, tagCheck] = await Promise.all([
665
+ checkDuplicateByMobile(env, cache, plan.mobile),
666
+ tagNames.length
667
+ ? resolveTagIds(env, tagNames)
668
+ .then((rt) => ({ requested: tagNames, found: rt.found, missing: rt.skipped }))
669
+ .catch((error) => ({ requested: tagNames, missing: [], error: error?.message || '标签预检失败' }))
670
+ : Promise.resolve(null),
671
+ ]);
586
672
  if (dup.length > 1) {
587
673
  throw ehrValidationError('duplicate_ambiguous', `手机号 ${plan.mobile} 存在多条候选(数据异常),请人工核对后再决定,不自动新建`);
588
674
  }
@@ -621,6 +707,7 @@ const candidateImportPrepare = {
621
707
  details: plan.details,
622
708
  tags: Array.isArray(args.tags) ? args.tags : [],
623
709
  },
710
+ ...(tagCheck ? { tagCheck } : {}),
624
711
  continuation,
625
712
  expiresInSeconds: 600,
626
713
  });
@@ -684,43 +771,31 @@ const candidateImportApply = {
684
771
  throw error;
685
772
  throw ehrPartialError(`简历建档写入结果不确定(${error?.message || '未知错误'}):请先用人才库搜索手机号 ${payload.telephone} 核对是否已建档,禁止直接重试`, { candidateName: payload.candidateName, telephone: payload.telephone });
686
773
  }
687
- // ③ 初始化人才批次(失败不回滚人才,仅记 warning)
688
- let batchOk = null;
689
- let batchNote;
690
- try {
691
- await env.host.request({
692
- path: `/api/recruit/candidate/initTalentBatch?formDataId=${encodeURIComponent(talentId)}`,
693
- method: 'POST',
694
- operation: 'ehr.recruit.candidate.import.apply',
695
- });
696
- batchOk = true;
697
- }
698
- catch (error) {
699
- batchOk = false;
700
- batchNote = `人才已建档,但初始化人才批次失败:${error?.message || '未知错误'}(可在人才卡片手动处理)`;
701
- }
702
- // ④ 触发后台智能标签规则(规则未配置时不产生标签,属正常)
703
- let labelMatch = null;
704
- try {
705
- const r = (await env.host.request({
706
- path: `/api/recruit/label/matchTalentLabel?talentId=${encodeURIComponent(talentId)}`,
707
- method: 'POST',
708
- body: {},
709
- operation: 'ehr.recruit.candidate.import.apply',
710
- }));
711
- labelMatch = r?.data === undefined ? 'TRIGGERED' : String(r.data);
712
- }
713
- catch {
714
- labelMatch = 'FAILED(不影响建档,可稍后在人才卡片手动触发)';
715
- }
716
- // ⑤ 平台标签(按名命中清单写入,不存在则跳过)
717
- let tagResult = { applied: [], skipped: [] };
718
- try {
719
- tagResult = await applyPlatformTags(env, talentId, Array.isArray(payload.tags) ? payload.tags.map(String) : []);
720
- }
721
- catch (error) {
722
- tagResult = { applied: [], skipped: Array.isArray(payload.tags) ? payload.tags.map(String) : [] };
723
- }
774
+ // ③④⑤ 初始化批次 / 触发电商后台标签规则 / 平台标签:三者只依赖 talentId,并行执行(各自 catch 等价原语义)
775
+ const batchTask = env.host
776
+ .request({
777
+ path: `/api/recruit/candidate/initTalentBatch?formDataId=${encodeURIComponent(talentId)}`,
778
+ method: 'POST',
779
+ operation: 'ehr.recruit.candidate.import.apply',
780
+ })
781
+ .then(() => ({ ok: true, note: undefined }))
782
+ .catch((error) => ({
783
+ ok: false,
784
+ note: `人才已建档,但初始化人才批次失败:${error?.message || '未知错误'}(可在人才卡片手动处理)`,
785
+ }));
786
+ const labelTask = env.host
787
+ .request({
788
+ path: `/api/recruit/label/matchTalentLabel?talentId=${encodeURIComponent(talentId)}`,
789
+ method: 'POST',
790
+ body: {},
791
+ operation: 'ehr.recruit.candidate.import.apply',
792
+ })
793
+ .then((r) => (r?.data === undefined ? 'TRIGGERED' : String(r.data)))
794
+ .catch(() => 'FAILED(不影响建档,可稍后在人才卡片手动触发)');
795
+ const tagTask = applyPlatformTags(env, talentId, Array.isArray(payload.tags) ? payload.tags.map(String) : []).catch(() => ({ applied: [], skipped: Array.isArray(payload.tags) ? payload.tags.map(String) : [] }));
796
+ const [batchOutcome, labelMatch, tagResult] = await Promise.all([batchTask, labelTask, tagTask]);
797
+ const batchOk = batchOutcome.ok;
798
+ const batchNote = batchOutcome.note;
724
799
  // ⑥ 产物链接:人才卡片单页 + 人才库列表定位(自用系统追加 recruitType=useSelf)
725
800
  const baseUrl = session.baseUrl.replace(/\/+$/, '');
726
801
  const extra = String(cache.selfUse) === '1' ? '&recruitType=useSelf' : '';