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