♥️作者:小宋1021
🤵♂️个人主页:小宋1021主页
♥️坚持分析平时学习到的项目以及学习到的软件开发知识,和大家一起努力呀!!!
🎈🎈加油! 加油! 加油! 加油
🎈欢迎评论 💬点赞👍🏻 收藏 📂加关注+!
效果展示:

这个功能是在后端实现的,首先我们要把自己的ip地址加在企业微信官网的ip白名单里。
然后我们实现发送企业微信通知的接口:
SocialClientService:
java
package com.todod.basemanage.module.system.service.social;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.todod.basemanage.framework.common.pojo.PageResult;
import com.todod.basemanage.module.system.api.social.dto.SocialWxQrcodeReqDTO;
import com.todod.basemanage.module.system.api.social.dto.SocialWxaSubscribeMessageSendReqDTO;
import com.todod.basemanage.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
import com.todod.basemanage.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
import com.todod.basemanage.module.system.dal.dataobject.social.SocialClientDO;
import com.todod.basemanage.module.system.enums.social.SocialTypeEnum;
import com.xingyuv.jushauth.model.AuthUser;
import jakarta.validation.Valid;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.subscribemsg.TemplateInfo;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import java.util.List;
import java.util.Map;
/**
* 社交应用 Service 接口
*
* @author admin
*/
public interface SocialClientService {
/**
* 获得社交平台的授权 URL
*
* @param socialType 社交平台的类型 {@link SocialTypeEnum}
* @param userType 用户类型
* @param redirectUri 重定向 URL
* @return 社交平台的授权 URL
*/
String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri);
/**
* 请求社交平台,获得授权的用户
*
* @param socialType 社交平台的类型
* @param userType 用户类型
* @param code 授权码
* @param state 授权 state
* @return 授权的用户
*/
AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state);
// =================== 微信公众号独有 ===================
/**
* 创建微信公众号的 JS SDK 初始化所需的签名
*
* @param userType 用户类型
* @param url 访问的 URL 地址
* @return 签名
*/
WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url);
// =================== 微信小程序独有 ===================
/**
* 获得微信小程序的手机信息
*
* @param userType 用户类型
* @param phoneCode 手机授权码
* @return 手机信息
*/
WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode);
/**
* 获得小程序二维码
*
* @param reqVO 请求信息
* @return 小程序二维码
*/
byte[] getWxaQrcode(SocialWxQrcodeReqDTO reqVO);
/**
* 获得微信小程订阅模板
*
* 缓存的目的:考虑到微信小程序订阅消息选择好模版后几乎不会变动,缓存增加查询效率
*
* @param userType 用户类型
* @return 微信小程订阅模板
*/
List<TemplateInfo> getSubscribeTemplateList(Integer userType);
/**
* 发送微信小程序订阅消息
*
* @param reqDTO 请求
* @param templateId 模版编号
* @param openId 会员 openId
*/
void sendSubscribeMessage(SocialWxaSubscribeMessageSendReqDTO reqDTO, String templateId, String openId);
// =================== 客户端管理 ===================
/**
* 创建社交客户端
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createSocialClient(@Valid SocialClientSaveReqVO createReqVO);
/**
* 更新社交客户端
*
* @param updateReqVO 更新信息
*/
void updateSocialClient(@Valid SocialClientSaveReqVO updateReqVO);
/**
* 删除社交客户端
*
* @param id 编号
*/
void deleteSocialClient(Long id);
/**
* 获得社交客户端
*
* @param id 编号
* @return 社交客户端
*/
SocialClientDO getSocialClient(Long id);
/**
* 获得社交客户端分页
*
* @param pageReqVO 分页查询
* @return 社交客户端分页
*/
PageResult<SocialClientDO> getSocialClientPage(SocialClientPageReqVO pageReqVO);
void sendWxMPMessage(String openId, String templateId, String page, Map<String, String> dataMap) throws Exception;
void sendWxEnMessage( String openId,String title,String description,String url) throws Exception;
}
SocialClientServiceImpl:
java
package com.todod.basemanage.module.system.service.social;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.todod.basemanage.framework.common.enums.CommonStatusEnum;
import com.todod.basemanage.framework.common.enums.UserTypeEnum;
import com.todod.basemanage.framework.common.pojo.PageResult;
import com.todod.basemanage.framework.common.util.cache.CacheUtils;
import com.todod.basemanage.framework.common.util.http.HttpUtils;
import com.todod.basemanage.framework.common.util.object.BeanUtils;
import com.todod.basemanage.module.system.api.social.dto.SocialWxQrcodeReqDTO;
import com.todod.basemanage.module.system.api.social.dto.SocialWxaSubscribeMessageSendReqDTO;
import com.todod.basemanage.module.system.controller.admin.socail.vo.client.SocialClientPageReqVO;
import com.todod.basemanage.module.system.controller.admin.socail.vo.client.SocialClientSaveReqVO;
import com.todod.basemanage.module.system.dal.dataobject.social.SocialClientDO;
import com.todod.basemanage.module.system.dal.mysql.social.SocialClientMapper;
import com.todod.basemanage.module.system.dal.redis.RedisKeyConstants;
import com.todod.basemanage.module.system.enums.social.SocialTypeEnum;
import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.xingyuv.jushauth.config.AuthConfig;
import com.xingyuv.jushauth.model.AuthCallback;
import com.xingyuv.jushauth.model.AuthResponse;
import com.xingyuv.jushauth.model.AuthUser;
import com.xingyuv.jushauth.request.AuthRequest;
import com.xingyuv.jushauth.utils.AuthStateUtils;
import com.xingyuv.justauth.AuthRequestFactory;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.subscribemsg.TemplateInfo;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
import me.chanjar.weixin.cp.api.WxCpMessageService;
import me.chanjar.weixin.cp.api.impl.WxCpMessageServiceImpl;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.subscribe.WxMpSubscribeMessage;
import me.chanjar.weixin.mp.bean.template.WxMpTemplate;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.todod.basemanage.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.todod.basemanage.framework.common.util.collection.MapUtils.findAndThen;
import static com.todod.basemanage.framework.common.util.json.JsonUtils.toJsonString;
import static com.todod.basemanage.module.system.enums.ErrorCodeConstants.*;
/**
* 社交应用 Service 实现类
*
* @author admin
*/
@Service
@Slf4j
public class SocialClientServiceImpl implements SocialClientService {
/**
* 小程序码要打开的小程序版本
* <p>
* 1. release:正式版
* 2. trial:体验版
* 3. developer:开发版
*/
@Value("${basemanage.wxa-code.env-version:release}")
public String envVersion;
/**
* 订阅消息跳转小程序类型
* <p>
* 1. developer:开发版
* 2. trial:体验版
* 3. formal:正式版
*/
@Value("${basemanage.wxa-subscribe-message.miniprogram-state:formal}")
public String miniprogramState;
@Value("${justauth.type.WECHAT_ENTERPRISE.client-id}")
private String clientId;
@Value("${justauth.type.WECHAT_ENTERPRISE.client-secret}")
private String clientSecret;
@Value("${justauth.type.WECHAT_MP.client-id}")
private String clientIdMP;
@Value("${justauth.type.WECHAT_MP.client-secret}")
private String clientSecretMP;
@Value("${justauth.type.WECHAT_ENTERPRISE.agent-id}")
private int agentId;
@Resource
private AuthRequestFactory authRequestFactory;
@Resource
private WxMpService wxMpService;
@Resource
private WxMpProperties wxMpProperties;
@Resource
private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Service 注入了它
/**
* 缓存 WxMpService 对象
* <p>
* key:使用微信公众号的 appId + secret 拼接,即 {@link SocialClientDO} 的 clientId 和 clientSecret 属性。
* 为什么 key 使用这种格式?因为 {@link SocialClientDO} 在管理后台可以变更,通过这个 key 存储它的单例。
* <p>
* 为什么要做 WxMpService 缓存?因为 WxMpService 构建成本比较大,所以尽量保证它是单例。
*/
private final LoadingCache<String, WxMpService> wxMpServiceCache = CacheUtils.buildAsyncReloadingCache(
Duration.ofSeconds(10L),
new CacheLoader<String, WxMpService>() {
@Override
public WxMpService load(String key) {
String[] keys = key.split(":");
return buildWxMpService(keys[0], keys[1]);
}
});
@Resource
private WxMaService wxMaService;
@Resource
private WxMaProperties wxMaProperties;
/**
* 缓存 WxMaService 对象
* <p>
* 说明同 {@link #wxMpServiceCache} 变量
*/
private final LoadingCache<String, WxMaService> wxMaServiceCache = CacheUtils.buildAsyncReloadingCache(
Duration.ofSeconds(10L),
new CacheLoader<String, WxMaService>() {
@Override
public WxMaService load(String key) {
String[] keys = key.split(":");
return buildWxMaService(keys[0], keys[1]);
}
});
@Resource
private SocialClientMapper socialClientMapper;
@Override
public String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri) {
// 获得对应的 AuthRequest 实现
AuthRequest authRequest = buildAuthRequest(socialType, userType);
// 生成跳转地址
String authorizeUri = authRequest.authorize(AuthStateUtils.createState());
return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri);
}
@Override
public AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state) {
// 构建请求
AuthRequest authRequest = buildAuthRequest(socialType, userType);
AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build();
// 执行请求
AuthResponse<?> authResponse = authRequest.login(authCallback);
log.info("[getAuthUser][请求社交平台 type({}) request({}) response({})]", socialType,
toJsonString(authCallback), toJsonString(authResponse));
if (!authResponse.ok()) {
throw exception(SOCIAL_USER_AUTH_FAILURE, authResponse.getMsg());
}
return (AuthUser) authResponse.getData();
}
/**
* 构建 AuthRequest 对象,支持多租户配置
*
* @param socialType 社交类型
* @param userType 用户类型
* @return AuthRequest 对象
*/
@VisibleForTesting
AuthRequest buildAuthRequest(Integer socialType, Integer userType) {
// 1. 先查找默认的配置项,从 application-*.yaml 中读取
AuthRequest request = authRequestFactory.get(SocialTypeEnum.valueOfType(socialType).getSource());
Assert.notNull(request, String.format("社交平台(%d) 不存在", socialType));
// 2. 查询 DB 的配置项,如果存在则进行覆盖
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(socialType, userType);
if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
// 2.1 构造新的 AuthConfig 对象
AuthConfig authConfig = (AuthConfig) ReflectUtil.getFieldValue(request, "config");
AuthConfig newAuthConfig = ReflectUtil.newInstance(authConfig.getClass());
BeanUtil.copyProperties(authConfig, newAuthConfig);
// 2.2 修改对应的 clientId + clientSecret 密钥
newAuthConfig.setClientId(client.getClientId());
newAuthConfig.setClientSecret(client.getClientSecret());
if (client.getAgentId() != null) { // 如果有 agentId 则修改 agentId
newAuthConfig.setAgentId(client.getAgentId());
}
// 2.3 设置会 request 里,进行后续使用
ReflectUtil.setFieldValue(request, "config", newAuthConfig);
}
return request;
}
// =================== 微信公众号独有 ===================
@Override
@SneakyThrows
public WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url) {
WxMpService service = getWxMpService(userType);
return service.createJsapiSignature(url);
}
/**
* 获得 clientId + clientSecret 对应的 WxMpService 对象
*
* @param userType 用户类型
* @return WxMpService 对象
*/
@VisibleForTesting
WxMpService getWxMpService(Integer userType) {
// 第一步,查询 DB 的配置项,获得对应的 WxMpService 对象
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
SocialTypeEnum.WECHAT_MP.getType(), userType);
if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
return wxMpServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret());
}
// 第二步,不存在 DB 配置项,则使用 application-*.yaml 对应的 WxMpService 对象
return wxMpService;
}
/**
* 创建 clientId + clientSecret 对应的 WxMpService 对象
*
* @param clientId 微信公众号 appId
* @param clientSecret 微信公众号 secret
* @return WxMpService 对象
*/
public WxMpService buildWxMpService(String clientId, String clientSecret) {
// 第一步,创建 WxMpRedisConfigImpl 对象
WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl(
new RedisTemplateWxRedisOps(stringRedisTemplate),
wxMpProperties.getConfigStorage().getKeyPrefix());
configStorage.setAppId(clientId);
configStorage.setSecret(clientSecret);
// 第二步,创建 WxMpService 对象
WxMpService service = new WxMpServiceImpl();
service.setWxMpConfigStorage(configStorage);
return service;
}
// =================== 微信小程序独有 ===================
@Override
public WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode) {
WxMaService service = getWxMaService(userType);
try {
return service.getUserService().getPhoneNoInfo(phoneCode);
} catch (WxErrorException e) {
log.error("[getPhoneNoInfo][userType({}) phoneCode({}) 获得手机号失败]", userType, phoneCode, e);
throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_PHONE_CODE_ERROR);
}
}
@Override
public byte[] getWxaQrcode(SocialWxQrcodeReqDTO reqVO) {
WxMaService service = getWxMaService(UserTypeEnum.MEMBER.getValue());
try {
return service.getQrcodeService().createWxaCodeUnlimitBytes(
ObjUtil.defaultIfEmpty(reqVO.getScene(), SocialWxQrcodeReqDTO.SCENE),
reqVO.getPath(),
ObjUtil.defaultIfNull(reqVO.getCheckPath(), SocialWxQrcodeReqDTO.CHECK_PATH),
envVersion,
ObjUtil.defaultIfNull(reqVO.getWidth(), SocialWxQrcodeReqDTO.WIDTH),
ObjUtil.defaultIfNull(reqVO.getAutoColor(), SocialWxQrcodeReqDTO.AUTO_COLOR),
null,
ObjUtil.defaultIfNull(reqVO.getHyaline(), SocialWxQrcodeReqDTO.HYALINE));
} catch (WxErrorException e) {
log.error("[getWxQrcode][reqVO({}) 获得小程序码失败]", reqVO, e);
throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_QRCODE_ERROR);
}
}
@Override
@Cacheable(cacheNames = RedisKeyConstants.WXA_SUBSCRIBE_TEMPLATE, key = "#userType",
unless = "#result == null")
public List<TemplateInfo> getSubscribeTemplateList(Integer userType) {
WxMaService service = getWxMaService(userType);
try {
WxMaSubscribeService subscribeService = service.getSubscribeService();
return subscribeService.getTemplateList();
} catch (WxErrorException e) {
log.error("[getSubscribeTemplate][userType({}) 获得小程序订阅消息模版]", userType, e);
throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_TEMPLATE_ERROR);
}
}
@Override
public void sendSubscribeMessage(SocialWxaSubscribeMessageSendReqDTO reqDTO, String templateId, String openId) {
WxMaService service = getWxMaService(reqDTO.getUserType());
try {
WxMaSubscribeService subscribeService = service.getSubscribeService();
subscribeService.sendSubscribeMsg(buildMessageSendReqDTO(reqDTO, templateId, openId));
} catch (WxErrorException e) {
log.error("[sendSubscribeMessage][reqVO({}) templateId({}) openId({}) 发送小程序订阅消息失败]", reqDTO, templateId, openId, e);
throw exception(SOCIAL_CLIENT_WEIXIN_MINI_APP_SUBSCRIBE_MESSAGE_ERROR);
}
}
/**
* 构建发送消息请求参数
*
* @param reqDTO 请求
* @param templateId 模版编号
* @param openId 会员 openId
* @return 微信小程序订阅消息请求参数
*/
private WxMaSubscribeMessage buildMessageSendReqDTO(SocialWxaSubscribeMessageSendReqDTO reqDTO,
String templateId, String openId) {
// 设置订阅消息基本参数
WxMaSubscribeMessage subscribeMessage = new WxMaSubscribeMessage().setLang(WxMaConstants.MiniProgramLang.ZH_CN)
.setMiniprogramState(miniprogramState).setTemplateId(templateId).setToUser(openId).setPage(reqDTO.getPage());
// 设置具体消息参数
Map<String, String> messages = reqDTO.getMessages();
if (CollUtil.isNotEmpty(messages)) {
reqDTO.getMessages().keySet().forEach(key -> findAndThen(messages, key, value ->
subscribeMessage.addData(new WxMaSubscribeMessage.MsgData(key, value))));
}
return subscribeMessage;
}
/**
* 获得 clientId + clientSecret 对应的 WxMpService 对象
*
* @param userType 用户类型
* @return WxMpService 对象
*/
@VisibleForTesting
WxMaService getWxMaService(Integer userType) {
// 第一步,查询 DB 的配置项,获得对应的 WxMaService 对象
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
SocialTypeEnum.WECHAT_MINI_APP.getType(), userType);
if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
return wxMaServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret());
}
// 第二步,不存在 DB 配置项,则使用 application-*.yaml 对应的 WxMaService 对象
return wxMaService;
}
/**
* 创建 clientId + clientSecret 对应的 WxMaService 对象
*
* @param clientId 微信小程序 appId
* @param clientSecret 微信小程序 secret
* @return WxMaService 对象
*/
private WxMaService buildWxMaService(String clientId, String clientSecret) {
// 第一步,创建 WxMaRedisBetterConfigImpl 对象
WxMaRedisBetterConfigImpl configStorage = new WxMaRedisBetterConfigImpl(
new RedisTemplateWxRedisOps(stringRedisTemplate),
wxMaProperties.getConfigStorage().getKeyPrefix());
configStorage.setAppid(clientId);
configStorage.setSecret(clientSecret);
// 第二步,创建 WxMpService 对象
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(configStorage);
return service;
}
// =================== 客户端管理 ===================
@Override
public Long createSocialClient(SocialClientSaveReqVO createReqVO) {
// 校验重复
validateSocialClientUnique(null, createReqVO.getUserType(), createReqVO.getSocialType());
// 插入
SocialClientDO client = BeanUtils.toBean(createReqVO, SocialClientDO.class);
socialClientMapper.insert(client);
return client.getId();
}
@Override
public void updateSocialClient(SocialClientSaveReqVO updateReqVO) {
// 校验存在
validateSocialClientExists(updateReqVO.getId());
// 校验重复
validateSocialClientUnique(updateReqVO.getId(), updateReqVO.getUserType(), updateReqVO.getSocialType());
// 更新
SocialClientDO updateObj = BeanUtils.toBean(updateReqVO, SocialClientDO.class);
socialClientMapper.updateById(updateObj);
}
@Override
public void deleteSocialClient(Long id) {
// 校验存在
validateSocialClientExists(id);
// 删除
socialClientMapper.deleteById(id);
}
private void validateSocialClientExists(Long id) {
if (socialClientMapper.selectById(id) == null) {
throw exception(SOCIAL_CLIENT_NOT_EXISTS);
}
}
/**
* 校验社交应用是否重复,需要保证 userType + socialType 唯一
* <p>
* 原因是,不同端(userType)选择某个社交登录(socialType)时,需要通过 {@link #buildAuthRequest(Integer, Integer)} 构建对应的请求
*
* @param id 编号
* @param userType 用户类型
* @param socialType 社交类型
*/
private void validateSocialClientUnique(Long id, Integer userType, Integer socialType) {
SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
socialType, userType);
if (client == null) {
return;
}
if (id == null // 新增时,说明重复
|| ObjUtil.notEqual(id, client.getId())) { // 更新时,如果 id 不一致,说明重复
throw exception(SOCIAL_CLIENT_UNIQUE);
}
}
@Override
public SocialClientDO getSocialClient(Long id) {
return socialClientMapper.selectById(id);
}
@Override
public PageResult<SocialClientDO> getSocialClientPage(SocialClientPageReqVO pageReqVO) {
return socialClientMapper.selectPage(pageReqVO);
}
@Override
public void sendWxMPMessage(String openId, String templateId, String page, Map<String, String> dataMap) throws Exception {
// WxMpService wxMpService1 = wxMpServiceCache.get(clientId + ":" + clientSecret);
// String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend?access_token=" + wxMpService1.getAccessToken();
// Map<String, Object> body = new HashMap<>();
// body.put("template_id", reqDTO.getTemplateId());
// body.put("page", reqDTO.getPage());
// body.put("touser", reqDTO.getOpenId());
// body.put("data", reqDTO.getMessages());
// body.put("miniprogram_state", "formal");
// body.put("lang", "zh_CN");
// String result = HttpUtil.post(url, body);
// JSONObject jo = JSONObject.parseObject(result);
// if (jo.getInteger("errcode") != 0) {
// throw new Exception(jo.getString("errmsg"));
// }
WxMpService wxMpService1 = wxMpServiceCache.get(clientIdMP + ":" + clientSecretMP);
WxMpSubscribeMessage wxMpSubscribeMessage = WxMpSubscribeMessage.builder()
.toUser(openId)
.templateId(templateId)
.url(page)
.dataMap(dataMap)
.build();
// List<WxMpTemplate> wxMpTemplates = wxMpService1.getTemplateMsgService().getAllPrivateTemplate();
wxMpService1.getSubscribeMsgService().send(wxMpSubscribeMessage);
// wxMpService1.getTemplateMsgService().sendTemplateMsg(templateMessage);
}
@Override
public void sendWxEnMessage(String openId, String title, String description, String url) throws Exception {
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
config.setCorpId(clientId); // 设置微信企业号的appid
config.setCorpSecret(clientSecret); // 设置微信企业号的app corpSecret
config.setAgentId(agentId); // 设置微信企业号应用ID
WxCpServiceImpl wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(config);
WxCpMessageService wxCpMessageService = new WxCpMessageServiceImpl(wxCpService);
WxCpMessage wxCpMessage = WxCpMessage
.TEXTCARD()
.agentId(agentId) // 企业号应用ID
.toUser(openId)
.title(title)
.description(description)
.url(url)
.build();
wxCpMessageService.send(wxCpMessage);
}
}
发送方法:
java
// 发送宿舍报修完毕通知(独立方法)
private void sendDormRepair(DormRepairApplyDO dormRepairApplyDO) {
try {
SocialClientService socialClientService = SpringUtil.getBean(SocialClientService.class);
SocialUserService socialUserService = SpringUtil.getBean(SocialUserService.class);
List<Long> intervieweeIds = Collections.singletonList(dormRepairApplyDO.getUserId());
List<String> openIds = socialUserService.listOpenIdByUserIds(intervieweeIds);
if (CollUtil.isNotEmpty(openIds)) {
String dateStr = LocalDateTimeUtil.format(LocalDateTime.now(), "yyyy年MM月dd日");
String content = "<div class=\"gray\">" + dateStr + "</div> <div class=\"normal\"></div>" +
"访客:<div class=\"highlight\">" + adminUserApi.getUser(dormRepairApplyDO.getUserId()).getNickname() + "</div>" +
"您提交的宿舍报修已经完毕,请您检查。";
socialClientService.sendWxEnMessage(
CollUtil.join(openIds, "|"),
"宿舍报修完毕通知",
content,
"http://thbtestqywx.langtaosoft.com:58080"
);
}
} catch (Exception e) {
log.error("发送宿舍报修完毕失败", e);
}
}