Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
修复评审意见:修复 agentId 分组 null 冲突 bug,修正 Javadoc HTML 结构,完善 README 配置限制说明和…
…示例代码

Agent-Logs-Url: https://github.com/binarywang/WxJava/sessions/dcb81708-f62f-4f63-837b-0e62c1da2883

Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
  • Loading branch information
Copilot and binarywang authored Apr 11, 2026
commit aaa3e7e9fc57273dbacd10632a28138a864f8951
9 changes: 7 additions & 2 deletions solon-plugins/wx-java-cp-multi-solon-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
如需同时使用多种权限范围,可在 `wx.cp.corps` 下配置多个条目,每个条目使用对应权限的 Secret,通过不同的 `tenantId` 区分后使用。

Comment thread
binarywang marked this conversation as resolved.
> **注意**:
> 当前 starter/插件实现会校验同一 `corp-id` 下的 `agent-id` **必须唯一**,并且 **只能有一个条目不填写 `agent-id`**。
> 当前插件实现会校验同一 `corp-id` 下的 `agent-id` **必须唯一**,并且 **只能有一个条目不填写 `agent-id`**。
> 如果在同一 `corp-id` 下同时配置多个未填写 `agent-id` 的条目,会因 token/ticket 缓存 key 冲突而在启动时直接抛异常。
## 快速开始

Expand Down Expand Up @@ -77,6 +77,7 @@ import com.binarywang.solon.wxjava.cp_multi.service.WxCpMultiServices;
import me.chanjar.weixin.cp.api.WxCpDepartmentService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.WxCpUserService;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

Expand All @@ -96,7 +97,11 @@ public class DemoService {
// 通讯录同步 Secret 具有部门/成员增删改查等权限
WxCpService contactService = wxCpMultiServices.getWxCpService("contact");
WxCpDepartmentService departmentService = contactService.getDepartmentService();
departmentService.update(department);
// 更新部门示例(WxCpDepart 包含 id、name、parentId 等字段)
WxCpDepart depart = new WxCpDepart();
depart.setId(100L);
depart.setName("新部门名称");
departmentService.update(depart);
// todo ...
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

Expand All @@ -37,13 +38,12 @@ protected WxCpMultiServices wxCpMultiServices(WxCpMultiProperties wxCpMultiPrope
/**
* 校验同一个企业下,agentId 是否唯一,避免使用 redis 缓存 token、ticket 时错乱。
*
* <p>同一企业(corpId 相同)下可配置多个条目以使用不同的权限 Secret,例如:
* <p>同一企业(corpId 相同)下可配置多个条目以使用不同的权限 Secret,例如:</p>
* <ul>
* <li>自建应用条目:填写应用对应的 corpSecret 和 agentId</li>
* <li>通讯录同步条目:填写通讯录同步 Secret,agentId 可不填(null)</li>
* </ul>
* 但同一 corpId 下不允许出现重复的 agentId(包括多个 null)。
* </p>
* <p>但同一 corpId 下不允许出现重复的 agentId(包括多个 null)。</p>
*
* 查看 {@link me.chanjar.weixin.cp.config.impl.AbstractWxCpInRedisConfigImpl#setAgentId(Integer)}
*/
Expand All @@ -57,8 +57,8 @@ protected WxCpMultiServices wxCpMultiServices(WxCpMultiProperties wxCpMultiPrope
String corpId = entry.getKey();
// 校验每个企业下,agentId 是否唯一
boolean multi = entry.getValue().stream()
// 通讯录没有 agentId,如果不判断是否为空,这里会报 NPE 异常
.collect(Collectors.groupingBy(c -> c.getAgentId() == null ? 0 : c.getAgentId(), Collectors.counting()))
// 通讯录没有 agentId,使用字符串转换避免 null 与 agentId=0 冲突
.collect(Collectors.groupingBy(c -> Objects.toString(c.getAgentId(), "null"), Collectors.counting()))
.entrySet().stream().anyMatch(e -> e.getValue() > 1);
if (multi) {
throw new RuntimeException("请确保企业微信配置唯一性[" + corpId + "]");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@

如需同时使用多种权限范围,可在 `wx.cp.corps` 下配置多个条目,每个条目使用对应权限的 Secret,通过不同的 `tenantId` 区分后使用。
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spring-boot-starters/wx-java-cp-multi-spring-boot-starter/README.md:23 这里说可通过不同 tenantId 配置多个条目同时使用多种 Secret,但当前实现会将 agentId == null 统一归为 0 并禁止同一 corpId 下出现多个 null。若同时配置多个“不需要 agent-id”的 Secret(如通讯录同步 + 客户联系)会触发唯一性校验异常,文档可提示这一限制。

Severity: medium

Other Locations
  • solon-plugins/wx-java-cp-multi-solon-plugin/README.md:23

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.


Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里提到“可配置多个条目…通讯录同步条目不填 agent-id”,同时表格中也有多个“不填 agent-id”的 Secret 类型。需要补充说明:当前 starter/插件实现会校验同一 corp-idagent-id 必须唯一,且 只能有一个条目 agent-id 为空(否则 token/ticket 缓存 key 会冲突并直接抛异常)。否则用户可能按表格同时配置多个不填 agent-id 的条目而启动失败。

Suggested change
> **配置限制说明**
> - 当前 starter/插件实现会校验:同一 `corp-id` 下,`agent-id` **必须唯一**
> - 同一 `corp-id` 下,**只能有一个条目不填 `agent-id`**
> - 否则会因为 token/ticket 缓存 key 冲突而在启动时直接抛异常
>
> 因此,像“通讯录同步 Secret”“客户联系 Secret”这类通常不填写 `agent-id` 的配置,**不能**在同一个 `corp-id` 下同时配置多个都为空 `agent-id` 的条目;如确有多个条目,请确保其中最多只有一个未填写 `agent-id``

Copilot uses AI. Check for mistakes.
> **配置限制说明**:
> - 当前 starter 实现会校验:同一 `corp-id` 下,`agent-id` **必须唯一**
> - 同一 `corp-id` 下,**只能有一个条目不填 `agent-id`**
> - 否则会因为 token/ticket 缓存 key 冲突而在启动时直接抛异常
>
> 因此,像"通讯录同步 Secret""客户联系 Secret"这类通常不填写 `agent-id` 的配置,**不能**在同一个 `corp-id` 下同时配置多个 `agent-id` 均为空的条目;如确有多个条目,请确保其中最多只有一个未填写 `agent-id`。

## 快速开始

1. 引入依赖
Expand Down Expand Up @@ -74,6 +81,7 @@ import com.binarywang.spring.starter.wxjava.cp.service.WxCpMultiServices;
import me.chanjar.weixin.cp.api.WxCpDepartmentService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.WxCpUserService;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

Expand All @@ -93,7 +101,11 @@ public class DemoService {
// 通讯录同步 Secret 具有部门/成员增删改查等权限
WxCpService contactService = wxCpMultiServices.getWxCpService("contact");
WxCpDepartmentService departmentService = contactService.getDepartmentService();
departmentService.update(department);
// 更新部门示例(WxCpDepart 包含 id、name、parentId 等字段)
WxCpDepart depart = new WxCpDepart();
depart.setId(100L);
depart.setName("新部门名称");
departmentService.update(depart);
// todo ...
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -59,8 +60,8 @@ protected WxCpMultiServices wxCpMultiServices(WxCpMultiProperties wxCpMultiPrope
String corpId = entry.getKey();
// 校验每个企业下,agentId 是否唯一
boolean multi = entry.getValue().stream()
// 通讯录没有 agentId,如果不判断是否为空,这里会报 NPE 异常
.collect(Collectors.groupingBy(c -> c.getAgentId() == null ? 0 : c.getAgentId(), Collectors.counting()))
// 通讯录没有 agentId,使用字符串转换避免 null 与 agentId=0 冲突
.collect(Collectors.groupingBy(c -> Objects.toString(c.getAgentId(), "null"), Collectors.counting()))
.entrySet().stream().anyMatch(e -> e.getValue() > 1);
if (multi) {
throw new RuntimeException("请确保企业微信配置唯一性[" + corpId + "]");
Expand Down