跳转至

企业微信配置与集成机制

前端入口:obpm-manager-vue3/src/components/weixin.vue
管理 API:obpm-manager/.../wechat/WechatAuthtimeController.java
核心服务:obpm-core/.../support/weixin/WeixinService.java、WeixinSecretCache、QyApiService
测试扫码:obpm-common/.../wecom/WeixinQrCodeTestSupport.java(内存 ticket,不登录)
扫码登录:obpm-signon/.../LoginController.java
OAuth SSO:obpm-runtime/.../RuntimeSecurityFilter + WeixinService.auth
接口明细另见 [[../../restful-api/manager/wechat-authtime]]、[[../../restful-api/signon/login]]

本文梳理管理台「企业微信」配置项,以及**通讯录同步、扫码登录、URL 跳转(OAuth)、消息推送**四条主流程在前后端中的工作机制。


1. 总览

企业管理中心在域(租户)维度绑定企业微信。启用后,平台用域级 CorpID / Secret 与各软件的 AgentId / Secret,调用企业微信开放接口完成组织同步、免登跳转与待办消息。

flowchart TB
  subgraph UI["管理台 weixin.vue"]
    CFG["域级配置(分组)<br/>CorpID / 通讯录Secret / 只读应用 / 扫码三项"]
    APP["软件级 AgentId + Secret"]
    ACT["保存 / 组内同步 / 测试扫码 / 生成跳转链接"]
  end

  subgraph Persist["持久化 T_DOMAIN"]
    COL["WEIXIN_* 列 + WEIXIN_CONFIG JSON"]
  end

  subgraph Hub["运行时枢纽"]
    CACHE["WeixinSecretCache"]
    TOKEN["QyApiService.getAccessToken<br/>qyapi gettoken"]
  end

  subgraph Flows["业务能力"]
    SYNC["通讯录双向同步"]
    QR["PC 扫码登录"]
    OAUTH["应用内 OAuth 跳转 / SSO"]
    MSG["流程待办 / 图文 / 文本消息"]
  end

  CFG --> Persist
  APP --> Persist
  Persist --> CACHE
  CACHE --> TOKEN
  TOKEN --> SYNC & OAUTH & MSG
  Persist --> QR

身份对齐约定(贯穿所有流程):

OBPM 企业微信
用户 loginno 成员 userid
部门 weixinDeptId 部门 id
OAuth / 消息 appid 企业 CorpID(不是小程序 AppId)

2. 前端页面与配置项

2.1 入口、布局与开关

项 说明
菜单位置 域管理 → 微信配置(Domain.vue 加载 weixin.vue)
功能开关 Constant.ts → Setup.domain.weixinConfig
启用方式 weixinProxyType:none(不启用)/ EnterpriseWeChat(企业微信)
历史遗留 模板仍保留 cloud 云代理区块;当前单选仅暴露 none / EnterpriseWeChat。常量中还有旧值 local(企业号本地绑定),管理台 UI 已不再配置

页面布局(工具栏不随内容滚动):

  • 顶部 .weixin-toolbar:header_item,固定不滚;按钮仅 保存。
  • 下方 .weixin-scroll:分组表单与软件列表,独立 overflow-y: auto。
  • 父级 .weixinCon 为纵向 flex(height: 100%,overflow: hidden)。

同步、测试扫码不在顶部工具栏,而在对应分组**内容区字段同一行/下一行**:

位置 按钮
双向同步(读/写)通讯录 验证链接、同步本地组织架构到企业微信、从企业微信同步组织架构本地
单向同步(读)通讯录 验证、从企业微信同步组织架构本地
扫码登录 测试扫码(弹窗出码,不登录系统)

验证连接成功后只提示验证结果;通讯录同步仍在对应分组内操作。

分组标题左侧绿色竖线与标题文字垂直居中;必填红星只出现在文案**右侧**(require-asterisk-position="right")。

2.2 域级配置字段(wechatConfigs)

开启企业微信后,页面按能力分组(与钉钉配置页同一套 part / smallHeader 样式):

分组 前端字段 界面文案 落库 用途
启用企业微信 weixinCorpID 企业微信CorpID(必填) WEIXIN_CORP_ID 企业身份;OAuth appid、gettoken corpid
启用企业微信 serverHost 外网访问系统地址 SERVER_HOST OAuth redirect_uri 基址、消息跳转、验证可达性
启用企业微信 weixinVerifyFileName 企业微信认证文件 WEIXIN_CONFIG.verifyFileName 可信域名校验文件名;磁盘 {storageRoot}/weixin-verify/
双向同步(读/写)通讯录 weixinCorpSecret 通讯录Secret WEIXIN_CORP_SECRET 通讯录写权限 token;OBPM→微信写组织
双向同步(读/写)通讯录 weixinSyncRwEnable 开启 WEIXIN_SYNC_RW_ENABLE 是否启用该组能力
单向同步(读)通讯录 weixinAgentId / weixinSecret 应用AgentId(已开通通讯录权限) / 应用Secret WEIXIN_CONFIG 保留键 EnterpriseWeChat 微信→OBPM 读组织、同步读 token
单向同步(读)通讯录 weixinSyncReadEnable 开启 WEIXIN_SYNC_READ_ENABLE 是否启用该组能力
扫码登录 weixinQrCodeAgentId 应用AgentId(已开通扫码登录权限) WEIXIN_QRCODE_AGENTID PC 扫码登录应用
扫码登录 weixinQrCodeSecret 应用Secret WEIXIN_QRCODE_SECRET 扫码换 token
扫码登录 weixinQrCodeCallbackUrl 扫码CallbackUrl WEIXIN_QRCODE_CALLBACKURL 正式扫码回调地址(测试扫码的 redirect_uri 取其协议+域名)
扫码登录 weixinQrCodeEnable 开启 WEIXIN_QRCODE_ENABLE 是否启用扫码登录

另外:weixinProxyType 在「启用企业微信」分组标题旁单选(none / EnterpriseWeChat),列 WEIXIN_PROXY_TYPE。

表单校验:选中企业微信时,weixinCorpID 必填;某分组勾选「开启」后,该组字段必填(双向:通讯录 Secret;单向:AgentId+Secret;扫码:AgentId+Secret+CallbackUrl)。未开启的分组不校验。

未配置只读通讯录 AgentId/Secret 时,WeixinSecretCache.get(domainId, "EnterpriseWeChat") 仍回退到域下第一个已配软件级凭证(兼容旧数据)。

2.3 软件级配置(wechatConfigs.apps[])

域下已绑定软件列表,每项可编辑:

字段 说明
weixinAgentId 企业微信自建应用 AgentId
weixinSecret 该应用 Secret(发消息、应用级 OAuth、JS-SDK)

存储不在独立表,而在域字段 WEIXIN_CONFIG(JSON):

{
  "weixinAgentId": {
    "EnterpriseWeChat": "1000001",
    "<applicationId>": "1000003"
  },
  "weixinSecret": {
    "EnterpriseWeChat": "<contacts-read-secret>",
    "<applicationId>": "<app-secret>"
  },
  "verifyFileName": "WW_verify_AIlEBTeMZWjzofq8.txt"
}

保留键 EnterpriseWeChat 表示域级「单向同步(读)通讯录」凭证,不是真实软件 id。软件级仍按 applicationId 存 AgentId/Secret。

对应 Java:WeixinConfig / DomainVO.getWeixinAgentId(appId) / setWeixinSecret(appId, secret)。

2.4 页面操作 ↔ API

操作 前端方法 API(src/api.js) 后端
加载配置 created → getWechatConfig GET .../domain/{id}/wechat getWechatConfig
保存域配置 onSaveBtnClick PUT .../domain/{id}/wechat saveWechatConfig
上传认证文件 uploadVerifyFile POST .../wechat/verifyfile uploadWeixinVerifyFile
验证连接 onVerifyBtnClick GET .../wechat/corp/{corpid}/corpsecret/{corpsecret}?serverHost= validationExtranetAccessAddress
验证只读通讯录 Secret onVerifyReadSecret GET .../wechat/accesstoken?corpid=&corpsecret= verifyWechatAccessToken(gettoken 成功即通过,不返回 token)
保存 AgentId onSaveWeixinAgentId PUT .../updateWeixinAgentId?id= updateWeixinAgentId
保存应用 Secret onSaveWeixinSecret PUT .../updateWeixinSecret?secret= updateWeixinSecret
生成跳转链接 genWeChatURL GET .../getwechaturl getWechatUrl
微信→OBPM 同步 onSynFromWeixin PUT .../synchfromwechat synchFromWechat
OBPM→微信 同步 onSync2Weixin PUT .../synch2wechat synch2Wechat
测试扫码 onTestQrCode POST .../wechat/qrcode/test + 轮询 GET .../qrcode/test/status startWechatQrCodeTest / getWechatQrCodeTestStatus;回调 GET .../qrcode/test/callback 匿名

基址:${manager-context}/api/authtime。

2.5 企业微信域名认证文件

企业微信校验可信域名时会请求站点根路径:

https://{host}/WW_verify_{token}.txt

实现:

  1. 管理台「启用企业微信」组上传 WW_verify_xxx.txt(文件名必须匹配 ^WW_verify_[A-Za-z0-9]+\.txt$,上限 16KB)。
  2. 文件写入 {storageRoot}/weixin-verify/{原文件名};文件名记入 WEIXIN_CONFIG.verifyFileName。
  3. WeixinDomainVerifyFilter(obpm-common,order HIGHEST_PRECEDENCE+2)拦截 GET/HEAD,原样返回 text/plain 内容;未找到则 404。
  4. 微服务下站点根路径由 Nginx 反代到 manager:/WW_verify_* → {manager}/WW_verify_*(避免被静态 location / 吃掉)。lite 一体化且 context 为 / 时可直接由过滤器响应。

公开访问不走登录;上传接口需管理员鉴权。


3. 数据模型与凭证枢纽

3.1 主要表字段

T_DOMAIN(企业域)

列 含义
WEIXIN_PROXY_TYPE 代理类型
WEIXIN_CORP_ID / WEIXIN_CORP_SECRET 企业 ID / 通讯录 Secret
SERVER_HOST 公网基址
WEIXIN_QRCODE_* 扫码登录三项
WEIXIN_SYNC_RW_ENABLE / WEIXIN_SYNC_READ_ENABLE / WEIXIN_QRCODE_ENABLE 双向同步 / 单向同步 / 扫码登录开关(未落库时按对应 Secret 是否已填推断)
WEIXIN_CONFIG 按软件的 AgentId/Secret JSON
WEIXIN_TOKEN / WEIXIN_ENCODING_AESKEY 回调加解密(管理台本页未暴露,用于事件回调)
WEIXIN_AGENT_ID 旧版单应用 AgentId(兼容)

实体:DomainVO(core)、DomainPO(usercenter)、signon.auth.model.Domain(扫码读同一列,字段名 weixinCorpId)。

T_DEPARTMENT

列 含义
WEIXIN_DEPT_ID 与企业微信部门 id 的映射

3.2 WeixinSecret 与双 Secret 模型

运行时统一封装为 WeixinSecret:corpID、corpSecret、agentId、serverHost、token、encodingAESKey。

flowchart LR
  D["DomainVO"] --> C1["WeixinSecretCache.get(domainId)<br/>CorpID + 通讯录Secret"]
  D --> C2["WeixinSecretCache.get(domainId, appId)<br/>CorpID + 应用Secret + AgentId"]
  C1 --> W["通讯录写 / 部分同步"]
  C2 --> A["发消息 / OAuth / JS-SDK"]
  C1 & C2 --> T["QyApiService.getAccessToken<br/>https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=&corpsecret="]
缓存取法 Secret 来源 典型用途
get(domainId) weixinCorpSecret(通讯录) 创建/更新微信侧部门与用户(写)
get(domainId, "EnterpriseWeChat") WEIXIN_CONFIG 保留键 AgentId+Secret;若未配则回退第一个已配软件 双向/单向同步的**读** token
get(domainId, applicationId) 该软件 AgentId+Secret 发消息 / OAuth / JS-SDK

Token 内存缓存 key:corpid + corpsecret。配置变更后 saveWechatConfig 会 WeixinServiceProxy.cleanWeixinSecretCache()。


4. 配置保存与验证流程

sequenceDiagram
  participant Page as weixin.vue
  participant API as WechatAuthtimeController
  participant Dom as DomainProcess / T_DOMAIN
  participant Cache as WeixinSecretCache
  participant WX as 企业微信 qyapi

  Page->>API: GET /domain/{id}/wechat
  API->>Dom: doView
  API-->>Page: wechatConfigs + apps

  Page->>API: GET .../corp/{corpid}/corpsecret/{secret}?serverHost=
  API->>WX: gettoken(corpid, corpsecret)
  API->>API: HTTP GET serverHost/.../static/mobile/index.html
  API-->>Page: 验证成功 / 失败

  Page->>API: PUT /domain/{id}/wechat (整包配置)
  API->>Dom: setWeixin* + doCreateOrUpdate
  API->>Cache: clear
  API-->>Page: 保存成功

**验证连接**两步:

  1. 用页面上的 CorpID + 通讯录 Secret 换 access_token(可不先保存)。
  2. 探测 serverHost(兼容去掉 /obpm)下移动端首页是否 HTTP 200。

5. 通讯录同步

入口按钮文案与方向:

按钮 API 实现 方向
从企业微信同步组织架构本地 PUT .../synchfromwechat WeixinService.synchFromWeixin 微信 → OBPM
同步本地组织架构到企业微信 PUT .../synch2wechat WeixinService.synch2Weixin OBPM → 微信

结果弹窗 weixin_result.vue 展示:DEPT_ADD_SUCCESS/FAIL、USER_ADD_SUCCESS/FAIL、ERRORS[]。

前置条件:License 检查(当前 validLicenseAuth() 恒为 true);企业微信侧有部门;EnterpriseWeChat 模式下通常还需至少一个软件已配 AgentId+Secret(读 token)。

5.1 微信 → OBPM(synchFromWeixin)

flowchart TD
  A["取 access_token<br/>Cache.get(domainId, EnterpriseWeChat)"] --> B["QyApiService.getDepartmentList"]
  B --> C["按 level 处理部门"]
  C --> C1["根部门:更新本地域根名称 + weixinDeptId"]
  C --> C2["子部门:按 weixinDeptId / 同名同层匹配或新建"]
  C --> D["按部门拉取成员 getUsersByDepartment"]
  D --> E{"loginno == wx.userid 是否存在?"}
  E -->|否| F["新建 UserVO<br/>loginno=userid<br/>默认密码等"]
  E -->|是| G["更新姓名/手机/邮箱/部门/扩展字段"]
  F & G --> H["回写成功失败计数与 ERRORS"]

要点:

  • 部门映射写入 DepartmentVO.weixinDeptId。
  • 用户主键对齐:User.userid → UserVO.loginno;新建时赋默认密码、标准日历、在职状态,可拉头像。
  • 多部门成员会挂到多个本地部门;默认部门取同步遍历中的部门。

5.2 OBPM → 微信(synch2Weixin)

flowchart TD
  A["读 token = get(domain, EnterpriseWeChat)<br/>写 token = get(domain) 通讯录Secret"] --> B["查询本地域有效部门 level 升序"]
  B --> C["根部门:无则 createDepartment,有则 update"]
  C --> D["子部门:按 weixinDeptId 更新或 create,回写 weixinDeptId"]
  D --> E["遍历域用户 queryByDomain"]
  E --> F{"微信是否已有 loginno?"}
  F -->|有| G["字段有变更则 updateUser(写 token)"]
  F -->|无| H{"在职且手机或邮箱非空?"}
  H -->|是| I["createUser,userid=loginno"]
  H -->|否| J["记入 ERRORS 跳过"]

要点:

  • **读**用应用侧 token,**写**用通讯录 Secret(modify_access_token)。
  • 失效部门/用户、无手机且无邮箱的用户不同步创建。
  • 日常在管理台改用户时,UserAuthtimeController / UserUtil 还会异步投递 queue-user-weixin,调用 createOrUpdateUser2Weixin 做增量同步。

6. 扫码登录(PC)

与应用内 OAuth 是两条路径:扫码走 signon,配置使用 扫码专用 AgentId / Secret / CallbackUrl。

sequenceDiagram
  participant Login as 登录页 signon-web
  participant Signon as LoginController
  participant DB as T_DOMAIN
  participant WX as 企业微信

  Login->>Signon: GET /api/runtime/login/getwxconfig?domainName=
  Signon->>DB: 读 WEIXIN_CORP_ID / QRCODE_*
  Signon-->>Login: appId=CorpID, agentId, callbackUrl
  Login->>WX: 企业微信扫码组件(WwLogin 等)
  WX->>Signon: GET /api/runtime/login/wxqrcodelogin?code=&state=
  Note over Signon: state = contentPath@domainName
  Signon->>WX: gettoken(CorpID, weixinQrCodeSecret)
  Signon->>WX: getuserinfo → UserId
  Signon->>DB: Account(username=UserId) + User(domain)
  Signon-->>Login: Set-Cookie accessToken,跳转 dispatcher.html
步骤 说明
取配置 appId = domain.weixinCorpId(即管理台 CorpID)
换用户 WeixinUtil.getAccessToken(corpId, weixinQrCodeSecret) + getUserId
落本地用户 Account.username / 域内用户需与企业微信 UserId(通常即 loginno)一致
回调 URL 管理台配置的 weixinQrCodeCallbackUrl,需与企业微信应用可信域名一致

管理台占位示例:http://www.xxx.com/signon/runtime/login/wxqrcodelogin(部署时按实际 signon 上下文调整)。

6.1 管理台「测试扫码」

扫码登录分组**内容区**(CallbackUrl 下方)提供 测试扫码,用于验证 AgentId / Secret / 回调域是否可用,不会登录系统。顶部工具栏无此按钮。

sequenceDiagram
  participant Page as weixin.vue
  participant API as WechatAuthtimeController
  participant Store as WeixinQrCodeTestSupport
  participant WX as 企业微信 WwLogin

  Page->>API: POST /domain/{id}/wechat/qrcode/test
  API->>Store: 创建 ticket(5 分钟)
  API-->>Page: appId / agentId / redirectUri / state=ticket
  Page->>WX: WwLogin 弹出二维码
  WX->>API: GET .../qrcode/test/callback?code=&state=ticket
  Note over API: 匿名;redirect_uri 取 CallbackUrl 的协议+域名
  API->>WX: gettoken(CorpID, weixinQrCodeSecret) + getuserinfo
  API->>Store: ticket = success(UserId) / fail
  Page->>API: 轮询 GET .../qrcode/test/status?ticket=
  API-->>Page: pending / success / fail

要点:

  • 弹窗用企业微信官方 WwLogin 出码;扫完后 iframe 跳到测试回调页,管理台轮询(或 postMessage)展示成功/失败。
  • redirect_uri 必须落在应用「授权回调域」:从已保存的 weixinQrCodeCallbackUrl 取 host,拼 {manager-context}/api/authtime/domain/{id}/wechat/qrcode/test/callback。本机 Vite(如 localhost:5174)若回调域不是该 host,扫码后企业微信无法打到当前 manager。
  • 回调匿名(ManagerSecurityFilter 放行该路径);开始/轮询接口仍需管理员登录。
  • 成功时展示企业微信 UserId;非企业成员(仅 OpenId)记为失败。

7. URL 跳转(应用内 OAuth / SSO)

用于:企业微信工作台「进入系统」、流程待办图文卡片、表单二维码在微信内打开等。

7.1 管理台「生成跳转链接」

getWechatUrl 拼装:

https://open.weixin.qq.com/connect/oauth2/authorize
  ?appid={weixinCorpID}
  &redirect_uri={URLEncode(serverHost/obpm/api/sso?application=...&jumpTo=...)}
  &response_type=code
  &scope=snsapi_base
  &agentid={软件 AgentId}
  &state={domainId}
  #wechat_redirect
  • 普通软件:jumpTo → /static/mobile/index.html#/?application={appId}
  • KM 特例:application=km,跳 KMS 移动页

前端 weixinUrl.vue 展示可复制链接。

7.2 运行时免登链路

sequenceDiagram
  participant User as 企业微信客户端
  participant WX as open.weixin.qq.com
  participant RT as Runtime /api/sso
  participant Filter as RuntimeSecurityFilter
  participant Auth as WeixinService.auth
  participant QY as qyapi

  User->>WX: 打开授权 URL
  WX->>RT: redirect_uri?code=&state=domainId&application=
  Filter->>Filter: URI 含 /sso 且带 code/state → 微信 OAuth
  Filter->>Auth: WeixinServiceProxy.auth
  Auth->>QY: gettoken(应用 Secret) + getuserinfo(code, agentId)
  Auth->>Auth: loginno / 手机 / 邮箱 匹配 UserVO
  Auth-->>Filter: accessToken + serverHost
  Filter-->>User: 脚本跳转 jumpTo?accessToken=

关键实现:

  1. RuntimeSecurityFilter:未登录且命中 /sso+code+state 时走微信 OAuth(实现里 User-Agent 判断写死为常量 "MicroMessenger",实际以 URI/参数为准)。
  2. WeixinService.auth:state=域 id;用 WeixinSecretCache.get(domainId, applicationId);UserId 依次按 loginno → 手机 → 邮箱查找;签发 Cookie accessToken,返回 token,serverHost。
  3. Filter 拼 serverHost + jumpTo + accessToken 完成落地页跳转。

7.3 其它拼装 OAuth URL 的位置

场景 代码
流程待办图文 WeixinService.send → redirect 到 /obpm/api/sso?...&jumpTo=打开文档
关注企业号欢迎图 EventCallbackService.handleSubscribeEvent
表单二维码微信内打开 QRCodeFiledScanEventReadyServlet.getWeiXinOAuthUrl

共同点:appid 一律用 CorpID。


8. 发送消息

8.1 触发入口

入口 说明
流程通知 Notification 注册 WeixinMode;待办等节点触发 WeixinMode.send → WeixinService.send
脚本 / 工具 MessageUtil.sendTextMessage / sendRichTextMessage / sendMessage
关注/进入应用回调 EventCallbackService 直接 MessageService.send

8.2 待办图文消息流程

flowchart LR
  N["流程 Notification"] --> M["WeixinMode"]
  M --> S["WeixinService.send(title, desc, loginno, doc)"]
  S --> C["WeixinSecretCache.get(domainId, applicationId)"]
  S --> U["拼 OAuth 链接<br/>appid=CorpID → /obpm/api/sso → 打开表单"]
  S --> Q["NewsMessage 入 JMS<br/>queue-message-weixin"]
  Q --> H["WeixinMessageQueue.handle"]
  H --> API["MessageService.send<br/>qyapi message/send"]

要点:

  • 接收人:touser = 用户 loginno(企业微信 userid)。
  • agentid:来自该软件在 WEIXIN_CONFIG 中的 AgentId。
  • Token:该软件应用 Secret 换取。
  • 异步:WeixinMessageQueue 监听 queue-message-weixin,真正 POST https://qyapi.weixin.qq.com/cgi-bin/message/send。
  • 用户增量同步走另一队列 queue-user-weixin。

8.3 其它消息类型

方法 类型 说明
send news 待办:标题 + 摘要 + OAuth 深链
sendRichTextMessage news 自定义 url/pic
sendTextMessage text 纯文本;pm/qm 等内置应用 id 有映射
sendMessage 自定义 JSON 按企业微信消息格式透传

均受 validLicenseAuth() 门控(当前恒 true)。


9. 相关能力(本页衍生)

能力 说明
JS-SDK Runtime WeixinServiceController → getJsapiConfig;appId=CorpID,ticket 按 CorpID 缓存
事件回调 validWeixinUrl / handelWeixinCallbackEvent:用 WEIXIN_TOKEN + ENCODING_AESKEY + CorpID 做 WXBizMsgCrypt

接口清单见 [[../../restful-api/manager/wechat-authtime]]。


10. 配置清单(落地检查)

在企业微信管理后台与 OBPM 管理台需对齐:

  1. CorpID → weixinCorpID(必填)
  2. 通讯录同步 Secret → weixinCorpSecret(OBPM→微信写组织必备)
  3. 只读通讯录应用 AgentId + Secret → 域级 weixinAgentId / weixinSecret(微信→OBPM 读组织;未配时回退软件级凭证)
  4. 每个要进工作台/发消息的软件:自建应用 AgentId + Secret → 表格编辑
  5. 外网 serverHost:可被企业微信服务器与终端访问;OAuth 可信域名与之匹配
  6. 域名认证文件:在「启用企业微信」组上传企业微信下发的 WW_verify_xxx.txt,使 https://{host}/WW_verify_xxx.txt 可匿名访问
  7. 扫码登录应用(可选):开启后 AgentId / Secret / 回调 URL 必填;可用组内 测试扫码 验证(不登录)
  8. 用户对齐:loginno 与企业微信成员账号一致(或至少手机/邮箱能匹配 OAuth)

11. 实现备注(源码现状)

  1. 只读通讯录凭证:域级 AgentId/Secret 写入 WEIXIN_CONFIG 保留键 EnterpriseWeChat,与软件级配置共用 JSON,不新增表列。
  2. License:validLicenseAuth() 内写死 true,原 WarpProcessFactory.isWeixinEnable() 已注释。
  3. 双 token 同步:synch2Weixin 读用只读通讯录(或回退软件)Secret、写用通讯录 Secret;通讯录 API 权限需在企业微信侧正确授权。
  4. 云代理 / local:代码与常量仍有残留,当前管理台主路径是 EnterpriseWeChat。
  5. 域名认证文件:上传接口写入存储目录;公开 GET 必须打到能读到该目录的服务(默认 Nginx 反代到 manager),不要只把文件拷到 Tomcat ROOT。
  6. 分组开启开关:WEIXIN_SYNC_RW_ENABLE / WEIXIN_SYNC_READ_ENABLE / WEIXIN_QRCODE_ENABLE。lite 的 ddl-auto=none 不会自动加列,需执行:
ALTER TABLE T_DOMAIN
  ADD COLUMN WEIXIN_SYNC_RW_ENABLE BIT NULL,
  ADD COLUMN WEIXIN_SYNC_READ_ENABLE BIT NULL,
  ADD COLUMN WEIXIN_QRCODE_ENABLE BIT NULL;
  1. isRequireWeixinAuth:User-Agent 写成字面量 "MicroMessenger",未读请求头;实际依赖 URI /sso + code + state。
  2. 页面滚动:工具栏与内容拆开(.weixin-toolbar / .weixin-scroll),避免保存条随表单滚动消失。
  3. 测试扫码:WeixinQrCodeTestSupport 内存 ticket(约 5 分钟);回调路径由 ManagerSecurityFilter 匿名放行;正式登录仍走 signon wxqrcodelogin。

12. 源码索引

层级 路径
配置页 web/obpm-manager-vue3/src/components/weixin.vue
跳转结果 / 同步结果 weixinUrl.vue、weixin_result.vue
前端 API web/obpm-manager-vue3/src/api.js(约 7.x 微信段,含 startWeixinQrCodeTest / getWeixinQrCodeTestStatus)
管理控制器 java/obpm-manager/.../wechat/WechatAuthtimeController.java
测试扫码 ticket java/obpm-common/.../support/wecom/WeixinQrCodeTestSupport.java
测试扫码回调放行 java/obpm-manager/.../filter/ManagerSecurityFilter.java(/wechat/qrcode/test/callback)
认证文件过滤器 java/obpm-common/.../web/WeixinDomainVerifyFilter.java、.../support/wecom/WeixinDomainVerifySupport.java
域模型 / 按软件配置 DomainVO、WeixinConfig、DomainPO
凭证缓存 WeixinSecretCache、WeixinSecret
企业微信 HTTP QyApiService、MessageService
业务门面 WeixinService、WeixinServiceProxy
消息/用户队列 WeixinMessageQueue、JmsConfig.QUEUE_*_WEIXIN
流程通知 Notification、WeixinMode
OAuth SSO RuntimeSecurityFilter、WeixinService.auth
扫码登录 signon/.../LoginController(getwxconfig / wxqrcodelogin)、WeixinUtil
表单二维码 QRCodeFiledScanEventReadyServlet