weaver-work-cli 0.1.42 → 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.
Files changed (318) hide show
  1. package/README.md +17 -0
  2. package/dist/chunks/{archive-J4I6MCKF.js → archive-P6TBQGKL.js} +13 -5
  3. package/dist/chunks/{archive-oa-BRZKKTO4.js → archive-oa-7TQ2NXOH.js} +12 -5
  4. package/dist/chunks/{asset-L7D4FAOZ.js → asset-3ELRG37G.js} +11 -4
  5. package/dist/chunks/{asset-idle-DADLLV75.js → asset-idle-WIGMUFMD.js} +7 -3
  6. package/dist/chunks/{attachment-content-K4C7VLWQ.js → attachment-content-E3276UOV.js} +5 -4
  7. package/dist/chunks/{blog-BVGQ7NZL.js → blog-C5NMZAAC.js} +11 -4
  8. package/dist/chunks/{caizhilian-SAADNFD6.js → caizhilian-5XSM2DFP.js} +13 -6
  9. package/dist/chunks/{calendar-Q7NQY5Z2.js → calendar-FI2WNSBO.js} +12 -5
  10. package/dist/chunks/{chunk-YRSZQUD2.js → chunk-3YBDYOC4.js} +3 -3
  11. package/dist/chunks/{chunk-OOUTBLZ4.js → chunk-56EZERK4.js} +1 -1
  12. package/dist/chunks/chunk-6N4JPNFL.js +76 -0
  13. package/dist/chunks/{chunk-ZUX3P6BQ.js → chunk-727FH2NI.js} +1 -1
  14. package/dist/chunks/chunk-7BDPM5ST.js +11 -0
  15. package/dist/chunks/{chunk-EKWAQSLU.js → chunk-BCVYBYYT.js} +432 -2248
  16. package/dist/chunks/{chunk-W7BEHOSR.js → chunk-CWYGFU5B.js} +2 -2
  17. package/dist/chunks/{chunk-NOODWMCL.js → chunk-D4ADSZ7H.js} +1 -1
  18. package/dist/chunks/{chunk-SA6VBIHY.js → chunk-ETNJSKMM.js} +214 -16
  19. package/dist/chunks/{chunk-BBKDXQEC.js → chunk-F4E4EM35.js} +3 -3
  20. package/dist/chunks/{chunk-IZ7S7QUS.js → chunk-FAZTGX7S.js} +6 -6
  21. package/dist/chunks/{chunk-NKZRQXST.js → chunk-FRZKBMSW.js} +52 -36
  22. package/dist/chunks/{chunk-BYBSCN4X.js → chunk-G7PQWD4L.js} +6 -3
  23. package/dist/chunks/{chunk-GEWYMQME.js → chunk-GAMZLAG2.js} +1 -1
  24. package/dist/chunks/{chunk-R4CHUSKC.js → chunk-GM6J7Q4B.js} +4 -4
  25. package/dist/chunks/{chunk-APVFJUQH.js → chunk-GRDRG6HP.js} +3 -3
  26. package/dist/chunks/{chunk-LDZQPUIA.js → chunk-HIT4Y6OI.js} +1 -1
  27. package/dist/chunks/{chunk-EZALDOQH.js → chunk-HP7JIYMT.js} +5 -2
  28. package/dist/chunks/{chunk-LADPYOWC.js → chunk-IAZ3UPY6.js} +3 -3
  29. package/dist/chunks/{chunk-ZEDWSH32.js → chunk-IC62NFM5.js} +1 -1
  30. package/dist/chunks/{chunk-P26ZWSKU.js → chunk-KIHNAS25.js} +5 -2
  31. package/dist/chunks/{chunk-BIPYLLVS.js → chunk-N4M2DDFE.js} +15 -15
  32. package/dist/chunks/{chunk-QKNKR4RH.js → chunk-OF4S23UB.js} +4 -4
  33. package/dist/chunks/{chunk-JPRO6ER2.js → chunk-PC7VKEB5.js} +57 -60
  34. package/dist/chunks/{chunk-4PD5NWAX.js → chunk-PUQS5MWL.js} +2 -2
  35. package/dist/chunks/{chunk-2LV74IWP.js → chunk-Q4OYAQYH.js} +1 -1
  36. package/dist/chunks/{chunk-72CKAUAG.js → chunk-QVSWRLLU.js} +7 -5
  37. package/dist/chunks/{chunk-4RAE6JXP.js → chunk-TA7FXXJD.js} +6 -3
  38. package/dist/chunks/{chunk-GPMFD4RD.js → chunk-TXUG266F.js} +1 -1
  39. package/dist/chunks/{chunk-FOAA27U5.js → chunk-UFIT2UU3.js} +16 -4
  40. package/dist/chunks/{chunk-LUSPKZKY.js → chunk-UG5G54VL.js} +1 -0
  41. package/dist/chunks/{chunk-NIAJ5ZCG.js → chunk-UL5XUQ25.js} +5 -2
  42. package/dist/chunks/{chunk-FMPJJYYI.js → chunk-WRXSAVKO.js} +1 -1
  43. package/dist/chunks/{chunk-G4UR6NXN.js → chunk-WSF4NNMR.js} +3 -3
  44. package/dist/chunks/chunk-XHK4MDR5.js +2497 -0
  45. package/dist/chunks/{chunk-3KTFS4IA.js → chunk-XNIK66I4.js} +19 -9
  46. package/dist/chunks/{chunk-3SO6QL6U.js → chunk-YWX377BY.js} +5 -2
  47. package/dist/chunks/{chunk-BYATLLEF.js → chunk-Z3GDFVJR.js} +1 -1
  48. package/dist/chunks/{chunk-GHXCDPTM.js → chunk-Z7VYWPZV.js} +1 -1
  49. package/dist/chunks/{conflict-F2OMZRTO.js → conflict-ARLSZJ6V.js} +4 -3
  50. package/dist/chunks/{continuation-2CKSBLA6.js → continuation-3S37AUSH.js} +4 -3
  51. package/dist/chunks/{continuation-RN6PZN2M.js → continuation-3XLYYTKV.js} +4 -3
  52. package/dist/chunks/{continuation-HZIZRZBX.js → continuation-HFW2YT5S.js} +4 -3
  53. package/dist/chunks/{continuation-NLECEJPX.js → continuation-KI7DRRZN.js} +4 -3
  54. package/dist/chunks/{contract-5BETHRSG.js → contract-DNIIW5VJ.js} +13 -5
  55. package/dist/chunks/{cowork-3MN6EQQO.js → cowork-GMLRGVIW.js} +11 -4
  56. package/dist/chunks/{create-flow-5FQNNMVO.js → create-flow-J22BO65E.js} +8 -7
  57. package/dist/chunks/{ebuilder-form-SBHOYBUD.js → ebuilder-form-ANV2FHYV.js} +12 -7
  58. package/dist/chunks/{ehr-KMOJULKG.js → ehr-GSTGAIY3.js} +266 -24
  59. package/dist/chunks/{employee-SAK2QYXX.js → employee-22BGJ3QS.js} +3 -3
  60. package/dist/chunks/{env-LB7NBL2O.js → env-BX3VRFS7.js} +4 -3
  61. package/dist/chunks/{esb-W2PJCFCX.js → esb-ATAIASX2.js} +12 -7
  62. package/dist/chunks/{factory-6ZFQXQ46.js → factory-PETTFME6.js} +3 -2
  63. package/dist/chunks/{fna-ZQPCUV4R.js → fna-YEKBSFSX.js} +14 -8
  64. package/dist/chunks/{group-chat-2HHAJN46.js → group-chat-BFVXAYFX.js} +5 -4
  65. package/dist/chunks/{host-ATKVNZAT.js → host-HRBXEPDQ.js} +5 -5
  66. package/dist/chunks/{host-BQH22NTQ.js → host-LR55CTHP.js} +5 -5
  67. package/dist/chunks/{host-X2CSLFM6.js → host-SUOY6VYQ.js} +5 -5
  68. package/dist/chunks/{host-4CBHGOHT.js → host-SZGV4UNT.js} +5 -5
  69. package/dist/chunks/{host-YTODKMSL.js → host-WIKN2EJ5.js} +5 -5
  70. package/dist/chunks/{hrm-FFM4UJFS.js → hrm-NRDO4W5G.js} +11 -7
  71. package/dist/chunks/{im-VEHKDQPB.js → im-IQ2HN23S.js} +8 -7
  72. package/dist/chunks/{invoice-LVIKSIIF.js → invoice-MNRW76PP.js} +636 -1768
  73. package/dist/chunks/{jiuchuanhui-X6DINO5P.js → jiuchuanhui-DTRBAX4N.js} +14 -6
  74. package/dist/chunks/{lazy-dispatch-KSWTN5L6.js → lazy-dispatch-ZVWAI25B.js} +7 -6
  75. package/dist/chunks/{mail-VDKRGUD3.js → mail-ZVAUXOJA.js} +16 -14
  76. package/dist/chunks/{meeting-CLC6HP3Z.js → meeting-FEVPZ67S.js} +21 -14
  77. package/dist/chunks/{okr-CHG4OO3U.js → okr-SDH3E5RA.js} +12 -5
  78. package/dist/chunks/{operations-5QL3AECO.js → operations-62N6EP3C.js} +4 -3
  79. package/dist/chunks/{plan-XWR75667.js → plan-E35JFDI7.js} +12 -5
  80. package/dist/chunks/{project-5BXOOKMG.js → project-73QXBAB2.js} +11 -4
  81. package/dist/chunks/reception-UWZVACBN.js +1899 -0
  82. package/dist/chunks/{recruit-stage-DGMFNNDE.js → recruit-stage-4MAOCKFY.js} +320 -57
  83. package/dist/chunks/registry-IM5G23LS.js +24 -0
  84. package/dist/chunks/{registry-RHMW6ANW.js → registry-JDUS4E7D.js} +7 -6
  85. package/dist/chunks/{registry-7FFOXIAW.js → registry-KNKSCJNT.js} +7 -6
  86. package/dist/chunks/{registry-Z43434VG.js → registry-PO7SI256.js} +4 -4
  87. package/dist/chunks/{registry-OZSMDVPP.js → registry-PVUZQDDQ.js} +3 -3
  88. package/dist/chunks/{room-recommend-62H7ZQQ6.js → room-recommend-H7KLXA5R.js} +6 -5
  89. package/dist/chunks/{schedule-FNXKH3DQ.js → schedule-ESZIBAUO.js} +6 -5
  90. package/dist/chunks/{workflow-ADHKCAJK.js → workflow-CWJFJLQU.js} +13 -8
  91. package/dist/cmd/action.js +6 -0
  92. package/dist/cmd/identity/index.js +45 -0
  93. package/dist/cmd/index.js +2 -0
  94. package/dist/core/continuation-ttl.js +18 -0
  95. package/dist/core/error-codes.js +85 -0
  96. package/dist/core/logger.js +11 -0
  97. package/dist/index.js +37 -31
  98. package/dist/internal/e10/auth/commands.js +163 -8
  99. package/dist/internal/e10/auth/error-log.js +182 -0
  100. package/dist/internal/e10/auth/session.js +17 -3
  101. package/dist/internal/e10/auth-recovery.js +39 -12
  102. package/dist/internal/e10/context.js +17 -2
  103. package/dist/internal/skills/install.js +9 -1
  104. package/dist/shortcuts/archive/continuation.js +2 -1
  105. package/dist/shortcuts/archive/index.js +3 -0
  106. package/dist/shortcuts/archive/operations/confirm.js +2 -1
  107. package/dist/shortcuts/archive-oa/continuation.js +2 -1
  108. package/dist/shortcuts/archive-oa/index.js +2 -0
  109. package/dist/shortcuts/archive-oa/operations/confirm.js +2 -1
  110. package/dist/shortcuts/asset/continuation.js +2 -1
  111. package/dist/shortcuts/asset/index.js +2 -0
  112. package/dist/shortcuts/asset-idle/index.js +2 -0
  113. package/dist/shortcuts/blog/continuation.js +2 -1
  114. package/dist/shortcuts/blog/index.js +2 -0
  115. package/dist/shortcuts/caizhilian/continuation.js +2 -1
  116. package/dist/shortcuts/caizhilian/index.js +2 -0
  117. package/dist/shortcuts/caizhilian/operations/confirm.js +3 -2
  118. package/dist/shortcuts/calendar/continuation.js +2 -1
  119. package/dist/shortcuts/calendar/index.js +2 -0
  120. package/dist/shortcuts/calendar/operations/write.js +1 -1
  121. package/dist/shortcuts/contract/continuation.js +2 -1
  122. package/dist/shortcuts/contract/index.js +2 -0
  123. package/dist/shortcuts/contract/operations/write.js +2 -1
  124. package/dist/shortcuts/cowork/continuation.js +2 -1
  125. package/dist/shortcuts/cowork/index.js +2 -0
  126. package/dist/shortcuts/ebuilder-form/continuation.js +2 -1
  127. package/dist/shortcuts/ebuilder-form/index.js +2 -0
  128. package/dist/shortcuts/ebuilder-form/operations/write.js +3 -2
  129. package/dist/shortcuts/ehr/continuation.js +2 -1
  130. package/dist/shortcuts/ehr/index.js +2 -0
  131. package/dist/shortcuts/ehr/operations/attend-write.js +1 -1
  132. package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +182 -3
  133. package/dist/shortcuts/ehr/operations/recruit-position.js +134 -2
  134. package/dist/shortcuts/ehr/operations/recruit-write.js +1 -1
  135. package/dist/shortcuts/esb/continuation.js +2 -1
  136. package/dist/shortcuts/esb/index.js +2 -0
  137. package/dist/shortcuts/esb/operations/trigger.js +2 -1
  138. package/dist/shortcuts/fna/continuation.js +2 -1
  139. package/dist/shortcuts/fna/index.js +2 -0
  140. package/dist/shortcuts/fna/operations/invoice-writeoff.js +1 -1
  141. package/dist/shortcuts/fna/operations/loan.js +1 -1
  142. package/dist/shortcuts/hrm/index.js +2 -0
  143. package/dist/shortcuts/im/continuation.js +2 -1
  144. package/dist/shortcuts/index.js +5 -0
  145. package/dist/shortcuts/invoice/continuation.js +2 -1
  146. package/dist/shortcuts/invoice/index.js +14 -15
  147. package/dist/shortcuts/invoice/invoice-record.js +93 -0
  148. package/dist/shortcuts/invoice/manifest.js +190 -393
  149. package/dist/shortcuts/invoice/operations/add.js +2 -1
  150. package/dist/shortcuts/invoice/operations/delete.js +2 -1
  151. package/dist/shortcuts/invoice/operations/import.js +2 -1
  152. package/dist/shortcuts/invoice/operations/issuing-contract-detail.js +86 -0
  153. package/dist/shortcuts/invoice/operations/issuing-contracts.js +210 -0
  154. package/dist/shortcuts/invoice/operations/registry.js +17 -17
  155. package/dist/shortcuts/invoice/operations/reim-auto.js +4 -569
  156. package/dist/shortcuts/invoice/operations/reim.js +52 -341
  157. package/dist/shortcuts/invoice/operations/shared.js +21 -4
  158. package/dist/shortcuts/invoice/operations/update.js +2 -1
  159. package/dist/shortcuts/invoice/projection.js +10 -62
  160. package/dist/shortcuts/jiuchuanhui/continuation.js +2 -1
  161. package/dist/shortcuts/jiuchuanhui/index.js +2 -0
  162. package/dist/shortcuts/jiuchuanhui/operations/datajson.js +2 -1
  163. package/dist/shortcuts/jiuchuanhui/operations/esb.js +2 -1
  164. package/dist/shortcuts/mail/continuation.js +2 -1
  165. package/dist/shortcuts/mail/index.js +2 -0
  166. package/dist/shortcuts/mail/operations/mail-blacklist.js +1 -1
  167. package/dist/shortcuts/mail/operations/mail-contacts.js +1 -1
  168. package/dist/shortcuts/mail/operations/mail-send.js +1 -1
  169. package/dist/shortcuts/mail/operations/mail-sign.js +1 -1
  170. package/dist/shortcuts/mail/operations/mail-template.js +1 -1
  171. package/dist/shortcuts/meeting/continuation.js +2 -1
  172. package/dist/shortcuts/meeting/index.js +2 -0
  173. package/dist/shortcuts/meeting/operations/change.js +1 -1
  174. package/dist/shortcuts/meeting/operations/create.js +1 -1
  175. package/dist/shortcuts/meeting/operations/eb/create-flow.js +16 -7
  176. package/dist/shortcuts/meeting/operations/eb/decision.js +1 -1
  177. package/dist/shortcuts/meeting/operations/eb/factory.js +1 -1
  178. package/dist/shortcuts/meeting/operations/lifecycle.js +1 -1
  179. package/dist/shortcuts/meeting/operations/receipts.js +1 -1
  180. package/dist/shortcuts/meeting/operations/signs.js +1 -1
  181. package/dist/shortcuts/okr/continuation.js +2 -1
  182. package/dist/shortcuts/okr/index.js +2 -0
  183. package/dist/shortcuts/okr/operations/write.js +1 -1
  184. package/dist/shortcuts/plan/continuation.js +2 -1
  185. package/dist/shortcuts/plan/index.js +2 -0
  186. package/dist/shortcuts/plan/operations/write.js +1 -1
  187. package/dist/shortcuts/project/continuation.js +2 -1
  188. package/dist/shortcuts/project/index.js +2 -0
  189. package/dist/shortcuts/reception/constants.js +53 -0
  190. package/dist/shortcuts/reception/errors.js +54 -0
  191. package/dist/shortcuts/reception/host.js +125 -0
  192. package/dist/shortcuts/reception/index.js +198 -0
  193. package/dist/shortcuts/reception/manifest.js +177 -0
  194. package/dist/shortcuts/reception/operations/ask.js +71 -0
  195. package/dist/shortcuts/reception/operations/browsertool.js +58 -0
  196. package/dist/shortcuts/reception/operations/compose.js +129 -0
  197. package/dist/shortcuts/reception/operations/customparams.js +74 -0
  198. package/dist/shortcuts/reception/operations/doc.js +238 -0
  199. package/dist/shortcuts/reception/operations/docrender.js +36 -0
  200. package/dist/shortcuts/reception/operations/panels.js +179 -0
  201. package/dist/shortcuts/reception/operations/registry.js +26 -0
  202. package/dist/shortcuts/reception/operations/render-assets.js +184 -0
  203. package/dist/shortcuts/reception/operations/render.js +123 -0
  204. package/dist/shortcuts/reception/operations/runs.js +38 -0
  205. package/dist/shortcuts/reception/operations/schedule.js +127 -0
  206. package/dist/shortcuts/reception/operations/shared.js +196 -0
  207. package/dist/shortcuts/reception/operations/snapshot.js +68 -0
  208. package/dist/shortcuts/reception/operations/types.js +1 -0
  209. package/dist/shortcuts/reception/operations.js +33 -0
  210. package/dist/shortcuts/reception/upload.js +218 -0
  211. package/dist/shortcuts/recruit-stage/context.js +145 -33
  212. package/dist/shortcuts/recruit-stage/continuation.js +2 -1
  213. package/dist/shortcuts/recruit-stage/operations/jd-create.js +106 -17
  214. package/dist/shortcuts/recruit-stage/operations/resume-import.js +166 -10
  215. package/dist/shortcuts/workflow/continuation.js +2 -1
  216. package/dist/shortcuts/workflow/index.js +2 -0
  217. package/dist/shortcuts/workflow/operations/form.js +32 -8
  218. package/dist/shortcuts/workflow/operations/write.js +1 -1
  219. package/docs/_catalog.md +3 -0
  220. package/docs/agent-invoice.md +1 -1
  221. package/docs/archive-oa.md +1 -1
  222. package/docs/caizhilian.md +1 -1
  223. package/docs/calendar.md +1 -1
  224. package/docs/contract.md +1 -1
  225. package/docs/e10-auth.md +16 -0
  226. package/docs/ehr.md +2 -2
  227. package/docs/esb.md +1 -1
  228. package/docs/im.md +1 -1
  229. package/docs/invoice.md +8 -12
  230. package/docs/okr.md +1 -1
  231. package/docs/reception.md +119 -0
  232. package/package.json +1 -1
  233. package/scripts/clean.mjs +43 -2
  234. package/skill-template/business-info.json +18 -2
  235. package/skill-template/domains/caizhilian.md +1 -1
  236. package/skill-template/domains/reception-flow.md +18 -0
  237. package/skill-template/domains/yepiaotong.md +4 -7
  238. package/skills/weaver-e10-archive-oa/references/source-manifest.json +14 -14
  239. package/skills/weaver-e10-blog/references/blog-publish.md +1 -1
  240. package/skills/weaver-e10-blog/references/source-manifest.json +7 -7
  241. package/skills/weaver-e10-caizhilian/references/source-manifest.json +21 -21
  242. package/skills/weaver-e10-caizhilian/references/write-protocol.md +2 -2
  243. package/skills/weaver-e10-calendar/references/calendar-write.md +1 -1
  244. package/skills/weaver-e10-cowork/SKILL.md +1 -1
  245. package/skills/weaver-e10-ebuilder-form/SKILL.md +1 -1
  246. package/skills/weaver-e10-ebuilder-form/references/custom-api.md +1 -1
  247. package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +1 -1
  248. package/skills/weaver-e10-esb/SKILL.md +2 -2
  249. package/skills/weaver-e10-esb/references/source-manifest.json +22 -22
  250. package/skills/weaver-e10-esb/references/trigger.md +2 -2
  251. package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +1 -1
  252. package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +1 -1
  253. package/skills/weaver-e10-jinchengda/references/contract-request-write.md +1 -1
  254. package/skills/weaver-e10-jinchengda/references/source-manifest.json +29 -29
  255. package/skills/weaver-e10-jucailin/SKILL.md +1 -1
  256. package/skills/weaver-e10-jucailin/references/attend-write.md +2 -2
  257. package/skills/weaver-e10-jucailin/references/recruit-create.md +12 -3
  258. package/skills/weaver-e10-jucailin/references/recruit-write.md +1 -1
  259. package/skills/weaver-e10-meeting/SKILL.md +8 -6
  260. package/skills/weaver-e10-meeting/references/meeting-change.md +1 -1
  261. package/skills/weaver-e10-meeting/references/meeting-create.md +1 -1
  262. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +1 -1
  263. package/skills/weaver-e10-meeting/references/meeting-verification.md +1 -1
  264. package/skills/weaver-e10-okr/references/okr-align.md +1 -1
  265. package/skills/weaver-e10-okr/references/okr-keyresult.md +1 -1
  266. package/skills/weaver-e10-okr/references/okr-write.md +1 -1
  267. package/skills/weaver-e10-okr/references/source-manifest.json +8 -8
  268. package/skills/weaver-e10-plan/references/plan-report-write.md +1 -1
  269. package/skills/weaver-e10-plan/references/source-manifest.json +20 -20
  270. package/skills/weaver-e10-qiyecheng/references/loan-management.md +1 -1
  271. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +18 -18
  272. package/skills/weaver-e10-reception-flow/SKILL.md +173 -0
  273. 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
  274. package/skills/weaver-e10-reception-flow/data/fields-snapshot.json +213 -0
  275. package/skills/weaver-e10-reception-flow/references/browsertool.md +68 -0
  276. package/skills/weaver-e10-reception-flow/references/env-pitfalls.md +51 -0
  277. package/skills/weaver-e10-reception-flow/references/fields-snapshot.md +227 -0
  278. package/skills/weaver-e10-reception-flow/references/guide.md +179 -0
  279. package/skills/weaver-e10-reception-flow/scripts/locate.sh +14 -0
  280. package/skills/weaver-e10-reception-flow/scripts/render.py +724 -0
  281. package/skills/weaver-e10-recruit-stage/SKILL.md +9 -5
  282. package/skills/weaver-e10-recruit-stage/lib/recruit-xiaoe-file.mjs +1 -1
  283. package/skills/weaver-e10-recruit-stage/lib/xiaoe-session.mjs +66 -0
  284. package/skills/weaver-e10-recruit-stage/references/position-templates.md +202 -0
  285. package/skills/weaver-e10-recruit-stage/references/recruit-jd-create.md +22 -0
  286. package/skills/weaver-e10-recruit-stage/references/recruit-resume-import.md +14 -1
  287. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +6 -0
  288. package/skills/weaver-e10-shijingran/SKILL.md +5 -5
  289. package/skills/weaver-e10-shijingran/references/source-manifest.json +37 -36
  290. package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +2 -0
  291. package/skills/weaver-e10-wenshuding/references/source-manifest.json +3 -3
  292. package/skills/weaver-e10-workflow/references/source-manifest.json +32 -32
  293. package/skills/weaver-e10-yepiaotong/SKILL.md +19 -26
  294. package/skills/weaver-e10-yepiaotong/references/invoice-detail.md +13 -10
  295. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +2 -0
  296. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +194 -155
  297. package/skills/weaver-e10-yepiaotong/references/invoice-output-view.md +28 -32
  298. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +5 -1
  299. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +8 -10
  300. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +211 -616
  301. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +149 -117
  302. package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +17 -20
  303. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +20 -39
  304. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +55 -22
  305. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -17
  306. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +88 -92
  307. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +144 -354
  308. package/skills/weaver-e10-yimiaoban/SKILL.md +1 -1
  309. package/skills/weaver-e10-yimiaoban/references/msg-write.md +1 -1
  310. package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +1 -1
  311. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +7 -7
  312. package/dist/chunks/chunk-TTPJJJC4.js +0 -465
  313. package/dist/chunks/registry-BKBZPBAJ.js +0 -23
  314. package/dist/shortcuts/invoice/markdown.js +0 -172
  315. package/dist/shortcuts/invoice/operations/issuing-qys.js +0 -424
  316. package/skills/weaver-e10-meeting.zip +0 -0
  317. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +0 -131
  318. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +0 -179
@@ -1,172 +0,0 @@
1
- import { invoiceValidationError } from './errors.js';
2
- export const OUTPUT_FORMATS = ['json', 'markdown'];
3
- /** 支持 markdown 渲染的 operation 及其固定视图(渲染档自带字段口径)。 */
4
- const MARKDOWN_VIEWS = {
5
- 'invoice.list': 'summary',
6
- 'invoice.enterprise.list': 'summary',
7
- 'invoice.get': 'detail',
8
- };
9
- export const MARKDOWN_OPERATIONS = new Set(Object.keys(MARKDOWN_VIEWS));
10
- export function normalizeFormat(value) {
11
- if (value === undefined || value === null || value === '')
12
- return undefined;
13
- const format = String(value).trim();
14
- if (!OUTPUT_FORMATS.includes(format)) {
15
- throw invoiceValidationError('format_invalid', `--format 只支持 ${OUTPUT_FORMATS.join(' / ')}`);
16
- }
17
- return format;
18
- }
19
- /** 该 operation 在 markdown 档下使用的语义视图。 */
20
- export function markdownViewFor(operation) {
21
- const view = MARKDOWN_VIEWS[operation];
22
- if (!view) {
23
- throw invoiceValidationError('format_unsupported', `${operation} 不支持 --format markdown(仅 ${[...MARKDOWN_OPERATIONS].join('、')})`);
24
- }
25
- return view;
26
- }
27
- export function assertMarkdownSupported(operation, format) {
28
- if (format === 'markdown')
29
- markdownViewFor(operation);
30
- }
31
- function text(value) {
32
- if (value === undefined || value === null)
33
- return '';
34
- return String(value).replace(/^\uFEFF/u, '').trim();
35
- }
36
- /** markdown 表格里不能出现裸 `|` 和换行,否则列会错位。 */
37
- function cell(value, fallback = '—') {
38
- const raw = text(value);
39
- if (!raw)
40
- return fallback;
41
- return raw.replace(/\|/gu, '\\|').replace(/\r?\n/gu, ' ');
42
- }
43
- /** 金额统一带千分位与两位小数;非数值原样返回,缺值给 `—`。 */
44
- function money(value) {
45
- const raw = text(value);
46
- if (!raw)
47
- return '—';
48
- const num = Number(raw);
49
- if (!Number.isFinite(num))
50
- return raw;
51
- const [int, frac = ''] = Math.abs(num).toFixed(2).split('.');
52
- return `${num < 0 ? '-' : ''}¥${int.replace(/\B(?=(\d{3})+(?!\d))/gu, ',')}.${frac}`;
53
- }
54
- function shortType(value) {
55
- const raw = text(value);
56
- if (!raw)
57
- return '—';
58
- if (raw.includes('专用'))
59
- return '专票';
60
- if (raw.includes('普通'))
61
- return '普票';
62
- return raw;
63
- }
64
- function scopeLabel(scope) {
65
- if (scope === 'enterprise')
66
- return '企业票夹';
67
- if (scope === 'personal')
68
- return '个人票夹';
69
- return '票夹';
70
- }
71
- function reimCell(item) {
72
- const requests = Array.isArray(item.reimRequests) ? item.reimRequests.filter(Boolean) : [];
73
- if (!requests.length)
74
- return '未挂单';
75
- return `已挂单→${requests.map((name) => text(name)).join('、')}`;
76
- }
77
- function linkCell(record) {
78
- const number = text(record.number);
79
- const url = text(record.detailUrl);
80
- if (!number)
81
- return '—';
82
- return url ? `[${number}](${url})` : number;
83
- }
84
- function renderList(operation, data) {
85
- const items = Array.isArray(data.items) ? data.items : [];
86
- const lines = [];
87
- const scope = operation === 'invoice.enterprise.list' ? 'enterprise' : data.scope;
88
- const head = [`**${scopeLabel(scope)} · 共 ${text(data.total) || items.length} 张 · 合计 ${money(data.totalAmount)}**`];
89
- const pageNote = `本页 ${items.length} 条${data.hasMore ? ',还有更多' : ''}`;
90
- lines.push(`${head[0]}(${pageNote})`);
91
- if (data.totalAmountExcludingTax !== undefined) {
92
- lines.push(`不含税合计 ${money(data.totalAmountExcludingTax)}`);
93
- }
94
- lines.push('');
95
- lines.push('| # | 发票号码 | 开票日期 | 票种 | 价税合计 | 购方 | 销方 | 报销 |');
96
- lines.push('| --- | --- | --- | --- | --- | --- | --- | --- |');
97
- if (!items.length) {
98
- lines.push('| — | — | — | — | — | — | — | — |');
99
- return lines.join('\n');
100
- }
101
- items.forEach((item, index) => {
102
- const record = item && typeof item === 'object' ? item : {};
103
- lines.push([
104
- '',
105
- index + 1,
106
- linkCell(record),
107
- cell(record.date),
108
- shortType(record.typeName),
109
- money(record.total),
110
- cell(record.buyer),
111
- cell(record.payer),
112
- cell(reimCell(record), '未挂单'),
113
- '',
114
- ].join(' | ').trim());
115
- });
116
- return lines.join('\n');
117
- }
118
- function renderDetail(data) {
119
- const items = Array.isArray(data.items) ? data.items : [];
120
- if (!items.length)
121
- return '未查到发票详情。';
122
- return items.map((item) => {
123
- const record = item && typeof item === 'object' ? item : {};
124
- const numberCell = linkCell(record);
125
- const title = numberCell === '—' ? (text(record.fid) || '发票') : numberCell;
126
- const lines = [];
127
- // 号码本身即详情页入口(title 已带链接),不再单列一行 [打开详情]。
128
- lines.push(`**${title}** · ${cell(record.typeName, '未知票种')}`);
129
- lines.push('');
130
- lines.push('| 项目 | 值 |');
131
- lines.push('| --- | --- |');
132
- const rows = [
133
- // 发票号码/代码放在首两行:票面标识必须出现在「项目」列里,便于核对与复制;
134
- // 号码带 detailUrl 超链接,点击直达 E10 发票详情页。
135
- // 数电票(全电发票)没有发票代码,空值按 — 显示,不要伪造。
136
- ['发票号码', numberCell],
137
- ['发票代码', cell(record.code)],
138
- ['开票日期', cell(record.date)],
139
- ['不含税金额', money(record.amount)],
140
- ['税额', money(record.taxAmount)],
141
- ['价税合计', money(record.total)],
142
- ['销方', cell(record.payer)],
143
- ['购方', cell(record.buyer)],
144
- ['费用说明', cell(record.expenseNote)],
145
- ['开票人', cell(record.issuer)],
146
- ['查验标记', checkStateText(record.checkState)],
147
- ['报销', reimCell(record)],
148
- ['附件', attachmentText(record.attachments)],
149
- ];
150
- for (const [label, value] of rows)
151
- lines.push(`| ${label} | ${value} |`);
152
- return lines.join('\n');
153
- }).join('\n\n---\n\n');
154
- }
155
- /** `checkState` 是查验标记(0=未做过查验登记),措辞必须与票面 valid 区分开。 */
156
- function checkStateText(value) {
157
- if (value === undefined || value === null)
158
- return '—';
159
- return Number(value) === 0 ? '未查验(0)' : `已查验(${text(value)})`;
160
- }
161
- function attachmentText(attachments) {
162
- const list = Array.isArray(attachments) ? attachments : [];
163
- if (!list.length)
164
- return '无';
165
- return `${list.length} 个:${list.map((entry) => text(entry?.name) || text(entry?.id) || '未命名').join('、')}`;
166
- }
167
- /** 渲染入口:按 operation 选择模板。data 必须是投影后的语义视图。 */
168
- export function renderInvoiceMarkdown(operation, data) {
169
- const view = markdownViewFor(operation);
170
- const body = view === 'detail' ? renderDetail(data) : renderList(operation, data);
171
- return `${body}\n`;
172
- }
@@ -1,424 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { InvoiceCliError, invoiceValidationError } from '../errors.js';
3
- import { asNonEmptyString, assertBusinessSuccess } from './shared.js';
4
- const LEDGER_PATH = '/api/ebuilder/form/list/getListDatas';
5
- const LEDGER_LIST_ID = '1201416963938369627';
6
- const LEDGER_PASS_ID = '1201416959744065575';
7
- const LEDGER_APP_ID = '846297243998732291';
8
- const LEDGER_MENU_ID = '5416292802968839298';
9
- /** urlPageTitle:合同商品信息 */
10
- const LEDGER_PAGE_TITLE = '5ZCI5ZCM5ZWG5ZOB5L+h5oGv';
11
- const LEDGER_PAGE_SIZE = 50;
12
- const LEDGER_MAX_PAGES = 40;
13
- /** 待开票合同数据:数据 key → 可读字段。含契约锁、泛微及其他合同。 */
14
- export const QYS_LEDGER_FIELDS = [
15
- { id: '1314988311673275798', key: 'contractNo', label: '合同号', kind: 'text' },
16
- { id: '1314988311673275801', key: 'contractFlow', label: '合同审批流程', kind: 'relation' },
17
- { id: '1314988311673275775', key: 'contractCategory', label: '合同种类', kind: 'text' },
18
- { id: '1314988311673275790', key: 'productType', label: '产品类型', kind: 'option' },
19
- { id: '1314988311673275776', key: 'productTypeDetail', label: '产品类型明细', kind: 'text' },
20
- { id: '1314988311673275783', key: 'accountingCompany', label: '核算公司', kind: 'option' },
21
- { id: '1314988311673275784', key: 'invoiceGroupFlag', label: '开票分组标识', kind: 'number' },
22
- { id: '1314988311673275793', key: 'sourceFlag', label: '来源标识', kind: 'text' },
23
- { id: '1314988311673275808', key: 'flowDetailId', label: '流程明细的id', kind: 'text' },
24
- { id: '1314988311673275781', key: 'invoiceType', label: '发票类型', kind: 'option' },
25
- { id: '1314988311673275806', key: 'purchaserName', label: '购买方名称', kind: 'text' },
26
- { id: '1314988311673275807', key: 'purchaserTaxNo', label: '购买方税号', kind: 'text' },
27
- { id: '1314988311673275809', key: 'purchaserAddress', label: '购买方地址', kind: 'text' },
28
- { id: '1314988311673275810', key: 'purchaserTel', label: '购买方电话', kind: 'text' },
29
- { id: '1314988311673275811', key: 'purchaserBankName', label: '购买方开户行', kind: 'text' },
30
- { id: '1314988311673275802', key: 'purchaserBankAccount', label: '购买方开户行账号', kind: 'text' },
31
- { id: '1314988311673275800', key: 'invoiceItemName', label: '开票名称', kind: 'text' },
32
- { id: '1314988311673275799', key: 'goodsName', label: '商品名称', kind: 'text' },
33
- { id: '1314988311673275803', key: 'revenueCode', label: '商品税收分类编码', kind: 'text' },
34
- { id: '1314988311673275804', key: 'taxRate', label: '商品税率', kind: 'relation' },
35
- { id: '1314988311673275780', key: 'specification', label: '规格型号', kind: 'text' },
36
- { id: '1314988311673275785', key: 'unit', label: '单位', kind: 'text' },
37
- { id: '1314988311673275805', key: 'quantity', label: '商品数量', kind: 'number' },
38
- { id: '1314988311673275794', key: 'unitPrice', label: '商品单价', kind: 'money' },
39
- { id: '1314988311673275795', key: 'amount', label: '开票金额', kind: 'money' },
40
- { id: '1314988311673275789', key: 'uninvoicedAmount', label: '未开票金额', kind: 'money' },
41
- { id: '1314988311673275787', key: 'invoicedAmount', label: '已开票金额', kind: 'money' },
42
- { id: '1314988311673275788', key: 'invoicingAmount', label: '开票中金额', kind: 'money' },
43
- { id: '1314988311673275777', key: 'amountDiffers', label: '开票金额存在差异', kind: 'option' },
44
- { id: '1314988311673275796', key: 'thirdPartyPurchase', label: '是否三方采购商品', kind: 'option' },
45
- { id: '1314988311673275812', key: 'invoiceNo', label: '发票号码', kind: 'text' },
46
- { id: '1314988311673275797', key: 'invoiceFlow', label: '开票流程ID', kind: 'relation' },
47
- { id: '1314988311673275791', key: 'invoiceDate', label: '开票时间', kind: 'date' },
48
- { id: '1314988311673275792', key: 'discarded', label: '是否废弃', kind: 'option' },
49
- { id: '1314988311673275778', key: 'discardedDate', label: '废弃时间', kind: 'date' },
50
- { id: '1314988311673275779', key: 'contactName', label: '客户联系人', kind: 'text' },
51
- { id: '1314988311673275782', key: 'contactPhone', label: '客户联系人电话', kind: 'text' },
52
- { id: '1314988311673275786', key: 'contactEmail', label: '客户联系人邮箱', kind: 'text' },
53
- ];
54
- function textValue(value) {
55
- if (value === undefined || value === null)
56
- return null;
57
- const text = String(value);
58
- return text.trim() === '' ? null : text;
59
- }
60
- function optionValue(value) {
61
- const first = Array.isArray(value) ? value[0] : value;
62
- if (!first || typeof first !== 'object')
63
- return null;
64
- const item = first;
65
- const id = textValue(item.id);
66
- const name = textValue(item.name);
67
- if (id === null && name === null)
68
- return null;
69
- return { id: id ?? '', name: name ?? '' };
70
- }
71
- export function convertQysLedgerRow(raw) {
72
- const formDataId = textValue(raw.form_data_id) ?? textValue(raw.id);
73
- if (!formDataId)
74
- throw invoiceValidationError('ledger_row_invalid', '台账行缺少 form_data_id');
75
- const row = {
76
- formDataId,
77
- title: textValue(raw.name),
78
- dataStatus: optionValue(raw.data_status)?.name ?? null,
79
- };
80
- for (const field of QYS_LEDGER_FIELDS) {
81
- const value = raw[field.id];
82
- row[field.key] = field.kind === 'option' || field.kind === 'relation' ? optionValue(value) : textValue(value);
83
- }
84
- return row;
85
- }
86
- function toCents(value, name) {
87
- if (value === null || !/^\d+(?:\.\d{1,2})?$/u.test(value)) {
88
- throw invoiceValidationError('ledger_amount_invalid', `${name} 必须是最多两位小数的非负金额,当前值:${value ?? '空'}`);
89
- }
90
- const [whole, fraction = ''] = value.split('.');
91
- return Number(whole) * 100 + Number(fraction.padEnd(2, '0'));
92
- }
93
- function formatCents(cents) {
94
- return `${Math.floor(cents / 100)}.${String(cents % 100).padStart(2, '0')}`;
95
- }
96
- function isPositiveCents(value) {
97
- return value !== null && /^\d+(?:\.\d+)?$/u.test(value) && Number(value) > 0;
98
- }
99
- /** 已开票、开票中或已废弃的行不能再开票,返回原因;可开票时返回空数组。 */
100
- export function qysRowBlockers(row) {
101
- const blockers = [];
102
- if (row.invoiceNo)
103
- blockers.push(`已有发票号码 ${row.invoiceNo}`);
104
- if (row.invoiceFlow)
105
- blockers.push(`已关联开票流程 ${row.invoiceFlow.name || row.invoiceFlow.id}`);
106
- if (isPositiveCents(row.invoicingAmount))
107
- blockers.push(`开票中金额 ${row.invoicingAmount}`);
108
- if (row.discarded?.name === '是' || row.discardedDate)
109
- blockers.push('已废弃');
110
- return blockers;
111
- }
112
- function parseSpan(value) {
113
- if (typeof value === 'string' && value.trim().startsWith('[')) {
114
- try {
115
- return optionValue(JSON.parse(value));
116
- }
117
- catch {
118
- return null;
119
- }
120
- }
121
- return optionValue(value);
122
- }
123
- function cellText(data, display, key) {
124
- const raw = data[key] !== undefined && data[key] !== null && data[key] !== '' ? data[key] : display[key];
125
- return textValue(raw);
126
- }
127
- function moneyText(data, display, key) {
128
- const text = cellText(data, display, key);
129
- return text === null ? null : text.replace(/,/g, '');
130
- }
131
- /** 获取待开票合同数据:getListDatas 的 data / displayData 行,转成与旧列表相同的可读字段。 */
132
- export function convertPendingLedgerRow(data, display = {}) {
133
- const formDataId = textValue(data.form_data_id) ?? textValue(data.id);
134
- if (!formDataId)
135
- throw invoiceValidationError('ledger_row_invalid', '台账行缺少 form_data_id');
136
- const statusText = textValue(display.data_status);
137
- return {
138
- formDataId,
139
- title: textValue(data.name) ?? textValue(display.name),
140
- dataStatus: statusText && !/^\d+$/u.test(statusText) ? statusText : null,
141
- contractNo: cellText(data, display, 'hth'),
142
- contractFlow: parseSpan(display.htsplcSpan),
143
- contractCategory: cellText(data, display, 'htzl'),
144
- productType: parseSpan(display.cplxSpan),
145
- productTypeDetail: cellText(data, display, 'cplxmx'),
146
- accountingCompany: parseSpan(display.hsgs_idSpan),
147
- invoiceGroupFlag: cellText(data, display, 'kpfzbs'),
148
- sourceFlag: cellText(data, display, 'lybs'),
149
- flowDetailId: cellText(data, display, 'lcmxid'),
150
- invoiceType: parseSpan(display.fplxSpan),
151
- purchaserName: cellText(data, display, 'gmfmc'),
152
- purchaserTaxNo: cellText(data, display, 'gmfsh'),
153
- purchaserAddress: cellText(data, display, 'gmfdz'),
154
- purchaserTel: cellText(data, display, 'gmfdh'),
155
- purchaserBankName: cellText(data, display, 'gmfkhx'),
156
- purchaserBankAccount: cellText(data, display, 'gmfkhxzh'),
157
- invoiceItemName: cellText(data, display, 'kpmc'),
158
- goodsName: cellText(data, display, 'spmc'),
159
- revenueCode: cellText(data, display, 'spshflbm'),
160
- taxRate: parseSpan(display.spslSpan),
161
- specification: cellText(data, display, 'ggxh'),
162
- unit: cellText(data, display, 'dw'),
163
- quantity: cellText(data, display, 'spslkwk'),
164
- unitPrice: moneyText(data, display, 'spdjkwk'),
165
- amount: moneyText(data, display, 'kpje'),
166
- uninvoicedAmount: moneyText(data, display, 'wkpje'),
167
- invoicedAmount: moneyText(data, display, 'ykpje'),
168
- invoicingAmount: moneyText(data, display, 'kpzje'),
169
- amountDiffers: parseSpan(display.kpjeczcySpan),
170
- thirdPartyPurchase: parseSpan(display.sfsfcgSpan),
171
- invoiceNo: cellText(data, display, 'fphm'),
172
- invoiceFlow: parseSpan(display.kplcidSpan),
173
- invoiceDate: cellText(data, display, 'kpsj'),
174
- discarded: parseSpan(display.sfzfSpan),
175
- discardedDate: cellText(data, display, 'zfsj'),
176
- contactName: cellText(data, display, 'khlxr'),
177
- contactPhone: cellText(data, display, 'khlxdh'),
178
- contactEmail: cellText(data, display, 'khlxyx'),
179
- };
180
- }
181
- async function fetchLedgerPage(host, pageNo, tableuid, operation) {
182
- const result = await host.invoiceRequest({
183
- path: LEDGER_PATH,
184
- query: { passid: LEDGER_PASS_ID, cid: LEDGER_PASS_ID },
185
- headers: { ebbusinessid: LEDGER_LIST_ID },
186
- operation,
187
- body: {
188
- current: pageNo,
189
- pageSize: LEDGER_PAGE_SIZE,
190
- requiredMatch: 1,
191
- tableuid,
192
- mapResult: '1',
193
- recheckQuery: '1',
194
- cusMenuId: LEDGER_MENU_ID,
195
- urlPageTitle: LEDGER_PAGE_TITLE,
196
- [`appId_${LEDGER_LIST_ID}`]: LEDGER_APP_ID,
197
- searchParamData: {
198
- searchType: '3',
199
- quickSearchFields: {},
200
- commonSearchFields: {},
201
- type: 'and',
202
- groupFields: {},
203
- },
204
- listId: LEDGER_LIST_ID,
205
- isFollow: 0,
206
- isShareToMe: 0,
207
- filterCondition: {},
208
- browser: 'Chrome',
209
- },
210
- });
211
- assertBusinessSuccess(result, 'qys_ledger_query_failed', '获取待开票合同数据失败');
212
- const payload = result?.data;
213
- const dataRows = payload?.data;
214
- const displayRows = payload?.displayData;
215
- if (!Array.isArray(dataRows) || !Array.isArray(displayRows)) {
216
- throw new InvoiceCliError('api', 'qys_ledger_query_failed', '获取待开票合同数据的返回缺少 data.data 或 data.displayData', { exitCode: 1 });
217
- }
218
- return dataRows.map((data, index) => ({
219
- data,
220
- display: displayRows[index] && typeof displayRows[index] === 'object' ? displayRows[index] : {},
221
- }));
222
- }
223
- /** total / hasMore 不可靠,按本页未取满或出现重复行结束。 */
224
- async function scanLedger(host, operation, visit) {
225
- const tableuid = randomUUID().replace(/-/g, '');
226
- const seen = new Set();
227
- let scanned = 0;
228
- for (let pageNo = 1; pageNo <= LEDGER_MAX_PAGES; pageNo += 1) {
229
- const page = await fetchLedgerPage(host, pageNo, tableuid, operation);
230
- let fresh = 0;
231
- for (const pair of page) {
232
- const row = convertPendingLedgerRow(pair.data, pair.display);
233
- if (seen.has(row.formDataId))
234
- continue;
235
- seen.add(row.formDataId);
236
- fresh += 1;
237
- scanned += 1;
238
- if (visit(row))
239
- return { scanned, complete: true };
240
- }
241
- if (page.length < LEDGER_PAGE_SIZE || fresh === 0)
242
- return { scanned, complete: true };
243
- }
244
- return { scanned, complete: false };
245
- }
246
- function matchesKeyword(row, keyword) {
247
- const haystack = [row.contractNo, row.purchaserName, row.contractFlow?.name, row.goodsName, row.invoiceItemName, row.formDataId];
248
- return haystack.some((value) => typeof value === 'string' && value.includes(keyword));
249
- }
250
- /**
251
- * 台账常把开户行名称和账号一起写进「购买方开户行账号」(如 `招商银行福田支行 8135 8668 8310 001`)。
252
- * 拆成名称与账号两段:账号取末尾(或开头)连续的数字段,原样保留其中的空格和连字符。
253
- */
254
- export function splitBankNameAndAccount(bankName, bankAccount) {
255
- const name = (bankName ?? '').trim();
256
- const account = (bankAccount ?? '').trim();
257
- const trailing = /^(.*?[^\d\s-])\s*(\d[\d\s-]*\d)$/u.exec(account);
258
- const leading = trailing ? null : /^(\d[\d\s-]*\d)\s*([^\d\s-].*)$/u.exec(account);
259
- const rawText = trailing ? trailing[1] : leading ? leading[2] : '';
260
- const textPart = rawText
261
- .replace(/[\s,,;;::]*(?:银行账号|银行帐号|账号|帐号|账户|帐户)?[\s,,;;::]*$/u, '')
262
- .replace(/^[\s,,;;::]*(?:开户行|开户银行)?[\s,,;;::]*/u, '')
263
- .trim();
264
- const digitPart = trailing ? trailing[2] : leading ? leading[1] : '';
265
- if (!textPart || !digitPart)
266
- return { bankName: name, bankAccount: account, split: false };
267
- return { bankName: name || textPart, bankAccount: digitPart, split: true };
268
- }
269
- export function isSpecialInvoiceTypeName(name) {
270
- return name.includes('专票') || name.includes('专用发票');
271
- }
272
- /** 一张开票流程对应一个“合同号 + 购方”分组;金额只累计可开票行。 */
273
- export class QysLedgerGrouper {
274
- groups = new Map();
275
- add(row, blocked) {
276
- const contractNo = row.contractNo ?? '';
277
- const purchaserName = row.purchaserName ?? '';
278
- const key = `${contractNo}|${purchaserName}`;
279
- let group = this.groups.get(key);
280
- if (!group) {
281
- group = {
282
- contractNo,
283
- contractFlowId: row.contractFlow?.id ?? '',
284
- contractFlowName: row.contractFlow?.name ?? '',
285
- purchaserName,
286
- purchaserTaxNos: new Set(),
287
- invoiceTypes: new Set(),
288
- goodsNames: new Set(),
289
- taxRates: new Set(),
290
- specifications: new Set(),
291
- sellerNames: new Set(),
292
- bankName: null,
293
- bankAccount: null,
294
- formDataIds: [],
295
- amountCents: 0,
296
- invalidAmountRows: [],
297
- blockedRows: 0,
298
- };
299
- this.groups.set(key, group);
300
- }
301
- if (row.accountingCompany?.name)
302
- group.sellerNames.add(row.accountingCompany.name);
303
- if (blocked) {
304
- group.blockedRows += 1;
305
- return;
306
- }
307
- group.formDataIds.push(row.formDataId);
308
- if (!group.contractFlowId && row.contractFlow) {
309
- group.contractFlowId = row.contractFlow.id;
310
- group.contractFlowName = row.contractFlow.name;
311
- }
312
- if (row.purchaserTaxNo)
313
- group.purchaserTaxNos.add(row.purchaserTaxNo);
314
- if (row.invoiceType?.name)
315
- group.invoiceTypes.add(row.invoiceType.name);
316
- const goodsName = row.invoiceItemName ?? row.goodsName;
317
- if (goodsName)
318
- group.goodsNames.add(goodsName);
319
- if (row.taxRate?.name)
320
- group.taxRates.add(row.taxRate.name);
321
- if (row.specification)
322
- group.specifications.add(row.specification);
323
- if (group.bankName === null && group.bankAccount === null && (row.purchaserBankName || row.purchaserBankAccount)) {
324
- group.bankName = row.purchaserBankName ?? null;
325
- group.bankAccount = row.purchaserBankAccount ?? null;
326
- }
327
- if (row.amount !== null && /^\d+(?:\.\d{1,2})?$/u.test(row.amount)) {
328
- group.amountCents += toCents(row.amount, '开票金额');
329
- }
330
- else {
331
- group.invalidAmountRows.push(row.formDataId);
332
- }
333
- }
334
- result(includeEmpty) {
335
- const output = [];
336
- for (const group of this.groups.values()) {
337
- if (!includeEmpty && group.formDataIds.length === 0)
338
- continue;
339
- const warnings = [];
340
- const specialTypes = [...group.invoiceTypes].filter(isSpecialInvoiceTypeName);
341
- const specialInvoiceWithoutTaxNo = group.purchaserTaxNos.size === 0 && specialTypes.length > 0;
342
- if (specialInvoiceWithoutTaxNo) {
343
- warnings.push(`购方无税号,不能开专票(台账发票类型:${specialTypes.join('、')}),请先在台账改为普票再发起`);
344
- }
345
- const bank = splitBankNameAndAccount(group.bankName, group.bankAccount);
346
- if (bank.split) {
347
- warnings.push(`台账「购买方开户行账号」混有开户行名称,已拆分为开户行名称「${bank.bankName}」、账号「${bank.bankAccount}」`);
348
- }
349
- if (!group.contractNo)
350
- warnings.push('台账行缺少合同号,无法按合同号发起开票流程');
351
- if (group.sellerNames.size > 1)
352
- warnings.push(`同组销售方(核算公司)不一致:${[...group.sellerNames].join('、')}`);
353
- if (group.invoiceTypes.size > 1)
354
- warnings.push(`同组发票类型不一致:${[...group.invoiceTypes].join('、')}`);
355
- if (group.purchaserTaxNos.size > 1)
356
- warnings.push(`同组购方税号不一致:${[...group.purchaserTaxNos].join('、')}`);
357
- if (group.invalidAmountRows.length)
358
- warnings.push(`开票金额无法识别,未计入合计:${group.invalidAmountRows.join('、')}`);
359
- if (group.blockedRows > 0) {
360
- warnings.push(`同合同另有 ${group.blockedRows} 行已开票、开票中或已废弃,流程联动可能一并带出,请在 E10 核对明细`);
361
- }
362
- output.push({
363
- contractNo: group.contractNo,
364
- contractFlowId: group.contractFlowId,
365
- contractFlowName: group.contractFlowName,
366
- purchaserName: group.purchaserName,
367
- purchaserTaxNo: [...group.purchaserTaxNos].join('、'),
368
- purchaserBankName: bank.bankName,
369
- purchaserBankAccount: bank.bankAccount,
370
- invoiceTypes: [...group.invoiceTypes],
371
- specialInvoiceWithoutTaxNo,
372
- goodsNames: [...group.goodsNames],
373
- taxRates: [...group.taxRates],
374
- specifications: [...group.specifications],
375
- sellerNames: [...group.sellerNames],
376
- rowCount: group.formDataIds.length,
377
- formDataIds: group.formDataIds,
378
- totalAmount: formatCents(group.amountCents),
379
- blockedRows: group.blockedRows,
380
- warnings,
381
- });
382
- }
383
- return output;
384
- }
385
- }
386
- export class InvoiceIssuingQysListOperation {
387
- name = 'invoice.issuing.qys.list';
388
- async execute(input, { host }) {
389
- const keyword = input.keyword === undefined || input.keyword === '' ? undefined : asNonEmptyString(input.keyword, 'keyword');
390
- const contractNo = input.contractNo === undefined || input.contractNo === '' ? undefined : asNonEmptyString(input.contractNo, 'contractNo');
391
- const includeIssued = input.includeIssued === true;
392
- const limit = input.limit === undefined ? 20 : Number(input.limit);
393
- if (!Number.isInteger(limit) || limit < 1 || limit > 100)
394
- throw invoiceValidationError('input_invalid', 'limit 必须是 1-100 的整数');
395
- const items = [];
396
- const grouper = new QysLedgerGrouper();
397
- let matched = 0;
398
- const scan = await scanLedger(host, this.name, (row) => {
399
- if (contractNo && row.contractNo !== contractNo)
400
- return false;
401
- if (keyword && !matchesKeyword(row, keyword))
402
- return false;
403
- const blockers = qysRowBlockers(row);
404
- grouper.add(row, blockers.length > 0);
405
- if (!includeIssued && blockers.length)
406
- return false;
407
- matched += 1;
408
- if (items.length < limit)
409
- items.push({ ...row, issuable: blockers.length === 0, blockers });
410
- return false;
411
- });
412
- return {
413
- status: 'COMPLETE',
414
- data: {
415
- items,
416
- groups: grouper.result(includeIssued),
417
- matched,
418
- truncated: matched > items.length,
419
- scanned: scan.scanned,
420
- scanComplete: scan.complete,
421
- },
422
- };
423
- }
424
- }
Binary file