weaver-work-cli 0.1.40 → 0.1.44
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 +17 -0
- package/dist/chunks/{archive-JHTONRST.js → archive-P6TBQGKL.js} +13 -5
- package/dist/chunks/{archive-oa-FCHLCPHC.js → archive-oa-7TQ2NXOH.js} +12 -5
- package/dist/chunks/{asset-RLIHC7DB.js → asset-3ELRG37G.js} +11 -4
- package/dist/chunks/{asset-idle-KVOFTLCP.js → asset-idle-WIGMUFMD.js} +7 -3
- package/dist/chunks/{attachment-content-RZYDB3MB.js → attachment-content-E3276UOV.js} +5 -4
- package/dist/chunks/{blog-42OZTJNP.js → blog-C5NMZAAC.js} +11 -4
- package/dist/chunks/{caizhilian-KRK547K5.js → caizhilian-5XSM2DFP.js} +13 -6
- package/dist/chunks/{calendar-RTWAMKHD.js → calendar-FI2WNSBO.js} +71 -26
- package/dist/chunks/{chunk-CXRQWOZ5.js → chunk-3YBDYOC4.js} +3 -3
- package/dist/chunks/{chunk-OOUTBLZ4.js → chunk-56EZERK4.js} +1 -1
- package/dist/chunks/chunk-6N4JPNFL.js +76 -0
- package/dist/chunks/{chunk-ZUX3P6BQ.js → chunk-727FH2NI.js} +1 -1
- package/dist/chunks/chunk-7BDPM5ST.js +11 -0
- package/dist/chunks/{chunk-LN447PY2.js → chunk-BCVYBYYT.js} +432 -2247
- package/dist/chunks/{chunk-7E6MUOEK.js → chunk-CWYGFU5B.js} +2 -2
- package/dist/chunks/{chunk-NOODWMCL.js → chunk-D4ADSZ7H.js} +1 -1
- package/dist/chunks/{chunk-WFFNM65B.js → chunk-ETNJSKMM.js} +281 -29
- package/dist/chunks/{chunk-CAQNBBQA.js → chunk-F4E4EM35.js} +3 -3
- package/dist/chunks/{chunk-4CTESSKI.js → chunk-FAZTGX7S.js} +6 -6
- package/dist/chunks/chunk-FRZKBMSW.js +2562 -0
- package/dist/chunks/{chunk-BYBSCN4X.js → chunk-G7PQWD4L.js} +6 -3
- package/dist/chunks/{chunk-NJKREDA3.js → chunk-GAMZLAG2.js} +1 -1
- package/dist/chunks/{chunk-FLS4DPGP.js → chunk-GM6J7Q4B.js} +28 -15
- package/dist/chunks/{chunk-NETCCARD.js → chunk-GRDRG6HP.js} +3 -3
- package/dist/chunks/chunk-HIT4Y6OI.js +1238 -0
- package/dist/chunks/{chunk-EZALDOQH.js → chunk-HP7JIYMT.js} +5 -2
- package/dist/chunks/{chunk-IZSSVYAG.js → chunk-IAZ3UPY6.js} +3 -3
- package/dist/chunks/{chunk-ZEDWSH32.js → chunk-IC62NFM5.js} +1 -1
- package/dist/chunks/{chunk-P26ZWSKU.js → chunk-KIHNAS25.js} +5 -2
- package/dist/chunks/{chunk-57IECMWX.js → chunk-N4M2DDFE.js} +29 -15
- package/dist/chunks/{chunk-JWRZM2H2.js → chunk-OF4S23UB.js} +4 -4
- package/dist/chunks/{chunk-VNBU55SL.js → chunk-PC7VKEB5.js} +80 -2458
- package/dist/chunks/{chunk-G2JSIUWF.js → chunk-PUQS5MWL.js} +91 -2
- package/dist/chunks/{chunk-E7OK5WD5.js → chunk-Q4OYAQYH.js} +5 -5
- package/dist/chunks/{chunk-7BRU4EFH.js → chunk-QVSWRLLU.js} +35 -6
- package/dist/chunks/{chunk-T6EGVBKU.js → chunk-TA7FXXJD.js} +6 -3
- package/dist/chunks/{chunk-GPMFD4RD.js → chunk-TXUG266F.js} +1 -1
- package/dist/chunks/{chunk-4TEDNCON.js → chunk-UFIT2UU3.js} +354 -56
- package/dist/chunks/{chunk-LUSPKZKY.js → chunk-UG5G54VL.js} +1 -0
- package/dist/chunks/{chunk-NIAJ5ZCG.js → chunk-UL5XUQ25.js} +5 -2
- package/dist/chunks/{chunk-FMPJJYYI.js → chunk-WRXSAVKO.js} +1 -1
- package/dist/chunks/{chunk-7U577Q7U.js → chunk-WSF4NNMR.js} +3 -3
- package/dist/chunks/chunk-XHK4MDR5.js +2497 -0
- package/dist/chunks/{chunk-LFMSDBZN.js → chunk-XNIK66I4.js} +326 -161
- package/dist/chunks/{chunk-3SO6QL6U.js → chunk-YWX377BY.js} +5 -2
- package/dist/chunks/{chunk-BYATLLEF.js → chunk-Z3GDFVJR.js} +1 -1
- package/dist/chunks/{chunk-I566ZYNF.js → chunk-Z7VYWPZV.js} +1 -1
- package/dist/chunks/{conflict-VR55AOOO.js → conflict-ARLSZJ6V.js} +4 -3
- package/dist/chunks/{continuation-2CKSBLA6.js → continuation-3S37AUSH.js} +4 -3
- package/dist/chunks/{continuation-RN6PZN2M.js → continuation-3XLYYTKV.js} +4 -3
- package/dist/chunks/{continuation-HZIZRZBX.js → continuation-HFW2YT5S.js} +4 -3
- package/dist/chunks/{continuation-NLECEJPX.js → continuation-KI7DRRZN.js} +4 -3
- package/dist/chunks/{contract-HI4FNPYE.js → contract-DNIIW5VJ.js} +13 -5
- package/dist/chunks/{cowork-HJLI353D.js → cowork-GMLRGVIW.js} +31 -14
- package/dist/chunks/create-flow-J22BO65E.js +56 -0
- package/dist/chunks/{ebuilder-form-HTGI63UU.js → ebuilder-form-ANV2FHYV.js} +12 -7
- package/dist/chunks/{ehr-GYXIYH3A.js → ehr-GSTGAIY3.js} +695 -1255
- package/dist/chunks/{employee-SAK2QYXX.js → employee-22BGJ3QS.js} +3 -3
- package/dist/chunks/{env-DW3G4HUO.js → env-BX3VRFS7.js} +4 -3
- package/dist/chunks/{esb-I5INCEFE.js → esb-ATAIASX2.js} +12 -7
- package/dist/chunks/{factory-TKXGXS6L.js → factory-PETTFME6.js} +3 -2
- package/dist/chunks/{fna-K2MHTQ24.js → fna-YEKBSFSX.js} +14 -8
- package/dist/chunks/{group-chat-VYBNMJLG.js → group-chat-BFVXAYFX.js} +7 -4
- package/dist/chunks/{host-D5SERMAJ.js → host-HRBXEPDQ.js} +5 -5
- package/dist/chunks/{host-JM4YVHFM.js → host-LR55CTHP.js} +5 -5
- package/dist/chunks/{host-L3VLITMT.js → host-SUOY6VYQ.js} +5 -5
- package/dist/chunks/{host-ZUQTJYYK.js → host-SZGV4UNT.js} +5 -5
- package/dist/chunks/{host-256GVCAH.js → host-WIKN2EJ5.js} +5 -5
- package/dist/chunks/{hrm-VLRBKTZB.js → hrm-NRDO4W5G.js} +11 -7
- package/dist/chunks/{im-QK3VTLXK.js → im-IQ2HN23S.js} +11 -10
- package/dist/chunks/{invoice-T5JTA32H.js → invoice-MNRW76PP.js} +636 -1768
- package/dist/chunks/{jiuchuanhui-P2FNEQVZ.js → jiuchuanhui-DTRBAX4N.js} +14 -6
- package/dist/chunks/{lazy-dispatch-XRRI46M6.js → lazy-dispatch-ZVWAI25B.js} +7 -6
- package/dist/chunks/{mail-3Y7MJ6PS.js → mail-ZVAUXOJA.js} +16 -14
- package/dist/chunks/{meeting-M7LTXGJE.js → meeting-FEVPZ67S.js} +21 -13
- package/dist/chunks/{okr-OBC6S67L.js → okr-SDH3E5RA.js} +12 -5
- package/dist/chunks/{operations-5QL3AECO.js → operations-62N6EP3C.js} +4 -3
- package/dist/chunks/{plan-5H6I53SK.js → plan-E35JFDI7.js} +12 -5
- package/dist/chunks/{project-L75QZV4S.js → project-73QXBAB2.js} +49 -25
- package/dist/chunks/reception-UWZVACBN.js +1899 -0
- package/dist/chunks/recruit-stage-4MAOCKFY.js +4770 -0
- package/dist/chunks/registry-IM5G23LS.js +24 -0
- package/dist/chunks/{registry-UGRBCBHO.js → registry-JDUS4E7D.js} +7 -6
- package/dist/chunks/{registry-RXPN6BBT.js → registry-KNKSCJNT.js} +7 -6
- package/dist/chunks/{registry-NYPYMZXG.js → registry-PO7SI256.js} +4 -4
- package/dist/chunks/{registry-QGHFNUWS.js → registry-PVUZQDDQ.js} +3 -3
- package/dist/chunks/{room-recommend-A3UDC3CA.js → room-recommend-H7KLXA5R.js} +6 -5
- package/dist/chunks/{schedule-5GCACCK7.js → schedule-ESZIBAUO.js} +6 -5
- package/dist/chunks/{workflow-M5ZJ7DWF.js → workflow-CWJFJLQU.js} +15 -10
- package/dist/cmd/action.js +6 -0
- package/dist/cmd/identity/index.js +45 -0
- package/dist/cmd/index.js +2 -0
- package/dist/core/continuation-ttl.js +18 -0
- package/dist/core/error-codes.js +85 -0
- package/dist/core/logger.js +11 -0
- package/dist/index.js +41 -30
- package/dist/internal/e10/auth/commands.js +164 -8
- package/dist/internal/e10/auth/error-log.js +182 -0
- package/dist/internal/e10/auth/messages.js +6 -0
- package/dist/internal/e10/auth/session.js +34 -3
- package/dist/internal/e10/auth/xiaoe.js +286 -44
- package/dist/internal/e10/auth-recovery.js +72 -14
- package/dist/internal/e10/context.js +72 -13
- package/dist/internal/e10/index.js +1 -1
- package/dist/internal/e10/network-error.js +93 -0
- package/dist/internal/e10/request-runtime.js +6 -0
- package/dist/internal/skills/install.js +9 -1
- package/dist/shortcuts/archive/continuation.js +2 -1
- package/dist/shortcuts/archive/index.js +3 -0
- package/dist/shortcuts/archive/operations/confirm.js +2 -1
- package/dist/shortcuts/archive-oa/continuation.js +2 -1
- package/dist/shortcuts/archive-oa/index.js +2 -0
- package/dist/shortcuts/archive-oa/operations/confirm.js +2 -1
- package/dist/shortcuts/asset/continuation.js +2 -1
- package/dist/shortcuts/asset/index.js +2 -0
- package/dist/shortcuts/asset-idle/index.js +2 -0
- package/dist/shortcuts/blog/continuation.js +2 -1
- package/dist/shortcuts/blog/index.js +2 -0
- package/dist/shortcuts/caizhilian/continuation.js +2 -1
- package/dist/shortcuts/caizhilian/index.js +2 -0
- package/dist/shortcuts/caizhilian/operations/confirm.js +3 -2
- package/dist/shortcuts/calendar/continuation.js +2 -1
- package/dist/shortcuts/calendar/index.js +2 -0
- package/dist/shortcuts/calendar/operations/read.js +31 -22
- package/dist/shortcuts/calendar/operations/write.js +46 -2
- package/dist/shortcuts/contract/continuation.js +2 -1
- package/dist/shortcuts/contract/index.js +2 -0
- package/dist/shortcuts/contract/operations/write.js +2 -1
- package/dist/shortcuts/cowork/continuation.js +2 -1
- package/dist/shortcuts/cowork/index.js +2 -0
- package/dist/shortcuts/cowork/operations/discuss-write.js +5 -1
- package/dist/shortcuts/cowork/operations/item-write.js +1 -7
- package/dist/shortcuts/cowork/operations/member-write.js +3 -1
- package/dist/shortcuts/cowork/operations/permission-write.js +5 -1
- package/dist/shortcuts/cowork/operations/shared.js +7 -0
- package/dist/shortcuts/ebuilder-form/continuation.js +2 -1
- package/dist/shortcuts/ebuilder-form/index.js +2 -0
- package/dist/shortcuts/ebuilder-form/operations/write.js +3 -2
- package/dist/shortcuts/ehr/continuation.js +2 -1
- package/dist/shortcuts/ehr/index.js +2 -0
- package/dist/shortcuts/ehr/operations/attend-write.js +44 -2
- 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 +317 -63
- package/dist/shortcuts/ehr/operations/recruit-position.js +134 -2
- package/dist/shortcuts/ehr/operations/recruit-write.js +263 -18
- package/dist/shortcuts/ehr/operations/recruit.js +10 -4
- package/dist/shortcuts/ehr/operations/shared.js +47 -0
- package/dist/shortcuts/esb/continuation.js +2 -1
- package/dist/shortcuts/esb/index.js +2 -0
- package/dist/shortcuts/esb/operations/trigger.js +2 -1
- package/dist/shortcuts/fna/continuation.js +2 -1
- package/dist/shortcuts/fna/index.js +2 -0
- package/dist/shortcuts/fna/operations/invoice-writeoff.js +1 -1
- package/dist/shortcuts/fna/operations/loan.js +1 -1
- package/dist/shortcuts/hrm/index.js +2 -0
- package/dist/shortcuts/hrm/operations/org.js +118 -0
- package/dist/shortcuts/im/continuation.js +2 -1
- package/dist/shortcuts/index.js +10 -0
- package/dist/shortcuts/invoice/continuation.js +2 -1
- package/dist/shortcuts/invoice/index.js +14 -15
- package/dist/shortcuts/invoice/invoice-record.js +93 -0
- package/dist/shortcuts/invoice/manifest.js +190 -393
- package/dist/shortcuts/invoice/operations/add.js +2 -1
- package/dist/shortcuts/invoice/operations/delete.js +2 -1
- package/dist/shortcuts/invoice/operations/import.js +2 -1
- package/dist/shortcuts/invoice/operations/issuing-contract-detail.js +86 -0
- package/dist/shortcuts/invoice/operations/issuing-contracts.js +210 -0
- package/dist/shortcuts/invoice/operations/registry.js +17 -17
- package/dist/shortcuts/invoice/operations/reim-auto.js +4 -569
- package/dist/shortcuts/invoice/operations/reim.js +52 -341
- package/dist/shortcuts/invoice/operations/shared.js +21 -4
- package/dist/shortcuts/invoice/operations/update.js +2 -1
- package/dist/shortcuts/invoice/projection.js +10 -62
- package/dist/shortcuts/jiuchuanhui/continuation.js +2 -1
- package/dist/shortcuts/jiuchuanhui/index.js +2 -0
- package/dist/shortcuts/jiuchuanhui/operations/datajson.js +2 -1
- package/dist/shortcuts/jiuchuanhui/operations/esb.js +2 -1
- package/dist/shortcuts/mail/continuation.js +2 -1
- package/dist/shortcuts/mail/index.js +2 -0
- package/dist/shortcuts/mail/operations/mail-blacklist.js +1 -1
- package/dist/shortcuts/mail/operations/mail-contacts.js +1 -1
- package/dist/shortcuts/mail/operations/mail-send.js +1 -1
- package/dist/shortcuts/mail/operations/mail-sign.js +1 -1
- package/dist/shortcuts/mail/operations/mail-template.js +1 -1
- package/dist/shortcuts/meeting/continuation.js +2 -1
- package/dist/shortcuts/meeting/index.js +2 -0
- package/dist/shortcuts/meeting/operations/change.js +1 -1
- package/dist/shortcuts/meeting/operations/create.js +1 -1
- package/dist/shortcuts/meeting/operations/eb/catalog.js +4 -1
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +101 -35
- package/dist/shortcuts/meeting/operations/eb/decision.js +1 -1
- package/dist/shortcuts/meeting/operations/eb/factory.js +34 -1
- package/dist/shortcuts/meeting/operations/eb/group-chat.js +25 -3
- package/dist/shortcuts/meeting/operations/eb/person-cache.js +96 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +33 -11
- package/dist/shortcuts/meeting/operations/lifecycle.js +1 -1
- package/dist/shortcuts/meeting/operations/receipts.js +1 -1
- package/dist/shortcuts/meeting/operations/signs.js +1 -1
- package/dist/shortcuts/okr/continuation.js +2 -1
- package/dist/shortcuts/okr/index.js +2 -0
- package/dist/shortcuts/okr/operations/write.js +1 -1
- package/dist/shortcuts/plan/continuation.js +2 -1
- package/dist/shortcuts/plan/index.js +2 -0
- package/dist/shortcuts/plan/operations/write.js +1 -1
- package/dist/shortcuts/project/continuation.js +2 -1
- package/dist/shortcuts/project/index.js +2 -0
- 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/reception/constants.js +53 -0
- package/dist/shortcuts/reception/errors.js +54 -0
- package/dist/shortcuts/reception/host.js +125 -0
- package/dist/shortcuts/reception/index.js +198 -0
- package/dist/shortcuts/reception/manifest.js +177 -0
- package/dist/shortcuts/reception/operations/ask.js +71 -0
- package/dist/shortcuts/reception/operations/browsertool.js +58 -0
- package/dist/shortcuts/reception/operations/compose.js +129 -0
- package/dist/shortcuts/reception/operations/customparams.js +74 -0
- package/dist/shortcuts/reception/operations/doc.js +238 -0
- package/dist/shortcuts/reception/operations/docrender.js +36 -0
- package/dist/shortcuts/reception/operations/panels.js +179 -0
- package/dist/shortcuts/reception/operations/registry.js +26 -0
- package/dist/shortcuts/reception/operations/render-assets.js +184 -0
- package/dist/shortcuts/reception/operations/render.js +123 -0
- package/dist/shortcuts/reception/operations/runs.js +38 -0
- package/dist/shortcuts/reception/operations/schedule.js +127 -0
- package/dist/shortcuts/reception/operations/shared.js +196 -0
- package/dist/shortcuts/reception/operations/snapshot.js +68 -0
- package/dist/shortcuts/reception/operations/types.js +1 -0
- package/dist/shortcuts/reception/operations.js +33 -0
- package/dist/shortcuts/reception/upload.js +218 -0
- package/dist/shortcuts/recruit-stage/context.js +231 -0
- package/dist/shortcuts/recruit-stage/continuation.js +74 -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 +719 -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 +1354 -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/continuation.js +2 -1
- package/dist/shortcuts/workflow/index.js +2 -0
- package/dist/shortcuts/workflow/operations/form.js +32 -8
- package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +13 -6
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +17 -24
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +14 -9
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +50 -8
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +2 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +17 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +7 -39
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +3 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +51 -15
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +16 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +151 -63
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.subGroup.js +56 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +39 -14
- package/dist/shortcuts/workflow/operations/write.js +1 -1
- package/docs/_catalog.md +3 -0
- package/docs/agent-invoice.md +1 -1
- package/docs/archive-oa.md +1 -1
- package/docs/caizhilian.md +1 -1
- package/docs/calendar.md +1 -1
- package/docs/contract.md +1 -1
- package/docs/e10-auth.md +23 -1
- package/docs/ehr.md +2 -2
- package/docs/esb.md +1 -1
- package/docs/im.md +1 -1
- package/docs/invoice.md +8 -12
- package/docs/okr.md +1 -1
- package/docs/operation-manual.md +8 -0
- package/docs/reception.md +119 -0
- package/package.json +1 -1
- package/scripts/clean.mjs +43 -2
- package/scripts/install-skill-to-xiaoe.mjs +105 -0
- package/scripts/package-skill.mjs +4 -2
- package/skill-template/business-info.json +42 -2
- package/skill-template/domains/caizhilian.md +1 -1
- package/skill-template/domains/reception-flow.md +18 -0
- package/skill-template/domains/recruit-stage.md +29 -0
- package/skill-template/domains/yepiaotong.md +4 -7
- package/skills/weaver-e10-archive-oa/references/source-manifest.json +14 -14
- package/skills/weaver-e10-blog/references/blog-publish.md +1 -1
- package/skills/weaver-e10-blog/references/source-manifest.json +7 -7
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +21 -21
- package/skills/weaver-e10-caizhilian/references/write-protocol.md +2 -2
- package/skills/weaver-e10-calendar/SKILL.md +2 -1
- package/skills/weaver-e10-calendar/references/calendar-write.md +55 -1
- package/skills/weaver-e10-cowork/SKILL.md +1 -1
- package/skills/weaver-e10-cowork/references/cowork-write.md +3 -1
- package/skills/weaver-e10-ebuilder-form/SKILL.md +1 -1
- package/skills/weaver-e10-ebuilder-form/references/custom-api.md +1 -1
- package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +1 -1
- package/skills/weaver-e10-esb/SKILL.md +2 -2
- package/skills/weaver-e10-esb/references/source-manifest.json +22 -22
- package/skills/weaver-e10-esb/references/trigger.md +2 -2
- package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +1 -1
- package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +1 -1
- package/skills/weaver-e10-jinchengda/references/contract-request-write.md +1 -1
- package/skills/weaver-e10-jinchengda/references/source-manifest.json +29 -29
- package/skills/weaver-e10-jucailin/SKILL.md +1 -1
- package/skills/weaver-e10-jucailin/references/attend-write.md +10 -2
- 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 +14 -5
- package/skills/weaver-e10-jucailin/references/recruit-read.md +1 -1
- package/skills/weaver-e10-jucailin/references/recruit-write.md +5 -4
- package/skills/weaver-e10-mail/SKILL.md +1 -1
- package/skills/weaver-e10-meeting/SKILL.md +39 -7
- package/skills/weaver-e10-meeting/references/meeting-change.md +1 -1
- package/skills/weaver-e10-meeting/references/meeting-create.md +1 -1
- package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +1 -1
- package/skills/weaver-e10-meeting/references/meeting-verification.md +1 -1
- package/skills/weaver-e10-okr/references/okr-align.md +1 -1
- package/skills/weaver-e10-okr/references/okr-keyresult.md +1 -1
- package/skills/weaver-e10-okr/references/okr-write.md +1 -1
- package/skills/weaver-e10-okr/references/source-manifest.json +8 -8
- package/skills/weaver-e10-plan/references/plan-report-write.md +1 -1
- package/skills/weaver-e10-plan/references/source-manifest.json +20 -20
- package/skills/weaver-e10-qiyecheng/references/loan-management.md +1 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +18 -18
- package/skills/weaver-e10-reception-flow/SKILL.md +173 -0
- package/skills/weaver-e10-reception-flow/assets//350/241/214/347/250/213/345/215/225/346/250/241/346/235/277-/346/263/233/345/276/256.docx +0 -0
- package/skills/weaver-e10-reception-flow/data/fields-snapshot.json +213 -0
- package/skills/weaver-e10-reception-flow/references/browsertool.md +68 -0
- package/skills/weaver-e10-reception-flow/references/env-pitfalls.md +51 -0
- package/skills/weaver-e10-reception-flow/references/fields-snapshot.md +227 -0
- package/skills/weaver-e10-reception-flow/references/guide.md +179 -0
- package/skills/weaver-e10-reception-flow/scripts/locate.sh +14 -0
- package/skills/weaver-e10-reception-flow/scripts/render.py +724 -0
- package/skills/weaver-e10-recruit-stage/SKILL.md +230 -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/lib/xiaoe-session.mjs +66 -0
- package/skills/weaver-e10-recruit-stage/references/position-templates.md +202 -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 +95 -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 +451 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resume-parse.md +128 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-search-candidate.md +146 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-urge-feedback.md +69 -0
- package/skills/weaver-e10-shared/SKILL.md +1 -1
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +10 -2
- package/skills/weaver-e10-shijingran/SKILL.md +7 -6
- package/skills/weaver-e10-shijingran/references/operations.md +3 -1
- package/skills/weaver-e10-shijingran/references/source-manifest.json +30 -28
- package/skills/weaver-e10-shijingran/references/write-operations.md +2 -0
- package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +2 -0
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +3 -3
- package/skills/weaver-e10-workflow/SKILL.md +4 -2
- package/skills/weaver-e10-workflow/aigroup/default.json +11 -9
- package/skills/weaver-e10-workflow/references/source-manifest.json +32 -32
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +23 -13
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +62 -20
- package/skills/weaver-e10-yepiaotong/SKILL.md +28 -36
- package/skills/weaver-e10-yepiaotong/references/invoice-agent-entry.md +6 -3
- package/skills/weaver-e10-yepiaotong/references/invoice-detail.md +13 -10
- package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +2 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +194 -155
- package/skills/weaver-e10-yepiaotong/references/invoice-output-view.md +28 -32
- package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +5 -1
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +8 -10
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +211 -616
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +149 -117
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +17 -20
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +20 -39
- package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +55 -22
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -17
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +88 -92
- package/skills/weaver-e10-yepiaotong/references/source-manifest.json +144 -354
- package/skills/weaver-e10-yimiaoban/SKILL.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/msg-write.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +7 -7
- package/dist/chunks/chunk-SPRHHSVC.js +0 -465
- package/dist/chunks/registry-KMHCPAAD.js +0 -22
- package/dist/shortcuts/invoice/markdown.js +0 -172
- package/dist/shortcuts/invoice/operations/issuing-qys.js +0 -424
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +0 -131
- package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +0 -179
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { ExitCode, isCliError, toErrorEnvelope } from '../../core/errors.js';
|
|
3
|
+
import { reportPlatformError } from '../../core/error-codes.js';
|
|
3
4
|
import { createJiuchuanhuiContinuationSigner } from './continuation.js';
|
|
4
5
|
import { createJiuchuanhuiHost } from './host.js';
|
|
5
6
|
import { jiuchuanhuiManifest } from './manifest.js';
|
|
@@ -82,6 +83,7 @@ async function executeAndPrint(ctx, operation, input) {
|
|
|
82
83
|
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
83
84
|
}
|
|
84
85
|
catch (error) {
|
|
86
|
+
reportPlatformError(error);
|
|
85
87
|
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
86
88
|
process.exitCode = isCliError(error) ? error.exitCode : ExitCode.GeneralError;
|
|
87
89
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_SECONDS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { jiuchuanhuiConfirmationError, jiuchuanhuiPartialError, jiuchuanhuiValidationError, isJiuchuanhuiNetworkError, } from '../errors.js';
|
|
2
3
|
import { asObject, asPositiveString, byIdBody, datasBody, listBody, listRecords, pagingFrom, resultDataIds, sessionMatches, stripForbiddenKeys, workflow, } from './shared.js';
|
|
3
4
|
/**
|
|
@@ -32,7 +33,7 @@ export class DatajsonWritePrepareOperation {
|
|
|
32
33
|
data: {
|
|
33
34
|
preview,
|
|
34
35
|
continuation: continuationToken,
|
|
35
|
-
expiresInSeconds:
|
|
36
|
+
expiresInSeconds: CONTINUATION_TTL_SECONDS,
|
|
36
37
|
workflow: workflow(this.applyOperation, 'AWAITING_CONFIRMATION'),
|
|
37
38
|
},
|
|
38
39
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_SECONDS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { jiuchuanhuiConfirmationError, jiuchuanhuiPartialError, jiuchuanhuiValidationError, isJiuchuanhuiNetworkError, } from '../errors.js';
|
|
2
3
|
import { asObject, asNonEmptyString, esbBody, esbOutcome, sessionMatches, workflow } from './shared.js';
|
|
3
4
|
/**
|
|
@@ -36,7 +37,7 @@ export class EsbWritePrepareOperation {
|
|
|
36
37
|
data: {
|
|
37
38
|
preview,
|
|
38
39
|
continuation: continuationToken,
|
|
39
|
-
expiresInSeconds:
|
|
40
|
+
expiresInSeconds: CONTINUATION_TTL_SECONDS,
|
|
40
41
|
workflow: workflow(this.applyOperation, 'AWAITING_CONFIRMATION'),
|
|
41
42
|
},
|
|
42
43
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS } from '../../core/continuation-ttl.js';
|
|
1
2
|
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
3
|
import { existsSync } from 'node:fs';
|
|
3
4
|
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
@@ -35,7 +36,7 @@ function signature(payload, key) {
|
|
|
35
36
|
}
|
|
36
37
|
export function createMailContinuationSigner(ctx) {
|
|
37
38
|
return {
|
|
38
|
-
async issue(payload, ttlMs =
|
|
39
|
+
async issue(payload, ttlMs = CONTINUATION_TTL_MS) {
|
|
39
40
|
const issuedAt = Date.now();
|
|
40
41
|
const body = encode({ ...payload, issuedAt, expiresAt: issuedAt + ttlMs });
|
|
41
42
|
const sig = signature(body, await loadKey(ctx));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { ExitCode, isCliError, toErrorEnvelope } from '../../core/errors.js';
|
|
3
|
+
import { reportPlatformError } from '../../core/error-codes.js';
|
|
3
4
|
import { createMailContinuationSigner } from './continuation.js';
|
|
4
5
|
import { createMailHost } from './host.js';
|
|
5
6
|
import { mailManifest } from './manifest.js';
|
|
@@ -83,6 +84,7 @@ async function executeAndPrint(ctx, operation, input) {
|
|
|
83
84
|
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
84
85
|
}
|
|
85
86
|
catch (error) {
|
|
87
|
+
reportPlatformError(error);
|
|
86
88
|
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
87
89
|
process.exitCode = isCliError(error) ? error.exitCode : ExitCode.GeneralError;
|
|
88
90
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { mailValidationError } from '../errors.js';
|
|
2
3
|
import { WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
|
|
3
|
-
const CONTINUATION_TTL_MS = 600_000;
|
|
4
4
|
const BLACKLIST_SCHEMA = schemaOf({
|
|
5
5
|
operateType: { type: 'string', description: 'add / delete' },
|
|
6
6
|
mailAddress: SCHEMA_STRING,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { mailValidationError } from '../errors.js';
|
|
2
3
|
import { WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
|
|
3
|
-
const CONTINUATION_TTL_MS = 600_000;
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
// 联系人 新增/编辑(prepare/apply)
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { randomBytes } from 'node:crypto';
|
|
2
3
|
import { mailValidationError } from '../errors.js';
|
|
3
4
|
import { WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
|
|
4
|
-
const CONTINUATION_TTL_MS = 600_000;
|
|
5
5
|
function b64(s) {
|
|
6
6
|
return Buffer.from(s, 'utf8').toString('base64');
|
|
7
7
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { mailValidationError } from '../errors.js';
|
|
2
3
|
import { READ, WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
|
|
3
|
-
const CONTINUATION_TTL_MS = 600_000;
|
|
4
4
|
const SIGN_SCHEMA = schemaOf({
|
|
5
5
|
id: SCHEMA_STRING,
|
|
6
6
|
signName: SCHEMA_STRING,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { mailValidationError } from '../errors.js';
|
|
2
3
|
import { WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
|
|
3
|
-
const CONTINUATION_TTL_MS = 600_000;
|
|
4
4
|
const TEMPLATE_SCHEMA = schemaOf({
|
|
5
5
|
id: SCHEMA_STRING,
|
|
6
6
|
templateType: SCHEMA_STRING,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS } from '../../core/continuation-ttl.js';
|
|
1
2
|
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
3
|
import { existsSync } from 'node:fs';
|
|
3
4
|
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
@@ -35,7 +36,7 @@ function signature(payload, key) {
|
|
|
35
36
|
}
|
|
36
37
|
export function createMeetingContinuationSigner(ctx) {
|
|
37
38
|
return {
|
|
38
|
-
async issue(payload, ttlMs =
|
|
39
|
+
async issue(payload, ttlMs = CONTINUATION_TTL_MS) {
|
|
39
40
|
const issuedAt = Date.now();
|
|
40
41
|
const body = encode({ ...payload, issuedAt, expiresAt: issuedAt + ttlMs });
|
|
41
42
|
const sig = signature(body, await loadKey(ctx));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { ExitCode, isCliError, toErrorEnvelope } from '../../core/errors.js';
|
|
3
|
+
import { reportPlatformError } from '../../core/error-codes.js';
|
|
3
4
|
import { createMeetingContinuationSigner } from './continuation.js';
|
|
4
5
|
import { createMeetingHost } from './host.js';
|
|
5
6
|
import { meetingManifest, OPERATION_INDEX_HINT } from './manifest.js';
|
|
@@ -87,6 +88,7 @@ async function executeAndPrint(ctx, operation, input) {
|
|
|
87
88
|
ctx.output.write(successEnvelope(operation, result), { json: true });
|
|
88
89
|
}
|
|
89
90
|
catch (error) {
|
|
91
|
+
reportPlatformError(error);
|
|
90
92
|
console.error(JSON.stringify(failureEnvelope(error), null, 2));
|
|
91
93
|
process.exitCode = isCliError(error) ? error.exitCode : ExitCode.GeneralError;
|
|
92
94
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_SECONDS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import { meetingConfirmationError, meetingPartialError, meetingValidationError } from '../errors.js';
|
|
3
4
|
import { meetingSuccess, SCHEMA_DATETIME_MINUTE, SCHEMA_ID } from './types.js';
|
|
4
5
|
import { assertDateTimeMinute, extractRows, mergeSnapshot, toIdCsv, toIdString } from './shared.js';
|
|
5
|
-
const CONTINUATION_TTL_SECONDS = 600;
|
|
6
6
|
const LIST_PATH = '/api/meeting/search/getMeetingList';
|
|
7
7
|
function fingerprint(value) {
|
|
8
8
|
return createHash('sha256').update(JSON.stringify(value ?? null)).digest('hex').slice(0, 32);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_SECONDS } from '../../../core/continuation-ttl.js';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import { meetingConflictError, meetingConfirmationError, meetingPartialError, meetingValidationError } from '../errors.js';
|
|
3
4
|
import { meetingSuccess, SCHEMA_DATETIME_MINUTE, SCHEMA_ID } from './types.js';
|
|
4
5
|
import { assertDateTimeMinute, extractConflict, mergeSnapshot, toIdCsv, toIdString, } from './shared.js';
|
|
5
|
-
const CONTINUATION_TTL_SECONDS = 600;
|
|
6
6
|
function fingerprint(value) {
|
|
7
7
|
return createHash('sha256').update(JSON.stringify(value ?? null)).digest('hex').slice(0, 32);
|
|
8
8
|
}
|
|
@@ -276,7 +276,10 @@ export const EB_ENDPOINTS = [
|
|
|
276
276
|
interfacePk: 'query_roomusage_list',
|
|
277
277
|
countPk: 'query_roomusage_count',
|
|
278
278
|
queryParams: ['mt_id', 'address', 'enddatetime', 'begindatetime'],
|
|
279
|
-
|
|
279
|
+
dateFilter: true,
|
|
280
|
+
paramAliases: { roomId: 'address', room_id: 'address', day: 'date' },
|
|
281
|
+
summary: 'EB 版会议室占用列表(query_roomusage_list + count)。按日期过滤传 date(yyyy-MM-dd)'
|
|
282
|
+
+ '或 begindatetime/enddatetime;**不传任何时间条件 = 返回全量历史**,不是接口不支持过滤',
|
|
280
283
|
},
|
|
281
284
|
{
|
|
282
285
|
domain: 'roomUsage',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_MS, CONTINUATION_TTL_SECONDS } from '../../../../core/continuation-ttl.js';
|
|
1
2
|
import { existsSync } from 'node:fs';
|
|
2
3
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
4
|
import { homedir } from 'node:os';
|
|
@@ -9,6 +10,7 @@ import { EB_BASE, ebBusinessSuccess, writeBody } from './factory.js';
|
|
|
9
10
|
import { loadRooms, recommendRooms } from './room-recommend.js';
|
|
10
11
|
import { dayOf, filterUsages, invalidateDayUsages, loadDayUsages } from './usage-cache.js';
|
|
11
12
|
import { pickRememberedFlow, readFlowPick, rememberFlowPick } from './flow-memory.js';
|
|
13
|
+
import { resolveNamesCached } from './person-cache.js';
|
|
12
14
|
/**
|
|
13
15
|
* 通过**流程**新建 EB 会议(`meeting.eb.meeting.create.flow`)。
|
|
14
16
|
*
|
|
@@ -75,30 +77,17 @@ async function loadCreateForm(env, workflowId) {
|
|
|
75
77
|
workflowName: String(wf.name ?? wf.workflowName ?? '').trim() || undefined,
|
|
76
78
|
};
|
|
77
79
|
}
|
|
78
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* 取员工姓名(**缓存优先**:命中直接返回,未命中才打 hrm.employee.batch)。
|
|
82
|
+
*
|
|
83
|
+
* 2026-11-04 用户要求:一次建会会查 3~5 次同一批人,每次 ~2s,必须缓存。
|
|
84
|
+
* 缓存位置 `person-v1-<租户>.json`,TTL 24h(见 person-cache.ts)。
|
|
85
|
+
*/
|
|
79
86
|
async function resolveEmployeeNames(env, ids) {
|
|
80
|
-
const map = new Map();
|
|
81
87
|
const unique = [...new Set(ids.map((id) => String(id).trim()).filter((id) => id !== ''))];
|
|
82
88
|
if (unique.length === 0)
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
const { hrmEmployeeOperations } = await import('../../../hrm/operations/employee.js');
|
|
86
|
-
const batch = hrmEmployeeOperations.find((operation) => operation.name === 'hrm.employee.batch');
|
|
87
|
-
if (!batch)
|
|
88
|
-
return map;
|
|
89
|
-
const result = await batch.handler({ ids: unique }, env);
|
|
90
|
-
const rows = (result?.data?.rows ?? result?.data?.userList ?? []);
|
|
91
|
-
for (const row of rows) {
|
|
92
|
-
const id = String(row.id ?? '').trim();
|
|
93
|
-
const name = String(row.name ?? '').trim();
|
|
94
|
-
if (id && name)
|
|
95
|
-
map.set(id, name);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// 查不到姓名就退回「以 id 当名称」,工作流多数能按 id 直接命中
|
|
100
|
-
}
|
|
101
|
-
return map;
|
|
89
|
+
return new Map();
|
|
90
|
+
return resolveNamesCached(env, unique);
|
|
102
91
|
}
|
|
103
92
|
/**
|
|
104
93
|
* 把「员工 id 或姓名」解析成 `{ id, name }`。
|
|
@@ -290,6 +279,13 @@ export async function shapeBrowserValues(env, values) {
|
|
|
290
279
|
readable.address = String(shaped.address);
|
|
291
280
|
}
|
|
292
281
|
}
|
|
282
|
+
// 邀请函要用「人话版本」的时间(预置函走 readable,之前这里没放,导致预置函时间缺失)
|
|
283
|
+
if (shaped.begin_datetime !== undefined && String(shaped.begin_datetime).trim() !== '') {
|
|
284
|
+
readable.begin_datetime = String(shaped.begin_datetime).trim();
|
|
285
|
+
}
|
|
286
|
+
if (shaped.end_datetime !== undefined && String(shaped.end_datetime).trim() !== '') {
|
|
287
|
+
readable.end_datetime = String(shaped.end_datetime).trim();
|
|
288
|
+
}
|
|
293
289
|
const personFields = ['hrm_members', 'caller', 'contacter'];
|
|
294
290
|
const idPool = [];
|
|
295
291
|
for (const key of personFields) {
|
|
@@ -1038,6 +1034,36 @@ export function shouldAutoPickFlow(args) {
|
|
|
1038
1034
|
return true;
|
|
1039
1035
|
return String(process.env.WEAVER_MEETING_FLOW_CHOICE ?? '').trim().toLowerCase() === 'auto';
|
|
1040
1036
|
}
|
|
1037
|
+
/**
|
|
1038
|
+
* 把邀请函 docx 发到会议群(IM 两段式:prepare → apply)。
|
|
1039
|
+
*
|
|
1040
|
+
* ⛔ 只传 file、**不带 txt**:实测「txt + file」同传时服务端只落文本、文件被丢弃
|
|
1041
|
+
* (2026-11-04 用户截图:群里只有一行「会议邀请函:xxx」)。
|
|
1042
|
+
* 失败只记 warning —— 会议和邀请函都已生成,发群失败不该影响建会结果。
|
|
1043
|
+
*/
|
|
1044
|
+
async function sendInvitationToGroup(env, groupId, filePath, warnings) {
|
|
1045
|
+
const started = Date.now();
|
|
1046
|
+
try {
|
|
1047
|
+
const { buildImEnv } = await import('./group-chat.js');
|
|
1048
|
+
const { getImOperation } = await import('../../../im/operations/registry.js');
|
|
1049
|
+
const imEnv = await buildImEnv(env);
|
|
1050
|
+
const prepared = await getImOperation('im.msg.send.group.prepare').handler({ groupId, file: filePath }, imEnv);
|
|
1051
|
+
const continuation = String(prepared?.data?.continuation ?? '');
|
|
1052
|
+
const applied = continuation
|
|
1053
|
+
? await getImOperation('im.msg.send.group.apply').handler({ continuation, confirm: true }, imEnv)
|
|
1054
|
+
: null;
|
|
1055
|
+
const ok = applied?.ok === true;
|
|
1056
|
+
if (!ok) {
|
|
1057
|
+
warnings.push(`邀请函没能发到群里(${String(applied?.error?.message ?? prepared?.error?.message ?? '未知原因').slice(0, 150)});`
|
|
1058
|
+
+ '文件已生成,可手动转发。');
|
|
1059
|
+
}
|
|
1060
|
+
return { ok, ms: Date.now() - started };
|
|
1061
|
+
}
|
|
1062
|
+
catch (error) {
|
|
1063
|
+
warnings.push(`邀请函发群异常(不影响建会):${String(error?.message ?? error).slice(0, 150)}`);
|
|
1064
|
+
return { ok: false, ms: Date.now() - started };
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1041
1067
|
/** 解析要用的建会流程 id:入参优先(可多个),其次固化列表,最后才是应用设置里的 mt_new_wf。 */
|
|
1042
1068
|
export async function resolveWorkflowId(env, args) {
|
|
1043
1069
|
const explicitList = normalizeWorkflowIds(args.workflowId);
|
|
@@ -1493,9 +1519,16 @@ const ebMeetingCreateFlowPrepare = {
|
|
|
1493
1519
|
const roomMemberCount = declaredTotal
|
|
1494
1520
|
?? (memberIds.length > 0 ? memberIds.length + (callerInMembers ? 0 : 1) : undefined);
|
|
1495
1521
|
// 有没有客户:决定要不要优先推接待类会议室(crm_members 可能是数组、"id,id" 或名称)
|
|
1496
|
-
|
|
1522
|
+
// 2026-11-04 补:用户只在话里说了「接待某某客户」、没传 crm_members 时,也要识别出来 ——
|
|
1523
|
+
// 否则"带客户优先接待类"这条规则永远不生效(用户实测推荐了 3 间普通会议室)。
|
|
1524
|
+
const crmMentionedInText = detectCrmMentionInText(String(args.mt_name ?? ''), String(args.mt_desc ?? ''), String(args.other_remark ?? ''));
|
|
1525
|
+
// 「接待湖北省政府客户」这种说法不含「客户是/为」句式,上面的正则接不住 —— 再用关键词兜一层。
|
|
1526
|
+
const customerWords = /(接待|招待|客户|贵宾|来访)/u.test(`${String(args.mt_name ?? '')} ${String(args.mt_desc ?? '')} ${String(args.other_remark ?? '')}`);
|
|
1527
|
+
const hasCustomer = (Array.isArray(args.crm_members)
|
|
1497
1528
|
? args.crm_members.length > 0
|
|
1498
|
-
: String(args.crm_members ?? '').trim() !== ''
|
|
1529
|
+
: String(args.crm_members ?? '').trim() !== '')
|
|
1530
|
+
|| Boolean(crmMentionedInText)
|
|
1531
|
+
|| customerWords;
|
|
1499
1532
|
// 全天占用缓存(2026-11-03 用户方案):不带 address 条件一次拉当天全部会议室占用(~2s,
|
|
1500
1533
|
// 5 分钟 TTL),推荐 busy 判定与指定房间的占用检测**共用同一份**;同一天内改时间/换房间
|
|
1501
1534
|
// 不再打占用接口。提交成功后当天缓存立即作废(见提交成功处)。
|
|
@@ -2021,8 +2054,11 @@ const ebMeetingCreateFlowPrepare = {
|
|
|
2021
2054
|
})();
|
|
2022
2055
|
const shaped = await shapeBrowserValues(env, {
|
|
2023
2056
|
mt_name: args.mt_name,
|
|
2024
|
-
|
|
2025
|
-
|
|
2057
|
+
// ⛔ 2026-11-05 修:用户只说「明天下午」时,时间是 CLI 按 time_slot 展开出来的(beginText/endText),
|
|
2058
|
+
// 原始入参 args.begin_datetime 是空的 —— 以前这里直接取 args,表单两个时间字段就空着,
|
|
2059
|
+
// 页面打开后默认成"当前时间"(用户实测:填 11-06 13:00–18:00,表单显示 11-05 17:25)。
|
|
2060
|
+
begin_datetime: beginText || args.begin_datetime,
|
|
2061
|
+
end_datetime: endText || args.end_datetime,
|
|
2026
2062
|
mt_desc: args.mt_desc,
|
|
2027
2063
|
address: addressInput,
|
|
2028
2064
|
customize_address: args.customize_address,
|
|
@@ -2123,9 +2159,7 @@ const ebMeetingCreateFlowPrepare = {
|
|
|
2123
2159
|
+ '传 crm_detail_mode:"only" 再配 crm_member_details 才覆盖本次自动带入。');
|
|
2124
2160
|
}
|
|
2125
2161
|
else if (auto.missing.length > 0) {
|
|
2126
|
-
warnings.push(`已写「参会客户」,但没能自动带出「${auto.missing.join('、')}」的联系人(CRM
|
|
2127
|
-
+ '请把已查到的联系人直接告给用户核对;确实没有联系人时问一次姓名+手机号,'
|
|
2128
|
-
+ '再以 crm_member_details:[{"xm":"张三","sjhm":"13800000000"}] 重新 prepare。');
|
|
2162
|
+
warnings.push(`已写「参会客户」,但没能自动带出「${auto.missing.join('、')}」的联系人(CRM 里没建档联系人)。`);
|
|
2129
2163
|
}
|
|
2130
2164
|
}
|
|
2131
2165
|
}
|
|
@@ -2251,13 +2285,24 @@ const ebMeetingCreateFlowPrepare = {
|
|
|
2251
2285
|
// 建群要素:apply 拿到会议 id 后先建群、再把群 id 回写 imchat_groupid
|
|
2252
2286
|
groupChat: {
|
|
2253
2287
|
memberIds: groupMemberIds,
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2288
|
+
// ⛔ 2026-11-04 修:用户只说"明天上午"(time_slot)时,begin_datetime 是 CLI 展开出来的,
|
|
2289
|
+
// `shaped.values` 里**没有**这个键 —— 直接取会得到空串,群消息里"开始时间/结束时间"就空着。
|
|
2290
|
+
// 这里统一用展开后的 beginText/endText。
|
|
2291
|
+
beginDatetime: beginText,
|
|
2292
|
+
endDatetime: endText,
|
|
2293
|
+
// ⛔ 2026-11-04 修:shaped.address 在这之前已被解析成 `{id,name}` 对象,
|
|
2294
|
+
// 直接 String() 会变成 "[object Object]" 打进群消息(用户实测看到的就是这个)。
|
|
2295
|
+
// 群消息要的是人话名称,这里优先取 name。
|
|
2296
|
+
address: (() => {
|
|
2297
|
+
const value = shaped.values.address;
|
|
2298
|
+
if (value && typeof value === 'object')
|
|
2299
|
+
return String(value.name ?? value.id ?? '');
|
|
2300
|
+
return String(value ?? '');
|
|
2301
|
+
})(),
|
|
2257
2302
|
},
|
|
2258
2303
|
},
|
|
2259
2304
|
fingerprint: JSON.stringify({ workflowId, main, ...(detailPayload ? { details: detailPayload } : {}) }),
|
|
2260
|
-
},
|
|
2305
|
+
}, CONTINUATION_TTL_MS);
|
|
2261
2306
|
return meetingSuccess('meeting.eb.meeting.create.flow.prepare', {
|
|
2262
2307
|
status: 'AWAITING_CONFIRMATION',
|
|
2263
2308
|
preview: {
|
|
@@ -2285,7 +2330,7 @@ const ebMeetingCreateFlowPrepare = {
|
|
|
2285
2330
|
...(Object.keys(decisions).length > 0 ? { decisions } : {}),
|
|
2286
2331
|
},
|
|
2287
2332
|
continuation,
|
|
2288
|
-
expiresInSeconds:
|
|
2333
|
+
expiresInSeconds: CONTINUATION_TTL_SECONDS,
|
|
2289
2334
|
}, warnings.length > 0 ? { warnings } : {});
|
|
2290
2335
|
},
|
|
2291
2336
|
};
|
|
@@ -2526,6 +2571,16 @@ const ebMeetingCreateFlowApply = {
|
|
|
2526
2571
|
// 落盘失败不影响输出表单;补绑时可改传 requestId
|
|
2527
2572
|
}
|
|
2528
2573
|
}
|
|
2574
|
+
// 邀请函也要发群(2026-11-04 用户实测:浏览器填单这一档建了群却没收不到邀请函)。
|
|
2575
|
+
// 这里发的是**预置函**(按申请单信息生成,字段可能有【待补充】),审批通过后可用 meetingId 重新生成。
|
|
2576
|
+
const browserWarnings = [];
|
|
2577
|
+
let browserInvitation = pre.invitation;
|
|
2578
|
+
const browserGroupId = String(groupChat?.groupId ?? '').trim();
|
|
2579
|
+
const browserInvitePath = String(pre.invitation?.filePath ?? '').trim();
|
|
2580
|
+
if (browserGroupId && browserInvitePath) {
|
|
2581
|
+
const sent = await sendInvitationToGroup(env, browserGroupId, browserInvitePath, browserWarnings);
|
|
2582
|
+
browserInvitation = { ...pre.invitation, sentToGroup: { groupId: browserGroupId, ok: sent.ok } };
|
|
2583
|
+
}
|
|
2529
2584
|
return meetingSuccess('meeting.eb.meeting.create.flow.apply', {
|
|
2530
2585
|
status: 'BROWSER_FILL',
|
|
2531
2586
|
workflowId: payload.workflowId,
|
|
@@ -2539,7 +2594,7 @@ const ebMeetingCreateFlowApply = {
|
|
|
2539
2594
|
finalMarkdownHint: '把 finalMarkdown 原样贴在回复最后(从 <browsertool> 到 </browsertool>,不包代码块);'
|
|
2540
2595
|
+ '不贴这段=用户看不到表单,也不能说"表单已打开"。',
|
|
2541
2596
|
message: String(submittedData.message ?? ''),
|
|
2542
|
-
invitation:
|
|
2597
|
+
invitation: browserInvitation,
|
|
2543
2598
|
...(groupChat ? { groupChat } : {}),
|
|
2544
2599
|
timings: { submitMs: Date.now() - submitStartedAt, invitationMs: pre.ms },
|
|
2545
2600
|
}, {
|
|
@@ -2554,8 +2609,11 @@ const ebMeetingCreateFlowApply = {
|
|
|
2554
2609
|
? [`群聊没建成功(${String(groupChat.error ?? '未知原因')}):会议照常可以在页面里提交,群需要手工建或稍后重试。`]
|
|
2555
2610
|
: []),
|
|
2556
2611
|
`邀请函已按申请单信息**预生成**(预置函,${String(pre.invitation.filePath ?? '见 filePath')}):`
|
|
2557
|
-
+
|
|
2612
|
+
+ (browserInvitation.sentToGroup?.ok
|
|
2613
|
+
? '已把 docx 发到会议群;字段可能含【待补充】,审批通过、会议生成后可用 mtId 再跑一次 meeting.invitation.render 拿完整版本。'
|
|
2614
|
+
: '请下载后人工核对、自行发送;流程审批通过、会议生成后可用 mtId 再跑一次 meeting.invitation.render 拿完整字段版本。'),
|
|
2558
2615
|
'⛔ 不要因为"没有 requestId / 没有会议 id"重复 apply —— 填单要在那个浏览器页面里点提交。',
|
|
2616
|
+
...browserWarnings,
|
|
2559
2617
|
],
|
|
2560
2618
|
});
|
|
2561
2619
|
}
|
|
@@ -2712,6 +2770,14 @@ const ebMeetingCreateFlowApply = {
|
|
|
2712
2770
|
+ '审批通过、会议生成后可用 mtId 再跑一次 meeting.invitation.render 拿到完整字段版本。'
|
|
2713
2771
|
+ '⛔ 本 operation 不重复提交流程 —— 不要因为"没有会议 id"就重复 apply。');
|
|
2714
2772
|
}
|
|
2773
|
+
// 邀请函自动发群(2026-11-04 用户要求):群已建好 + 邀请函文件已生成 → 把 docx 直接发进群里。
|
|
2774
|
+
const inviteGroupId = String(groupChat?.groupId ?? '').trim();
|
|
2775
|
+
const inviteFilePath = String(invitation?.filePath ?? '').trim();
|
|
2776
|
+
if (inviteGroupId && inviteFilePath) {
|
|
2777
|
+
const sent = await sendInvitationToGroup(env, inviteGroupId, inviteFilePath, warnings);
|
|
2778
|
+
invitation.sentToGroup = { groupId: inviteGroupId, ok: sent.ok };
|
|
2779
|
+
timings.invitationSendMs = sent.ms;
|
|
2780
|
+
}
|
|
2715
2781
|
return meetingSuccess('meeting.eb.meeting.create.flow.apply', {
|
|
2716
2782
|
status: 'COMPLETE',
|
|
2717
2783
|
timings,
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
* - `meeting.eb.decision.publish`:写决议(概述 + 明细)→ 自动写回会议为已决议(含部分失败语义);
|
|
15
15
|
* - `meeting.eb.sign.mark`:按「会议 + 参会人」自动定位签到记录,走 update 补签 / 补签退。
|
|
16
16
|
*/
|
|
17
|
+
import { CONTINUATION_TTL_SECONDS } from '../../../../core/continuation-ttl.js';
|
|
17
18
|
import { EB_BASE, ebBusinessSuccess, extractEbRows, fingerprint, normalizeEbWrite, queryBody, requireConfirm, verifyLease, writeBody, } from './factory.js';
|
|
18
19
|
import { EB_ENDPOINTS } from './catalog.js';
|
|
19
20
|
import { meetingSuccess } from '../types.js';
|
|
20
21
|
import { meetingPartialError, meetingValidationError } from '../../errors.js';
|
|
21
22
|
import { toIdString } from '../shared.js';
|
|
22
|
-
const CONTINUATION_TTL_SECONDS = 600;
|
|
23
23
|
const DATE_PATTERN = '^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}$';
|
|
24
24
|
/** 本地时间的 yyyy-MM-dd HH:mm:ss(EB 的签到/完成时间字段要求带秒)。 */
|
|
25
25
|
function formatSecondNow() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CONTINUATION_TTL_SECONDS } from '../../../../core/continuation-ttl.js';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import { meetingConfirmationError, meetingPartialError, meetingValidationError } from '../../errors.js';
|
|
3
4
|
import { meetingSuccess, SCHEMA_ID } from '../types.js';
|
|
@@ -58,7 +59,6 @@ async function buildPersonnelText(env, data) {
|
|
|
58
59
|
}
|
|
59
60
|
return out;
|
|
60
61
|
}
|
|
61
|
-
const CONTINUATION_TTL_SECONDS = 600;
|
|
62
62
|
/**
|
|
63
63
|
* EB 响应成功判定。
|
|
64
64
|
* EB 的响应体与标准版不同:成功时顶层常为 `{datajson:{...}}`(可能不带 status/code),
|
|
@@ -212,6 +212,18 @@ function buildReadInputSchema(endpoint) {
|
|
|
212
212
|
for (const param of endpoint.queryParams ?? []) {
|
|
213
213
|
properties[param] = { type: 'string', description: `EB 筛选参数(URL 占位符名 ${param})` };
|
|
214
214
|
}
|
|
215
|
+
// 便捷日期参数(2026-11-04):模型最常传的就是 date,别让它因为"没这个参数"去拿全量再下错结论。
|
|
216
|
+
if (endpoint.dateFilter) {
|
|
217
|
+
properties.date = {
|
|
218
|
+
type: 'string',
|
|
219
|
+
pattern: '^\\d{4}-\\d{2}-\\d{2}$',
|
|
220
|
+
description: '按日期过滤(yyyy-MM-dd):等价于 begindatetime=当天 00:00 + enddatetime=当天 23:59。'
|
|
221
|
+
+ '⛔ 不传 date 且不传起止时间 = 返回**全量历史**(不是接口不支持按日期过滤)',
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
for (const [alias, target] of Object.entries(endpoint.paramAliases ?? {})) {
|
|
225
|
+
properties[alias] = { type: 'string', description: `入参别名,等价于 ${target}` };
|
|
226
|
+
}
|
|
215
227
|
for (const param of endpoint.mainTableParams ?? []) {
|
|
216
228
|
properties[param] = {
|
|
217
229
|
type: 'string',
|
|
@@ -297,6 +309,27 @@ function buildReadOperation(endpoint) {
|
|
|
297
309
|
if (value !== undefined && value !== null && value !== '')
|
|
298
310
|
query[param] = value;
|
|
299
311
|
}
|
|
312
|
+
// 别名落地(roomId→address 之类);只在目标参数没传时生效,不覆盖显式值
|
|
313
|
+
for (const [alias, target] of Object.entries(endpoint.paramAliases ?? {})) {
|
|
314
|
+
const value = args[alias];
|
|
315
|
+
if (value === undefined || value === null || value === '')
|
|
316
|
+
continue;
|
|
317
|
+
if (query[target] === undefined) {
|
|
318
|
+
if (target === 'date')
|
|
319
|
+
continue; // date 不是 query 参数,下面单独展开
|
|
320
|
+
query[target] = value;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// 便捷日期:date(或别名 day)→ 当天的 begindatetime/enddatetime
|
|
324
|
+
if (endpoint.dateFilter) {
|
|
325
|
+
const day = String(args.date ?? args.day ?? '').trim().slice(0, 10);
|
|
326
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(day)) {
|
|
327
|
+
if (query.begindatetime === undefined)
|
|
328
|
+
query.begindatetime = `${day} 00:00`;
|
|
329
|
+
if (query.enddatetime === undefined)
|
|
330
|
+
query.enddatetime = `${day} 23:59`;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
300
333
|
if (endpoint.kind === 'get') {
|
|
301
334
|
const response = await env.host.request({
|
|
302
335
|
method: 'POST',
|
|
@@ -33,7 +33,7 @@ async function buildEsbEnv(env) {
|
|
|
33
33
|
const { createEsbContinuationSigner } = await import('../../../esb/continuation.js');
|
|
34
34
|
return { ctx: env.ctx, host: createEsbHost(env.ctx), continuation: createEsbContinuationSigner(env.ctx) };
|
|
35
35
|
}
|
|
36
|
-
async function buildImEnv(env) {
|
|
36
|
+
export async function buildImEnv(env) {
|
|
37
37
|
const { createImHost } = await import('../../../im/host.js');
|
|
38
38
|
const { createImContinuationSigner } = await import('../../../im/continuation.js');
|
|
39
39
|
return { ctx: env.ctx, host: createImHost(env.ctx), continuation: createImContinuationSigner(env.ctx) };
|
|
@@ -203,8 +203,30 @@ async function triggerGroupFlow(env, input, meetingName, memberIds) {
|
|
|
203
203
|
enddatetime: String(input.endDatetime ?? ''),
|
|
204
204
|
hrmmembers: memberIds.join(','),
|
|
205
205
|
};
|
|
206
|
-
if (input.address)
|
|
207
|
-
|
|
206
|
+
if (input.address) {
|
|
207
|
+
// ⛔ 2026-11-04 用户反馈:建群动作流把 `address` **原样打进群消息**(「会议地点:100502820000000226」)。
|
|
208
|
+
// ESB 模板改不了,所以这里先把它解析成会议室名称再传;解析不到才退回原值。
|
|
209
|
+
// 另外入参可能是 `{id,name}` 对象或被 String() 过的 "[object Object]",一并兜住。
|
|
210
|
+
const raw = input.address;
|
|
211
|
+
let addressText = raw && typeof raw === 'object'
|
|
212
|
+
? String(raw.name ?? raw.id ?? '')
|
|
213
|
+
: String(raw).trim();
|
|
214
|
+
if (addressText === '[object Object]')
|
|
215
|
+
addressText = '';
|
|
216
|
+
if (addressText) {
|
|
217
|
+
try {
|
|
218
|
+
const { resolveAddressRoom } = await import('./create-flow.js');
|
|
219
|
+
const room = await resolveAddressRoom(env, addressText);
|
|
220
|
+
if (room?.name)
|
|
221
|
+
addressText = room.name;
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// 台账读不到不影响建群,退回原值
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (addressText)
|
|
228
|
+
mainTable.address = addressText;
|
|
229
|
+
}
|
|
208
230
|
try {
|
|
209
231
|
const { getEsbOperation } = await import('../../../esb/operations/registry.js');
|
|
210
232
|
const esbEnv = await buildEsbEnv(env);
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { readCache, writeCache, cacheScopeSuffix } from './cache.js';
|
|
2
|
+
const PERSON_TTL_MS = 24 * 60 * 60 * 1000;
|
|
3
|
+
const BATCH_MAX = 100;
|
|
4
|
+
function personKey(scope) {
|
|
5
|
+
return `person-v1-${scope}`;
|
|
6
|
+
}
|
|
7
|
+
/** 读缓存里的全部人员(id → 记录),过期的条目会被丢弃。 */
|
|
8
|
+
async function readAll(env) {
|
|
9
|
+
const scope = await cacheScopeSuffix(env);
|
|
10
|
+
const hit = await readCache(env, personKey(scope), { ttlMs: PERSON_TTL_MS * 30 });
|
|
11
|
+
if (!hit)
|
|
12
|
+
return {};
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
const fresh = {};
|
|
15
|
+
for (const [id, record] of Object.entries(hit.data ?? {})) {
|
|
16
|
+
if (record && now - Number(record.savedAt || 0) <= PERSON_TTL_MS)
|
|
17
|
+
fresh[id] = record;
|
|
18
|
+
}
|
|
19
|
+
return fresh;
|
|
20
|
+
}
|
|
21
|
+
async function writeAll(env, all) {
|
|
22
|
+
const scope = await cacheScopeSuffix(env);
|
|
23
|
+
await writeCache(env, personKey(scope), all);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 批量取人员信息(缓存优先,未命中的才打 `hrm.employee.batch`)。
|
|
27
|
+
* 返回 id → 记录;查不到的人不会出现在结果里。
|
|
28
|
+
*/
|
|
29
|
+
export async function resolvePersonsCached(env, ids, options = {}) {
|
|
30
|
+
const wanted = [...new Set(ids.map((id) => String(id ?? '').trim()).filter((id) => id !== ''))];
|
|
31
|
+
const persons = new Map();
|
|
32
|
+
if (wanted.length === 0)
|
|
33
|
+
return { persons, requests: 0, fromCache: 0 };
|
|
34
|
+
const all = options.refresh === true ? {} : await readAll(env);
|
|
35
|
+
const missing = [];
|
|
36
|
+
let fromCache = 0;
|
|
37
|
+
for (const id of wanted) {
|
|
38
|
+
const hit = all[id];
|
|
39
|
+
if (hit) {
|
|
40
|
+
persons.set(id, hit);
|
|
41
|
+
fromCache += 1;
|
|
42
|
+
}
|
|
43
|
+
else
|
|
44
|
+
missing.push(id);
|
|
45
|
+
}
|
|
46
|
+
if (missing.length === 0)
|
|
47
|
+
return { persons, requests: 0, fromCache };
|
|
48
|
+
let requests = 0;
|
|
49
|
+
for (let index = 0; index < missing.length; index += BATCH_MAX) {
|
|
50
|
+
const chunk = missing.slice(index, index + BATCH_MAX);
|
|
51
|
+
try {
|
|
52
|
+
const { hrmEmployeeOperations } = await import('../../../hrm/operations/employee.js');
|
|
53
|
+
const batch = hrmEmployeeOperations.find((operation) => operation.name === 'hrm.employee.batch');
|
|
54
|
+
if (!batch)
|
|
55
|
+
break;
|
|
56
|
+
const result = await batch.handler({ ids: chunk }, env);
|
|
57
|
+
requests += 1;
|
|
58
|
+
const rows = (result?.data?.rows ?? result?.data?.userList ?? []);
|
|
59
|
+
for (const row of rows) {
|
|
60
|
+
const id = String(row?.id ?? '').trim();
|
|
61
|
+
if (!id)
|
|
62
|
+
continue;
|
|
63
|
+
const record = {
|
|
64
|
+
id,
|
|
65
|
+
name: String(row?.name ?? '').trim(),
|
|
66
|
+
...(row?.department ? { department: String(row.department) } : {}),
|
|
67
|
+
...(row?.departmentId ? { departmentId: String(row.departmentId) } : {}),
|
|
68
|
+
...(row?.subCompany ? { subCompany: String(row.subCompany) } : {}),
|
|
69
|
+
...(row?.position ? { position: String(row.position) } : {}),
|
|
70
|
+
...(row?.mobile ? { mobile: String(row.mobile) } : {}),
|
|
71
|
+
...(row?.jobNum ? { jobNum: String(row.jobNum) } : {}),
|
|
72
|
+
...(row?.imCid ? { imCid: String(row.imCid) } : {}),
|
|
73
|
+
savedAt: Date.now(),
|
|
74
|
+
};
|
|
75
|
+
persons.set(id, record);
|
|
76
|
+
all[id] = record;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// 查失败不影响业务:调用方拿到的是缺项,自行降级
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (requests > 0)
|
|
84
|
+
await writeAll(env, all);
|
|
85
|
+
return { persons, requests, fromCache };
|
|
86
|
+
}
|
|
87
|
+
/** 兼容老用法:只要 id → 姓名。 */
|
|
88
|
+
export async function resolveNamesCached(env, ids) {
|
|
89
|
+
const { persons } = await resolvePersonsCached(env, ids);
|
|
90
|
+
const map = new Map();
|
|
91
|
+
for (const [id, person] of persons) {
|
|
92
|
+
if (person.name)
|
|
93
|
+
map.set(id, person.name);
|
|
94
|
+
}
|
|
95
|
+
return map;
|
|
96
|
+
}
|