package com.xinelu.mobile.utils; import com.alibaba.fastjson2.JSON; import com.xinelu.common.config.WeChatAppletChatConfig; import com.xinelu.common.config.WeChatOfficialAccountConfig; import com.xinelu.common.constant.Constants; import com.xinelu.common.entity.AccessToken; import com.xinelu.common.entity.MessageValueEntity; import com.xinelu.common.exception.ServiceException; import com.xinelu.common.utils.http.HttpUtils; import com.xinelu.mobile.domain.TemplateContent; import com.xinelu.mobile.vo.wechatofficialaccountcallback.PatientVO; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; /** * @Description 院后公众号公众方法工具类 * @Author 纪寒 * @Date 2024-03-21 13:42:31 * @Version 1.0 */ @Slf4j @Component public class WeChatOfficialAccountUtils { @Resource private RedisTemplate redisTemplate; @Resource private WeChatOfficialAccountConfig weChatOfficialAccountConfig; @Resource private WeChatAppletChatConfig weChatAppletChatConfig; /** * 返回成功状态码 */ private static final int SUCCESS_CODE = 0; /** * 获取院后微信公众号accessToken * * @return 微信公众号的accessToken */ public String getWeChatOfficialAccountAccessToken() { String accessToken; //公众号 String accessTokenRedisKey = Constants.WE_CHAT_OFFICIAL_ACCOUNT_ACCESS_TOKEN + "accessToken"; //从Redis中取出accessToken Object object = redisTemplate.opsForValue().get(accessTokenRedisKey); if (Objects.isNull(object)) { //没有,获取accessToken //公众号 String accessTokenUrl = Constants.WE_CHAT_ACCESS_TOKEN_URL + "&appid=" + weChatOfficialAccountConfig.getOfficialAccountAppId() + "&secret=" + weChatOfficialAccountConfig.getOfficialAccountAppSecret(); //发送请求 String result = HttpUtils.sendGet(accessTokenUrl); if (StringUtils.isBlank(result)) { throw new ServiceException("获取微信公众号accessToken信息失败", 201); } AccessToken officialAccountAccessToken = JSON.parseObject(result, AccessToken.class); if (Objects.isNull(officialAccountAccessToken)) { throw new ServiceException("获取微信公众号accessToken信息失败"); } if (Objects.nonNull(officialAccountAccessToken.getErrcode()) && officialAccountAccessToken.getErrcode() != SUCCESS_CODE) { throw new ServiceException("获取微信公众号accessToken信息失败,失败信息为:" + officialAccountAccessToken.getErrmsg(), 201); } if (StringUtils.isBlank(officialAccountAccessToken.getAccessToken())) { throw new ServiceException("微信公众号accessToken信息为空"); } accessToken = officialAccountAccessToken.getAccessToken(); //存入Redis中 redisTemplate.opsForValue().set(accessTokenRedisKey, accessToken, 3600, TimeUnit.SECONDS); } else { accessToken = (String) object; } return accessToken; } /** * 获取院后小程序accessToken * * @return 微信小程序的accessToken */ public String getWeChatAppletAccessToken() { String accessToken; //小程序 String accessTokenRedisKey = Constants.WE_CHAT_APPLET_ACCESS_TOKEN + "accessToken"; //从Redis中取出accessToken Object object = redisTemplate.opsForValue().get(accessTokenRedisKey); if (Objects.isNull(object)) { //没有,获取accessToken //小程序 String accessTokenUrl = Constants.WE_CHAT_ACCESS_TOKEN_URL + "&appid=" + weChatAppletChatConfig.getAppletId() + "&secret=" + weChatAppletChatConfig.getSecret(); //发送请求 String result = HttpUtils.sendGet(accessTokenUrl); if (StringUtils.isBlank(result)) { throw new ServiceException("获取微信小程序accessToken信息失败", 201); } AccessToken officialAccountAccessToken = JSON.parseObject(result, AccessToken.class); if (Objects.isNull(officialAccountAccessToken)) { throw new ServiceException("获取微信小程序accessToken信息失败"); } if (Objects.nonNull(officialAccountAccessToken.getErrcode()) && officialAccountAccessToken.getErrcode() != SUCCESS_CODE) { throw new ServiceException("获取微信小程序accessToken信息失败,失败信息为:" + officialAccountAccessToken.getErrmsg(), 201); } if (StringUtils.isBlank(officialAccountAccessToken.getAccessToken())) { throw new ServiceException("微信小程序accessToken信息为空"); } accessToken = officialAccountAccessToken.getAccessToken(); //存入Redis中 redisTemplate.opsForValue().set(accessTokenRedisKey, accessToken, 3600, TimeUnit.SECONDS); } else { accessToken = (String) object; } return accessToken; } /** * 微信公众号模板消息发送 */ public void sendOfficialAccountTemplateMessage() { //获取微信公众号的accessToken String accessToken = this.getWeChatOfficialAccountAccessToken(); //定义模板内容,公众模板内容 Map paramsMap = new LinkedHashMap<>(); paramsMap.put("touser", "oSwvX5qknp3DrAXfBgFjoMvG6WCI"); paramsMap.put("template_id", "WUCYtSbH-QFRV_fMcfmn86QLsz1zo881QW7fQNTWOjc"); //微信小程序跳转内容 Map miniprogramMap = new LinkedHashMap<>(); miniprogramMap.put("appid", "wxdc32268eca6b78f9"); miniprogramMap.put("pagepath", "pages/startup/startup"); //微信小程序模板data内容 Map dataMap = new LinkedHashMap<>(); dataMap.put("phrase7", new MessageValueEntity("泉医陪护")); dataMap.put("character_string3", new MessageValueEntity("000026315412331612100")); dataMap.put("time6", new MessageValueEntity("2024-03-25 16:21:32")); dataMap.put("time10", new MessageValueEntity("2024-03-27 10:00:00")); dataMap.put("thing11", new MessageValueEntity("济南市槐荫区首诺城市之光东座22楼E10")); paramsMap.put("miniprogram", miniprogramMap); paramsMap.put("data", dataMap); //拼接请求地址并发送 String messageUrl = Constants.OFFICIAL_ACCOUNT_TEMPLATE_SEND_URL + accessToken; String param = JSON.toJSONString(paramsMap); String result = HttpUtils.sendPostJson(messageUrl, param); //返回参数映射 AccessToken errCode = JSON.parseObject(result, AccessToken.class); if (Objects.nonNull(errCode) && Objects.nonNull(errCode.getErrcode())) { switch (errCode.getErrcode()) { case Constants.SUCCESS_ERROR_CODE: log.info("发送消息成功!"); break; case Constants.INVALID_CREDENTIAL_ACCESS_TOKEN_ISINVALID_OR_NOT_LATEST: log.error("取 access_token 时 AppSecret 错误,或者 access_token 无效!"); break; case Constants.INVALID_OPENID: log.error("不合法的 OpenId!"); break; case Constants.INVALID_ACCESS_TOKEN: log.error("合法的 access_token!"); break; case Constants.INVALID_TEMPLATE_ID: log.error("不合法的 template_id!"); break; case Constants.ARGUMENT_INVALID: log.error("参数无效!"); break; case Constants.API_UNAUTHORIZED: log.error("API 功能未授权!"); break; case Constants.DENY_SUBSCRIPTION: log.error("用户拒接订阅!"); break; default: break; } } } /** * 微信小程序模板消息发送 */ public Integer sendAppletTemplateMessage(PatientVO patientVO) { //微信模版组装 String thing5 = "每日阅读有助于了解当前情况哦"; String thing1 = "新入院注意事项指导、术前须知"; List templateContents = JSON.parseArray(patientVO.getAppletNodeContent(), TemplateContent.class); if (CollectionUtils.isNotEmpty(templateContents)) { TemplateContent templateContent = templateContents.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getName()) && Objects.nonNull(item.getValue()) && "thing5".equals(item.getName())).findFirst().orElse(new TemplateContent()); thing5 = templateContent.getValue(); TemplateContent templateContentTwo = templateContents.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getName()) && Objects.nonNull(item.getValue()) && "thing1".equals(item.getName())).findFirst().orElse(new TemplateContent()); thing1 = templateContentTwo.getValue(); } //获取微信小程序的accessToken String accessToken = this.getWeChatAppletAccessToken(); LocalDateTime now = LocalDateTime.now(); //定义模板内容 Map paramsMap = new LinkedHashMap<>(); paramsMap.put("touser", patientVO.getOpenId()); paramsMap.put("template_id", weChatAppletChatConfig.getHealthyPropagandaId()); paramsMap.put("miniprogram_state", "developer");//todo paramsMap.put("page", "pages/homepage/homepage"); Map dataMap = new LinkedHashMap<>(); dataMap.put("thing5", new MessageValueEntity(thing5)); dataMap.put("thing4", new MessageValueEntity(patientVO.getHospitalAgencyName())); dataMap.put("time3", new MessageValueEntity(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")))); dataMap.put("thing6", new MessageValueEntity(patientVO.getRouteNodeName() + "第" + patientVO.getRouteNodeDay() + "天")); dataMap.put("thing1", new MessageValueEntity(thing1)); paramsMap.put("data", dataMap); //拼接请求地址并发送 String messageUrl = Constants.OFFICIAL_ACCOUNT_SUBSCRIBE_SEND_URL + accessToken; String param = JSON.toJSONString(paramsMap); String result = HttpUtils.sendPostJson(messageUrl, param); //返回参数映射 AccessToken errCode = JSON.parseObject(result, AccessToken.class); if (Objects.nonNull(errCode) && Objects.nonNull(errCode.getErrcode())) { switch (errCode.getErrcode()) { case Constants.SUCCESS_ERROR_CODE: log.info("发送消息成功!"); break; case Constants.INVALID_CREDENTIAL_ACCESS_TOKEN_ISINVALID_OR_NOT_LATEST: log.error("取 access_token 时 AppSecret 错误,或者 access_token 无效!"); break; case Constants.INVALID_OPENID: log.error("不合法的 OpenId!"); break; case Constants.INVALID_ACCESS_TOKEN: log.error("合法的 access_token!"); break; case Constants.INVALID_TEMPLATE_ID: log.error("不合法的 template_id!"); break; case Constants.ARGUMENT_INVALID: log.error("参数无效!"); break; case Constants.API_UNAUTHORIZED: log.error("API 功能未授权!"); break; case Constants.DENY_SUBSCRIPTION: log.error("用户拒接订阅!"); break; default: break; } } return errCode.getErrcode(); } }