pom依赖
<dependencies>
<!--微信服务号第三方SDK-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-cp</artifactId>
<version>${weixin-java}</version>
</dependency>
</dependencies>
Redis初始类
@Component
public class RedissonClientInitializer {
@Value("${wecom.redis.database}")
private int database;
@Value("${wecom.redis.host}")
private String host;
@Value("${wecom.redis.port}")
private String port;
@Value("${wecom.redis.password}")
private String password;
public RedissonClient initialize() {
Config config = new Config();
config.useSingleServer().setAddress(String.format("redis://%s:%s", this.host, this.port));
if (!this.password.isEmpty()) {
config.useSingleServer().setPassword(this.password);
}
config.useSingleServer().setDatabase(this.database);
StringCodec codec = new StringCodec();
config.setCodec(codec);
return Redisson.create(config);
}
}
企业微信配置类
@Configuration
@RequiredArgsConstructor
@Slf4j
public class WxCpConfiguration {
private final AccountMapper accountMapper;
private final TenantMapper tenantMapper;
private final RedissonClientInitializer initializer;
private static Map<String, WxCpService> cpServices = new ConcurrentHashMap<>();
public WxCpService getCpService(String corpId, Integer agentId) {
WxCpService cpService = cpServices.get(corpId + agentId);
if (!Optional.ofNullable(cpService).isPresent()) {
Account account = accountMapper.selectOne(Wrappers.<Account>lambdaQuery().eq(Account::getUniqueId, corpId + agentId));
if (!ObjectUtils.isEmpty(account)) {
WxCpDefaultConfigImpl config = JSONObject.parseObject(account.getAccountConfig(), WxCpDefaultConfigImpl.class);
log.info("config:{}",config);
WxCpRedissonConfigImpl redissonConfig = new WxCpRedissonConfigImpl(initializer.initialize(), "workRedis:");
redissonConfig.setCorpId(config.getCorpId());
redissonConfig.setAgentId(config.getAgentId());
redissonConfig.setCorpSecret(config.getCorpSecret());
WxCpServiceImpl wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(redissonConfig);
setCpService(corpId, agentId, wxCpService);
log.info("缓存已更新:corpId:{},agentId:{}",corpId,agentId);
return wxCpService;
}
}
return Optional.ofNullable(cpService).orElseThrow(() -> {
log.error("未找到 corpId: {}, agentId: {} 对应的 WxCpService", corpId, agentId);
return new CommonException("未配置此service");
});
}
public static void setCpService(String corpId, Integer agentId,WxCpServiceImpl service) {
cpServices.put(corpId + agentId, service);
}
@PostConstruct
public void initServices() {
try {
List<Tenant> tenants = tenantMapper.selectList(Wrappers.emptyWrapper());
for (Tenant tenant : tenants) {
String dsKey = SecurityConstants.PROJECT_PREFIX + tenant.getTenantId();
DynamicDataSourceContextHolder.push(dsKey);
List<Account> accounts = accountMapper.selectList(new LambdaQueryWrapper<Account>().eq(Account::getSendChannel, 1));
List<WxCpDefaultConfigImpl> list = accounts.stream()
.map(account -> JSON.parseObject(account.getAccountConfig(), WxCpDefaultConfigImpl.class))
.collect(Collectors.toList());
cpServices = list.stream().map(this::apply).filter(Optional::isPresent).map(Optional::get)
.collect(Collectors.toMap(service -> service.getWxCpConfigStorage().getCorpId() + service.getWxCpConfigStorage().getAgentId(), a -> a));
}
} catch (Exception e) {
log.error("企业微信初始化失败",e);
} finally {
DynamicDataSourceContextHolder.clear();
}
}
private Optional<WxCpServiceImpl> apply(WxCpDefaultConfigImpl a) {
if (ObjectUtils.isEmpty(a)) {
Optional.ofNullable(new WxCpServiceImpl());
}
WxCpRedissonConfigImpl config = new WxCpRedissonConfigImpl(initializer.initialize(), "workRedis:");
config.setCorpId(a.getCorpId());
config.setAgentId(a.getAgentId());
config.setCorpSecret(a.getCorpSecret());
config.setToken(a.getToken());
config.setAesKey(a.getAesKey());
val service = new WxCpServiceImpl();
service.setWxCpConfigStorage(config);
log.info("初始化企业微信服务:corpId:{},agentId:{}",a.getCorpId(),a.getAgentId());
return Optional.of(service);
}
}
企业微信保存
@PostMapping("/wecom/save")
@ApiOperation("企业微信保存数据")
public R saveWecom(@RequestBody WxCpAccountDTO channelAccount) {
AccountService accountService = accountServiceFactory.getAccountService(ENTERPRISE_WE_CHAT_SERVICE_NAME+ACCOUNT);
accountService.save(channelAccount);
return R.ok();
}
@Override
@Transactional
public void save(WxCpAccountDTO accountDTO) {
Account existAccount = getExistAccount(accountDTO.getConfig());
if (existAccount != null) {
throw new CommonException("07020004", existAccount.getName(), userInfoMapper.selectByUsername(existAccount.getCreateBy()).getTrueName());
}
WxCpDefaultConfigImpl config = BeanCopyUtils.turnToVO(accountDTO.getConfig(), WxCpDefaultConfigImpl.class);
WxCpServiceImpl wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(config);
String name;
try {
WxCpAgent wxCpAgent = wxCpService.getAgentService().get(config.getAgentId());
name = wxCpAgent.getName();
String cover = wxCpAgent.getSquareLogoUrl();
accountDTO.setName(name);
accountDTO.setCover(cover);
accountDTO.setAccountConfig(JSONObject.toJSONString(accountDTO.getConfig()));
accountDTO.setUniqueId(config.getCorpId() + config.getAgentId());
WxCpRedissonConfigImpl redissonConfig = new WxCpRedissonConfigImpl(initializer.initialize(), "workRedis:");
redissonConfig.setCorpId(config.getCorpId());
redissonConfig.setAgentId(config.getAgentId());
redissonConfig.setCorpSecret(config.getCorpSecret());
wxCpService.setWxCpConfigStorage(redissonConfig);
WxCpConfiguration.setCpService(config.getCorpId(), config.getAgentId(), wxCpService);
} catch (WxErrorException e) {
log.error("企业微信用户信息绑定失败:", e);
throw new CommonException("07020002", WxCpErrorMsgEnum.findMsgByCode(e.getError().getErrorCode()));
}
accountDomainService.save(accountDTO);
}
账号表
@Data
@TableName("new_media_account")
@Accessors(chain = true)
public class Account extends BaseDomain {
private String name;
private String uniqueId;
private String cover;
private Integer sendChannel;
private String accountConfig;
private Integer status;
}
基类
@Getter
@Setter
@Accessors(chain = true)
public class BaseDomain extends BaseEntity{
private Integer autoPk;
@TableId(type = IdType.ASSIGN_ID)
private Long id;
@TableField(fill = FieldFill.INSERT)
private Integer tenantId;
@TableField(exist=false)
private Integer tenantIdManual;
@TableField(exist=false)
private Long groupByCount;
@TableLogic
private Integer isDelete=0;
public Long generateId(){
IdentifierGenerator identifierGenerator = SpringContextHolder.getBean(IdentifierGenerator.class);
Number number = identifierGenerator.nextId(this);
this.setId(number.longValue());
return getId();
}
}
@Getter
@Setter
@Accessors(chain = true)
public class BaseEntity implements Serializable {
@TableField(fill = FieldFill.INSERT)
private String createBy;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}