Properties文件配置
wechat.appId=
wechat.secret=
wechat.url=http://api.weixin.qq.com/sns/jscode2session
wechat.assessToken.url=http://api.weixin.qq.com/cgi-bin/token
wechat.subscribeMessage.url=http://api.weixin.qq.com/cgi-bin/message/subscribe/send
wechat.subscribeMessage.templateId=
@RestController
@RequestMapping("wechat")
@RequiredArgsConstructor
public class WechatController {
private final WechatService wechatService;
/**
* 根据code获得openId
*
* @param code code
* @return openId
* @throws IOException 异常信息
*/
@GetMapping("get-open-id")
public WechatLoginVO getOpenId(@RequestParam("code") String code) throws IOException {
return wechatService.getOpenId(code);
}
/**
* 小程序消息提醒
*
* @param wechatMessageBO 提醒讯息入参
*/
@PostMapping("subscribeMessage")
public void subscribeMessage(@RequestBody WechatMessageBO wechatMessageBO) {
wechatService.subscribeMessage(SymbolConst.BLANK, wechatMessageBO);
}
}
@Slf4j
@Service
public class WechatService {
@Value("${wechat.appId}")
private String appId;
@Value("${wechat.secret}")
private String secret;
@Value("${wechat.url}")
private String getAppOpenIdUrl;
@Value("${wechat.assessToken.url}")
private String getAccessTokenUrl;
@Value("${wechat.subscribeMessage.url}")
private String getSubscribeMessageUrl;
@Value("${wechat.subscribeMessage.templateId}")
private String templateId;
public WechatLoginVO getOpenId(String code) throws IOException {
String url = getAppOpenIdUrl + "?appid=" + appId +
"&secret=" + secret + "&js_code=" + code +
"&grant_type=" + "authorization_code";
log.info("获取小程序的openid请求信息:{}", JSON.toJSONString(url));
String res;
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClientBuilder.create().build();
HttpGet httpget = new HttpGet(url);
// 配置信息
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(NumberConst.INT_4096)
.setConnectionRequestTimeout(NumberConst.INT_4096)
.setSocketTimeout(NumberConst.INT_4096)
.setRedirectsEnabled(false).build();
httpget.setConfig(requestConfig);
response = httpClient.execute(httpget);
HttpEntity responseEntity = response.getEntity();
res = EntityUtils.toString(responseEntity);
log.info("响应内容为:{}", res);
} finally {
if (null != httpClient) {
httpClient.close();
}
if (null != response) {
response.close();
}
}
JSONObject jsonObject = JSON.parseObject(res);
String openid = jsonObject.getString("openid");
String sessionKey = jsonObject.getString("session_key");
log.info("openid为:{}, sessionKey为:{}", openid, sessionKey);
WechatLoginVO vo = new WechatLoginVO();
vo.setOpenId(openid);
vo.setSessionKey(sessionKey);
return vo;
}
public String getAccessToken() throws IOException {
//获取access_token
String url = getAccessTokenUrl + "?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
String res;
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClientBuilder.create().build();
HttpGet httpget = new HttpGet(url);
// 配置信息
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(NumberConst.INT_4096)
.setConnectionRequestTimeout(NumberConst.INT_4096)
.setSocketTimeout(NumberConst.INT_4096)
.setRedirectsEnabled(false).build();
httpget.setConfig(requestConfig);
response = httpClient.execute(httpget);
HttpEntity responseEntity = response.getEntity();
res = EntityUtils.toString(responseEntity);
log.info("响应内容为:{}", res);
} finally {
if (null != httpClient) {
httpClient.close();
}
if (null != response) {
response.close();
}
}
JSONObject myJson = JSONObject.parseObject(res);
String accessToken = myJson.get("access_token").toString();
RedisUtil.set(RedisKeyConst.WECHAT_ACCESS_TOKEN, accessToken, NumberConst.INT_1, TimeUnit.HOURS);
return accessToken;
}
/**
* 小程序消息提醒
*
* @param page 跳转页面(可不配)
* @param wechatMessageBO 提醒讯息入参
*/
public void subscribeMessage(String page, WechatMessageBO wechatMessageBO) {
String openId = wechatMessageBO.getOpenId();
Map<String, TemplateDataBO> map = wechatMessageBO.getMap();
log.info("微信提醒openId:{},订阅的消息为:{}", openId, JSON.toJSONString(map));
try {
String accessToken = RedisUtil.get(RedisKeyConst.WECHAT_ACCESS_TOKEN);
if (StringUtils.isBlank(accessToken)) {
accessToken = getAccessToken();
}
SubscribeMessageBO subscribeMessageBO = new SubscribeMessageBO();
// 拼接数据
subscribeMessageBO.setAccess_token(accessToken);
subscribeMessageBO.setTouser(openId);
//事先定义好的模板id
subscribeMessageBO.setTemplate_id(templateId);
subscribeMessageBO.setPage(page);
subscribeMessageBO.setData(map);
String json = JSONObject.toJSONString(subscribeMessageBO);
String ret = HttpRequest.post(getSubscribeMessageUrl + "?access_token=" + accessToken).body(json).execute().body();
log.info("小程序推送的结果为:{}", ret);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
模板数据处理:
private void sengWechatMessage(List<String> openIdList, OrderDTO orderDTO) {
String createUser = orderDTO.getCreateUser();
createUser = ObjectPropertyUtil.removeStrNumber(createUser);
Map<String, TemplateDataBO> map = new HashMap<>(NumberConst.INT_16);
map.put("thing2", new TemplateDataBO("服务订单待签收"));
Date from = Date.from(orderDTO.getCreateTime().atZone(ZoneId.systemDefault()).toInstant());
map.put("date3", new TemplateDataBO(new SimpleDateFormat(DateFormatConst.FORMAT_YYYY_MM_DD_HH_MM_SS).format(from)));
map.put("name7", new TemplateDataBO(createUser));
map.put("character_string15", new TemplateDataBO(orderDTO.getOrderCode()));
String thing8 = MessageConst.ORDER_SIGN_WECHAT_CONTENT;
map.put("thing8", new TemplateDataBO(thing8));
for (String openId : openIdList) {
log.info("订单单号:{}, 微信提醒openId:{}, 订阅的消息为:{}", orderDTO.getOrderCode(), openId, JSON.toJSONString(map));
WechatMessageBO wechatMessageBO = new WechatMessageBO();
wechatMessageBO.setOpenId(openId);
wechatMessageBO.setMap(map);
wechatClient.subscribeMessage(wechatMessageBO);
}
}
/**
* 小程序订阅提醒入参BO
*
* @author wangdelongWX1
* @date 2023/6/8 16:58
*/
@Data
@NoArgsConstructor
public class TemplateDataBO {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public TemplateDataBO(String value) {
this.value = value;
}
}
DateFormatConst
public class DateFormatConst {
public static final String FORMAT_YYYY = "yyyy";
public static final String FORMAT_YY = "yy";
public static final String FORMAT_MM_MONTH = "MM";
public static final String FORMAT_DD = "dd";
public static final String FORMAT_HH = "HH";
public static final String FORMAT_MM_MINUTE = "mm";
public static final String FORMAT_SS = "ss";
public static final String FORMAT_SSS = "SSS";
public static final String FORMAT_YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
public static final String FORMAT_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static final String FORMAT_YYYYMMDDHHMM = "yyyyMMddHHmm";
public static final String FORMAT_YYYYMMDDHH = "yyyyMMddHH";
public static final String FORMAT_YYYYMMDD = "yyyyMMdd";
public static final String FORMAT_YYYYMM = "yyyyMM";
public static final String FORMAT_YYMMDDHHMMSSSSS = "yyMMddHHmmssSSS";
public static final String FORMAT_YYMMDDHHMMSS = "yyMMddHHmmss";
public static final String FORMAT_YYMMDDHHMM = "yyMMddHHmm";
public static final String FORMAT_YYMMDDHH = "yyMMddHH";
public static final String FORMAT_YYMMDD = "yyMMdd";
public static final String FORMAT_YYMM = "yyMM";
public static final String FORMAT_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final String FORMAT_YYYY_MM_DD_H_MM_SS = "yyyy-MM-dd H:mm:ss";
public static final String FORMAT_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
public static final String FORMAT_YYYY_MM_DD = "yyyy-MM-dd";
public static final String FORMAT_YYYY_MM = "yyyy-MM";
private DateFormatConst() {
throw new IllegalStateException("DateFormatConst.class");
}
}