首页 > 基础资料 博客日记

weixin-java-cp-demo:基于Spring Boot和WxJava实现的微信企业号集群环境配置

2024-11-05 21:00:07基础资料围观35

文章weixin-java-cp-demo:基于Spring Boot和WxJava实现的微信企业号集群环境配置分享给大家,欢迎收藏Java资料网,专注分享技术知识

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));
				// 提取 accountConfig 字段,并将其映射为 List<WxCpDefaultConfigImpl>
				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;

	/**
	 * 唯一id
	 */
	private String uniqueId;

	/**
	 * 头像
	 */
	private String cover;

    /**
     * 发送渠道
     */
    private Integer sendChannel;

    /**
     * 账号配置
     */
    private String accountConfig;

	/**
	 * 账号状态 0-登录失效 1-登录成功
	 */
	private Integer status;
}

基类

@Getter
@Setter
@Accessors(chain = true)
public class BaseDomain extends BaseEntity{
	/**
	 * 自增主键
	 */
	private Integer autoPk;

	/**
	 * 业务主键
	 */
	@TableId(type = IdType.ASSIGN_ID)
	private Long id;

	/**
	 * 租户id
	 */
	@TableField(fill = FieldFill.INSERT)
	private Integer tenantId;

	@TableField(exist=false)
	private Integer tenantIdManual;

	@TableField(exist=false)
	private Long groupByCount;

	/**
	 * 逻辑删除的标记位(0:否,1:是)
	 * 赋予默认值是为了批量新增的时候不报非空字段的错误
	 */
	@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;

}

文章来源:https://blog.csdn.net/qq_17287341/article/details/141864204
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云