Browse Source

登录

master
zhizhi wu 5 years ago
parent
commit
fc0b3d06c3
  1. 41
      cloudutil/src/main/java/com/ccsens/cloudutil/feign/HealthFeignClient.java
  2. 84
      health/src/main/java/com/ccsens/health/api/WeixinController.java
  3. 16
      health/src/main/java/com/ccsens/health/bean/dto/EmployeeDto.java
  4. 11
      health/src/main/java/com/ccsens/health/service/IWeiXinService.java
  5. 29
      health/src/main/java/com/ccsens/health/service/WeiXinService.java
  6. 6
      tall/src/main/java/com/ccsens/tall/bean/dto/UserDto.java
  7. 2
      tall/src/main/java/com/ccsens/tall/service/IUserService.java
  8. 110
      tall/src/main/java/com/ccsens/tall/service/UserService.java
  9. 5
      tall/src/main/java/com/ccsens/tall/web/UserController.java
  10. 1
      tall/src/main/resources/application-test.yml
  11. 2
      util/home
  12. 5
      util/src/main/java/com/ccsens/util/CodeEnum.java
  13. 5
      util/src/main/java/com/ccsens/util/PropUtil.java
  14. 6
      util/src/main/java/com/ccsens/util/WebConstant.java
  15. 89
      util/src/main/java/com/ccsens/util/enterprisewx/WeiXinConstant.java
  16. 49
      util/src/main/java/com/ccsens/util/enterprisewx/vo/WeiXinVo.java

41
cloudutil/src/main/java/com/ccsens/cloudutil/feign/HealthFeignClient.java

@ -0,0 +1,41 @@
package com.ccsens.cloudutil.feign;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "health", path = "", fallbackFactory = HealthFeignClientFallBack.class)
public interface HealthFeignClient {
/**
* 获取suiteAccessToken
* @param suiteId
* @return
*/
@GetMapping("getSuiteAccessToken")
String getSuiteAccessToken(@RequestParam(name = "suiteId") String suiteId);
}
@Slf4j
@Component
class HealthFeignClientFallBack implements FallbackFactory<HealthFeignClient> {
@Override
public HealthFeignClient create(Throwable throwable) {
String msg = throwable == null ? "" : throwable.getMessage();
if (!StringUtils.isEmpty(msg)) {
log.error(msg);
}
return new HealthFeignClient() {
@Override
public String getSuiteAccessToken(String suiteId) {
return null;
}
};
}
}

84
health/src/main/java/com/ccsens/health/api/WeixinController.java

@ -4,10 +4,14 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ccsens.health.bean.dto.EmployeeDto;
import com.ccsens.health.bean.po.HealthAuth;
import com.ccsens.health.persist.dao.EmployeeDao;
import com.ccsens.health.service.IConstantService;
import com.ccsens.health.service.IWeiXinService;
import com.ccsens.util.HttpsUtil;
import com.ccsens.util.JacksonUtil;
import com.ccsens.util.JsonResponse;
import com.ccsens.util.RestTemplateUtil;
import com.ccsens.util.enterprisewx.AesException;
import com.ccsens.util.enterprisewx.WXBizMsgCrypt;
@ -15,16 +19,11 @@ import com.ccsens.util.enterprisewx.WeiXinConstant;
import com.ccsens.util.enterprisewx.dto.MessageDto;
import io.swagger.annotations.ApiModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author wu
@ -84,9 +83,8 @@ public class WeixinController {
* 数据回调URL post
*/
@PostMapping("userChangeNotice")
public String userChangeNoticePost(HttpServletRequest request, MessageDto dto) throws Exception{
public String userChangeNoticePost(MessageDto dto, @RequestBody String body) throws Exception{
log.info("数据回调请求参数:{}", dto);
String body = getBody(request);
String xmlStr = JacksonUtil.xmlToJson(body);
log.info("数据回到xml转换:{}", xmlStr);
JSONObject jsonObject = JSONObject.parseObject(xmlStr);
@ -99,11 +97,9 @@ public class WeixinController {
* 指令回调URL
*/
@PostMapping("authorizationChangeNotice")
public String authorizationChangeNotice(HttpServletRequest request, MessageDto dto) throws Exception{
log.info("指令回调请求参数:{}", dto);
String listString = getBody(request);
log.info("指令回调body:{}", listString);
String xmlStr = JacksonUtil.xmlToJson(listString);
public String authorizationChangeNotice(MessageDto dto, @RequestBody String body) throws Exception{
log.info("指令回调请求参数:{}, body:{}", dto, body);
String xmlStr = JacksonUtil.xmlToJson(body);
log.info("指令回到xml转换:{}", xmlStr);
JSONObject jsonObject = JSONObject.parseObject(xmlStr);
log.info("jsonObject:{}", jsonObject);
@ -119,13 +115,27 @@ public class WeixinController {
MessageDto.Ticket ticket = JSONObject.parseObject(jsonStr, MessageDto.Ticket.class);
constantService.saveConstant(WeiXinConstant.getSuiteTicket(ticket.getSuiteId()), ticket.getSuiteTicket());
//获取第三方应用凭证
getSuiteAccessToken(ticket.getSuiteId(),ticket.getSuiteTicket());
new Thread(new Runnable() {
@Override
public void run() {
getSuiteAccessToken(ticket.getSuiteId(),ticket.getSuiteTicket());
}
}).start();
break;
case "create_auth" :
MessageDto.Grant grant = JSONObject.parseObject(jsonStr, MessageDto.Grant.class);
constantService.saveConstant(WeiXinConstant.getTempAuthCodeKey(grant.getSuiteId()), grant.getAuthCode());
//获取永久授权
getPermanentCode(grant.getSuiteId(), grant.getAuthCode());
log.info("grant:{}", grant);
new Thread(new Runnable() {
@Override
public void run() {
getPermanentCode(grant.getSuiteId(), grant.getAuthCode());
}
}).start();
break;
case "change_auth" :
//TODO 变更授权通知
@ -135,6 +145,7 @@ public class WeixinController {
break;
//TODO 成员变更和部门变更通知
}
log.info("-----------------------------------------------------");
return "success";
}
@ -148,21 +159,6 @@ public class WeixinController {
weiXinService.getSuiteToken(suite_id, suite_ticket);
}
/**
* 读取body
* @param request
* @return
* @throws IOException
*/
private String getBody(HttpServletRequest request) throws IOException {
BufferedReader br = request.getReader();
String str = "";
String listString = "";
while ((str = br.readLine()) != null) {
listString += str;
}
return listString;
}
/**
* 获取永久授权码
@ -172,9 +168,9 @@ public class WeixinController {
public void getPermanentCode(String suiteId, String authCode){
String suiteTicket = constantService.getByKey(WeiXinConstant.getSuiteTicket(suiteId));
String suiteToken = weiXinService.getSuiteToken(suiteId, suiteTicket);
String accessToken = weiXinService.savePermanentCode(authCode, suiteToken);
if (StrUtil.isNotBlank(accessToken)) {
weiXinService.initDepartment(accessToken);
HealthAuth auth = weiXinService.savePermanentCode(authCode, suiteToken);
if (auth != null) {
weiXinService.initDepartment(auth.getAccessToken());
}
}
@ -189,4 +185,26 @@ public class WeixinController {
log.info("解析结果:{}", verifyURL);
return verifyURL;
}
/**
* 获取第三方应用凭证suiteAccessToken
* @param suiteId
* @return
*/
@GetMapping("getSuiteAccessToken")
public String getSuiteAccessToken(String suiteId) {
String suiteTicket = constantService.getByKey(WeiXinConstant.getSuiteTicket(suiteId));
return weiXinService.getSuiteToken(suiteId, suiteTicket);
}
/**
* 获取第三方应用凭证suiteAccessToken
* @param bind
* @return
*/
@GetMapping("bindUser")
public JsonResponse bindUser(@RequestBody EmployeeDto.Bind bind) {
weiXinService.bindUser(bind);
return JsonResponse.newInstance().ok();
}
}

16
health/src/main/java/com/ccsens/health/bean/dto/EmployeeDto.java

@ -0,0 +1,16 @@
package com.ccsens.health.bean.dto;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel("员工信息")
public class EmployeeDto {
@Data
@ApiModel("绑定用户")
public static class Bind{
private Long tallUserId;
private String userid;
}
}

11
health/src/main/java/com/ccsens/health/service/IWeiXinService.java

@ -1,5 +1,8 @@
package com.ccsens.health.service;
import com.ccsens.health.bean.dto.EmployeeDto;
import com.ccsens.health.bean.po.HealthAuth;
/**
* 企业微信相关业务
*/
@ -9,7 +12,7 @@ public interface IWeiXinService {
* 保存永久授权
* @param authCode 微信返回永久授权字符串
*/
String savePermanentCode(String authCode, String suiteAccessToken);
HealthAuth savePermanentCode(String authCode, String suiteAccessToken);
/**
* 获取第三方应用凭证
@ -32,4 +35,10 @@ public interface IWeiXinService {
* @param accessToken
*/
void initDepartment(String accessToken);
/**
* 用户绑定
* @param bind
*/
void bindUser(EmployeeDto.Bind bind);
}

29
health/src/main/java/com/ccsens/health/service/WeiXinService.java

@ -5,15 +5,18 @@ import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ccsens.health.bean.dto.EmployeeDto;
import com.ccsens.health.bean.po.*;
import com.ccsens.health.persist.dao.DepartmentDao;
import com.ccsens.health.persist.dao.DepartmentEmployeeDao;
import com.ccsens.health.persist.dao.EmployeeDao;
import com.ccsens.health.persist.mapper.HealthAuthAgentMapper;
import com.ccsens.health.persist.mapper.HealthAuthMapper;
import com.ccsens.util.CodeEnum;
import com.ccsens.util.RedisUtil;
import com.ccsens.util.RestTemplateUtil;
import com.ccsens.util.enterprisewx.WeiXinConstant;
import com.ccsens.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -75,6 +78,25 @@ public class WeiXinService implements IWeiXinService {
return accessToken;
}
@Override
public void bindUser(EmployeeDto.Bind bind) {
log.info("用户绑定:{}", bind);
EmployeeExample example = new EmployeeExample();
example.createCriteria().andUseridEqualTo(bind.getUserid());
List<Employee> employees = employeeDao.selectByExample(example);
log.info("有无用户信息");
if (CollectionUtil.isEmpty(employees)) {
throw new BaseException(CodeEnum.PARAM_ERROR);
}
Employee employee = employees.get(0);
if (employee.getTallUserId() == null || employee.getTallUserId() == 0) {
Employee bindEmployee = new Employee();
bindEmployee.setId(employee.getId());
bindEmployee.setTallUserId(bind.getTallUserId());
employeeDao.updateByPrimaryKeySelective(bindEmployee);
}
}
@Override
public String getSuiteToken(String suiteId, String suiteTicket) {
log.info("获取suiteToken, suiteId:{}, suiteTicket:{}", suiteId, suiteTicket);
@ -108,15 +130,16 @@ public class WeiXinService implements IWeiXinService {
}
@Override
public String savePermanentCode(String authCode, String suiteAccessToken) {
public HealthAuth savePermanentCode(String authCode, String suiteAccessToken) {
//授权成功通知
Map<String, String> params = new HashMap<>();
params.put("auth_code", authCode);
String url = WeiXinConstant.GET_PERMANENT_CODE + " ?suite_access_token=" + suiteAccessToken;
log.info("获取永久授权参数, auth_code:{}, suite:{}", authCode, suiteAccessToken);
String result = RestTemplateUtil.postBody(url, params);
log.info("获取永久授权返回:{}", result);
JSONObject json = JSONObject.parseObject(result);
if (json.getInteger(WeiXinConstant.ERR_CODE).intValue() != 0) {
if (json.getInteger(WeiXinConstant.ERR_CODE) !=null && json.getIntValue(WeiXinConstant.ERR_CODE) != 0) {
log.error("获取永久授权码异常:{}", result);
//TODO 异常如何处理
return null;
@ -128,7 +151,7 @@ public class WeiXinService implements IWeiXinService {
if (agent != null) {
healthAuthAgentMapper.insertSelective(agent);
}
return json.getString("access_token");
return auth;
}
@Override

6
tall/src/main/java/com/ccsens/tall/bean/dto/UserDto.java

@ -24,14 +24,16 @@ public class UserDto {
@ApiModelProperty("用户凭据|密码")
private String credential;
}
@ApiModelProperty("登录客户端:0-wxmp,1-H5,2-Android,3-IOS")
@ApiModelProperty("登录客户端:0-wxmp,1-H5,2-Android,3-IOS,4-WxEnterprise")
@NotNull(message = "client is required.")
private Integer client;
@ApiModelProperty("登录类型:0-wxmp,1-phone,2-email,3-accounts,4-OAUTH2_Wx,5-Wx_H5,6-OAUTH2_WeiBo")
@ApiModelProperty("登录类型:0-wxmp,1-phone,2-email,3-accounts,4-OAUTH2_Wx,5-Wx_H5,6-OAUTH2_WeiBo, 7-Wx_Enterprise")
@NotNull(message = "type is required.")
private Integer type;
@ApiModelProperty("登录信息")
private Data data;
@ApiModelProperty("通知消息")
private String redirect;
}
@Data

2
tall/src/main/java/com/ccsens/tall/service/IUserService.java

@ -14,7 +14,7 @@ import java.util.Map;
public interface IUserService {
UserVo.UserSign signin(WebConstant.CLIENT_TYPE clientType, WebConstant.IDENTIFY_TYPE identifyType,
String identifier, String credential, String clientIp) throws Exception;
String identifier, String credential, String clientIp, String redirect) throws Exception;
UserVo.TokenBean generateToken(WebConstant.CLIENT_TYPE client_type, Object subject, Map<String, Object> payLoads) throws Exception;

110
tall/src/main/java/com/ccsens/tall/service/UserService.java

@ -7,6 +7,7 @@ import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ccsens.cloudutil.feign.HealthFeignClient;
import com.ccsens.tall.bean.dto.ProjectDto;
import com.ccsens.tall.bean.dto.UserDto;
import com.ccsens.tall.bean.po.*;
@ -15,10 +16,13 @@ import com.ccsens.tall.exception.SmsException;
import com.ccsens.tall.persist.dao.*;
import com.ccsens.util.*;
import com.ccsens.util.bean.wx.po.WxOauth2UserInfo;
import com.ccsens.util.enterprisewx.WeiXinConstant;
import com.ccsens.util.enterprisewx.vo.WeiXinVo;
import com.ccsens.util.exception.BaseException;
import com.ccsens.util.wx.WxGzhUtil;
import com.ccsens.util.wx.WxXcxUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -28,6 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.xhtmlrenderer.css.parser.property.PrimitivePropertyBuilders;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
@ -57,6 +62,8 @@ public class UserService implements IUserService {
private SysProjectDao sysProjectDao;
@Autowired
private UserAttentionDao userAttentionDao;
@Autowired
private HealthFeignClient healthFeignClient;
/**
@ -64,10 +71,10 @@ public class UserService implements IUserService {
*/
@Override
public UserVo.UserSign signin(WebConstant.CLIENT_TYPE clientType, WebConstant.IDENTIFY_TYPE identifyType,
String identifier, String credential, String clientIp) throws Exception {
String identifier, String credential, String clientIp,String redirect) throws Exception {
UserVo.UserSign userSignVo = null;
//1.登陆
userSignVo = __signin(identifyType, identifier, credential);
userSignVo = __signin(identifyType, identifier, credential, redirect);
if (ObjectUtil.isNotNull(userSignVo) && ObjectUtil.isNotNull(userSignVo.getAuthId())) {
//2.添加登陆记录
__addSigninRecord(clientType, clientIp, userSignVo.getAuthId());
@ -76,8 +83,10 @@ public class UserService implements IUserService {
}
private UserVo.UserSign __signin(WebConstant.IDENTIFY_TYPE identifyType,
String identifier, String credential) throws Exception {
String identifier, String credential, String redirect) throws Exception {
switch (identifyType) {
case WxEnterprise:
return wxEnterpriseLogin(identifier, credential, redirect);
case Wxmp:
credential = credential == null ? "old" : credential;
return wxmplogin(identifier,credential);
@ -100,6 +109,33 @@ public class UserService implements IUserService {
return null;
}
/**
* 企业登录
* @param identifier
* @param credential
* @return
*/
private UserVo.UserSign wxEnterpriseLogin(String identifier, String credential, String redirect) {
log.info("企业微信登录:{},{}, {}");
String suiteId = WeiXinConstant.SuiteId.getValue(credential);
if (StrUtil.isBlank(suiteId) || StrUtil.isBlank(identifier)) {
throw new BaseException(CodeEnum.PARAM_ERROR);
}
String suiteAccessToken = healthFeignClient.getSuiteAccessToken(suiteId);
WeiXinVo.UserInfo userInfo = WeiXinConstant.getUserInfo(identifier, suiteAccessToken);
log.info("用户信息");
if (userInfo == null) {
throw new BaseException(CodeEnum.PARAM_ERROR);
}
WxEnterpriseParam param = new WxEnterpriseParam();
param.setRedirect(redirect);
param.setSuiteAccessToken(suiteAccessToken);
param.setUserTicket(userInfo.getUser_ticket());
UserVo.UserSign userSignVo = getUserSign(userInfo.getUserId(), null, (byte) WebConstant.IDENTIFY_TYPE.WxEnterprise.value, param);
return userSignVo;
}
/**
* 微信网页登陆
*
@ -348,19 +384,36 @@ public class UserService implements IUserService {
* 微信小程序
*/
private UserVo.UserSign wxmplogin(String code,String gameType) throws Exception {
UserVo.UserSign userSignVo = null;
//0.获取openid
WxXcxUtil.WechatUser wechatUser = WxXcxUtil.getUserInfo(code,gameType);
String openId = wechatUser.openid;
String unionId = wechatUser.unionid;
log.info("小程序登录,openid:{} ,unionId:{}", openId, unionId);
//1.查找对应账户,不存在则注册
UserVo.UserSign userSignVo = getUserSign(openId, unionId, (byte) WebConstant.IDENTIFY_TYPE.Wxmp.value,null);
return userSignVo;
}
@Data
private static class WxEnterpriseParam{
private String suiteAccessToken;
private String userTicket;
private String redirect;
}
/**
*
* @param openId
* @param unionId
* @return
*/
private UserVo.UserSign getUserSign(String openId, String unionId,
byte identifyType, WxEnterpriseParam param) {
UserVo.UserSign userSignVo;//1.查找对应账户,不存在则注册
List<SysAuth> authList = null;
SysAuth theAuth = null;
if(ObjectUtil.isNotNull(openId)) {
SysAuthExample authExample = new SysAuthExample();
authExample.createCriteria().andIdentifyTypeEqualTo((byte) WebConstant.IDENTIFY_TYPE.Wxmp.value)
authExample.createCriteria().andIdentifyTypeEqualTo(identifyType)
.andIdentifierEqualTo(openId);
authList = authDao.selectByExample(authExample);
}
@ -372,25 +425,31 @@ public class UserService implements IUserService {
sysAuthList = authDao.selectByExample(sysAuthExample);
}
if (CollectionUtil.isNotEmpty(sysAuthList)) {
// SysAuth sysAuth = sysAuthList.get(0);
//添加认证方式
theAuth = new SysAuth();
theAuth.setId(snowflake.nextId());
theAuth.setUserId(sysAuthList.get(0).getUserId());
theAuth.setIdentifyType((byte) WebConstant.IDENTIFY_TYPE.Wxmp.value);
theAuth.setIdentifier(openId);
theAuth.setCredential(unionId);
authDao.insertSelective(theAuth);
if (identifyType == WebConstant.IDENTIFY_TYPE.Wxmp.value) {
//添加认证方式
theAuth = new SysAuth();
theAuth.setId(snowflake.nextId());
theAuth.setUserId(sysAuthList.get(0).getUserId());
theAuth.setIdentifyType(identifyType);
theAuth.setIdentifier(openId);
theAuth.setCredential(unionId);
authDao.insertSelective(theAuth);
} else {
theAuth = sysAuthList.get(0);
}
} else {
//新建用户并保存微信信息
SysUser user = new SysUser();
user.setId(snowflake.nextId());
//企业微信获取详细用户信息,并绑定用户信息
getUserDetail(identifyType, param, user);
userDao.insertSelective(user);
//添加认证方式
theAuth = new SysAuth();
theAuth.setId(snowflake.nextId());
theAuth.setUserId(user.getId());
theAuth.setIdentifyType((byte) WebConstant.IDENTIFY_TYPE.Wxmp.value);
theAuth.setIdentifyType(identifyType);
theAuth.setIdentifier(openId);
theAuth.setCredential(unionId);
authDao.insertSelective(theAuth);
@ -416,6 +475,23 @@ public class UserService implements IUserService {
return userSignVo;
}
private void getUserDetail(byte identifyType, WxEnterpriseParam param, SysUser user) {
if (identifyType == WebConstant.IDENTIFY_TYPE.Wxmp.value) {
WeiXinVo.UserDetail userDetail = WeiXinConstant.getUserDetail(param.getSuiteAccessToken(), param.getUserTicket());
if (userDetail != null) {
user.setNickname(userDetail.getName());
user.setGender(userDetail.getGender());
user.setAvatarUrl(userDetail.getAvatar());
}
Map<String, Object> map = new HashMap<>();
map.put("tallUserId", user.getId());
map.put("userid", userDetail.getUserid());
String s = RestTemplateUtil.postBody(WeiXinConstant.getBindUrl(param.getRedirect()), map);
log.info("{}绑定关系结果:{}", s);
//TODO 绑定失败如何处理
}
}
/**
* 微信登陆后天添加用户和认证方式
*

5
tall/src/main/java/com/ccsens/tall/web/UserController.java

@ -52,16 +52,19 @@ public class UserController {
//1.验证参数
switch (clientType) {
case Wxmp:
case H5:
case Android:
case IOS:
case WxEnterprise:
break;
default:
throw new UserLoginException(-1, String.format("Not supported client type: %1$d(%2$s)",
clientType.value, clientType));
}
switch (identify_type) {
case WxEnterprise:
case Wxmp:
case OAUTH2_Wx:
case Wx_H5:
@ -86,7 +89,7 @@ public class UserController {
//2.调用业务方法(注册/添加登陆记录)
UserVo.UserSign userSignVo = userService.signin(
clientType, identify_type, identifier, credential,
ServletUtil.getClientIP(request));
ServletUtil.getClientIP(request), dto.getRedirect());
//3.生成token(access_token,refresh_token)
if (ObjectUtil.isNotNull(userSignVo)) {

1
tall/src/main/resources/application-test.yml

@ -29,3 +29,4 @@ swagger:
eureka:
instance:
ip-address: 49.233.89.188
gatewayUrl: https://test.tall.wiki/gateway/

2
util/home

@ -1 +1 @@
{"errcode":41030,"errmsg":"invalid page hint: [G0bX408102372]"}
{"errcode":41030,"errmsg":"invalid page hint: [0r6Ija0174b464]"}

5
util/src/main/java/com/ccsens/util/CodeEnum.java

@ -94,8 +94,9 @@ public enum CodeEnum {
NOT_SIGN_FIELD(77,"签到的字段不可用",true),
ALREADY_SIGN(78,"您已经签到过了,请勿重复签到",true),
ALREADY_ATTENTION(79,"您已经关注了这个项目",true),
NOT_EMPLOYEE(79,"未找到成员信息",true),
NOT_SITE(79,"未找到该场所",true)
NOT_EMPLOYEE(80,"未找到成员信息",true),
NOT_SITE(81,"未找到该场所",true),
LACK_CONFIG(82,"缺少配置",true),
;
public CodeEnum addMsg(String msg){

5
util/src/main/java/com/ccsens/util/PropUtil.java

@ -16,7 +16,12 @@ public class PropUtil {
public static String imgDomain;
public static String projectName;
public static String contextPath;
public static String gatewayUrl;
@Value("${gatewayUrl:}")
public void setGatewayUrl(String gatewayUrl) {
PropUtil.gatewayUrl = gatewayUrl;
}
@Value("${file.path:}")
public void setPath(String path) {
PropUtil.path = path;

6
util/src/main/java/com/ccsens/util/WebConstant.java

@ -146,7 +146,8 @@ public class WebConstant {
public enum CLIENT_TYPE {
Wxmp(0,"微信小程序"), H5(1,"网页"),Android(2
,"安卓客户端"),IOS(3,"苹果客户端");
,"安卓客户端"),IOS(3,"苹果客户端"),
WxEnterprise(4, "企业微信");
public int value;
public String phase;
@ -170,7 +171,7 @@ public class WebConstant {
Wxmp(0,"微信小程序"), Phone(1,"电话")
, Email(2,"Email"), Account(3,"账号")
,OAUTH2_Wx(4,"微信公众号"),Wx_H5(5,"网页微信登陆")
,OAUTH2_WeiBo(6,"微博");
,OAUTH2_WeiBo(6,"微博"),WxEnterprise(7, "企业微信"),;
public int value;
public String phase;
@ -188,6 +189,7 @@ public class WebConstant {
case 4: return OAUTH2_Wx;
case 5: return Wx_H5;
case 6: return OAUTH2_WeiBo;
case 7: return WxEnterprise;
default: return null;
}
}

89
util/src/main/java/com/ccsens/util/enterprisewx/WeiXinConstant.java

@ -1,10 +1,22 @@
package com.ccsens.util.enterprisewx;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ccsens.util.CodeEnum;
import com.ccsens.util.PropUtil;
import com.ccsens.util.RestTemplateUtil;
import com.ccsens.util.enterprisewx.vo.WeiXinVo;
import com.ccsens.util.exception.BaseException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
/**
* @author wu
*/
@Slf4j
public class WeiXinConstant {
public static final String token = "4CxIpRDBWHMiePP3x6muNe4hRj";
@ -16,10 +28,33 @@ public class WeiXinConstant {
public static final String secret= "HyhFPrD_7gObsQdX1RTTH6nDeJNduVKGuaF62zqmgYs";
public static final String ERR_CODE = "errcode";
public static final String ERR_MSG = "errmsg";
@Getter
public static enum SuiteId{
Health("health","wwb9ce2061d1cce110"),;
private String suiteType;
private String suiteValue;
private SuiteId(String suiteType, String suiteValue){
this.suiteType = suiteType;
this.suiteValue = suiteValue;
}
/**
* 根据类型获取value
* @param suiteType
* @return
*/
public static String getValue(String suiteType) {
switch (suiteType) {
case "health" : return Health.getSuiteValue();
default: return null;
}
}
}
/**
* 获取永久授权
*/
@ -28,7 +63,8 @@ public class WeiXinConstant {
public static final String GET_CORP_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_corp_token";
public static final String DEPARTMENT_LIST = "https://qyapi.weixin.qq.com/cgi-bin/department/list";
public static final String USER_LIST = "https://qyapi.weixin.qq.com/cgi-bin/user/list";
public static final String USER_INFO_3RD = "https://qyapi.weixin.qq.com/cgi-bin/service/getuserinfo3rd";
public static final String USER_DETAIL = "https://qyapi.weixin.qq.com/cgi-bin/service/getuserdetail3rd";
/**
* 获取第三方凭证
@ -75,7 +111,56 @@ public class WeiXinConstant {
* @return
*/
public static boolean pageResult(JSONObject result) {
return result.getIntValue(ERR_CODE) == 0;
return result.getInteger(ERR_CODE) == null || result.getIntValue(ERR_CODE) == 0;
}
/**
* 查询用户信息
* @param code
* @param suiteAccessToken
* @return
*/
public static WeiXinVo.UserInfo getUserInfo(String code, String suiteAccessToken) {
Map<String, Object> param = new HashMap<>();
param.put("suite_access_token", suiteAccessToken);
param.put("code", code);
WeiXinVo.UserInfo userInfo = (WeiXinVo.UserInfo) RestTemplateUtil.getForEntity(USER_INFO_3RD, param, WeiXinVo.UserInfo.class);
log.info("获取用户信息:{}", userInfo);
if (StrUtil.isNotBlank(userInfo.getErrcode()) && !"0".equals(userInfo.getErrcode())) {
return null;
}
return userInfo;
}
/**
* 获取用户详细信息
* @param suite_access_token
* @param user_ticket
* @return
*/
public static WeiXinVo.UserDetail getUserDetail(String suite_access_token, String user_ticket){
String url = USER_DETAIL + "?suite_access_token=" + suite_access_token;
Map<String, Object> param = new HashMap<>();
param.put("user_ticket", user_ticket);
String result = RestTemplateUtil.postBody(url, param);
log.info("获取用户详细信息返回:{}", result);
WeiXinVo.UserDetail userDetail = JSONObject.parseObject(result, WeiXinVo.UserDetail.class);
if (StrUtil.isNotBlank(userDetail.getErrcode()) && !"0".equals(userDetail.getErrcode())) {
return null;
}
return userDetail;
}
/**
* 获取绑定路径
* @param type
* @return
*/
public static String getBindUrl(String type){
if (StrUtil.isBlank(PropUtil.gatewayUrl)) {
throw new BaseException(CodeEnum.LACK_CONFIG);
}
return PropUtil.gatewayUrl + type + "/bindUser";
}
}

49
util/src/main/java/com/ccsens/util/enterprisewx/vo/WeiXinVo.java

@ -0,0 +1,49 @@
package com.ccsens.util.enterprisewx.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("微信相关接口返回")
public class WeiXinVo {
@Data
@ApiModel("微信用戶信息")
public static class UserInfo{
@ApiModelProperty("返回码")
private String errcode;
@ApiModelProperty("对返回码的文本描述内容")
private String errmsg;
@ApiModelProperty("用户所属企业的corpid")
private String CorpId;
@ApiModelProperty("用户在企业内的UserID,如果该企业与第三方应用有授权关系时,返回明文UserId,否则返回密文UserId")
private String UserId;
@ApiModelProperty("手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响)")
private String DeviceId;
@ApiModelProperty("成员票据,最大为512字节。")
private String user_ticket;
@ApiModelProperty("user_ticket的有效时间(秒),随user_ticket一起返回")
private String expires_in;
}
@Data
@ApiModel("用户详细信息")
public static class UserDetail{
@ApiModelProperty("返回码")
private String errcode;
@ApiModelProperty("对返回码的文本描述内容")
private String errmsg;
@ApiModelProperty("用户所属企业的corpid")
private String corpid;
@ApiModelProperty("成员UserID")
private String userid;
@ApiModelProperty("成员姓名,此字段从2019年12月30日起,对新创建第三方应用不再返回,2020年6月30日起,对所有历史第三方应用不再返回,第三方页面需要通过通讯录展示组件来展示名字")
private String name;
@ApiModelProperty("性别。0表示未定义,1表示男性,2表示女性")
private Byte gender;
@ApiModelProperty("头像url。仅在用户同意snsapi_privateinfo授权时返回")
private String avatar;
@ApiModelProperty("员工个人二维码(扫描可添加为外部联系人),仅在用户同意snsapi_privateinfo授权时返回")
private String qr_code;
}
}
Loading…
Cancel
Save