weaver-work-cli 0.1.33 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{archive-FVFY6GZN.js → archive-PDV724YK.js} +5 -4
- package/dist/chunks/{archive-oa-NW3OD4UV.js → archive-oa-4XE4MNXQ.js} +4 -3
- package/dist/chunks/{asset-7QJKMIDV.js → asset-PDL2QE2N.js} +8 -7
- package/dist/chunks/{attachment-content-OSAVA6K3.js → attachment-content-MDDGOE5E.js} +3 -3
- package/dist/chunks/{blog-I7SDPNW4.js → blog-UYR3EUXW.js} +5 -4
- package/dist/chunks/{caizhilian-O37ZIQNY.js → caizhilian-LG2X5NMF.js} +5 -4
- package/dist/chunks/{calendar-7KXE4ED3.js → calendar-FG4BAZHE.js} +4 -3
- package/dist/chunks/{chunk-Q6LWB5HX.js → chunk-6FTTSA45.js} +4 -3
- package/dist/chunks/{chunk-MQ2I5AA3.js → chunk-6LTFIFLM.js} +3 -2
- package/dist/chunks/{chunk-WRRJ4GG2.js → chunk-CORFRD7Q.js} +4 -3
- package/dist/chunks/{chunk-WY74UBJ6.js → chunk-DMV2TOMH.js} +2194 -240
- package/dist/chunks/{chunk-MEEFGWTM.js → chunk-ELYDWBZJ.js} +135 -10
- package/dist/chunks/{chunk-EEWPQE3O.js → chunk-FUWVHMVV.js} +7 -6
- package/dist/chunks/{chunk-HEL5XTYI.js → chunk-GGJFMNJM.js} +26 -4
- package/dist/chunks/{chunk-KAS45KNR.js → chunk-IZUDA353.js} +1 -1
- package/dist/chunks/{chunk-2FLWXFVS.js → chunk-J7USS3ED.js} +4 -4
- package/dist/chunks/{chunk-IHUYP6LO.js → chunk-JSMFPO43.js} +1 -1
- package/dist/chunks/{chunk-RBGOMK4Y.js → chunk-KKRL3REV.js} +5 -4
- package/dist/chunks/{chunk-OCU4RLHC.js → chunk-NI6GIPIM.js} +195 -36
- package/dist/chunks/{chunk-PRHJGPMA.js → chunk-NR6RKXPA.js} +2 -2
- package/dist/chunks/{chunk-D223PTXU.js → chunk-OJQUJZQF.js} +33 -7
- package/dist/chunks/{chunk-ILMBNVSG.js → chunk-UJJD4QWF.js} +4 -3
- package/dist/chunks/{chunk-6ATGWRZM.js → chunk-UZZBA6PV.js} +177 -14
- package/dist/chunks/{chunk-GFPXQIY2.js → chunk-VRYHGG6O.js} +2 -2
- package/dist/chunks/{chunk-NHA62QD7.js → chunk-XJY7G4DD.js} +3 -3
- package/dist/chunks/{chunk-VBCFFFGT.js → chunk-Z32KWY6G.js} +4 -1
- package/dist/chunks/{conflict-SFNEVJY5.js → conflict-BQZEQ4SP.js} +2 -2
- package/dist/chunks/contract-XIRAFTEV.js +9111 -0
- package/dist/chunks/{cowork-CKWYHXYB.js → cowork-BLG62BL2.js} +46 -26
- package/dist/chunks/{ebuilder-form-KOLJRVZD.js → ebuilder-form-NUKG5QW4.js} +3 -3
- package/dist/chunks/{ehr-WFOC3B4D.js → ehr-2STW5ILH.js} +174 -10
- package/dist/chunks/{esb-LJZTN663.js → esb-UUDQUNKY.js} +4 -4
- package/dist/chunks/{fna-F7QRIIZC.js → fna-6RCY4NU5.js} +15 -9
- package/dist/chunks/{host-VQ6JJXGQ.js → host-7RXEDMAH.js} +3 -3
- package/dist/chunks/{host-KXPTEWFS.js → host-EJZFROU3.js} +3 -3
- package/dist/chunks/{host-BCGUVEWX.js → host-FWDOSRH5.js} +3 -3
- package/dist/chunks/{host-DGE2TZD4.js → host-RHM3NPXV.js} +3 -3
- package/dist/chunks/{host-BQBRHVR3.js → host-UFF33TWJ.js} +3 -3
- package/dist/chunks/{hrm-NI6XAKW5.js → hrm-PKJ6ELSH.js} +3 -3
- package/dist/chunks/{im-7TRTF3KT.js → im-YJAXS7CO.js} +3 -3
- package/dist/chunks/{invoice-AOXWJKYT.js → invoice-HWVSXGX6.js} +3 -3
- package/dist/chunks/{jiuchuanhui-7NQWEZAW.js → jiuchuanhui-L7VKILZB.js} +4 -3
- package/dist/chunks/{lazy-dispatch-RNS4EE4S.js → lazy-dispatch-NMYEIHRH.js} +4 -4
- package/dist/chunks/{mail-VDHJAB4O.js → mail-B42RRU7G.js} +46 -24
- package/dist/chunks/{meeting-GA7XCNNP.js → meeting-CFYVBJSS.js} +77 -12
- package/dist/chunks/{okr-TQIRERPQ.js → okr-GCLF6V7W.js} +4 -3
- package/dist/chunks/{plan-4RY4LN2P.js → plan-ZVL7GBRI.js} +4 -3
- package/dist/chunks/{project-D6XT2OC5.js → project-4YWAAE2K.js} +4 -3
- package/dist/chunks/{registry-QKMI43Q6.js → registry-EP4VTHZS.js} +8 -8
- package/dist/chunks/{registry-JHRIDQ3A.js → registry-FRJ6H7BT.js} +4 -4
- package/dist/chunks/{registry-VOGKFFTR.js → registry-SG2PGVCF.js} +2 -2
- package/dist/chunks/{room-recommend-D4EUOOWY.js → room-recommend-R3JVUUAC.js} +4 -4
- package/dist/chunks/{schedule-XPFBHPCV.js → schedule-NIJBTYDO.js} +4 -4
- package/dist/chunks/{workflow-HLBZRWIY.js → workflow-BB24DFBY.js} +11 -4
- package/dist/index.js +31 -26
- package/dist/internal/e10/auth-recovery.js +114 -1
- package/dist/internal/e10/client.js +16 -2
- package/dist/internal/e10/fetch-timing.js +31 -0
- package/dist/internal/e10/request-runtime.js +108 -7
- package/dist/shortcuts/archive/host.js +3 -2
- package/dist/shortcuts/archive-oa/host.js +2 -1
- package/dist/shortcuts/asset/host.js +6 -5
- package/dist/shortcuts/blog/host.js +3 -2
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +2 -1
- package/dist/shortcuts/cowork/host.js +10 -1
- package/dist/shortcuts/cowork/operations/types.js +17 -2
- package/dist/shortcuts/ebuilder-form/host.js +3 -1
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/ehr/operations/recruit-write.js +35 -0
- package/dist/shortcuts/ehr/operations/recruit.js +147 -0
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +2 -1
- package/dist/shortcuts/fna/operations/expense-chart.js +19 -7
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/invoice/host.js +5 -4
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +10 -1
- package/dist/shortcuts/mail/operations/types.js +17 -2
- package/dist/shortcuts/meeting/host.js +3 -2
- package/dist/shortcuts/meeting/index.js +79 -1
- package/dist/shortcuts/meeting/invitation/text.js +71 -0
- package/dist/shortcuts/meeting/manifest.js +10 -0
- package/dist/shortcuts/meeting/operations/eb/catalog.js +5 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +6 -1
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +2105 -169
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +161 -8
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +36 -2
- package/dist/shortcuts/meeting/operations/eb-fallback.js +4 -0
- package/dist/shortcuts/meeting/operations/env.js +6 -0
- package/dist/shortcuts/meeting/operations/invitation.js +200 -28
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/endpoints.js +8 -3
- package/dist/shortcuts/workflow/operations/form.js +341 -36
- package/dist/shortcuts/workflow/operations.js +23 -1
- package/docs/ehr.md +1 -1
- package/docs/fna.md +2 -1
- package/package.json +1 -1
- package/skill-template/business-info.json +18 -0
- package/skill-template/domains/cowork.md +14 -0
- package/skills/weaver-e10-cowork/SKILL.md +101 -0
- package/skills/weaver-e10-cowork/references/cowork-read.md +90 -0
- package/skills/weaver-e10-cowork/references/cowork-write.md +131 -0
- package/skills/weaver-e10-cowork/references/safety-boundaries.md +45 -0
- package/skills/weaver-e10-jucailin/SKILL.md +21 -3
- package/skills/weaver-e10-jucailin/references/recruit-read.md +25 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +13 -0
- package/skills/weaver-e10-jucailin/references/salary.md +15 -11
- package/skills/weaver-e10-mail/SKILL.md +12 -9
- package/skills/weaver-e10-meeting/SKILL.md +499 -300
- package/skills/weaver-e10-meeting/references/meeting-eb.md +334 -0
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +64 -6
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-qiyecheng/SKILL.md +5 -2
- package/skills/weaver-e10-qiyecheng/references/catalog.md +2 -2
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +15 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +22 -21
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
|
@@ -52,6 +52,29 @@
|
|
|
52
52
|
> 未传 `sign_time` / `signback_time` / `sign_out_status` 时按"补签"语义**自动补当前时间**(带秒)并写入 `warnings`,
|
|
53
53
|
> 实际写入值在 `preview.after` 里可见;要指定时间请显式传 `sign_time`(`yyyy-MM-dd HH:mm:ss`,带秒)。
|
|
54
54
|
|
|
55
|
+
## 会议室列表:按名称查询(2026-10-30)
|
|
56
|
+
|
|
57
|
+
`meeting.eb.room.list` 支持 `room_name`(以及 `status` / `place` / `org_id` / `hrm_ids`)过滤,
|
|
58
|
+
条件走 body 的 `datajson.mainTable`,count 与 list 用**同一份**条件。
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# 精确名 → 服务端直接命中,1 次请求
|
|
62
|
+
weaver-work-cli --json meeting run meeting.eb.room.list --input-json '{"room_name":"测试会议室1"}'
|
|
63
|
+
|
|
64
|
+
# 部分词 → 服务端精确匹配不到(0 条),CLI 自动翻页扫全量并按「包含」重筛
|
|
65
|
+
weaver-work-cli --json meeting run meeting.eb.room.list --input-json '{"room_name":"重庆"}'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
⚠️ 三个实测事实(e-cology 生产,2026-10-30):
|
|
69
|
+
|
|
70
|
+
1. **服务端是精确匹配,不是 like**:`room_name=测试会议室1` → 1 条;`room_name=测试` → 服务端 0 条。
|
|
71
|
+
所以传部分词时 CLI 会兜底翻页扫描(结果带 `progress.page.fallback = {pages, scanned}`),
|
|
72
|
+
实测 155 条扫完约 5 秒。传 `noFallback:true` 可跳过扫描(精确匹配不到就直接 0 条)。
|
|
73
|
+
2. **`pageSize` 服务端不生效,恒定回 10 条** —— 要全量只能翻页(兜底就是这么做的)。
|
|
74
|
+
⛔ 别把"本页 10 条"当成"总共 10 间"。
|
|
75
|
+
3. **列表 0 条不等于没有会议室**:2026-10-29 全天该接口为 0 条(应用侧视图配置问题),
|
|
76
|
+
10-30 下午租户把「会议室名称」配成传入字段后恢复到 155 条。
|
|
77
|
+
|
|
55
78
|
## 常用命令
|
|
56
79
|
|
|
57
80
|
Windows PowerShell:
|
|
@@ -758,3 +781,314 @@ video_taskResult 为空 且 parse_content 为空 → 未触
|
|
|
758
781
|
|
|
759
782
|
实测遇到两次(`update_mt_decision_task` 首次调用、EB 列表接口),**重试即成功**,且数据未被写坏。
|
|
760
783
|
判定方法:报这个错时先 `list` 回查;没写进去再重试一次,**不要连试三次以上**。
|
|
784
|
+
|
|
785
|
+
## 提交方式:默认直提(2.41.0 起,2026-10-31 真机事故)
|
|
786
|
+
|
|
787
|
+
小e 的浏览器填单页(`<browsertool>` + `params.customParams`)**只给文本类字段赋值**:
|
|
788
|
+
|
|
789
|
+
| 字段类型 | customParams 传过去的效果 |
|
|
790
|
+
|---|---|
|
|
791
|
+
| 文本 / 多行文本 / 日期 / 数字 | ✅ 正常带出 |
|
|
792
|
+
| 浏览按钮(会议地点) | 未单独核实(用户只报了人员和客户为空) |
|
|
793
|
+
| 浏览按钮(**参会人员**) | ❌ 表单里空着 |
|
|
794
|
+
| 客户浏览按钮(**参会客户**) | ❌ 表单里空着 |
|
|
795
|
+
|
|
796
|
+
所以"我明明说了参会人和客户,表单里一个都没有"不是 CLI 没传,而是**那一档页面不支持**。
|
|
797
|
+
2026-10-31 起 `meeting.eb.meeting.create.flow.quick / apply` **默认 `submit_mode=direct`**:
|
|
798
|
+
直接 `workflow.createRequest action=submit` 写服务端,实测(requestId `1332418264069103616`):
|
|
799
|
+
|
|
800
|
+
- `hrm_members` / `crm_members` 全部落库,`meeting.eb.meeting.detail --id <meetingId>` 回读可见
|
|
801
|
+
(人员回姓名文本「王丹丹」、客户回 id「1258347137804009474」);
|
|
802
|
+
- 会议当场生成(`meetingId` 有值)→ 邀请函 `invitation.pending=false`,是**真实会议数据版**,
|
|
803
|
+
不再有「客户单位」「召集人」这些【待补充】;
|
|
804
|
+
- 返回里有 `requestId` + `meetingId`,⛔ 判成功看这两个 id,不要看有没有 `finalMarkdown`。
|
|
805
|
+
|
|
806
|
+
`submit_mode=browser` 保留原行为(预填 + 用户点提交),只在用户明确要求"自己核对表单"时用。
|
|
807
|
+
|
|
808
|
+
## 「召集人 / 联系人」缺省 = 当前登录人(2.43.0)
|
|
809
|
+
|
|
810
|
+
**为什么**:这两个字段以前只有显式传 `caller` / `contacter` 才有值,**换个人用(另一个账号)建会就整块空白** ——
|
|
811
|
+
流程单上看不出谁召集的,邀请函「召集人」落成【待补充】。现在默认"自己召集、自己联系"。
|
|
812
|
+
|
|
813
|
+
- 取 `session.userId` → `hrm.employee.batch` 换姓名 → 提交 `{id,name}`(Employee 组件要的形态);
|
|
814
|
+
- 各自独立兜底:只传了 `caller` 时,`contacter` 仍补当前登录人;显式传的值**一律不覆盖**;
|
|
815
|
+
- 返回 `preview.autoFilled = {"召集人":"卜伟领(4980…)","联系人":"卜伟领(4980…)"}` +
|
|
816
|
+
一条 warning「已按当前登录人补齐」;
|
|
817
|
+
- ⛔ 查不到姓名就**不填**(两个都缺时给 warning)—— 在 `userId ≠ 员工 id` 的租户里硬塞 id 会被服务端判
|
|
818
|
+
`NEEDS_CONFIRMATION`,提交直接卡住,比留空更糟。
|
|
819
|
+
|
|
820
|
+
真机实测(泛微生产 `e-cology.com.cn`,2026-10-31):`prepare` 里两个字段都是 `{id,name}`,
|
|
821
|
+
`apply` 后 `meetingId 1332426188317081604` 回读 `caller=卜伟领`、`contacter=卜伟领`,
|
|
822
|
+
邀请函正文「卜伟领 诚邀您参加…」。
|
|
823
|
+
|
|
824
|
+
## 提交前核对 & 客户联系人自动带入(2.44.0)
|
|
825
|
+
|
|
826
|
+
- `create.flow.prepare` 的 `preview.formPreview`:**人话 Markdown 表格**(字段名 → 值),
|
|
827
|
+
人员/客户都显示姓名不显示 id,空值 `—`。用途 = 替代走不通的浏览器填单核对环节:
|
|
828
|
+
**先贴给用户确认,再 apply/quick**。
|
|
829
|
+
- `create.flow.apply` / `quick` 的 `submittedPreview`:本次实际提交的字段表(同一渲染器),
|
|
830
|
+
提交后必须贴出来 —— 用户要「看得见填进去了什么」。
|
|
831
|
+
- 客户联系人**全自动**:传 `crm_members` 后,CLI 取该项的 `contacts`(`crm.search` 的 items 原样传过来就有),
|
|
832
|
+
没有就自己回查一次 `crm.search`,把**全部**联系人写成「参会客户明细」行
|
|
833
|
+
(`姓名` / `手机号码` / `备注=部门:X`)。要只留某几位才用 `crm_member_details` 覆盖。
|
|
834
|
+
- `meeting.eb.meeting.detail` 新增 `personnelText`(`caller`/`contacter`/`hrm_members`/`mt_creator`… → 姓名):
|
|
835
|
+
原字段是**原始存储值**(页面建单 = id、工作流建单 = 姓名文本),对外表述一律用 `personnelText`。
|
|
836
|
+
|
|
837
|
+
## 「参会客户」是 eBuilder 组件 —— 这是对的,别再劝人改表单(2.45.0 纠偏)
|
|
838
|
+
|
|
839
|
+
| 流程 | 「参会客户」字段 | 组件 |
|
|
840
|
+
| --- | --- | --- |
|
|
841
|
+
| 会议申请流程 `1326190634427154474`(文档里也写作「旧」) | `1332418251116929025` | `Ebuilder` |
|
|
842
|
+
| 会议申请流程(NEW)`1325677244111462606` | `1332437840406257666` | `Ebuilder` |
|
|
843
|
+
|
|
844
|
+
- ⛔ 2.44.0 及以前这里写的是「组件不吃客户值,要换回 Customer」——**这个判断是错的**(2026-10-31 用户纠正)。
|
|
845
|
+
同一张表单的「会议地点」也是 `Ebuilder`,一直写得进去;`Ebuilder` 就是吃 `{id,name}` 的浏览按钮。
|
|
846
|
+
- 流程单据 → 会议表的同步**由 ESB 动作流的字段映射负责**(2026-10-31 用户确认:「你发起流程后,
|
|
847
|
+
字段映射是靠 ESB 来的,这个我已经配置好了」),会议表那边落的是 `ufd_crm_members_new`。
|
|
848
|
+
⇒ **CLI 不再自己补写**会议表的 `crm_members`:那一列 dataKey 与页面字段不是同一个,
|
|
849
|
+
写它既不落页面、回读也永远为空,只会多出一条「客户没关联上」的假警报,把验收带偏。
|
|
850
|
+
需要回退旧行为时置 `WEAVER_MEETING_CRM_PATCH=1`(`patchMeetingCrmMembers` 仍在,只用于调试)。
|
|
851
|
+
- ⛔ 不要用会议表 `crm_members` 的空值判断客户有没有代进去;要看流程单据(`workflow.detail` 的
|
|
852
|
+
fieldValues 里带「客户名(id)」)或会议页面实际显示。
|
|
853
|
+
- 「参会客户明细」不受影响(普通明细表,姓名/手机照常落库)。
|
|
854
|
+
- `create.flow.prepare` 仍会按组件类型给一条说明(点名字段 id 与 `componentKey`),看到**照实转达**,
|
|
855
|
+
但**不要再建议改表单**。
|
|
856
|
+
|
|
857
|
+
## 流程建会字段:datakey(fieldId)固化
|
|
858
|
+
|
|
859
|
+
**为什么**:NEW 建会流程(`1325677244111462606`)的表单字段名带提示语 ——
|
|
860
|
+
`会议名称(请填写会议的具体名称)`、`开始时间(具体开始时间)`、`结束时间(具体结束时间)`。
|
|
861
|
+
按中文名**精确**匹配会全部落空,表现为 prepare 显示成功、但名称/时间实际没填进去(2026-10-30 真机踩到)。
|
|
862
|
+
现在两级兜底:① 归一化匹配(去掉括号提示语再比);② 解析结果按 workflowId 缓存成 datakey,之后直接用 id。
|
|
863
|
+
|
|
864
|
+
**泛微生产(www.e-cology.com.cn / t7akvdnf84)·「会议申请流程(NEW)」实测 datakey**:
|
|
865
|
+
|
|
866
|
+
| 语义键 | 表单字段 | datakey |
|
|
867
|
+
| --- | --- | --- |
|
|
868
|
+
| 会议名称 | 会议名称(请填写会议的具体名称) | 1325677252711735872 |
|
|
869
|
+
| 开始时间 | 开始时间(具体开始时间) | 1325677252711735890 |
|
|
870
|
+
| 结束时间 | 结束时间(具体结束时间) | 1325677252711735891 |
|
|
871
|
+
| 会议地点 | 会议地点 | 1325677252711735881 |
|
|
872
|
+
| 参会人员 | 参会人员 | 1325677252711735882 |
|
|
873
|
+
|
|
874
|
+
按 datakey 直接给值(绕过任何名字匹配,用 `fieldValues`):
|
|
875
|
+
|
|
876
|
+
```bash
|
|
877
|
+
weaver-work-cli --json meeting run meeting.eb.meeting.create.flow.prepare --input-json '{
|
|
878
|
+
"fieldValues": {
|
|
879
|
+
"1325677252711735872": "十一月开发进度沟通会",
|
|
880
|
+
"1325677252711735890": "2026-10-31 10:00",
|
|
881
|
+
"1325677252711735891": "2026-10-31 11:00",
|
|
882
|
+
"1325677252711735881": {"id":"1325772901753847972","name":"测试会议室1"},
|
|
883
|
+
"1325677252711735882": [{"id":"4980990112251498198","name":"卜伟领"}]
|
|
884
|
+
}
|
|
885
|
+
}'
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
⚠️ 浏览按钮类字段(会议地点 / 参会人员 / 召集人 / 联系人 / 会议类型)的值必须是 `{id,name}` 对象或数组,
|
|
889
|
+
纯文本会被服务端打回「请按名称选择」。
|
|
890
|
+
|
|
891
|
+
缓存文件:`~/.weaver-work-cli/meeting/cache/flow-fields-<workflowId>.json`。字段改名后仍按 datakey 填;
|
|
892
|
+
流程被重建、datakey 变了,删掉该文件让它重新解析即可。
|
|
893
|
+
|
|
894
|
+
## 查「CLI 到底有哪些能力」
|
|
895
|
+
|
|
896
|
+
```bash
|
|
897
|
+
weaver-work-cli meeting ops # 全部 135 项,纯文本、不压缩、按能力分组
|
|
898
|
+
weaver-work-cli meeting ops --grep suggest # 按名字/摘要搜(不区分大小写)
|
|
899
|
+
weaver-work-cli meeting ops --capability eb.meeting # 按分组看(支持前缀,如 --capability eb)
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
⛔ **不要用 `meeting schema --json` 判断能力存在性**:完整结果 308KB,stdout 只回 20KB 预览,
|
|
903
|
+
`operations` 数组被截到前 10 条,排在后面的 operation 一定看不到。
|
|
904
|
+
2026-10-30 真机事故就是这么来的——agent 在 schema 预览里没找到 `meeting.eb.meeting.create.suggest`,
|
|
905
|
+
于是回复用户「当前 CLI 版本没有建会建议时间操作」,而该 operation 一直存在且可用。
|
|
906
|
+
|
|
907
|
+
## 时间和会议室:必须由用户确认(timeConfirmed / roomConfirmed)
|
|
908
|
+
|
|
909
|
+
`create.flow.prepare` / `quick` 用两个标记区分「用户定的」和「agent 猜的」:
|
|
910
|
+
|
|
911
|
+
| 标记 | 传 true 的**唯一**两种情形 |
|
|
912
|
+
|---|---|
|
|
913
|
+
| `timeConfirmed` | ① 用户原话明确给出时间("明天 9 点到 10 点");② 用户在时段选项里点选后把 `options[].value` 整体原样回传 |
|
|
914
|
+
| `roomConfirmed` | ① 用户原话明确指定某间会议室;② 用户在房间选项里点选后把 `options[].value` 整体原样回传 |
|
|
915
|
+
|
|
916
|
+
不传(或 false)时:
|
|
917
|
+
- 即使传了 `begin_datetime`,也返回 `selectionType: 'slot'`(3 个时段选项),**不会**进确认摘要;
|
|
918
|
+
- 即使传了 `address`,也返回 `selectionType: 'room'`,把「你指定的那间」标成
|
|
919
|
+
`(你指定的,待确认)`排第一位,其余候选照常列在后面;
|
|
920
|
+
- `room_conflict`(占用拦截)只在 `roomConfirmed: true` 时才触发——没确认的房间不拦,只列出来。
|
|
921
|
+
|
|
922
|
+
这样设计的原因:2026-10-30 用户投诉「会议室没有推荐让我选择,时间没有推荐让我选择,智能体自己就决定了」。
|
|
923
|
+
旧行为里,agent 只要填了值 CLI 就照收,用户看到的是既成事实。
|
|
924
|
+
|
|
925
|
+
排查口诀:**选项回来的 `value` 要整体回传**(里面自带标记);只抄 `begin_datetime` / `address`
|
|
926
|
+
单个字段会丢掉确认标记,于是被再问一轮。这不是 bug。
|
|
927
|
+
|
|
928
|
+
## 闸门顺序:四要素先定,流程最后(2026-10-30 用户纠正)
|
|
929
|
+
|
|
930
|
+
`create.flow.prepare` 的顺序是固定的,**不要试图跳步**:
|
|
931
|
+
|
|
932
|
+
```
|
|
933
|
+
名称(mt_name,必填) → 时间(slot) → 地点(room / room_conflict / room_unavailable) → 流程(flow) → 确认(AWAITING_CONFIRMATION)
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
- 时间没确认(没带 `timeConfirmed`)时**不会出现 flow 选择**,先给时段;
|
|
937
|
+
地点没确认(没带 `roomConfirmed`)时同样不会出现 flow 选择,先给房间。
|
|
938
|
+
- 到 `selectionType: 'flow'` 这一步,四要素已经全部确认,返回里带 `confirmed`
|
|
939
|
+
(`mt_name` / `begin_datetime` / `end_datetime` / `address` / `addressName` / `hrm_members`),
|
|
940
|
+
每条 `options[].value` 也带着 `begin_datetime` / `end_datetime` / `address` + 两个确认标记。
|
|
941
|
+
**用户点选后把 value 整个回传**,下一轮直接 `AWAITING_CONFIRMATION`,不会再问时间/地点。
|
|
942
|
+
- 为什么要这样:用户原话「流程只是审批载体,应该先确认时间、人、地点、名称,再选流程」。
|
|
943
|
+
流程选择放到最后,用户在前三步就已经知道这会开不开得成,最后只是挑个审批口径。
|
|
944
|
+
|
|
945
|
+
## 时段候选到底核验了什么
|
|
946
|
+
|
|
947
|
+
`selectionType: 'slot'` 的每个候选都必须同时满足两件事,缺一不列:
|
|
948
|
+
|
|
949
|
+
1. **人空闲**:`findCommonFreeSlots` 先拉该时段所有会议候选 + 批量回执(`query_meeting_receipt_list`),
|
|
950
|
+
再叠加日程(ESB 动作流,**已过滤「会议日程」类型**,避免与会议回执重复计),
|
|
951
|
+
内存里按 30 分钟切槽判重叠 —— 任一参会人有占用就跳过该槽。
|
|
952
|
+
2. **会议室空闲**:每个「人空闲」的槽再并行跑 `room.recommend`(排除封存、容量不足、该时段被占用),
|
|
953
|
+
**一间可用房都没有的槽会被直接剔除**(不会出现"时间有了但没房间"的假选项)。
|
|
954
|
+
|
|
955
|
+
所以 `options[].reason` 里那句「N 人全部空闲(会议回执 + 日程已核);M 间会议室可用:…」是**核验结论**,
|
|
956
|
+
`options[].rooms` 是该时段真实的可用房间清单(含容量与推荐理由)。
|
|
957
|
+
|
|
958
|
+
边界(会写在 `warnings` 里,必须如实转达):
|
|
959
|
+
- **没传参会人** → 只核验了房间,人没核验;
|
|
960
|
+
- **姓名查不到员工 id** → 该人**未核验**(不会算进"全部空闲");
|
|
961
|
+
- **ESB 日程调用失败** → 退化为只看会议回执,`scheduleItems` 为空可判断;
|
|
962
|
+
- 被剔除的槽在 `skippedSlots` 里("人空闲但没房间"),可以据此解释为什么候选少。
|
|
963
|
+
|
|
964
|
+
## 指定的会议室怎么核验(2.39.3 起)
|
|
965
|
+
|
|
966
|
+
`prepare` 拿到 `address` 后,**先解析成台账里的真实房间**再核验,顺序是:
|
|
967
|
+
|
|
968
|
+
```
|
|
969
|
+
解析(id / 名称 / 名称(id)) → 存在性 → 封存状态 → 该时段占用 → 才允许进确认摘要
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
- **存在性**:名称在台账里找不到 → `selectionType: room` + 文案「没找到名为 X 的会议室」。
|
|
973
|
+
以前这种情况会被一路放行,地点按纯文本塞进表单,用户到流程页面提交时才被工作流打回
|
|
974
|
+
「请按名称选择」—— 报错位置离真实原因太远(2026-10-31 真机)。
|
|
975
|
+
- **封存(status=1)**:拦下并要求换房,不拿封存房去建会。
|
|
976
|
+
- **占用**:调 `meeting.eb.conflict.room`(`query_roomusage_list`)。
|
|
977
|
+
⛔ 2.39.2 及以前**只有纯数字 id 才查**,传名称(用户最常说的「测试会议室1」)整段被跳过,
|
|
978
|
+
一间已被占用的房照样进确认摘要 —— 这是 2026-10-31 用户质疑"最后一步才校验"时挖到的真因。
|
|
979
|
+
- **台账读失败 ≠ 房间不存在**:此时标记 `lookupFailed`,跳过占用判定但不拦(避免网络抖动被当成"没这间房");
|
|
980
|
+
能否核验要如实说,不能声称"已确认空闲"。
|
|
981
|
+
- 解析结果复用在三个地方:占用检测、确认摘要里的地点名、房间选项里「(你指定的,待确认)」的匹配。
|
|
982
|
+
|
|
983
|
+
## 参会客户:从名称到客户 id(2.39.5 定案)
|
|
984
|
+
|
|
985
|
+
会议流程主表上的「参会客户」是 **客户浏览按钮**(`CustomerComponent`,NEW 流程 fieldId `1326141435517583562`),
|
|
986
|
+
值必须是客户 id,传客户名称文本会被工作流打回。所以链路是「先查 → 用户确认 → 再传 id」:
|
|
987
|
+
|
|
988
|
+
| 步骤 | 调用 | 说明 |
|
|
989
|
+
|---|---|---|
|
|
990
|
+
| ① 查 | `meeting.eb.crm.search {"keyword":"上海泛微网络科技股份有限公司"}` | 走 ESB 动作流 `esbFlowId=904205116264026112`,入参字段 **`custom_name`** |
|
|
991
|
+
| ② 确认 | —— | ⛔ 不许自动取第一条(同 SKILL 规则 0.5);`exact:false` 时必须把命中名念给用户 |
|
|
992
|
+
| ③ 传值 | `create.flow.prepare` 的 `crm_members` | 把 search 的 `items` 原样传(`[{customerId,name}]`)最省事;`[{id,name}]`、`客户名(客户id)`、逗号分隔都认。⛔ **必须带名称**,只给 id 抛 `crm_name_required` |
|
|
993
|
+
|
|
994
|
+
**请求体(动作流契约,2026-10-31 真机核对)**
|
|
995
|
+
|
|
996
|
+
```json
|
|
997
|
+
{ "customParams": { "mainTable": { "custom_name": "泛微网络" } }, "esbFlowId": "904205116264026112" }
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
返回 `actionData.responseData.customData.mainTable = { mc, sjID }`:`sjID`=客户 id,`mc`=客户名称。
|
|
1001
|
+
|
|
1002
|
+
**三条真机事实(别再用猜的)**
|
|
1003
|
+
|
|
1004
|
+
1. **入参字段名就是 `custom_name`**。之前试 `mc`/`sjmc`/`khmc`/`customerName` 全部无效、
|
|
1005
|
+
误判成"模板空所以参数进不去"—— 真因是字段名不对。`esb.input-format`(copyCustomData)对这个流返回
|
|
1006
|
+
`customParams: null`,含义是「**没配自定义入参模板 = 透传**」,不是「模板是空对象 = 丢弃入参」。
|
|
1007
|
+
⇒ CLI 现在:模板 `null` 时用默认字段名 `custom_name` 照常发;只有模板明确是 `mainTable: {}` 才判
|
|
1008
|
+
`blocked:"esb_template_empty"`。
|
|
1009
|
+
2. **一次只回 1 条**(服务端是"包含匹配 + 取首个命中"):`当前`/`pageSize`/`rows` 都不改变结果,
|
|
1010
|
+
所以"查 10 条给用户挑"做不到。实测:
|
|
1011
|
+
| 关键词 | 返回 |
|
|
1012
|
+
|---|---|
|
|
1013
|
+
| 深圳市腾讯斐泰科技有限公司 | 深圳市腾讯斐泰科技有限公司 / 1320482515670098010(`exact:true`)|
|
|
1014
|
+
| 腾讯 | 深圳市腾讯斐泰科技有限公司 / 1320482515670098010(`exact:false`)|
|
|
1015
|
+
| 泛微 | 泛微 / 1331361148057387759(库里真有叫「泛微」的客户,**不是**上海泛微)|
|
|
1016
|
+
| 泛微网络 | 泛微网络科技有限公司 / 1330932351389754061 |
|
|
1017
|
+
| 上海泛微网络科技股份有限公司 | 上海泛微网络科技股份有限公司 / 1315014081515634745 |
|
|
1018
|
+
| 不存在的客户XYZ | `{mc:"", sjID:""}` 空行 → `items: []` |
|
|
1019
|
+
⇒ 给全称最稳;片段命中名跟用户说的不一致时**必须回问**。
|
|
1020
|
+
3. **`hasData` 恒为 0**,命中时也是 0 ⇒ 判空只看 `mc`/`sjID`,不要看 `hasData`(CLI 已不再用它下结论)。
|
|
1021
|
+
|
|
1022
|
+
- 出参:`items:[{customerId,name}]`、`total`、`exact`(命中名==关键词)、`singleBestMatch`、
|
|
1023
|
+
`source`(命中 customData 哪条路径)、`keywordField`(实际传的入参字段)、`blocked`。
|
|
1024
|
+
- 解析兼容多种输出形态(动作流改结构不用改代码):`customData.mainTable` 单条、
|
|
1025
|
+
`.list/rows/items/data…`、`customData.detail1|detail2…`,行被 `{mainTable:{…}}` 包一层也能剥开;
|
|
1026
|
+
字段别名兼容 `id/customerId`、`name/sjmc`。
|
|
1027
|
+
- 「应到客户数」(fieldId `1326141435517583564`)按 `crm_members` 条数**自动算**;
|
|
1028
|
+
要覆盖就显式传 `crm_member_count`。
|
|
1029
|
+
|
|
1030
|
+
## 参会客户明细(明细表,2.39.6 起;2.39.7 打通落库)
|
|
1031
|
+
|
|
1032
|
+
宿主表单里另有一张**明细表**「参会客户明细」,列固定 5 个:姓名 / 性别 / 职位 / 手机号码 / 备注。
|
|
1033
|
+
|
|
1034
|
+
**联系人与地址来自 ESB 出参 `lxr` / `khdz`**(2026-10-31 用户加上后的实测形状):
|
|
1035
|
+
|
|
1036
|
+
| ESB 字段 | 含义 | 真机值示例 |
|
|
1037
|
+
|---|---|---|
|
|
1038
|
+
| `lxr` | 联系人明细(数组) | `{"field_…706":"利明","field_…708":"11111111111","field_…707":"信息部"}` |
|
|
1039
|
+
| ↳ `field_1173221220888062706` | 姓名 | 利明 / 胡老师 / 谷俊 |
|
|
1040
|
+
| ↳ `field_1173221220888062708` | 手机号 | 11111111111 |
|
|
1041
|
+
| ↳ `field_1173221220888062707` | 部门(部分行没有) | 信息部 |
|
|
1042
|
+
| `khdz` | 客户地址明细(数组) | ⛔ **只回明细行 id**,没有地址文本 |
|
|
1043
|
+
|
|
1044
|
+
`crm.search` 会把 `lxr` 归一化成 `items[].contacts = [{name,mobile,dept}]`(按姓名+手机号去重),
|
|
1045
|
+
`khdz` 归一化成 `items[].addresses`(当前恒为空,同时回 `addressHint` 说明"ESB 没输出地址文本")。
|
|
1046
|
+
|
|
1047
|
+
用法:
|
|
1048
|
+
- **有 `contacts`** → 把「姓名(部门)手机号」列成选项让用户挑一位,⛔ 不许自己选;
|
|
1049
|
+
- **没有 `contacts`** → 问用户联系人姓名+手机号(有的话再要职位/性别);
|
|
1050
|
+
- 选定后与客户一起提交 `crm_member_details:[{"xm","sjhm","zw","xb"}]`(部门放 `zw`)。
|
|
1051
|
+
- `prepare` 发现「传了客户没带明细」会 warning 提醒,别忽略。
|
|
1052
|
+
|
|
1053
|
+
| 项 | 值(e-cology「会议申请流程」真机) |
|
|
1054
|
+
|---|---|
|
|
1055
|
+
| 宿主流程 | `1326190634427154474` 会议申请流程(eBuilder 表单 `1179906784309559297`,表 `uf_mt_work_chkhmx`)|
|
|
1056
|
+
| subFormId | `1332370499762806784`(= `data.details` 的键)|
|
|
1057
|
+
| 列字段 id | 姓名 `1332370499762806785`(xm) / 性别 `…786`(xb) / 职位 `…787`(zw) / 手机号码 `…788`(sjhm) / 备注 `1332370774666043392`(bz) |
|
|
1058
|
+
|
|
1059
|
+
**入参**:`create.flow.prepare` 的 `crm_member_details`
|
|
1060
|
+
|
|
1061
|
+
```json
|
|
1062
|
+
[{"xm":"张三","xb":"男","zw":"采购经理","sjhm":"13800000000","bz":"主谈"}]
|
|
1063
|
+
```
|
|
1064
|
+
中文键(`姓名/性别/职位/手机号码/备注`)与 `name/mobile/title/remark` 等别名都认;
|
|
1065
|
+
姓名与手机号都为空的行走丢弃;subFormId 与列字段 id **不用传**,CLI 从 `workflow.createForm` 的字段清单里按列名反查
|
|
1066
|
+
(`resolveCrmDetailTarget`:挑「有姓名列」且命中列数最多的那张表,不会误选会议议题/会议服务)。
|
|
1067
|
+
|
|
1068
|
+
**⛔ 三个必须知道的现实(2026-10-31 真机核实)**
|
|
1069
|
+
|
|
1070
|
+
1. **明细字段只认「发起节点布局」**。表建好、表单字段管理里也有、节点字段权限(`viewRelateConfig`)也勾了 display,
|
|
1071
|
+
但**没摆上发起节点布局**、或**摆在隐藏行**上时,`getFormLayout` 的 `pageLayouts[0].comps` 里虽然能看到这张
|
|
1072
|
+
DetailTable,它下面 5 个列字段却会被判「不可见」→ `workflow.createForm` 的 `fields` 里没有它们 →
|
|
1073
|
+
`data.details` 一提交就被 `bindInputFields` 判 `NOT_FOUND`。
|
|
1074
|
+
CLI 现在会返回 `layoutWarning`("明细表 N 的 k 个字段全部被判为不可见(该明细表所在的行/列在表单布局里是隐藏的)"),
|
|
1075
|
+
**看到它就去查布局,不要回"表单里没有这张明细表"**。查法:`pageLayouts[0].config.workbook.Sheet1.rows[<DetailTable 的 excel.row>].visible`
|
|
1076
|
+
为 `false` ⇒ 那一行是隐藏行(真机实例:明细表在 row 8,`visible:false, attrs:{hide:true}`)。
|
|
1077
|
+
修法:设计器里把明细表挪到可见行 / 取消隐藏该行,保存发布后重新载入表单。
|
|
1078
|
+
2. **明细表和触发它的主表字段常配「显示联动」**(本租户:`参会客户` 为空 ⇒ 整表 `hideLine`;非空 ⇒ `show`)。
|
|
1079
|
+
这是**正常配置,不是配错**。旧逻辑把它与"隐藏行"一视同仁 ⇒ 整表字段被丢,建会写不进明细。
|
|
1080
|
+
现在 `buildCreateFormData` 会认这种 `detail` + `show` 规则:字段照常下发并标 `conditional: true`,
|
|
1081
|
+
`layoutWarning` 里点名触发字段(如「明细表 1332370499762806784 因显示联动隐藏,触发字段:参会客户」)。
|
|
1082
|
+
主表字段自己也配了 `show` 的(`参会客户` 就是)同样处理 —— 否则 `crm_members` 根本映射不到字段。
|
|
1083
|
+
⇒ 看到 `conditional: true` **照常填**,填上触发字段表单里就显示了。
|
|
1084
|
+
3. **同一条流程上两者可能都齐全,也可能只占一半**:
|
|
1085
|
+
- 「会议申请流程」`1326190634427154474`:**同时有**「参会客户」(`1329100543558172681`)与「参会客户明细」;
|
|
1086
|
+
- 「会议申请流程(NEW)」`1325677244111462606`:有「参会客户」(`1326141435517583562`)/「应到客户数」,**没有**明细表。
|
|
1087
|
+
⇒ 落到没有该字段的流程时,`prepare` 的 `unmapped` 会提示(`crm_member_count` 属自动派生,已静默忽略),
|
|
1088
|
+
如实告知用户即可。
|
|
1089
|
+
|
|
1090
|
+
**真机落库证据(2026-10-31,requestId `1332389461976473600`)**:单据详情 `workflow.detail` 回读 —— 姓名「张三」/
|
|
1091
|
+
性别「男」/ 职位「采购经理」/ 手机号码「13800000000」/ 备注「主谈」全部落库,`参会客户` = 「深圳市腾讯斐泰科技有限公司」。
|
|
1092
|
+
|
|
1093
|
+
**⛔ 参会客户只给 id 会被静默存空**:客户浏览按钮按**名称**落 `dataOptions.content`,`[{id:"…",name:""}]`
|
|
1094
|
+
提交后单据里是空值、**不报错**。CLI 现在抛 `crm_name_required` 拦住,必须传 `[{id,name}]` 或 `客户名(客户id)`。
|
|
@@ -11,15 +11,63 @@
|
|
|
11
11
|
|
|
12
12
|
## 入参
|
|
13
13
|
|
|
14
|
+
**两种用法,二选一**:
|
|
15
|
+
|
|
14
16
|
| 参数 | 必填 | 说明 |
|
|
15
17
|
| --- | --- | --- |
|
|
16
|
-
| `mtId` |
|
|
18
|
+
| `mtId` | 二选一 | 会议 id(EB 版会议主键,长 id 用字符串)。给了就按**会议真实数据**生成 |
|
|
19
|
+
| `mt_name` | 二选一✓ | **无 `mtId` 时必填** —— 会议名称 |
|
|
20
|
+
| `begin_datetime` | 二选一✓ | **无 `mtId` 时必填** —— 开始时间 `yyyy-MM-dd HH:mm` |
|
|
21
|
+
| `end_datetime` | | 结束时间(不填则文档里结束时间是【待补充】) |
|
|
22
|
+
| `address` | | 会议地点/会议室**名称**(不是 id) |
|
|
23
|
+
| `hrm_members` | | 参会人姓名,逗号/顿号分隔 |
|
|
24
|
+
| `mt_desc` | | 会议内容/议题概要 |
|
|
25
|
+
| `org_members` | | 落款单位(不传则取当前登录人部门,取不到留【待补充】) |
|
|
26
|
+
| `caller` / `contacter` / `total_member` | | 召集人 / 联系人 / 参会人数 |
|
|
17
27
|
| `extra` | | 键值对。**① 租户自定义字段**,如 `{"guest_org":"某某集团"}`——会议接口不会返回这类字段,只能从这里传;**② 保留键 `agenda`** 手动指定议程(见下文「议程表」),仅在会议没有议题时生效 |
|
|
18
28
|
| `outputPath` | | 输出文件完整路径;缺省写到 `~/.weaver-work-cli/meeting/invitations/邀请函-{会议名}-{yyyyMMdd}.docx` |
|
|
19
29
|
|
|
30
|
+
> ⛔ **既没 `mtId` 又没 `mt_name`+`begin_datetime`** → 报 `invitation_source_required`。
|
|
31
|
+
|
|
32
|
+
**无 `mtId` 模式**用于「会议还没生成」(流程审批中、或只有申请单信息)时预生成**预置函**——
|
|
33
|
+
邀请函本就是给人下载后自己改再自己发的,不该卡在"会议必须有 id"。缺的字段黄色高亮【待补充】。
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# 无会议 id:按申请单信息出预置函
|
|
37
|
+
weaver-work-cli --json meeting run meeting.invitation.render --input-json \
|
|
38
|
+
'{"mt_name":"研讨AI对接会议管理落地","begin_datetime":"2026-10-31 09:00","end_datetime":"2026-10-31 12:00","address":"120会议室","hrm_members":"易鹏、卜伟领","extra":{"guest_org":"某某集团"}}'
|
|
39
|
+
```
|
|
40
|
+
|
|
20
41
|
## 出参
|
|
21
42
|
|
|
22
|
-
`filePath` / `fileName` / `bytes` / `meetingId` / `meetingName` / `filledFields[]` / `pendingFields[]
|
|
43
|
+
`text` / `filePath` / `fileName` / `bytes` / `meetingId` / `meetingName` / `filledFields[]` / `pendingFields[]` / **`dataSource`**,以及 `warnings`(有待补充字段时会列出)。
|
|
44
|
+
|
|
45
|
+
### `text`:对话内直接展示的正文(2.42.0 起)
|
|
46
|
+
|
|
47
|
+
**这是给"在对话里看"用的**,与 docx 同源同字段(走同一个占位符解析器和同一份议程行),
|
|
48
|
+
只是换成 Markdown:标题 / 称呼 / 邀请语 / 会议要素 / 议程表 / 落款 / 备注。
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
# 邀请函
|
|
52
|
+
|
|
53
|
+
**尊敬的 某某集团:**
|
|
54
|
+
|
|
55
|
+
王丹丹 诚邀您参加「灰度测试对业务的好处沟通会」,现将会议安排通知如下:
|
|
56
|
+
|
|
57
|
+
- **会议名称**:…
|
|
58
|
+
- **会议时间**:2026-11-01 14:00~15:00
|
|
59
|
+
…
|
|
60
|
+
| 议程安排 | 议程内容 | 议程时间 |
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
⛔ 用户要的是**在对话里看到邀请函内容**(2026-10-31 明确纠正:"不是发文件,是直接在智能体对话中来展示的")。
|
|
64
|
+
所以回复必须把 `text` 全文贴出来,`filePath` 只是附带的"可下载打印"说明。
|
|
65
|
+
⛔ 别把 `text` 包进代码块(会变成一段代码,不像邀请函),也别只贴前几行。
|
|
66
|
+
|
|
67
|
+
| `dataSource` | 含义 |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `meeting` | 按会议真实数据生成(`mtId` 模式),字段最全 |
|
|
70
|
+
| `payload` | 按申请单字段预生成(无 `mtId` 模式),属**预置函**,请人工核对 |
|
|
23
71
|
|
|
24
72
|
议程相关三个字段:
|
|
25
73
|
|
|
@@ -28,6 +76,8 @@
|
|
|
28
76
|
| `agendaSource` | `meeting.topic`=按会议议题自动填 / `extra`=调用方传入 / `template`=**没有议题,保留模板示例行** |
|
|
29
77
|
| `agendaRows` | 实际写入议程表的行数(`template` 时为 0) |
|
|
30
78
|
| `agendaTableFilled` | 是否真的重建了议程表 |
|
|
79
|
+
| `detailSupplemented` | 用 `meeting.eb.meeting.detail` 补回来的字段名(list 单查会丢「参会人员」,见「注意事项」) |
|
|
80
|
+
| `callerSource` | `meeting.caller` / `meeting.mt_creator` / `session.user`(发起人本人兜底) / `none` |
|
|
31
81
|
|
|
32
82
|
> ⚠️ `agendaSource=template` 时会同时给一条 `warnings`:议程表里还是模板的示例行
|
|
33
83
|
> (“15分钟/泛微公司介绍”),提醒人工改成真实议程 —— 客户看到的邀请函不该印着别人的议程。
|
|
@@ -106,8 +156,16 @@ weaver-work-cli --json meeting run meeting.invitation.render --input-json '{"mtI
|
|
|
106
156
|
|
|
107
157
|
## 注意事项
|
|
108
158
|
|
|
109
|
-
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
159
|
+
- **数据源:list 单查为主,detail 只用来「补空」**(2.42.0 起):
|
|
160
|
+
`meeting.eb.meeting.list` 单查在真机上会丢字段(2026-10-31 实测同一会议
|
|
161
|
+
`hrm_members` 在 list 里是空串、在 detail 里是「王丹丹」),所以 CLI 会用
|
|
162
|
+
`meeting.eb.meeting.detail` 补 **list 里为空的**白名单字段(`hrm_members`/`mt_desc`/`caller`/
|
|
163
|
+
`contacter`/时间/`total_member` 等),补回来的字段名列在出参 `detailSupplemented` 里。
|
|
164
|
+
⛔ **`address` 不从 detail 补** —— detail 的 `address` 是会议室 **id**,写进邀请函比空着更糟。
|
|
165
|
+
白名单外的新字段仍走 `{dataKey}` 兜底,跨环境语义不变。
|
|
166
|
+
- **召集人兜底顺序**:`meeting.caller`(会议自己填的)→ `meeting.mt_creator`(创建人)→
|
|
167
|
+
`session.user`(**发起人本人**,2.42.0 起)。看 `callerSource` 判断用的哪一个;
|
|
168
|
+
以前会议没填 caller 就直接【待补充】,邀请函开头那句「XXX 诚邀您参加」整句是空的。
|
|
169
|
+
- 生成后如需把文件发给对方,**本 operation 不提供发送能力**(IM/邮件都不走这里),由使用者自行处理;
|
|
170
|
+
对话里展示走 `text` 字段(见「出参」)。
|
|
113
171
|
- 模板出错时会在本地抛 `template_missing`,提示 CLI 包缺少 `templates/meeting/invitation.docx`;此时重装 CLI 即可,不要手工改模板路径。
|
|
Binary file
|
|
@@ -573,7 +573,7 @@
|
|
|
573
573
|
}
|
|
574
574
|
},
|
|
575
575
|
"artifactBaseline": {
|
|
576
|
-
"aggregateSha256": "
|
|
576
|
+
"aggregateSha256": "bae91aefcc30c01410c2288ae7b31fee438a77bdd50f5df894e7f10e249b6b5c",
|
|
577
577
|
"files": [
|
|
578
578
|
{
|
|
579
579
|
"path": "src/shortcuts/okr/errors.ts",
|
|
@@ -587,8 +587,8 @@
|
|
|
587
587
|
},
|
|
588
588
|
{
|
|
589
589
|
"path": "src/shortcuts/okr/host.ts",
|
|
590
|
-
"size":
|
|
591
|
-
"sha256": "
|
|
590
|
+
"size": 8072,
|
|
591
|
+
"sha256": "dd2a4a5773cd440e5f6136b7c106cf19f2dc26251d03ffb1d17983b921f27ae7"
|
|
592
592
|
},
|
|
593
593
|
{
|
|
594
594
|
"path": "src/shortcuts/okr/index.ts",
|
|
@@ -5,7 +5,7 @@ display_name_en: Weaver Qiyecheng FNA
|
|
|
5
5
|
description: 泛微齐业成费控中心(预算查询/费用中心/报销报表/借款管理/发票核销)的 E10 查询与提醒写操作能力,通过 weaver-work-cli fna 命令执行。
|
|
6
6
|
description_zh: 泛微齐业成费控中心助手:事前申请单预算详情、预算执行报表、报销/借款/预付核销金额、报销报表 AI 问答(自然语言出部门/期间/费用类型分组报表)、全公司借款汇总与列表、提醒还款、发票核销金额与列表、催票。所有能力通过 weaver-work-cli fna 命令执行,提醒还款与催票为写操作,必须先 prepare 预览并经用户明确确认后 apply。
|
|
7
7
|
description_en: Expense, budget and loan assistant for Weaver Qiyecheng FNA. Queries pre-application budget details, budget execution reports, reimbursed/loan/prepay amounts, natural-language expense reports (grouping by department, period or expense type), company-wide loan summary and list, invoice write-off summary and list. Sends repayment reminders and invoice call-tickets through the weaver-work-cli fna command with a prepare/apply confirmation chain.
|
|
8
|
-
version: 1.0.
|
|
8
|
+
version: 1.0.5
|
|
9
9
|
author: 泛微网络科技股份有限公司
|
|
10
10
|
agent_created: true
|
|
11
11
|
requires:
|
|
@@ -87,6 +87,7 @@ cliHelp: "weaver-work-cli fna --help"
|
|
|
87
87
|
- 费用中心日期口径不同:报销按明细费用日期、借款按流程创建时间、预付核销按核销记录创建时间。
|
|
88
88
|
- 借款费用中心接口 requestId/employeeId/workflowId 只认**数字**(字符串会静默返回空);超 2^53 的巨型 ID 保留字符串并提示人工核验。
|
|
89
89
|
- `fna.expense.chart` 是二开接口(`/api/secondev/fna/getExpenseChart`):服务端只把当前人/当前部门作为**提示文本**拼进 prompt,不做强制过滤,返回可能是全租户数据;个人金额口径必须改用 `fna.expense.reimbursed.sum`(按 `employeeId` 过滤),并在汇报中注明数据范围。
|
|
90
|
+
- `fna.expense.chart` 返回 `meta.permissionDenied=true`(或文案含「权限 / 越权」)表示当前账号数据权限不覆盖该范围,按执行原则第 9 条**立即停住**,不得改调其它接口拼装同一份报表。
|
|
90
91
|
|
|
91
92
|
## 执行原则
|
|
92
93
|
|
|
@@ -98,6 +99,7 @@ cliHelp: "weaver-work-cli fna --help"
|
|
|
98
99
|
6. 金额结论口径存疑时(如借款缺陷、瞬时空响应)先说明不确定性;`total=0` 或空列表提示「暂无记录」,不得伪造成功。
|
|
99
100
|
7. `fna.expense.chart` 的成败看 `data.kind` 而不是 `code`(`code` 恒为 200,追问/拦截也走 success):`rows`/`empty` 属正常,`clarify` 按文案补口径后最多重问一次,`blocked` 换更贴近报销业务的问法而**不是**自己写 SQL;`unexpected` 只描述现象并反馈维护者。
|
|
100
101
|
8. `fna.expense.chart` 每次调用都真实消耗一次大模型对话 + 一次 SQL,一轮对话最多问 1-2 次,禁止循环试探;`maxRows` 只截断本地展示、不改变服务端查询;列名由 AI SQL 别名决定,不要假设固定列名。
|
|
102
|
+
9. **权限拦截即终点(硬规则)**:`fna.expense.chart` 返回 `meta.permissionDenied=true`,或文案明确提示无数据权限 / 越权访问时,把接口原文如实告知用户并说明「当前账号数据权限不足,查不到该范围数据」,然后给出替代路径(换具备该权限的账号 / 请管理员扩权 / 由有权限方导出明细后再分析),由用户决定下一步。**禁止**换问法、换口径继续试探,**禁止**改调 `fna.expense.reimbursed.sum`、`fna.budget.*`、借款 / 发票核销等其它接口按部门 / 人员 / 金额自行拼装同一份报表,**禁止**自写 SQL 绕过——拼装结果与原报表口径不同源,属于越权尝试且极易产出错误结论。详见 [references/expense-chart.md](references/expense-chart.md) 的「无权限时的处理」。
|
|
101
103
|
|
|
102
104
|
## References
|
|
103
105
|
|
|
@@ -106,7 +108,7 @@ cliHelp: "weaver-work-cli fna --help"
|
|
|
106
108
|
| 接口目录与按模块路由 | [references/catalog.md](references/catalog.md) |
|
|
107
109
|
| 预算:事前申请单预算详情 / 预算执行报表 | [references/budget.md](references/budget.md) |
|
|
108
110
|
| 费用中心:报销 / 借款 / 预付核销 | [references/expense-center.md](references/expense-center.md) |
|
|
109
|
-
| 报销报表 AI 问答:自然语言出报表、五个 `kind
|
|
111
|
+
| 报销报表 AI 问答:自然语言出报表、五个 `kind`、无权限硬规则、额度与数据范围风险 | [references/expense-chart.md](references/expense-chart.md) |
|
|
110
112
|
| 借款管理:汇总 / 列表 / 提醒还款(prepare→apply) | [references/loan-management.md](references/loan-management.md) |
|
|
111
113
|
| 发票核销:金额 tab / 列表 / 催票(prepare→apply) | [references/invoice-writeoff.md](references/invoice-writeoff.md) |
|
|
112
114
|
| 源资料指纹与更新检测 | [references/source-manifest.json](references/source-manifest.json) |
|
|
@@ -139,5 +141,6 @@ weaver-work-cli --json fna run fna.loan.main.list --input-json '{"current":1,"pa
|
|
|
139
141
|
|
|
140
142
|
- 借款「确认已还 confirmRepay」、核销明细等页面按钮能力(源资料未提供接口)→ 见 `weaver-work-cli fna schema` 的 `withheldOperations`,不得编造 operation 或直连接口。
|
|
141
143
|
- 报销报表 AI 问答只接受自然语言 `userInput`:不接受自写 SQL、不暴露 AI 生成的 SQL,也没有 `scope=self/dept/tenant` 之类的强制过滤参数(服务端未提供)。
|
|
144
|
+
- 报表返回无权限后改调其它报销/借款/预算/流程接口拼装同一份报表,或自写 SQL 绕过权限边界——属于越权尝试,一律禁止。
|
|
142
145
|
- 姓名/流程名 → ID 的解析、创建借款单/预付单/事前申请单等需联动工作流的写流程(未提供接口依据)。
|
|
143
146
|
- 其它模块(发票票夹、人事、流程待办)请路由到对应 Skill,不在此重复实现。
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
- 报销口径:明细状态 `status=1`(审批完成)的 `reimburse_amount` 合计 = 已报销金额;无数据返回 `0.0`。
|
|
27
27
|
- ⚠️ 借款接口缺陷:仅统计首条借款记录(对外汇报注明);且首次/冷启动可能瞬时空响应(缺 data 键),CLI 自动重试最多 2 次。
|
|
28
28
|
- 借款接口 requestId 等必须传数字;预付核销接口日期按核销记录创建时间、employeeId 匹配预付单创建人。
|
|
29
|
-
- 报销报表 AI 问答(`fna.expense.chart`)是二开接口(`/api/secondev/fna/getExpenseChart`):自然语言进 AI 场景生成 SQL,服务端做租户隔离改写 + 安全校验后执行;返回 `kind=rows/empty/clarify/blocked/unexpected`(`code` 恒为 200,不能用它判成败)。每次调用消耗一次大模型对话 + 一次 SQL,且不做当前人强制过滤,详见 `expense-chart.md
|
|
29
|
+
- 报销报表 AI 问答(`fna.expense.chart`)是二开接口(`/api/secondev/fna/getExpenseChart`):自然语言进 AI 场景生成 SQL,服务端做租户隔离改写 + 安全校验后执行;返回 `kind=rows/empty/clarify/blocked/unexpected`(`code` 恒为 200,不能用它判成败)。每次调用消耗一次大模型对话 + 一次 SQL,且不做当前人强制过滤,详见 `expense-chart.md`。**返回无权限时(`meta.permissionDenied=true` 或文案含「权限 / 越权」)到此为止,不得改调其它接口拼数据,见 `expense-chart.md` 的「无权限时的处理」。**
|
|
30
30
|
|
|
31
31
|
## 三、借款管理(loan,管理员)
|
|
32
32
|
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
|
|
56
56
|
- 失败时按错误 envelope 的 `type/subtype` 处理:`confirmation.required` 缺确认;`partial.write_uncertain` 不确定结果立即停止并回查,禁止自动重试。
|
|
57
57
|
- 无记录时输出 `total=0`/空 `rows` 或 `segments:null`,提示「暂无记录」,不得伪造成功。
|
|
58
|
-
- `fna.expense.chart` 的「有结果」判断看 `kind`(不是 `code`):`code` 恒为 200,追问与安全拦截同样走 `WeaResult.success`;`clarify` 最多重问一次,`blocked` 换业务问法而不是自己写 SQL
|
|
58
|
+
- `fna.expense.chart` 的「有结果」判断看 `kind`(不是 `code`):`code` 恒为 200,追问与安全拦截同样走 `WeaResult.success`;`clarify` 最多重问一次,`blocked` 换业务问法而不是自己写 SQL;`meta.permissionDenied=true` 时不再追问,直接告知权限边界。
|
|
59
59
|
- 全部金额字段单位为元。
|
|
@@ -49,13 +49,25 @@ weaver-work-cli --json fna run fna.expense.chart --input-json '{"userInput":"202
|
|
|
49
49
|
|---|---|---|
|
|
50
50
|
| `rows` | 拿到结果集(`rows`/`columns`/`rowCount`) | 给「结论摘要 + 列名 + 行数」,不原样粘贴长 JSON;`truncated=true` 说明只展示前 `maxRows` 行,`meta.requestedRows` 是服务端实际返回行数 |
|
|
51
51
|
| `empty` | SQL 执行成功但 0 行 | 提示「暂无匹配记录」,可换问法再问一次,不得编造数据 |
|
|
52
|
-
| `clarify` | AI 判定需求不明确,`message` 是追问文案 |
|
|
52
|
+
| `clarify` | AI 判定需求不明确,`message` 是追问文案 | 转述文案,补充时间/部门/口径后**最多再问一次**;若文案属**权限类**(如「需求不明确,请注意权限」,此时 `meta.permissionDenied=true`),直接执行下文「无权限处理」硬规则,不再追问 |
|
|
53
53
|
| `blocked` | AI 生成的 SQL 未通过服务端安全校验 | 说明该问法触发安全拦截,换更贴近报销业务的问法;**不要**自己写 SQL 绕过 |
|
|
54
54
|
| `unexpected` | `data` 类型意外 | 只描述现象,不猜测数据,反馈维护者 |
|
|
55
55
|
|
|
56
56
|
- 列名由 AI 生成 SQL 的别名决定、**不固定**,展示时不要假设 `dept_name` / `total_amount` 一定存在。
|
|
57
57
|
- 金额单位为元;口径由 AI SQL 决定,关键结论建议用 `fna.expense.reimbursed.sum` 等标准接口交叉核对。
|
|
58
58
|
- `kind=clarify/blocked` 是按返回文案推断的(`meta.messageKindInferred=true`),原始 `message` 一并返回,口径存疑时以原文为准。
|
|
59
|
+
- `meta.permissionDenied` 是同一批字符串结果上的稳定布尔字段:文案含「权限 / 越权」即为 `true`(CLI 同时把它归到 `clarify`),其余为 `false`。判断权限时优先读它,不要自己再对中文做正则;`data.kind` 仍是 `rows/empty/clarify/blocked/unexpected` 五个值,不新增 kind。
|
|
60
|
+
|
|
61
|
+
## 无权限时的处理(硬规则)
|
|
62
|
+
|
|
63
|
+
**若报表接口返回无权限(`meta.permissionDenied=true`,即 `kind=clarify` 且文案含「权限」,或文案明确提示无数据权限 / 越权访问),则直接输出该结果,禁止再拼接参数去调用其他报销 / 借款 / 预算等查询接口。**
|
|
64
|
+
|
|
65
|
+
具体约束:
|
|
66
|
+
|
|
67
|
+
1. **到此为止**:把接口原文返回给用户(说明「当前账号数据权限不足,查不到该范围数据」),不再换问法、不再换口径、不再试探。
|
|
68
|
+
2. **不得绕行**:不允许为了「凑出」同一份报表,转而拼接 `fna.expense.reimbursed.sum`、`fna.budget.*`、借款 / 发票核销 / 流程查询(`workflow.search`、`ebuilder-form.*`)等其它接口,按部门 / 人员 / 金额自行拼装数据。这类拼装得到的数字与原报表口径不同源,属于越权尝试,且极易产出错误结论。
|
|
69
|
+
3. **不得自写 SQL**:`raw.sql` 之类需要自行拼 SQL 的方式同样禁止。
|
|
70
|
+
4. **正确做法**:如实告知权限边界 + 给出可行替代路径(换具备该数据权限的账号 / 请管理员扩权 / 由有权限方导出明细文件后再分析),由用户决定下一步。
|
|
59
71
|
|
|
60
72
|
## 注意
|
|
61
73
|
|
|
@@ -64,6 +76,7 @@ weaver-work-cli --json fna run fna.expense.chart --input-json '{"userInput":"202
|
|
|
64
76
|
3. **无服务端 LIMIT**:大租户下可能很慢或返回大量行;`maxRows` 只做本地截断。
|
|
65
77
|
4. **单轮问答**:每次请求生成新的会话 ID,不能凭上一次结果续聊;追问请把上下文重新写进新的 `userInput`。
|
|
66
78
|
5. **二开接口依赖**:路径是 `/api/secondev/fna/`(`FexsCommonController`)。若同租户其它 `fna.*` 正常、只有本 operation 返回 404 或 500,先怀疑该租户未安装 seconddev 的 fna 二开包,不要判为「能力不存在」。
|
|
79
|
+
6. **权限拦截即终点**:返回无权限时按上文「无权限时的处理」执行,直接输出结果,禁止拼接参数改写问法或改调其他报销 / 借款 / 预算接口绕行。
|
|
67
80
|
|
|
68
81
|
## 失败处理
|
|
69
82
|
|
|
@@ -74,5 +87,6 @@ weaver-work-cli --json fna run fna.expense.chart --input-json '{"userInput":"202
|
|
|
74
87
|
| `validation.max_rows_invalid` | `maxRows` 越界 | 用 1-5000 的整数 |
|
|
75
88
|
| `api.server_error`(HTTP 500) | 当前人查不到(服务端 NPE)/ AI 场景异常 / SQL 执行失败 | **不自动重试**;说明可能原因,必要时换标准接口 |
|
|
76
89
|
| `api.business_error` | `code != 200` | 按 `message` 转述,不猜测数据 |
|
|
90
|
+
| 返回无权限(`meta.permissionDenied=true`,文案含「权限 / 越权」) | 当前账号数据权限不覆盖该范围 | **直接输出该结果并说明权限边界**,不再换问法,禁止拼接参数改调其他报销 / 借款 / 预算接口 |
|
|
77
91
|
| `authentication.session_expired` | 登录态失效 | 先向用户确认 E10 登录域名,再刷新登录;不得带失效 Cookie 重试 |
|
|
78
92
|
| `network.timeout` | AI/SQL 串行超过 90s | 换更窄的时间范围;是否重试由用户决定(重试会再消耗一次模型额度) |
|