package com.jsowell.service; import com.alibaba.fastjson2.JSONObject; import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.util.StringUtils; import com.jsowell.common.util.http.HttpUtils; import com.jsowell.common.util.wxplatform.AesException; import com.jsowell.common.util.wxplatform.WXBizMsgCrypt; import com.jsowell.common.util.wxplatform.WXXmlToMapUtil; import com.jsowell.pile.dto.GetComponentTokenDTO; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.RandomStringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; /** * 代开发小程序Service * * @author Lemon * @Date 2023/7/27 15:58 */ @Service public class AgentDevService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private RedisCache redisCache; /** * 第三方平台 appid */ private static final String PLATFORM_APP_ID = "wxac3b282a58b9a4a8"; /** * 第三方平台 secret */ private static final String PLATFORM_APP_SECRET = "eb8adc2689b4f27be7ae75a4b646dbe6"; /** * 第三方平台 消息加解密Key */ private static final String PLATFORM_AES_KEY = "9TDTYLBLYGG1IOU9VOLXHNIKKJ65NU40S0ITJ0BFQOU"; /** * 第三方平台 消息校验Token */ private static final String PLATFORM_COMPONENT_TOKEN = "XD83ZUJWTVRB4OSN"; /** * 解析请求 * * @param timeStamp * @param nonce * @param msgSignature * @param postData * @return */ public String parseRequest(String timeStamp, String nonce, String msgSignature, String postData) { logger.info("==============================开始授权事件接收URL================================="); try { //这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid WXBizMsgCrypt pc = new WXBizMsgCrypt(PLATFORM_COMPONENT_TOKEN, PLATFORM_AES_KEY, PLATFORM_APP_ID); String xml = pc.decryptMsg(msgSignature, timeStamp, nonce, postData); Map result = WXXmlToMapUtil.xmlToMap(xml);// 将xml转为map logger.info("微信第三方平台推送消息解析后 result:{}", result); // 获取 infoType 确认是哪个事件 String infoType = MapUtils.getString(result, "InfoType"); if (StringUtils.equals("component_verify_ticket", infoType)) { // 授权票据 VerifyTicket(result); } } catch (AesException e) { e.printStackTrace(); } logger.info("==============================结束授权事件接收URL================================="); return "success"; } /** * 验证票据事件 * * @param map 微信第三方平台推送消息解析后的 map * @return */ private String VerifyTicket(Map map) { String componentVerifyTicket = MapUtils.getString(map, "ComponentVerifyTicket"); if (StringUtils.isEmpty(componentVerifyTicket)) { throw new RuntimeException("微信开放平台,第三方平台获取【验证票据】失败"); } String redisKey = CacheConstants.COMPONENT_VERIFY_TICKET + PLATFORM_APP_ID; // 查缓存,看是否已经过期 String verifyTicket = redisCache.getCacheObject(redisKey); if (verifyTicket != null) { // 先删除旧缓存 redisCache.deleteObject(redisKey); } // 存入Redis 过期时间 10 分钟 redisCache.setCacheObject(redisKey, componentVerifyTicket, 60 * 10, TimeUnit.SECONDS); verifyTicket = redisCache.getCacheObject(redisKey); // 存储平台授权票据,保存ticket // redisTemplate.opsForValue().set("component_verify_ticket", componentVerifyTicket, 60 * 12, TimeUnit.SECONDS); // String verifyTicket = redisTemplate.opsForValue().get("component_verify_ticket").toString(); logger.info("====================授权票据【ComponentVerifyTicket】:【" + verifyTicket + "】===================="); return verifyTicket; } /** * 获取第三方平台 token * * @param dto * @return */ public String getComponentToken(GetComponentTokenDTO dto) { String verifyTicket = dto.getVerifyTicket(); String redisKey = CacheConstants.COMPONENT_ACCESS_TOKEN + dto.getAppId(); // 先判断缓存中是否有 token String token = redisCache.getCacheObject(redisKey); if (StringUtils.isNotBlank(token)) { // 不为空直接返回 return token; } // 为空再去请求获取新令牌 String url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token"; if (StringUtils.isBlank(verifyTicket)) { // 获取缓存中的票据 verifyTicket = redisCache.getCacheObject(CacheConstants.COMPONENT_VERIFY_TICKET + dto.getAppId()); logger.info("获取第三方平台缓存中票据:{}", verifyTicket); } JSONObject jsonObject = new JSONObject(); jsonObject.put("component_appid", dto.getAppId()); jsonObject.put("component_appsecret", dto.getAppSecret()); jsonObject.put("component_verify_ticket", verifyTicket); String result = HttpUtils.sendPost(url, jsonObject.toString()); JSONObject jsonResult = JSONObject.parseObject(result); logger.info("获取第三方平台 token 请求结果:{}", JSONObject.toJSONString(jsonResult)); // 获取返回值中的 token token = jsonResult.getString("component_access_token"); if (token == null) { throw new RuntimeException("获取第三方平台 token 异常!"); } logger.info("获取第三方平台 token component_access_token:{}", token); // 存入redis, 有效期 1小时50分 redisCache.setCacheObject(redisKey, token, 60 * 110, TimeUnit.SECONDS); return token; } }