package com.zc.business.utils; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.system.mapper.SysUserMapper; import com.zc.business.constant.RedisKeyConstants; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; /** * @Description 企业微信Api工具 * * @author liuwenge * @date 2023/5/18 16:17 * @return null */ @Component public class QYWXUtil { @Resource private RedisCache redisCache; /** 企业id*/ @Value("${qywx.corpId}") private String corpId; /** 企业密钥*/ @Value("${qywx.corpsecret}") private String corpsecret; /** 应用id*/ @Value("${qywx.agentId}") private int agentId; @Resource private SysUserMapper sysUserMapper; /** * @Description 从缓存中获取access_token * * @author liuwenge * @date 2023/5/18 17:37 * @param * @return java.lang.String */ public String getAccessToken(){ // 从redis拿access_token String accessToken = redisCache.getCacheObject(RedisKeyConstants.QYWX_ACCESS_TOKEN); if (StringUtils.isEmpty(accessToken)) { // 如果redis里没有,则重新调http获取,以及存放到redis里 return getAccessTokenByHttp(); }else { // 如果redis里有,则先校验access_token失效有效时间是否快到了 Long expire = redisCache.getExpire(RedisKeyConstants.QYWX_ACCESS_TOKEN); System.out.println("access_token剩余时间:"+expire); // 当前时间+有效时间低于规定时间(秒)默认600秒 if (expire <= 600) { // 通过http获取最新access_token,且存到redis return getAccessTokenByHttp(); } else { return accessToken; // 直接返回access_token } } } /** * @Description 重新请求接口获取token,放入缓存 * * @author liuwenge * @date 2023/5/18 17:37 * @param * @return java.lang.String */ public String getAccessTokenByHttp(){ // 拼接获取access_token的url String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpId + "&corpsecret=" + corpsecret; // 调用get方法获取 String result = HttpUtils.sendGet(url); if (!StringUtils.isEmpty(result)) { // 把响应报文转成json对象 JSONObject objJsonObject = (JSONObject) JSONObject.parse(result); if (null != objJsonObject) { // 出错返回码,为0表示成功,非0表示调用失败 int iErrorCode = objJsonObject.getIntValue("errcode"); if (iErrorCode == 0) { String strAccessToken = objJsonObject.getString("access_token"); Integer expiresIn = objJsonObject.getInteger("expires_in"); // 设置到redis里,目前的存活时间为120分钟(7200秒) redisCache.setCacheObject(RedisKeyConstants.QYWX_ACCESS_TOKEN,strAccessToken,expiresIn, TimeUnit.SECONDS); return strAccessToken; } } } return null; } /** * @Description 通过手机号获取企业微信userId * 注意:请确保手机号的正确性,若出错的次数超出企业规模人数的20%,会导致1天不可调用 * @author liuwenge * @date 2023/5/19 9:07 * @param mobile 手机号 * @return java.lang.String */ public String getUserIdByMobile(String mobile){ if (StringUtils.isEmpty(mobile)){ return null; } //拼接请求路径 String accessToken = this.getAccessToken(); String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token=" + accessToken; //请求参数 Map params = new HashMap<>(); params.put("mobile",mobile); Gson gson = new Gson(); String jsonMessage = gson.toJson(params); //发起post请求 String result = HttpUtils.sendPost(url,jsonMessage); if (!StringUtils.isEmpty(result)) { // 把响应报文转成json对象 JSONObject objJsonObject = (JSONObject) JSONObject.parse(result); if (null != objJsonObject) { // 出错返回码,为0表示成功,非0表示调用失败 int iErrorCode = objJsonObject.getIntValue("errcode"); if (iErrorCode == 0) { //返回用户id return objJsonObject.getString("userid"); } else if (iErrorCode == 42001 || iErrorCode == 40014){ //access_token过期,重新获取 getAccessTokenByHttp(); //重新获取userId return getUserIdByMobile(mobile); } System.out.println("通过手机号获取userId失败! 错误码:" + iErrorCode + ", 错误信息:" + objJsonObject.getString("errmsg")); } } return null; } /** * @Description 给企业微信用户发送文本消息 * * @author liuwenge * @date 2023/5/19 9:43 * @param userId 消息接收人id(企业微信的userid) * @param content 消息内容 * @return java.util.Map */ public Map sendMessageByWxUserId(List userId,String content){ Map result = new HashMap<>(); if (userId.size() < 1 || userId.size() >= 1001){ result.put("msg","接收人不能为空,并且最多支持1000个"); result.put("code","0"); return result; } else if (StringUtils.isEmpty(content)){ result.put("msg","消息内容不能为空"); result.put("code","0"); return result; } //请求路径 String accessToken = this.getAccessToken(); String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken; //请求参数 Map params = new HashMap<>(); //指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个) String toUser = String.join("|",userId); params.put("touser",toUser); //消息类型,此时固定为:text params.put("msgtype","text"); //企业应用的id params.put("agentid",agentId); //消息内容,最长不超过2048个字节,超过将截断(支持id转译) Map text = new HashMap<>(); text.put("content",content); params.put("text",text); Gson gson = new Gson(); String jsonMessage = gson.toJson(params); //发起post请求 String httpResult = HttpUtils.sendPost(url,jsonMessage); if (!StringUtils.isEmpty(httpResult)) { // 把响应报文转成json对象 JSONObject objJsonObject = (JSONObject) JSONObject.parse(httpResult); if (null != objJsonObject) { // 出错返回码,为0表示成功,非0表示调用失败 int iErrorCode = objJsonObject.getIntValue("errcode"); System.out.println("发送企业微信消息,状态码: " + iErrorCode + ", 提示信息:" + objJsonObject.getString("errmsg")); if (iErrorCode == 0) { //返回消息id String msgId = objJsonObject.getString("msgid"); result.put("code","1"); result.put("msg","发送企业微信消息成功!"); result.put("data",msgId); } else if (iErrorCode == 42001 || iErrorCode == 40014){ //access_token过期,重新获取 getAccessTokenByHttp(); //重新发送文本消息 return sendMessageByWxUserId(userId,content); } else { result.put("code","0"); result.put("msg","发送企业微信消息失败!错误码:" + iErrorCode + ", 错误信息:" + objJsonObject.getString("errmsg")); } } } return result; } /** * @Description 给企业微信用户发送文本消息 * 注意:如不能保证手机号的正确性,此方法不建议使用,因企业微信有严格的错误频率限制,若出错的次数超出企业规模人数的20%,会导致1天不可调用 * @author liuwenge * @date 2023/5/19 9:43 * @param sysUser 消息接收人(此系统中的用户) * @param content 消息内容 * @return java.util.Map */ public Map sendMessageBySysUser(List sysUser, String content){ Map result = new HashMap<>(); if (sysUser.size() < 1 || sysUser.size() >= 1001){ result.put("msg","接收人不能为空,并且最多支持1000个"); result.put("code","0"); return result; } else if (StringUtils.isEmpty(content)){ result.put("msg","消息内容不能为空"); result.put("code","0"); return result; } //循环查出企业微信中的用户id List userList = new ArrayList<>(); String userId; for (SysUser user : sysUser) { userId = getUserIdByMobile(user.getPhonenumber()); if (!StringUtils.isEmpty(userId)){ userList.add(userId); System.out.println("已通过手机号:" + user.getPhonenumber() + "查询到企业微信用户:userId"); } } if (userList.size() < 1){ result.put("msg","未查到企业微信用户"); result.put("code","0"); return result; } result = sendMessageByWxUserId(userList,content); return result; } }