public interface WeiChatService { /** * 获取企业微信 access_token * @return access_token */ String getAccessToken(); /** * 获取所有部门列表 * @param accessToken * @param id * @return 部门列表 */ List<WeChatDeptDto> getDeptList(String accessToken, String id); /** * 获取部门成员列表 * @param accessToken * @param id * @return 部门成员列表 */ List<WeChatDeptUserDto> getDeptUserList(String accessToken, String id); /** * 获取成员详情,先要同步用户,才行发布工作通知 * @param accessToken * @param userid * @return 成员详情 */ WeChatDeptUserInfoDto getDeptUserInfo(String accessToken, String userid); /** * 工作通知--发送会议通知到企业微信 * https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN * @param touser 指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。 * @param content 消息内容 */ ResponseVo<Object> notice(String touser, String content);
}
@Service public class WeiChatServiceImpl implements WeiChatService { private static final Logger logger = LoggerFactory.getLogger(WeiChatServiceImpl.class); // 企业微信互联网访问域名 @Value("${weichat_host}") private String host; @Autowired private StringRedisTemplate redisTemplate; @Autowired private ServerConfig serviceConfig; @Autowired private MeetingService meetingService; @Autowired private UserService userService; @SneakyThrows @Override public String getAccessToken() { // 从redis中获取token信息 String accessToken = redisTemplate.opsForValue().get("WeiChat_AccessToken"); if (!StringUtil.isEmpty(accessToken)) { return accessToken; } // 发送http请求企业微信服务器,获取AccessToken String path = "/cgi-bin/gettoken"; String method = "GET"; Map<String, String> headers = new HashMap<String, String>(); Map<String, String> querys = new HashMap<String, String>(); // 从数据库查询corpid、corpsecret if (!redisTemplate.hasKey(SecurityConstant.EXT_APP_CONFIG)) { throw new RuntimeException("第三方接入配置获取失败,请重新配置!"); } ExternalAccessConfig config = JSONUtil.toBean(redisTemplate.opsForValue().get(SecurityConstant.EXT_APP_CONFIG), ExternalAccessConfig.class); if (StringUtils.isEmpty(config.getExtAppId())) { throw new RuntimeException("corpid获取失败,请重新配置!"); } if (StringUtils.isEmpty(config.getExtSecret())) { throw new RuntimeException("corpid获取失败,请重新配置!"); } querys.put("corpid", config.getExtAppId().trim()); querys.put("corpsecret", config.getExtSecret().trim()); host = getCurrentHost(); HttpResponse httpResponse = HttpUtil.doGet(host, path, method, headers, querys); String response = EntityUtils.toString(httpResponse.getEntity()); if (StringUtils.isEmpty(response)) { throw new RuntimeException("企业微信AccessToken获取失败!"); } JSONObject json = JSON.parseObject(response); try { // 将token信息保存到redis中,并设置过期时间 accessToken = json.getString("access_token"); //String ExpirationTime = json.getString("expires_in"); redisTemplate.opsForValue().set("WeiChat_AccessToken", accessToken, 3600, TimeUnit.SECONDS); // 打印消息 String message = String.format("获取token成功 access token: %s, expire_in: %s", json.getString("access_token"), json.getInteger("expires_in")); logger.info(message); return accessToken; } catch (Exception e) { String error = String.format("获取token失败 errcode: %s ,errmsg: %s", json.getInteger("errcode"), json.getString("errmsg")); logger.info(error); throw new RuntimeException(e); } } /** * 获取所有部门列表 * @param accessToken * @param id * @return 部门列表 */ @SneakyThrows public List<WeChatDeptDto> getDeptList(String accessToken, String id) { List<WeChatDeptDto> list = null; /** * redis中为获取到accessToken,从企业微信服务器获取 */ //https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=ACCESS_TOKEN&id=ID String path = "/cgi-bin/department/list"; String method = "GET"; Map<String, String> headers = new HashMap<String, String>(); Map<String, String> querys = new HashMap<String, String>(); querys.put("access_token", accessToken); if(!StringUtil.isEmpty(id)){ querys.put("id", id);//部门id。获取指定部门及其下的子部门(以及及子部门的子部门等等,递归)。 如果不填,默认获取全量组织架构 } host = getCurrentHost(); HttpResponse httpResponse = HttpUtil.doGet(host, path, method, headers, querys); String response = EntityUtils.toString(httpResponse.getEntity()); if (StringUtils.isEmpty(response)) { throw new RuntimeException("企业微信AccessToken获取失败!"); } JSONObject json = JSON.parseObject(response); try { String errcode = json.getString("errcode"); String department = json.getString("department"); logger.info("errcode = {}, department = {}", errcode, department); list = JSONUtil.toList(JSONUtil.parseArray(department), WeChatDeptDto.class); } catch (Exception e) { String error = String.format("获取token失败 errcode: %s ,errmsg: %s", json.getInteger("errcode"), json.getString("errmsg")); logger.info(error); throw new RuntimeException(e); } return list; } /** * 获取部门成员列表 * @param accessToken * @return 部门成员列表 */ @SneakyThrows public List<WeChatDeptUserDto> getDeptUserList(String accessToken, String id) { List<WeChatDeptUserDto> list = null; /** * redis中为获取到accessToken,从企业微信服务器获取 */ //https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD String path = "/cgi-bin/user/simplelist"; String method = "GET"; Map<String, String> headers = new HashMap<String, String>(); Map<String, String> querys = new HashMap<String, String>(); querys.put("access_token", accessToken); querys.put("department_id", id); querys.put("fetch_child", "0");//是否递归获取子部门下面的成员:1-递归获取,0-只获取本部门 host = getCurrentHost(); HttpResponse httpResponse = HttpUtil.doGet(host, path, method, headers, querys); String response = EntityUtils.toString(httpResponse.getEntity()); if (StringUtils.isEmpty(response)) { throw new RuntimeException("企业微信AccessToken获取失败!"); } JSONObject json = JSON.parseObject(response); try { String errcode = json.getString("errcode"); String userlist = json.getString("userlist"); logger.info("errcode = {}, userlist = {}", errcode, userlist); list = JSONUtil.toList(JSONUtil.parseArray(userlist), WeChatDeptUserDto.class); } catch (Exception e) { String error = String.format("获取token失败 errcode: %s ,errmsg: %s", json.getInteger("errcode"), json.getString("errmsg")); logger.info(error); throw new RuntimeException(e); } return list; } /** * 获取成员详情 * @param accessToken * @return 成员详情 */ @SneakyThrows public WeChatDeptUserInfoDto getDeptUserInfo(String accessToken, String userid) { //https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&userid=USERID String path = "/cgi-bin/user/get"; String method = "GET"; Map<String, String> headers = new HashMap<String, String>(); Map<String, String> querys = new HashMap<String, String>(); querys.put("access_token", accessToken); querys.put("userid", userid); host = getCurrentHost(); HttpResponse httpResponse = HttpUtil.doGet(host, path, method, headers, querys); String response = EntityUtils.toString(httpResponse.getEntity()); if (StringUtils.isEmpty(response)) { throw new RuntimeException("企业微信获取成员详情获取失败!"); } JSONObject json = JSON.parseObject(response); WeChatDeptUserInfoDto weChatDeptUserInfoDto = null; if(null != json){ try { String errcode = json.getString("errcode"); String username = json.getString("name"); weChatDeptUserInfoDto = JSONUtil.toBean(response, WeChatDeptUserInfoDto.class); logger.info("errcode = {}, username = {}", errcode, username); } catch (Exception e) { String error = String.format("获取成员详情失败 errcode: %s ,errmsg: %s", json.getInteger("errcode"), json.getString("errmsg")); logger.info(error); throw new RuntimeException(e); } } return weChatDeptUserInfoDto; } @SneakyThrows @Override public ResponseVo<Object> notice(String touser, String content) { //https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN String accessToken = this.getAccessToken(); String path = "/cgi-bin/message/send?access_token="; NoticeDto noticeDto = new NoticeDto(); if (!redisTemplate.hasKey(SecurityConstant.EXT_APP_CONFIG)) { throw new RuntimeException("第三方接入配置获取失败,请重新配置!"); } ExternalAccessConfig config = JSONUtil.toBean(redisTemplate.opsForValue().get(SecurityConstant.EXT_APP_CONFIG), ExternalAccessConfig.class); if (StringUtils.isEmpty(config.getExtAppId())) { throw new RuntimeException("corpid获取失败,请重新配置!"); } if (StringUtils.isEmpty(config.getExtSecret())) { throw new RuntimeException("corpid获取失败,请重新配置!"); } noticeDto.setAgentid(config.getExtAgentId()); noticeDto.setTouser(touser); Map<Object, Object> contentMap = new HashMap<Object, Object>(); contentMap.put("content", content); noticeDto.setText(contentMap); String jsonSrtData = JSONUtil.toJsonStr(noticeDto); host = getCurrentHost(); String response = HttpUtil.post(host + path, jsonSrtData, accessToken); if (StringUtils.isEmpty(response)) { throw new RuntimeException("企业微信发送通知失败!"); } JSONObject json = JSON.parseObject(response); if(null != json){ String errcode = json.getString("errcode"); String msgid = json.getString("msgid"); if("0".equals(errcode)){ logger.info("errcode = {}, touser = {}, msgid = {}", errcode, touser, msgid); }else { String error = String.format("企业微信发送通知失败 errcode: %s ,errmsg: %s", json.getInteger("errcode"), json.getString("errmsg")); logger.error(error); } } return null; }
/** * 获取用户id列表 */ private String getUserIdListStr(String sendAddress){ List<String> list = Arrays.asList(sendAddress.split(",")); StringBuilder userIdList = new StringBuilder(); for (String userName : list) { UserInfo userInfo = userService.findByUserName(userName); if (null != userInfo) { userIdList.append(userInfo.getId()).append("|"); } } //去除最后一个|符号 userIdList.deleteCharAt(userIdList.length()-1); return userIdList.toString(); }
}