新增 微信第三方平台 获取令牌接口

This commit is contained in:
Lemon
2023-07-28 14:47:26 +08:00
parent 82a964d70e
commit 162dec41d4
6 changed files with 163 additions and 25 deletions

View File

@@ -1,8 +1,11 @@
package com.jsowell.api.uniapp; package com.jsowell.api.uniapp;
import com.alibaba.fastjson2.JSONObject;
import com.jsowell.common.annotation.Anonymous; import com.jsowell.common.annotation.Anonymous;
import com.jsowell.common.core.controller.BaseController; import com.jsowell.common.core.controller.BaseController;
import com.jsowell.common.response.RestApiResponse;
import com.jsowell.pile.domain.AuthorizationEventResult; import com.jsowell.pile.domain.AuthorizationEventResult;
import com.jsowell.pile.dto.GetComponentTokenDTO;
import com.jsowell.service.AgentDevService; import com.jsowell.service.AgentDevService;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -24,7 +27,16 @@ public class AgentDevController extends BaseController {
@Autowired @Autowired
private AgentDevService agentDevService; private AgentDevService agentDevService;
@ApiOperation(value = "授权事件接收URL,验证票据") /**
* 授权事件接收URL,验证票据
* 微信平台 10 分钟推送一次
*
* @param timestamp
* @param nonce
* @param msgSignature
* @param postData
* @return
*/
@PostMapping("/platform/event") @PostMapping("/platform/event")
public ResponseEntity<AuthorizationEventResult> wechatPlatformEvent(@RequestParam("timestamp") String timestamp, public ResponseEntity<AuthorizationEventResult> wechatPlatformEvent(@RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce, @RequestParam("nonce") String nonce,
@@ -32,11 +44,11 @@ public class AgentDevController extends BaseController {
@RequestBody String postData) { @RequestBody String postData) {
AuthorizationEventResult<String> resultBean = new AuthorizationEventResult<>(); AuthorizationEventResult<String> resultBean = new AuthorizationEventResult<>();
ResponseEntity<AuthorizationEventResult> responseEntity; ResponseEntity<AuthorizationEventResult> responseEntity;
logger.debug("授权事件接收URL,验证票据"); logger.info("授权事件接收URL,验证票据");
try { try {
resultBean.setData(agentDevService.parseRequest(timestamp,nonce,msgSignature,postData)); resultBean.setData(agentDevService.parseRequest(timestamp, nonce, msgSignature, postData));
responseEntity = new ResponseEntity<>(resultBean, HttpStatus.OK); responseEntity = new ResponseEntity<>(resultBean, HttpStatus.OK);
logger.debug("第三方平台授权事件接收URL,验证票据成功"); logger.info("第三方平台授权事件接收URL,验证票据成功");
} catch (Exception e) { } catch (Exception e) {
logger.error("第三方平台授权事件接收URL,验证票据异常", e.getMessage(), e); logger.error("第三方平台授权事件接收URL,验证票据异常", e.getMessage(), e);
AuthorizationEventResult<String> errorResultBean = new AuthorizationEventResult<>(); AuthorizationEventResult<String> errorResultBean = new AuthorizationEventResult<>();
@@ -49,6 +61,25 @@ public class AgentDevController extends BaseController {
} }
/**
* 获取微信第三方平台令牌
*
* @param dto
* @return
*/
@PostMapping("/getComponentToken")
public RestApiResponse<?> getComponentToken(GetComponentTokenDTO dto) {
logger.info("获取第三方平台令牌 params:{}", JSONObject.toJSONString(dto));
RestApiResponse<?> response = null;
try {
String componentToken = agentDevService.getComponentToken(dto);
response = new RestApiResponse<>(componentToken);
} catch (Exception e) {
logger.error("获取第三方平台令牌 error", e);
response = new RestApiResponse<>(e);
}
logger.info("获取第三方平台令牌 result:{}", response);
return response;
}
} }

View File

@@ -1,17 +1,22 @@
package com.jsowell.service; package com.jsowell.service;
import com.alibaba.fastjson2.JSONObject;
import com.jsowell.common.constant.CacheConstants; import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.util.StringUtils; 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.AesException;
import com.jsowell.common.util.wxplatform.WXBizMsgCrypt; import com.jsowell.common.util.wxplatform.WXBizMsgCrypt;
import com.jsowell.common.util.wxplatform.WXXmlToMapUtil; import com.jsowell.common.util.wxplatform.WXXmlToMapUtil;
import com.jsowell.pile.dto.GetComponentTokenDTO;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -31,22 +36,22 @@ public class AgentDevService {
/** /**
* 第三方平台 appid * 第三方平台 appid
*/ */
private static final String PLATFORM_APP_ID = "****************"; private static final String PLATFORM_APP_ID = "wxac3b282a58b9a4a8";
/** /**
* 第三方平台 secret * 第三方平台 secret
*/ */
private static final String PLATFORM_APP_SECRET = "****************"; private static final String PLATFORM_APP_SECRET = "eb8adc2689b4f27be7ae75a4b646dbe6";
/** /**
* 第三方平台 消息加解密Key * 第三方平台 消息加解密Key
*/ */
private static final String PLATFORM_AES_KEY = "****************"; private static final String PLATFORM_AES_KEY = "9TDTYLBLYGG1IOU9VOLXHNIKKJ65NU40S0ITJ0BFQOU";
/** /**
* 第三方平台 消息校验Token * 第三方平台 消息校验Token
*/ */
private static final String PLATFORM_COMPONENT_TOKEN = "****************"; private static final String PLATFORM_COMPONENT_TOKEN = "XD83ZUJWTVRB4OSN";
/** /**
@@ -59,31 +64,96 @@ public class AgentDevService {
* @return * @return
*/ */
public String parseRequest(String timeStamp, String nonce, String msgSignature, String postData) { public String parseRequest(String timeStamp, String nonce, String msgSignature, String postData) {
logger.debug("==============================开始授权事件接收URL================================="); logger.info("==============================开始授权事件接收URL=================================");
try { try {
//这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid //这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid
WXBizMsgCrypt pc = new WXBizMsgCrypt(PLATFORM_COMPONENT_TOKEN, PLATFORM_AES_KEY, PLATFORM_APP_ID); WXBizMsgCrypt pc = new WXBizMsgCrypt(PLATFORM_COMPONENT_TOKEN, PLATFORM_AES_KEY, PLATFORM_APP_ID);
String xml = pc.decryptMsg(msgSignature, timeStamp, nonce, postData); String xml = pc.decryptMsg(msgSignature, timeStamp, nonce, postData);
Map<String, String> result = WXXmlToMapUtil.xmlToMap(xml);// 将xml转为map Map<String, String> result = WXXmlToMapUtil.xmlToMap(xml);// 将xml转为map
String componentVerifyTicket = MapUtils.getString(result, "ComponentVerifyTicket"); logger.info("微信第三方平台推送消息解析后 result:{}", result);
if (StringUtils.isNotEmpty(componentVerifyTicket)) { // 获取 infoType 确认是哪个事件
// 存入Redis 过期时间 12 小时 String infoType = MapUtils.getString(result, "InfoType");
String redisKey = CacheConstants.COMPONENT_VERIFY_TICKET;
redisCache.setCacheObject(redisKey, componentVerifyTicket, 60 * 12, TimeUnit.SECONDS); 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<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); 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 // 存储平台授权票据,保存ticket
// redisTemplate.opsForValue().set("component_verify_ticket", componentVerifyTicket, 60 * 12, TimeUnit.SECONDS); // redisTemplate.opsForValue().set("component_verify_ticket", componentVerifyTicket, 60 * 12, TimeUnit.SECONDS);
// String verifyTicket = redisTemplate.opsForValue().get("component_verify_ticket").toString(); // String verifyTicket = redisTemplate.opsForValue().get("component_verify_ticket").toString();
logger.debug("====================授权票据【ComponentVerifyTicket】" + verifyTicket + "】===================="); logger.info("====================授权票据【ComponentVerifyTicket】" + verifyTicket + "】====================");
} else { return verifyTicket;
throw new RuntimeException("微信开放平台,第三方平台获取【验证票据】失败");
} }
} catch (AesException e) {
e.printStackTrace();
/**
* 获取第三方平台 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;
} }
logger.debug("==============================结束授权事件接收URL================================="); // 为空再去请求获取新令牌
return "success"; 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;
} }
} }

View File

@@ -291,6 +291,7 @@ public class MemberService {
} }
public MemberWalletInfoVO getMemberWalletInfo(UniAppQueryMemberBalanceDTO dto) throws ParseException { public MemberWalletInfoVO getMemberWalletInfo(UniAppQueryMemberBalanceDTO dto) throws ParseException {
log.info("查询用户余额信息 service方法 start");
MemberWalletInfoVO vo = new MemberWalletInfoVO(); MemberWalletInfoVO vo = new MemberWalletInfoVO();
vo.setMemberId(dto.getMemberId()); vo.setMemberId(dto.getMemberId());
// 获取分页信息 // 获取分页信息
@@ -339,7 +340,7 @@ public class MemberService {
} }
// walletLogVO.setTotalAccountAmount(walletLogVO.getPrincipalBalance().add(walletLogVO.getGiftBalance())); // walletLogVO.setTotalAccountAmount(walletLogVO.getPrincipalBalance().add(walletLogVO.getGiftBalance()));
} }
log.info("查询用户余额信息 service方法 开始处理分页----");
List<MemberWalletLogVO> collect = list.stream() List<MemberWalletLogVO> collect = list.stream()
.skip((pageNum - 1) * pageSize) .skip((pageNum - 1) * pageSize)
.limit(pageSize) .limit(pageSize)
@@ -358,6 +359,7 @@ public class MemberService {
.build(); .build();
vo.setPageResponse(pageResponse); vo.setPageResponse(pageResponse);
log.info("查询用户余额信息 service方法 end");
return vo; return vo;
} }

View File

@@ -60,6 +60,7 @@ import com.jsowell.pile.dto.ApplyRefundDTO;
import com.jsowell.wxpay.response.WechatPayRefundRequest; import com.jsowell.wxpay.response.WechatPayRefundRequest;
import com.jsowell.wxpay.service.WxAppletRemoteService; import com.jsowell.wxpay.service.WxAppletRemoteService;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -1428,6 +1429,8 @@ public class SpringBootTestController {
String str = "JS160829"; String str = "JS160829";
System.out.println(Md5Utils.hash(str).toUpperCase(Locale.ROOT)); System.out.println(Md5Utils.hash(str).toUpperCase(Locale.ROOT));
*/ */
String s = RandomStringUtils.randomAlphanumeric(43).toUpperCase(Locale.ROOT);
System.out.println(s);
Date startTimeDate = sdf.parse("2022-11-26 10:44:11"); Date startTimeDate = sdf.parse("2022-11-26 10:44:11");
Date endTimeDate = sdf.parse("2022-11-27 12:45:11"); Date endTimeDate = sdf.parse("2022-11-27 12:45:11");

View File

@@ -106,10 +106,15 @@ public class CacheConstants {
public static final String GET_UNIAPP_CONNECTOR_LIST_BY_STATION_ID = "GET_UNIAPP_CONNECTOR_LIST_BY_STATION_ID:"; public static final String GET_UNIAPP_CONNECTOR_LIST_BY_STATION_ID = "GET_UNIAPP_CONNECTOR_LIST_BY_STATION_ID:";
/** /**
* 代开发小程序保存票据 * 微信第三方平台 票据
*/ */
public static final String COMPONENT_VERIFY_TICKET = "component_verify_ticket:"; public static final String COMPONENT_VERIFY_TICKET = "component_verify_ticket:";
/**
* 微信第三方平台 token
*/
public static final String COMPONENT_ACCESS_TOKEN = "component_access_token:";
/** /**
* 充电桩sn生成 key * 充电桩sn生成 key
*/ */

View File

@@ -0,0 +1,27 @@
package com.jsowell.pile.dto;
import lombok.Data;
/**
* 获取第三方平台令牌 DTO
*
* @author Lemon
* @Date 2023/7/28 14:05
*/
@Data
public class GetComponentTokenDTO {
/**
* 第三方平台 appId
*/
private String appId;
/**
* 第三方平台 appSecret
*/
private String appSecret;
/**
* 第三方平台 票据
*/
private String verifyTicket;
}