lau572
5 months ago
1 changed files with 271 additions and 0 deletions
@ -0,0 +1,271 @@ |
|||||
|
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"); |
||||
|
// 设置到redis里,目前的存活时间为120分钟(7200秒)
|
||||
|
redisCache.setCacheObject(RedisKeyConstants.QYWX_ACCESS_TOKEN,strAccessToken,7200, 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<String,Object> 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){ |
||||
|
//access_token过期,重新获取
|
||||
|
getAccessTokenByHttp(); |
||||
|
//重新获取userId
|
||||
|
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<java.lang.String,java.lang.Object> |
||||
|
*/ |
||||
|
public Map<String,Object> sendMessageByWxUserId(List<String> userId,String content){ |
||||
|
Map<String,Object> 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<String,Object> 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<String,String> 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){ |
||||
|
//access_token过期,重新获取
|
||||
|
getAccessTokenByHttp(); |
||||
|
//重新发送文本消息
|
||||
|
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<java.lang.String,java.lang.Object> |
||||
|
*/ |
||||
|
public Map<String,Object> sendMessageBySysUser(List<SysUser> sysUser, String content){ |
||||
|
Map<String,Object> 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<String> 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; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
Loading…
Reference in new issue