2023-07-27 16:44:48 +08:00
|
|
|
|
package com.jsowell.service;
|
|
|
|
|
|
|
2023-07-28 14:47:26 +08:00
|
|
|
|
import com.alibaba.fastjson2.JSONObject;
|
2023-07-27 16:44:48 +08:00
|
|
|
|
import com.jsowell.common.constant.CacheConstants;
|
|
|
|
|
|
import com.jsowell.common.core.redis.RedisCache;
|
|
|
|
|
|
import com.jsowell.common.util.StringUtils;
|
2023-07-28 14:47:26 +08:00
|
|
|
|
import com.jsowell.common.util.http.HttpUtils;
|
2023-07-27 16:44:48 +08:00
|
|
|
|
import com.jsowell.common.util.wxplatform.AesException;
|
|
|
|
|
|
import com.jsowell.common.util.wxplatform.WXBizMsgCrypt;
|
|
|
|
|
|
import com.jsowell.common.util.wxplatform.WXXmlToMapUtil;
|
2023-07-28 14:47:26 +08:00
|
|
|
|
import com.jsowell.pile.dto.GetComponentTokenDTO;
|
2023-07-27 16:44:48 +08:00
|
|
|
|
import org.apache.commons.collections.MapUtils;
|
2023-07-28 14:47:26 +08:00
|
|
|
|
import org.apache.commons.lang3.RandomStringUtils;
|
2023-07-27 16:44:48 +08:00
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
2023-07-28 14:47:26 +08:00
|
|
|
|
import java.util.Locale;
|
2023-07-27 16:44:48 +08:00
|
|
|
|
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
|
|
|
|
|
|
*/
|
2023-07-28 14:47:26 +08:00
|
|
|
|
private static final String PLATFORM_APP_ID = "wxac3b282a58b9a4a8";
|
2023-07-27 16:44:48 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 第三方平台 secret
|
|
|
|
|
|
*/
|
2023-07-28 14:47:26 +08:00
|
|
|
|
private static final String PLATFORM_APP_SECRET = "eb8adc2689b4f27be7ae75a4b646dbe6";
|
2023-07-27 16:44:48 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 第三方平台 消息加解密Key
|
|
|
|
|
|
*/
|
2023-07-28 14:47:26 +08:00
|
|
|
|
private static final String PLATFORM_AES_KEY = "9TDTYLBLYGG1IOU9VOLXHNIKKJ65NU40S0ITJ0BFQOU";
|
2023-07-27 16:44:48 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 第三方平台 消息校验Token
|
|
|
|
|
|
*/
|
2023-07-28 14:47:26 +08:00
|
|
|
|
private static final String PLATFORM_COMPONENT_TOKEN = "XD83ZUJWTVRB4OSN";
|
2023-07-27 16:44:48 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 解析请求
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param timeStamp
|
|
|
|
|
|
* @param nonce
|
|
|
|
|
|
* @param msgSignature
|
|
|
|
|
|
* @param postData
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
|
|
|
|
|
public String parseRequest(String timeStamp, String nonce, String msgSignature, String postData) {
|
2023-07-28 14:47:26 +08:00
|
|
|
|
logger.info("==============================开始授权事件接收URL=================================");
|
2023-07-27 16:44:48 +08:00
|
|
|
|
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<String, String> result = WXXmlToMapUtil.xmlToMap(xml);// 将xml转为map
|
2023-07-28 14:47:26 +08:00
|
|
|
|
logger.info("微信第三方平台推送消息解析后 result:{}", result);
|
|
|
|
|
|
// 获取 infoType 确认是哪个事件
|
|
|
|
|
|
String infoType = MapUtils.getString(result, "InfoType");
|
|
|
|
|
|
|
|
|
|
|
|
if (StringUtils.equals("component_verify_ticket", infoType)) {
|
|
|
|
|
|
// 授权票据
|
|
|
|
|
|
VerifyTicket(result);
|
2023-07-27 16:44:48 +08:00
|
|
|
|
}
|
2023-07-28 14:47:26 +08:00
|
|
|
|
|
2023-07-27 16:44:48 +08:00
|
|
|
|
} catch (AesException e) {
|
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
|
}
|
2023-07-28 14:47:26 +08:00
|
|
|
|
logger.info("==============================结束授权事件接收URL=================================");
|
2023-07-27 16:44:48 +08:00
|
|
|
|
return "success";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-28 14:47:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 验证票据事件
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param map 微信第三方平台推送消息解析后的 map
|
|
|
|
|
|
* @return
|
|
|
|
|
|
*/
|
|
|
|
|
|
private String VerifyTicket(Map<String, String> 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 + PLATFORM_APP_ID;
|
|
|
|
|
|
// 先判断缓存中是否有 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 (verifyTicket == null) {
|
|
|
|
|
|
// 获取缓存中的票据
|
|
|
|
|
|
verifyTicket = redisCache.getCacheObject(CacheConstants.COMPONENT_VERIFY_TICKET + PLATFORM_APP_ID);
|
|
|
|
|
|
}
|
|
|
|
|
|
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 = jsonObject.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;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-27 16:44:48 +08:00
|
|
|
|
}
|