package com.qqflow.engine.domain.ewechat.component; import com.qqflow.engine.common.service.RedissonService; import com.qqflow.engine.common.util.Assert; import com.qqflow.engine.common.util.RedisCache; import com.qqflow.engine.domain.ewechat.api.EnterpriseWechatApi; import com.qqflow.engine.domain.ewechat.assemble.EnterpriseWechatAssembler; import com.qqflow.engine.domain.ewechat.config.EnterpriseWechatProperties; import com.qqflow.engine.domain.ewechat.mapper.EnterpriseWechatCorpMapper; import com.qqflow.engine.domain.ewechat.enums.EnterpriseWechatInfoType; import com.qqflow.engine.domain.ewechat.model.enterprise.EnterpriseWechatEvent; import com.qqflow.engine.domain.ewechat.model.enterprise.callback.EnterpriseWechatAuthNotice; import com.qqflow.engine.domain.ewechat.model.enterprise.callback.EnterpriseWechatSuiteTicket; import com.qqflow.engine.domain.ewechat.model.enterprise.rsp.EnterpriseWechatPermanentCodeRsp; import com.qqflow.engine.domain.ewechat.model.enterprise.rsp.EnterpriseWechatSuiteAccessTokenRsp; import com.qqflow.engine.common.util.XmlUtil; import com.qqflow.engine.domain.ewechat.po.EnterpriseWechatCorp; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * @author WuWenYi * @see EnterpriseWechatInfoType * @since 2025/3/18 */ @Component @RequiredArgsConstructor public class EnterpriseWechatEventHandler { private static final String SUITE_TICKET_KEY_PREFIX = "suite_ticket::"; private static final String SUITE_ACCESS_TOKEN_KEY_PREFIX = "suite_access_token::"; private final EnterpriseWechatCorpMapper corpMapper; private final EnterpriseWechatAssembler assembler; private final EnterpriseWechatProperties wechatProperties; private final RedisCache redisCache; private final RedissonService redissonService; private final EnterpriseWechatApi enterpriseWechatApi; /** 授权事件 */ @EventListener(value = {EnterpriseWechatEvent.class}, condition = "#event.source.toString()=='create_auth'") public void createAuth(EnterpriseWechatEvent event) { EnterpriseWechatAuthNotice authNotice = XmlUtil.fromXml(event.getCallbackXml(), EnterpriseWechatAuthNotice.class); boolean locked = redissonService.tryLock("hanle-create-auth-event::" + authNotice.getSuiteId()); if (!locked) return; try { EnterpriseWechatPermanentCodeRsp permanentCodeRsp = this.fetchPermanentCode(authNotice); String corpid = permanentCodeRsp.getAuthCorpInfo().getCorpid(); EnterpriseWechatCorp wechatCorp = corpMapper.selectByCorpIdAndSuiteId(corpid, authNotice.getSuiteId()); if (wechatCorp == null) { corpMapper.insert(assembler.assembleCorp(permanentCodeRsp)); } else { wechatCorp.setPermanentCode(permanentCodeRsp.getPermanentCode()); corpMapper.updateById(wechatCorp); } } finally { redissonService.unlock("hanle-create-auth-event::" + authNotice.getSuiteId()); } } /** 取消授权事件 */ @EventListener(value = {EnterpriseWechatEvent.class}, condition = "#event.source.toString()=='cancel_auth'") public void cancelAuth(EnterpriseWechatEvent event) { // TODO: 取消授权事件处理 } /** 推送suite_ticket事件 */ @EventListener(value = {EnterpriseWechatEvent.class}, condition = "#event.source.toString()=='suite_ticket'") public void suiteTicket(EnterpriseWechatEvent event) { EnterpriseWechatSuiteTicket suiteTicket = XmlUtil.fromXml(event.getCallbackXml(), EnterpriseWechatSuiteTicket.class); String key = SUITE_TICKET_KEY_PREFIX + suiteTicket.getSuiteId(); redisCache.setCacheObject(key, suiteTicket.getSuiteTicket(), 60 * 30, TimeUnit.SECONDS); } /** 永久授权码更新事件(企业重新授权时触发) */ @EventListener(value = {EnterpriseWechatEvent.class}, condition = "#event.source.toString()=='reset_permanent_code'") public void resetPermanentCode(EnterpriseWechatEvent event) { EnterpriseWechatAuthNotice authNotice = XmlUtil.fromXml(event.getCallbackXml(), EnterpriseWechatAuthNotice.class); boolean locked = redissonService.tryLock("handle-reset-permanent-code::" + authNotice.getSuiteId()); if (!locked) return; try { EnterpriseWechatPermanentCodeRsp permanentCodeRsp = this.fetchPermanentCode(authNotice); String corpid = permanentCodeRsp.getAuthCorpInfo().getCorpid(); EnterpriseWechatCorp wechatCorp = corpMapper.selectByCorpIdAndSuiteId(corpid, authNotice.getSuiteId()); if (wechatCorp != null) { wechatCorp.setPermanentCode(permanentCodeRsp.getPermanentCode()); wechatCorp.setCorpName(permanentCodeRsp.getAuthCorpInfo().getCorpName()); corpMapper.updateById(wechatCorp); } } finally { redissonService.unlock("handle-reset-permanent-code::" + authNotice.getSuiteId()); } } /** 获取永久授权码:suite_ticket → suite_access_token → permanent_code */ private EnterpriseWechatPermanentCodeRsp fetchPermanentCode(EnterpriseWechatAuthNotice authNotice) { String suiteTicket = redisCache.getCacheObject(SUITE_TICKET_KEY_PREFIX + authNotice.getSuiteId()); Assert.notBlank(suiteTicket, "suite_ticket不存在"); EnterpriseWechatSuiteAccessTokenRsp tokenRsp = enterpriseWechatApi.getSuiteAccessToken( wechatProperties.getSuiteId(), wechatProperties.getSuiteSecret(), suiteTicket); redisCache.setCacheObject(SUITE_ACCESS_TOKEN_KEY_PREFIX + authNotice.getSuiteId(), tokenRsp.getSuiteAccessToken(), tokenRsp.getExpiresIn(), TimeUnit.SECONDS); return enterpriseWechatApi.getPermanentCode(tokenRsp.getSuiteAccessToken(), authNotice.getAuthCode()); } }