package com.iplatform.base;
|
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.iplatform.base.util.NotificationUtils;
|
import com.iplatform.base.util.RestTemplateUtils;
|
import com.iplatform.core.BeanContextAware;
|
import com.iplatform.model.vo.NotificationTemplateVo;
|
import com.iplatform.model.vo.WeChatAccessTokenVo;
|
import com.walker.infrastructure.arguments.Variable;
|
import com.walker.infrastructure.utils.StringUtils;
|
import com.walker.push.Notification;
|
import org.springframework.web.client.RestTemplate;
|
|
import java.text.MessageFormat;
|
import java.util.List;
|
|
public abstract class WechatBaseController extends PlatformAdapterController{
|
|
// public void setRestTemplate(RestTemplate restTemplate) {
|
// this.restTemplate = restTemplate;
|
// }
|
// private RestTemplate restTemplate;
|
|
/**
|
* 平台统一根据模板,发送提醒通知。
|
* @param mark 通知标识,如:发货、订单等,从:sf_notification 表查询
|
* @param variableList 业务数据,key,value
|
* @param userId 用户ID
|
* @date 2023-08-25
|
*/
|
protected void pushNotificationWithTemplate(String mark, List<Variable> variableList, long userId){
|
if(StringUtils.isEmpty(mark)){
|
throw new IllegalArgumentException("必须输入通知模板标记:mark");
|
}
|
if(StringUtils.isEmptyList(variableList)){
|
throw new IllegalArgumentException("必须输入推送消息业务数据:variableList");
|
}
|
NotificationTemplateVo templateVo = this.getNotificationTemplateCache().get(mark);
|
if(templateVo == null){
|
logger.error("通知模板缓存不存在,mark={}", mark);
|
return;
|
}
|
|
// 1:存在微信公众号推送方式
|
if(templateVo.getWechat()){
|
String openId = this.getUser(userId).getWx_open_id();
|
if(StringUtils.isEmpty(openId)){
|
logger.error("用户openId为空,无法发送微信公众号通知, userId={}", userId);
|
return;
|
}
|
String accessToken = this.acquirePublicAccessToken();
|
if(StringUtils.isEmpty(accessToken)){
|
logger.error("推送公众号消息失败,accessToken获取为空,mark={}, userId={}", mark, userId);
|
return;
|
}
|
|
Notification notification = NotificationUtils.acquireWechatNotification(accessToken
|
, templateVo.getWechatTempId(), openId, variableList);
|
this.getPushManager().push(notification, null);
|
}
|
|
// 2:存在短信推送
|
if(templateVo.getSms()){
|
String userPhone = this.getUser(userId).getPhonenumber();
|
if(StringUtils.isEmpty(userPhone)){
|
logger.error("用户手机号为空,无法发送短信通知, userId={}", userId);
|
return;
|
}
|
Notification smsNotification = NotificationUtils.acquireSmsNotification(templateVo.getSmsTempId(), userPhone, variableList, "短信通知");
|
this.getPushManager().push(smsNotification, null);
|
}
|
|
// 3:存在微信小程序推送方式
|
if(templateVo.getRoutine()){
|
throw new UnsupportedOperationException("未实现微信小程序消息通知");
|
}
|
}
|
|
/**
|
* 获取微信小程序(access_token),并设置缓存。
|
* @return
|
* @date 2023-09-16
|
*/
|
protected String acquireMiniAccessToken(){
|
String appId = this.getArgumentVariable(WechatConstants.WECHAT_MINI_APPID).getStringValue();
|
if(StringUtils.isEmpty(appId)){
|
throw new PlatformRuntimeException("请先配置微信参数:小程序appid");
|
}
|
String miniAccessToken = this.getWechatCache().getMiniAccessToken();
|
if(StringUtils.isNotEmpty(miniAccessToken)){
|
logger.debug("缓存中已有'access_token':{}", miniAccessToken);
|
return miniAccessToken;
|
}
|
|
String secret = this.getArgumentVariable(WechatConstants.WECHAT_MINI_APPSECRET).getStringValue();
|
if (StringUtils.isEmpty(secret)) {
|
throw new PlatformRuntimeException("微信小程序secret未设置");
|
}
|
// String url = MessageFormat.format(WechatConstants.WECHAT_ACCESS_TOKEN_URL, appId, secret);
|
// logger.debug("url = {}", url);
|
// ObjectNode objectNode = RestTemplateUtils.getData(url, BeanContextAware.getBeanByType(RestTemplate.class));
|
// if(objectNode == null){
|
// throw new PlatformRuntimeException("微信平台接口异常,没任何数据返回!");
|
// }
|
// logger.debug(objectNode.toString());
|
ObjectNode objectNode = this.acquireAccessTokenNode(appId, secret);
|
WeChatAccessTokenVo accessTokenVo = null;
|
|
try {
|
// if (objectNode.has("errcode") && !objectNode.get("errcode").asText().equals("0")) {
|
// if (objectNode.has("errmsg")) {
|
// // 保存到微信异常表
|
//// wxExceptionDispose(data, StrUtil.format("微信获取accessToken异常,{}端", type));
|
// throw new PlatformRuntimeException("微信接口调用失败:" + objectNode.get("errcode") + objectNode.get("errmsg"));
|
// }
|
// }
|
this.checkStatusError(objectNode);
|
accessTokenVo = new WeChatAccessTokenVo();
|
accessTokenVo.setAccessToken(objectNode.get("access_token").asText());
|
accessTokenVo.setExpiresIn(objectNode.get("expires_in").asInt());
|
// accessTokenVo = JsonUtils.jsonStringToObject(result, WeChatAccessTokenVo.class);
|
this.getWechatCache().putMiniAccessToken(accessTokenVo.getAccessToken(), accessTokenVo.getExpiresIn().longValue() - 1800L);
|
logger.info("调用一次微信远程接口获取'mini_accessToken',并缓存:{}", accessTokenVo.getAccessToken());
|
return accessTokenVo.getAccessToken();
|
|
} catch (Exception e) {
|
throw new RuntimeException("json字符串转对象错误:" + objectNode, e);
|
}
|
}
|
|
/**
|
* 获取微信公众号(普通)access_token
|
* @return
|
* @date 2023-08-23
|
*/
|
protected String acquirePublicAccessToken(
|
// String appId, String type
|
){
|
String appId = this.getArgumentVariable(WechatConstants.WECHAT_PUBLIC_APPID).getStringValue();
|
if(StringUtils.isEmpty(appId)){
|
throw new PlatformRuntimeException("请先配置微信参数:公众号appid");
|
}
|
String publicAccessToken = this.getWechatCache().getPublicAccessToken();
|
if(StringUtils.isNotEmpty(publicAccessToken)){
|
logger.debug("缓存中已有'access_token':{}", publicAccessToken);
|
return publicAccessToken;
|
}
|
String secret = this.getArgumentVariable(WechatConstants.WECHAT_PUBLIC_APPSECRET).getStringValue();
|
if (StringUtils.isEmpty(secret)) {
|
throw new PlatformRuntimeException("微信公众号secret未设置");
|
}
|
|
// String url = MessageFormat.format(WechatConstants.WECHAT_ACCESS_TOKEN_URL, appId, secret);
|
// logger.debug("url = {}", url);
|
// ObjectNode objectNode = RestTemplateUtils.getData(url, BeanContextAware.getBeanByType(RestTemplate.class));
|
// if(objectNode == null){
|
// throw new PlatformRuntimeException("微信平台接口异常,没任何数据返回!");
|
// }
|
// logger.debug(objectNode.toString());
|
ObjectNode objectNode = this.acquireAccessTokenNode(appId, secret);
|
WeChatAccessTokenVo accessTokenVo = null;
|
try {
|
// if (objectNode.has("errcode") && !objectNode.get("errcode").asText().equals("0")) {
|
// if (objectNode.has("errmsg")) {
|
// // 保存到微信异常表
|
//// wxExceptionDispose(data, StrUtil.format("微信获取accessToken异常,{}端", type));
|
// throw new PlatformRuntimeException("微信接口调用失败:" + objectNode.get("errcode") + objectNode.get("errmsg"));
|
// }
|
// }
|
this.checkStatusError(objectNode);
|
accessTokenVo = new WeChatAccessTokenVo();
|
accessTokenVo.setAccessToken(objectNode.get("access_token").asText());
|
accessTokenVo.setExpiresIn(objectNode.get("expires_in").asInt());
|
// accessTokenVo = JsonUtils.jsonStringToObject(result, WeChatAccessTokenVo.class);
|
this.getWechatCache().putPublicAccessToken(accessTokenVo.getAccessToken(), accessTokenVo.getExpiresIn().longValue() - 1800L);
|
logger.info("调用一次微信远程接口获取'public_accessToken',并缓存:{}", accessTokenVo.getAccessToken());
|
return accessTokenVo.getAccessToken();
|
|
} catch (Exception e) {
|
throw new RuntimeException("json字符串转对象错误:" + objectNode, e);
|
}
|
}
|
|
private ObjectNode acquireAccessTokenNode(String appId, String secret){
|
String url = MessageFormat.format(WechatConstants.WECHAT_ACCESS_TOKEN_URL, appId, secret);
|
logger.debug("url = {}", url);
|
ObjectNode objectNode = RestTemplateUtils.getData(url, BeanContextAware.getBeanByType(RestTemplate.class));
|
if(objectNode == null){
|
throw new PlatformRuntimeException("微信平台接口异常,没任何数据返回!");
|
}
|
logger.debug(objectNode.toString());
|
return objectNode;
|
}
|
|
private void checkStatusError(ObjectNode objectNode){
|
// ObjectNode objectNode = JsonUtils.jsonStringToObjectNode(result);
|
if (objectNode.has("errcode") && !objectNode.get("errcode").asText().equals("0")) {
|
if (objectNode.has("errmsg")) {
|
// 保存到微信异常表
|
// wxExceptionDispose(data, StrUtil.format("微信获取accessToken异常,{}端", type));
|
throw new PlatformRuntimeException("微信接口调用失败:" + objectNode.get("errcode") + objectNode.get("errmsg"));
|
} else {
|
throw new PlatformRuntimeException("微信接口调用失败:" + objectNode.get("errcode"));
|
}
|
}
|
}
|
|
/**
|
* 返回微信基础配置缓存对象。
|
* @return
|
* @date 2023-08-23
|
*/
|
protected WechatCacheProvider getWechatCache(){
|
return BeanContextAware.getBeanByType(WechatCacheProvider.class);
|
}
|
|
}
|