name: kdshrpmsg description: >- Design and implement Kingdee EAS/SHR workflow todo and to-be-read message push to external portals or Weaver/Fanwei via MessageWebServiceDao. Use for 待办, 待阅, PORTAL-002/003/006/007/011/012/013, OAMessageWebServiceDao, WeaverMessageWebServiceDao, BMCMessage, assignReadRecord, receiveOAConfig, BaoYPro, Weaver, ReceiveTodoRequestByJson, weaverTodoConfig, pcurl entryPath, or ESB portal message integration on Kingdee SHR. BEFORE coding: ask intake questions in this skill (channel, API, identity, deep link, config file).
Reusable pattern from YHPro (玉湖,已测通) and BaoYPro (报业 / 泛微统一待办). Do not copy secrets; adapt per customer.
Related SSO deep-link entry: skill kdshrsso (BaoYPro: Option B-qy /qy/auth/weaver/app.do).
Coding discipline (do not guess platform getters / uncertain fields): skill kdshr-dev.
When implementing 待办 / 待阅 for a new project or new channel, do not start coding until goals are confirmed. Ask in one batch. If SSO is in the same delivery, run kdshrsso intake first (or together).
syscode+flowid+workflow+receiver;YH:taskId)?flowid 是否用 procInstId?/qy/auth/weaver/app.do)?审批页 path?*MessageWebServiceDao,还是 Router fan-out 多渠道?默认 独立 Dao + enabled 开关,少动已上线渠道。weaverTodoConfig.properties;钉钉/飞书用 dingtalkTodoConfig / feishuTodoConfig,不要改名合并成一个大文件。isremark 等)——无文档则先按 weaver-baoy-plan 草案请用户改。wf.delayMs)经验值。set-server-env、integration-config、weaverTodoConfig、WSConfig.xml、login/logout JS、DDL/jar;缺哪项就问「本项目要不要配」。给出 目标确认表:渠道、配置文件名(含清单勾选)、SPI 策略、深链模板、人员字段、状态映射来源。用户确认后再改代码。用户说「按报业/按 BaoYPro」时可复述默认假设请一次确认。
做 待办/待阅(尤其 Weaver + SSO)时,Agent 必须对照下表逐项核对;其他项目若漏配,要主动列出并问用户「是否需要配置」,不得默认跳过。
与 SSO 重叠项同时对照 skill kdshrsso Go-live。总清单见项目 docs/integration/go-live-prod.html。
| # | 文件(相对 EAS_HOME) |
用途 | 关键须改的关键项 | 新项目是否要 |
|---|---|---|---|---|
| 1 | server/bin/set-server-env.sh(或 Windows 等价) |
选读哪份 integration JSON | ENV=test\|prod → INTEGRATION_CONFIG_PATH |
要(有 SSO/qy 时) |
| 2 | server/properties/integration-config-{env}.json |
SSO OAuth、SHR、泛微 ecology | shrServerName、dataCenter、allowedPrefixes、appId/appSecret、callbackUrl、weaver.ecologyUrl |
要(有 SSO 时) |
| 3 | server/properties/{客户}/weaverTodoConfig.properties |
待办 OpenAPI + 待阅 sendMsg | openapi.host、凭证、syscode、shrServerName、sso.appId、notify.moduleId/eventId/tenantKey |
要(有 Weaver 待办/待阅时) |
| 4 | server/profiles/server1/config/portalConfig/WSConfig.xml |
平台消息 SPI 注册 | <path>=Dao 全类名;<dataCenter>=账套(与 json 一致) |
要(走 MessageWebServiceDao 时) |
| 5 | server/properties/{客户}/weaverTodo-ddl.sql |
CallLog / assignReadRecord | 生产库是否已建表 | 首次上线要执行 |
报业示例目录名 baoye/;其他客户换自己的 properties 子目录,不要把多渠道揉进一个文件。
| # | 文件 | 用途 | 关键项 |
|---|---|---|---|
| 6 | server/deploy/eas.ear/sso_web.war/common/js/login_withForm.js |
门户进 SHR SSO | ENV_CONFIG.prod.*;getCurrentEnv() 识别生产 Host |
| 7 | server/deploy/easweb.ear/shr_web.war/scripts/gui/logoutHR.js |
退出转泛微 | currentEnv / 生产 ecologyUrl(或按 host) |
| # | 项 | 说明 |
|---|---|---|
| 8 | 二开 jar(如 weaverTodo / qy 相关) | 放入 lib/sp 等,仅改配置不部署代码无效 |
| 9 | qy.war context=/qy |
SSO 入口与 callback 依赖 |
| 10 | 泛微后台 | callback 注册、退出白名单、异构 syscode/IP、消息中心 module/event 规则 |
WSConfig.xml 的 dataCenter、notify.moduleId/eventId、ENV=prod、logoutHR currentEnv)。| 项 | 值 |
|---|---|
| SHR | https://hr.szpgm.com/shr |
| 泛微 OpenAPI | http://172.16.37.23:20600 |
| dataCenter | SNG(json 与 WSConfig 一致) |
| notify | tenant=t6srq5l4vh module=100011 event=241221 |
| 覆盖包 | D:\workcode\baoye\patch\正式单点部署(测试包:...\test单点部署) |
When user says 上线 / 切生产, coordinate with kdshrsso Go-live, and walk the 配置文件清单 above (do not only edit weaverTodoConfig).
Key production fields for Weaver todo/notify (weaverTodoConfig.properties):
| Key | Set to production |
|---|---|
weaver.openapi.host |
生产 OpenAPI/ecology |
weaver.corpid / app_key / app_secret |
生产开放平台 |
weaver.syscode |
生产已注册标识 |
weaver.shrServerName |
生产 SHR(redirect) |
weaver.sso.appId |
与 integration-config-prod.json 中 appId 一致 |
weaver.sso.entryPath |
通常仍 /qy/auth/weaver/app.do |
weaver.notify.tenantKey |
按客户(报业 t6srq5l4vh) |
weaver.notify.moduleId / eventId |
按环境(报业生产 100011 / 241221;测试 139141 / 287602) |
Also must set: ENV=prod、integration-config-prod.json、WSConfig.xml <dataCenter>、login/logout JS。
Full checklist: project docs/integration/go-live-prod.html。
报业生产 SHR:https://hr.szpgm.com/shr。
| Scenario | Fit |
|---|---|
| Push workflow 待办 to enterprise portal / OA | Yes |
| Push BMC 通知/待阅 to portal | Yes |
| Portal APIs match YH PORTAL-* REST + HTTP Basic + ESB envelope | Yes |
| Weaver/Fanwei/统一待办中心 (BaoYPro) via ReceiveTodo API | Yes — see weaver-baoy-plan.md |
| Only DingTalk/Feishu, no portal | Partial — separate channel + config file; skip PORTAL-* / Weaver receive |
| Replace product message center entirely | No |
Need portal sync for SHR workflow/messages?
│
├─ Implement MessageWebServiceDao (platform SPI) — NEVER invent a parallel push framework
│ ├─ Todo: addMessage / addCompletedMessage / removeMessage
│ └─ ToBeRead: updateMessages(id, MsgStatus, ctx)
│
├─ Downstream?
│ ├─ YH-style ESB PORTAL-* → TodoMessageServer + receiveOAConfig
│ └─ Weaver E10:
│ ├─ 待办 → receiveRequestInfo(weaverTodo + weaverTodoConfig)
│ └─ BMC 通知/待阅 → 消息中心 sendMsg(勿再用 isremark=8)
│
├─ Deep link back to SHR?
│ ├─ Weaver: relative /qy/auth/weaver/app.do?appId&redirect=approveAbs (kdshrsso B-qy)
│ ├─ Future DingTalk/Feishu: that platform SSO entry + same approveAbs
│ └─ Never rely on Unified /auth/app + UA for PC Weaver todos
│
└─ Config naming
├─ Keep weaverTodoConfig.properties for Weaver only (do not mega-rename for BY)
└─ Later: dingtalkTodoConfig.properties / feishuTodoConfig.properties
| Project | Downstream | API style |
|---|---|---|
| YHPro | Enterprise portal ESB | Multiple PORTAL-* URLs |
| BaoYPro | Weaver / Fanwei / eteams | One receiveRequestInfo (+ OpenAPI oauth) |
Reuse YHPro SPI/hooks idea; replace HTTP payload and status fields. Detail: weaver-baoy-plan.md
不再走统一待办 receiveRequestInfo / isremark=8。实现类:WeaverToBeReadMessageServer + WeaverSendMsgClient。
| 项 | 约定 |
|---|---|
| 接口 | /papi/openapi/api/mc/msg/sendMsg(weaver.openapi.sendMsgPath) |
| 人员 | 只要 workCode,不传 employeeId |
| 发送人 | BMCMessageInfo.getSenderId() → getUserById → UserInfo.getNumber() / getName() |
| 接收人 | getReceiver() → resolveReceiverWorkcode |
| title | getTitle() |
| text | getBody();空则回退 title |
| todo | false;已读不回写泛微 |
| entity.pcUrl | 有 BMC url 才传(SSO 相对入口) |
| channels | 默认 [1](IM) |
| 配置 | weaver.notify.tenantKey / moduleId / eventId / channels |
| 环境固定参数 | 测试:tenant=t6srq5l4vh module=139141 event=287602;生产:tenant=t6srq5l4vh module=100011 event=241221(切环境只改 properties,勿混用) |
| 配置热加载 | WeaverTodoConfig 按文件 mtime 重载,改 notify 参数一般不用重启 |
| 日志前缀 | 待办 [WEAVER-TODO];待阅 [WEAVER-TOREAD](含 WeaverSendMsgClient) |
| CallLog | 表 OAMsgCallLog;OperType=通知发送;RequestUrl=host+path(不含 token);ResponseResult=对方完整 JSON |
| OpenAPI token | JVM 级缓存(跨多次 new Dao);authorize 遇 Sentinel/-10 有限次退避重试 |
SPI:updateMessages(UNREADED) → sendMsg;addMessage 且 type 含「通知」→ 跳过(避免再推 isremark=0)。
wf.delayMs 执行顺序(勿颠倒)旧错法:先 sleep(wf.delayMs) 再查 AssignmentId —— sleep 期间若任务撤回,AssignRead 已空,会误报 assignId 为空。
正确顺序(WeaverTodoMessageServer.addMessage):
waitAssignIdByMsgId,预算约 wf.delayMs,步进 500ms)pcurlsaveAssignRecord 先落本地关联delayForWf()(整段 wf.delayMs),让「待办转已办」等并发先落定receiveRequestInfo 推 isremark=0已办/删除路径可先 delayForWf() 再查库(与新增不同)。配置项:weaver.wf.delayMs(报业常用 8000)。
Coding discipline:skill kdshr-dev。
platform workflow / BMC
→ XxxMessageWebServiceDao
→ Todo / ToBeRead servers → PORTAL-*
→ MessageCommonUtil (Basic + JSON)
platform workflow
→ WeaverMessageWebServiceDao
→ WeaverTodoMessageServer
→ WeaverReceiveTodoClient (OpenAPI token + receiveRequestInfo)
→ pcurl from WeaverTodoSupport (entryPath + appId + redirect)
platform BMC 通知
→ WeaverMessageWebServiceDao.updateMessages(UNREADED)
→ WeaverToBeReadMessageServer
→ WeaverSendMsgClient (同 OpenAPI token + sendMsg)
Config: {EAS_HOME}/server/properties/baoye/weaverTodoConfig.properties
Key: weaver.sso.entryPath (default /qy/auth/weaver/app.do) + weaver.sso.appId;通知另见 weaver.notify.*。
| Method | YH PORTAL | Weaver 待办 isremark | BaoYPro BMC 通知 |
|---|---|---|---|
addMessage |
002 | 0(type 含「通知」则跳过) | — |
addCompletedMessage |
006 then 003 | 2; flow end → 4 | — |
removeMessage |
007 | -1 | — |
updateMessages |
011 / 012 | (历史方案 isremark=8,BaoY 不用) | sendMsg(未读);已读不回写 |
- [ ] 1. Downstream API doc + env + auth
- [ ] 2. Person mapping field (工号 / cfidmusercode / …)
- [ ] 3. MessageWebServiceDao facade + servers
- [ ] 4. Per-channel properties (weaverTodoConfig / receiveOAConfig / …)
- [ ] 5. assignReadRecord / CallLog
- [ ] 6. Register SPI in product
- [ ] 7. BMC hook if 待阅 needed
- [ ] 8. PC URL: SSO wrap (kdshrsso) + approve page
- [ ] 9. Mobile URL if required
- [ ] 10. E2E create → approve → complete/delete
MessageWebServiceDao.sso.entryPath.| Avoid | Why |
|---|---|
| Bypass MessageWebServiceDao | Missed callbacks |
| Absolute pcurl to Weaver | API rejects / 外链规则不符 |
Unified /auth/app for Weaver PC todo |
UA → unsupported_client |
| Rename weaverTodoConfig to “todoConfig” mid-project | Risk / little gain |
| One config file for Weaver OpenAPI + DingTalk push | Secrets and APIs differ |
| Soft-fail empty person mapping | Wrong assignee |
MessageWebServiceDao WeaverMessageWebServiceDao
WeaverTodoMessageServer WeaverTodoSupport WeaverTodoConfig
weaver.sso.entryPath receiveRequestInfo syscode s-HRCloud
assignReadRecord OAMsgCallLog receiveOAConfig PORTAL-002
| Doc | Content |
|---|---|
| yhpro-reference.md | YHPro package + field mapping |
| portal-api-map.md | PORTAL field quick map |
| weaver-baoy-plan.md | BaoYPro Weaver todo (implemented notes) |
| weaver-receive-todo-api.md | Weaver E10 field extract |
| kdshrsso Option B-qy | SSO entry / logout / AttackFilter |