微信模板消息通知、微信获取AccessToken

This commit is contained in:
songmingsong
2024-12-06 11:14:23 +08:00
parent e1c95fb137
commit c062952ae6
16 changed files with 373 additions and 14 deletions

View File

@ -0,0 +1,123 @@
package com.ycwl.basic.service.impl.mobile;
import com.alibaba.fastjson.JSONObject;
import com.ycwl.basic.config.WechatConfig;
import com.ycwl.basic.constant.NumberConstant;
import com.ycwl.basic.constant.WeiXinConstant;
import com.ycwl.basic.enums.BizCodeEnum;
import com.ycwl.basic.exception.AppException;
import com.ycwl.basic.model.wx.WechatAccessTokenVO;
import com.ycwl.basic.model.wx.WechatMessageSubscribeForm;
import com.ycwl.basic.model.wx.WechatMssVO;
import com.ycwl.basic.service.mobile.WxNotifyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import static com.ycwl.basic.constant.WeiXinConstant.*;
/**
* @Author: songmingsong
* @CreateTime: 2024-12-06
* @Description: 微信消息通知实现
* @Version: 1.0
*/
@Slf4j
@Service
public class WxNotifyServiceImpl implements WxNotifyService {
private final RestTemplate restTemplate = new RestTemplate();
@Autowired
private WechatConfig wechatConfig;
/**
* 缓存accessToken
*/
private Map<String, AccessTokenCacheEntity> cacheAccessTokenMap = new ConcurrentHashMap<>();
@Override
public String getAccessToken() {
String cacheKey = wechatConfig.getMiniProgramAppId() + wechatConfig.getMiniProgramSecret();
AccessTokenCacheEntity accessTokenCacheEntity = cacheAccessTokenMap.get(cacheKey);
if (accessTokenCacheEntity != null && accessTokenCacheEntity.expireDate.getTime() > System.currentTimeMillis()) {
return accessTokenCacheEntity.accessToken;
}
String url = String.format(WeiXinConstant.ACCESS_TOKEN_WITH_PARAM, wechatConfig.getMiniProgramAppId(), wechatConfig.getMiniProgramSecret());
ResponseEntity<WechatAccessTokenVO> responseEntity = restTemplate.getForEntity(url, WechatAccessTokenVO.class);
if (HttpStatus.OK == responseEntity.getStatusCode()) {
WechatAccessTokenVO accessTokenVO = responseEntity.getBody();
if (accessTokenVO.isSuccess()) {
accessTokenCacheEntity = new AccessTokenCacheEntity();
accessTokenCacheEntity.accessToken = accessTokenVO.getAccess_token();
// 设置过期时间减100秒防止网络延迟失效
accessTokenCacheEntity.expireDate = new Date(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(accessTokenVO.getExpires_in() - NumberConstant.HUNDRED));
// 缓存一份,有效期内避免重复请求
cacheAccessTokenMap.put(cacheKey, accessTokenCacheEntity);
return accessTokenVO.getAccess_token();
} else {
log.error("[微信token]请求AccessToken出现异常错误信息为{}{}", accessTokenVO.getErrcode(), accessTokenVO.getErrmsg());
throw new AppException(BizCodeEnum.REQUEST_WECHAT_FAIL);
}
}
throw new AppException(BizCodeEnum.REQUEST_WECHAT_FAIL);
}
/**
* 给用户发送通知
*
* @param info
* @return
*/
@Override
public JSONObject pushMessage(WechatMessageSubscribeForm info) {
RestTemplate restTemplate = new RestTemplate();
String url = MESSAGE_SEND_URL + getAccessToken();
// 拼接推送的模板
WechatMssVO wxMssVO = new WechatMssVO();
wxMssVO.setTouser(info.getOpenId()); // 用户的openId
wxMssVO.setTemplate_id(wechatConfig.getTemplateId()); // 订阅消息模板id
wxMssVO.setLang(info.getLang()); // 语言类型
wxMssVO.setMiniprogram_state(info.getMiniprogram_state()); // 跳转小程序类型
wxMssVO.setPage(info.getPage());
// // TODO: 推送的内容
// Map<String, WechatTemplateData> map = new HashMap<>();
// map.put("msg", new WechatTemplateData("发消息了"));
wxMssVO.setData(info.getData());
// 发送
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, wxMssVO, String.class);
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getBody()));
Integer errcode = jsonObject.getInteger(WECHAT_ERRCODE);
String errmsg = jsonObject.getString(WECHAT_ERRMSG);
if (errcode != NumberConstant.ZERO) {
throw new AppException(errcode, errmsg);
}
return JSONObject.parseObject(JSONObject.toJSONString(responseEntity.getBody()));
}
private class AccessTokenCacheEntity {
/**
* token
*/
private String accessToken;
/**
* 有效期到
*/
private Date expireDate;
}
}

View File

@ -23,9 +23,9 @@ import com.ycwl.basic.enums.BizCodeEnum;
import com.ycwl.basic.enums.OrderStateEnum;
import com.ycwl.basic.exception.AppException;
import com.ycwl.basic.model.pc.order.resp.OrderRespVO;
import com.ycwl.basic.model.wxPay.WXPayOrderReqVO;
import com.ycwl.basic.model.wxPay.WxPayRespVO;
import com.ycwl.basic.model.wxPay.WxchatCallbackSuccessData;
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
import com.ycwl.basic.model.wx.WxPayRespVO;
import com.ycwl.basic.model.wx.WxchatCallbackSuccessData;
import com.ycwl.basic.service.HttpService;
import com.ycwl.basic.service.mobile.WxPayService;
import com.ycwl.basic.service.pc.OrderService;

View File

@ -0,0 +1,17 @@
package com.ycwl.basic.service.mobile;
import com.alibaba.fastjson.JSONObject;
import com.ycwl.basic.model.wx.WechatMessageSubscribeForm;
public interface WxNotifyService {
/**
* 获取微信token
*/
String getAccessToken();
/**
* 发送模板消息
*/
JSONObject pushMessage(WechatMessageSubscribeForm info);
}

View File

@ -1,8 +1,8 @@
package com.ycwl.basic.service.mobile;
import com.ycwl.basic.model.wxPay.WXPayOrderReqVO;
import com.ycwl.basic.model.wxPay.WxPayRespVO;
import com.ycwl.basic.model.wxPay.WxchatCallbackSuccessData;
import com.ycwl.basic.model.wx.WXPayOrderReqVO;
import com.ycwl.basic.model.wx.WxPayRespVO;
import com.ycwl.basic.model.wx.WxchatCallbackSuccessData;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;