Browse Source

Merge branch 'master' of gitee.com:ccsens_s/ccsenscloud

master
zhangye 6 years ago
parent
commit
aa56d6b522
  1. 41
      cloudutil/src/main/java/com/ccsens/cloudutil/feign/HealthFeignClient.java
  2. 122
      health/src/main/java/com/ccsens/health/api/WeixinController.java
  3. 16
      health/src/main/java/com/ccsens/health/bean/dto/EmployeeDto.java
  4. 15
      health/src/main/java/com/ccsens/health/persist/dao/DepartmentDao.java
  5. 14
      health/src/main/java/com/ccsens/health/persist/dao/DepartmentEmployeeDao.java
  6. 8
      health/src/main/java/com/ccsens/health/persist/dao/EmployeeDao.java
  7. 13
      health/src/main/java/com/ccsens/health/service/IWeiXinService.java
  8. 193
      health/src/main/java/com/ccsens/health/service/WeiXinService.java
  9. 17
      health/src/main/resources/mapper_dao/DepartmentDao.xml
  10. 17
      health/src/main/resources/mapper_dao/DepartmentEmployeeDao.xml
  11. 19
      health/src/main/resources/mapper_dao/EmployeeDao.xml
  12. 6
      tall/src/main/java/com/ccsens/tall/bean/dto/UserDto.java
  13. 2
      tall/src/main/java/com/ccsens/tall/service/IUserService.java
  14. 96
      tall/src/main/java/com/ccsens/tall/service/UserService.java
  15. 5
      tall/src/main/java/com/ccsens/tall/web/UserController.java
  16. 1
      tall/src/main/resources/application-test.yml
  17. 1
      util/home
  18. 3
      util/src/main/java/com/ccsens/util/CodeEnum.java
  19. 5
      util/src/main/java/com/ccsens/util/PropUtil.java
  20. 6
      util/src/main/java/com/ccsens/util/WebConstant.java
  21. 90
      util/src/main/java/com/ccsens/util/enterprisewx/WeiXinConstant.java
  22. 1
      util/src/main/java/com/ccsens/util/enterprisewx/dto/MessageDto.java
  23. 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;
}
};
}
}

122
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 cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; 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.IConstantService;
import com.ccsens.health.service.IWeiXinService; import com.ccsens.health.service.IWeiXinService;
import com.ccsens.util.HttpsUtil; import com.ccsens.util.HttpsUtil;
import com.ccsens.util.JacksonUtil; import com.ccsens.util.JacksonUtil;
import com.ccsens.util.JsonResponse;
import com.ccsens.util.RestTemplateUtil; import com.ccsens.util.RestTemplateUtil;
import com.ccsens.util.enterprisewx.AesException; import com.ccsens.util.enterprisewx.AesException;
import com.ccsens.util.enterprisewx.WXBizMsgCrypt; import com.ccsens.util.enterprisewx.WXBizMsgCrypt;
@ -15,15 +19,11 @@ import com.ccsens.util.enterprisewx.WeiXinConstant;
import com.ccsens.util.enterprisewx.dto.MessageDto; import com.ccsens.util.enterprisewx.dto.MessageDto;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/** /**
* @author wu * @author wu
@ -54,37 +54,88 @@ public class WeixinController {
* 数据回调URL * 数据回调URL
*/ */
@GetMapping("userChangeNotice") @GetMapping("userChangeNotice")
public String userChangeNotice(MessageDto dto) throws Exception{ public String userChangeNoticeGet(MessageDto dto) throws Exception{
log.info("数据回调请求参数:{}", dto); log.info("数据回调请求参数:{}", dto);
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.corpID); WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.corpID);
String verifyURL = wxcpt.VerifyURL(dto.getMsg_signature(), dto.getTimestamp(), dto.getNonce(), dto.getEchostr()); String verifyURL = wxcpt.VerifyURL(dto.getMsg_signature(), dto.getTimestamp(), dto.getNonce(), dto.getEchostr());
log.info("数据回调解析结果:{}", verifyURL); log.info("数据回调解析结果:{}", verifyURL);
return verifyURL; return verifyURL;
} }
/** /**
* 指令回调URL * 指令回调get
* @param dto
* @return
* @throws Exception
*/ */
@GetMapping("authorizationChangeNotice") @GetMapping("authorizationChangeNotice")
public String authorizationChangeNotice(MessageDto dto) throws Exception{ public String authorizationChangeNoticeGet(MessageDto dto) throws Exception {
log.info("请求参数:{}", dto); log.info("请求参数:{}", dto);
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.corpID); WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.corpID);
String verifyURL = wxcpt.VerifyURL(dto.getMsg_signature(), dto.getTimestamp(), dto.getNonce(), dto.getEchostr()); String verifyURL = wxcpt.VerifyURL(dto.getMsg_signature(), dto.getTimestamp(), dto.getNonce(), dto.getEchostr());
log.info("解析结果:{}", verifyURL); log.info("解析结果:{}", verifyURL);
if (StrUtil.isBlank(verifyURL) || !(verifyURL.startsWith("<xml") || verifyURL.startsWith("<XML"))){
return verifyURL; return verifyURL;
} }
/**
* 数据回调URL post
*/
@PostMapping("userChangeNotice")
public String userChangeNoticePost(MessageDto dto, @RequestBody String body) throws Exception{
log.info("数据回调请求参数:{}", dto);
String xmlStr = JacksonUtil.xmlToJson(body);
log.info("数据回到xml转换:{}", xmlStr);
JSONObject jsonObject = JSONObject.parseObject(xmlStr);
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.corpID);
String verifyURL = wxcpt.VerifyURL(dto.getMsg_signature(), dto.getTimestamp(), dto.getNonce(), jsonObject.getString("Encrypt"));
log.info("数据回调解析结果:{}", verifyURL);
return "success";
}
/**
* 指令回调URL
*/
@PostMapping("authorizationChangeNotice")
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);
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.suiteID);
String verifyURL = wxcpt.VerifyURL(dto.getMsg_signature(), dto.getTimestamp(), dto.getNonce(), jsonObject.getString("Encrypt"));
log.info("解析结果:{}", verifyURL);
String jsonStr = JacksonUtil.xmlToJson(verifyURL); String jsonStr = JacksonUtil.xmlToJson(verifyURL);
JSONObject json = JSONObject.parseObject(jsonStr); JSONObject json = JSONObject.parseObject(jsonStr);
log.info("指令回调业务参数:{}", json);
switch (json.getString("InfoType")){ switch (json.getString("InfoType")){
case "suite_ticket" : case "suite_ticket" :
MessageDto.Ticket ticket = JSONObject.parseObject(jsonStr, MessageDto.Ticket.class); MessageDto.Ticket ticket = JSONObject.parseObject(jsonStr, MessageDto.Ticket.class);
constantService.saveConstant(WeiXinConstant.getSuiteTicket(ticket.getSuiteId()), ticket.getSuiteTicket()); constantService.saveConstant(WeiXinConstant.getSuiteTicket(ticket.getSuiteId()), ticket.getSuiteTicket());
//获取第三方应用凭证
new Thread(new Runnable() {
@Override
public void run() {
getSuiteAccessToken(ticket.getSuiteId(),ticket.getSuiteTicket());
}
}).start();
break; break;
case "create_auth" : case "create_auth" :
MessageDto.Grant grant = JSONObject.parseObject(jsonStr, MessageDto.Grant.class); MessageDto.Grant grant = JSONObject.parseObject(jsonStr, MessageDto.Grant.class);
constantService.saveConstant(WeiXinConstant.getTempAuthCodeKey(grant.getSuiteId()), grant.getAuthCode()); constantService.saveConstant(WeiXinConstant.getTempAuthCodeKey(grant.getSuiteId()), grant.getAuthCode());
getPermanentCode(grant.getAuthCode()); //获取永久授权
log.info("grant:{}", grant);
new Thread(new Runnable() {
@Override
public void run() {
getPermanentCode(grant.getSuiteId(), grant.getAuthCode());
}
}).start();
break; break;
case "change_auth" : case "change_auth" :
//TODO 变更授权通知 //TODO 变更授权通知
@ -94,22 +145,39 @@ public class WeixinController {
break; break;
//TODO 成员变更和部门变更通知 //TODO 成员变更和部门变更通知
} }
return verifyURL; log.info("-----------------------------------------------------");
return "success";
} }
/**
* 异步获取suite_access_token
* @param suite_id
* @param suite_ticket
*/
@Async
public void getSuiteAccessToken(String suite_id, String suite_ticket) {
weiXinService.getSuiteToken(suite_id, suite_ticket);
}
/** /**
* 获取永久授权码 * 获取永久授权码
* @param authCode * @param authCode
*/ */
@Async @Async
public void getPermanentCode(String authCode){ public void getPermanentCode(String suiteId, String authCode){
weiXinService.savePermanentCode(authCode); String suiteTicket = constantService.getByKey(WeiXinConstant.getSuiteTicket(suiteId));
// TODO 读取部门信息和成员信息 String suiteToken = weiXinService.getSuiteToken(suiteId, suiteTicket);
HealthAuth auth = weiXinService.savePermanentCode(authCode, suiteToken);
if (auth != null) {
weiXinService.initDepartment(auth.getAccessToken());
}
} }
/** /**
* 系统验证 * 系统验证
*/ */
@GetMapping("reciveSysMsg") @RequestMapping(value = "reciveSysMsg",method = {RequestMethod.POST, RequestMethod.GET})
public String reciveSysMsg(MessageDto dto) throws Exception{ public String reciveSysMsg(MessageDto dto) throws Exception{
log.info("请求参数:{}", dto); log.info("请求参数:{}", dto);
WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.corpID); WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinConstant.token, WeiXinConstant.encodingAESKey, WeiXinConstant.corpID);
@ -117,4 +185,26 @@ public class WeixinController {
log.info("解析结果:{}", verifyURL); log.info("解析结果:{}", verifyURL);
return 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;
}
}

15
health/src/main/java/com/ccsens/health/persist/dao/DepartmentDao.java

@ -0,0 +1,15 @@
package com.ccsens.health.persist.dao;
import com.ccsens.health.bean.po.Department;
import com.ccsens.health.persist.mapper.DepartmentMapper;
import java.util.List;
public interface DepartmentDao extends DepartmentMapper {
/**
* 批量添加部門信息
* @param departmentList
*/
void insertBatch(List<Department> departmentList);
}

14
health/src/main/java/com/ccsens/health/persist/dao/DepartmentEmployeeDao.java

@ -0,0 +1,14 @@
package com.ccsens.health.persist.dao;
import com.ccsens.health.bean.po.DepartmentEmployee;
import com.ccsens.health.persist.mapper.DepartmentEmployeeMapper;
import java.util.List;
public interface DepartmentEmployeeDao extends DepartmentEmployeeMapper {
/**
* 批量添加部門员工信息
* @param des
*/
void insertBatch(List<DepartmentEmployee> des);
}

8
health/src/main/java/com/ccsens/health/persist/dao/EmployeeDao.java

@ -1,8 +1,16 @@
package com.ccsens.health.persist.dao; package com.ccsens.health.persist.dao;
import com.ccsens.health.bean.po.Employee;
import com.ccsens.health.persist.mapper.EmployeeMapper; import com.ccsens.health.persist.mapper.EmployeeMapper;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List;
@Repository @Repository
public interface EmployeeDao extends EmployeeMapper { public interface EmployeeDao extends EmployeeMapper {
/**
* 批量添加部門信息
* @param employees
*/
void insertBatch(List<Employee> employees);
} }

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

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

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

@ -5,21 +5,28 @@ import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.ccsens.health.bean.po.Department; import com.ccsens.health.bean.dto.EmployeeDto;
import com.ccsens.health.bean.po.HealthAuth; import com.ccsens.health.bean.po.*;
import com.ccsens.health.bean.po.HealthAuthAgent; 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.HealthAuthAgentMapper;
import com.ccsens.health.persist.mapper.HealthAuthMapper; import com.ccsens.health.persist.mapper.HealthAuthMapper;
import com.ccsens.util.CodeEnum;
import com.ccsens.util.RedisUtil; import com.ccsens.util.RedisUtil;
import com.ccsens.util.RestTemplateUtil; import com.ccsens.util.RestTemplateUtil;
import com.ccsens.util.WebConstant;
import com.ccsens.util.enterprisewx.WeiXinConstant; import com.ccsens.util.enterprisewx.WeiXinConstant;
import com.ccsens.util.exception.BaseException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList; import java.util.ArrayList;
@ -38,8 +45,16 @@ public class WeiXinService implements IWeiXinService {
private HealthAuthMapper healthAuthMapper; private HealthAuthMapper healthAuthMapper;
@Resource @Resource
private HealthAuthAgentMapper healthAuthAgentMapper; private HealthAuthAgentMapper healthAuthAgentMapper;
@Autowired @Resource
private RedisUtil redisUtil; private RedisUtil redisUtil;
@Resource
private PlatformTransactionManager transactionManager;
@Resource
private DepartmentDao departmentDao;
@Resource
private EmployeeDao employeeDao;
@Resource
private DepartmentEmployeeDao departmentEmployeeDao;
@Override @Override
public String getAccessToken(String suiteId, String corpId, String permanent_code ) { public String getAccessToken(String suiteId, String corpId, String permanent_code ) {
@ -64,7 +79,26 @@ public class WeiXinService implements IWeiXinService {
} }
@Override @Override
public void getSuiteToken(String suiteId, String suiteTicket) { 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); log.info("获取suiteToken, suiteId:{}, suiteTicket:{}", suiteId, suiteTicket);
String key = WeiXinConstant.getSuiteAccessToken(suiteId); String key = WeiXinConstant.getSuiteAccessToken(suiteId);
String suiteAccessToken = (String)redisUtil.get(key); String suiteAccessToken = (String)redisUtil.get(key);
@ -75,7 +109,7 @@ public class WeiXinService implements IWeiXinService {
int expireTime = 1200; int expireTime = 1200;
if (expire > expireTime) { if (expire > expireTime) {
log.info("有效时长大于1200,无需更新"); log.info("有效时长大于1200,无需更新");
return; return suiteAccessToken;
} }
} }
@ -89,23 +123,26 @@ public class WeiXinService implements IWeiXinService {
if (!WeiXinConstant.pageResult(result)) { if (!WeiXinConstant.pageResult(result)) {
log.info("获取suite_ticket异常"); log.info("获取suite_ticket异常");
// TODO // TODO
return; return null;
} }
redisUtil.set(key, result.getString("suite_access_token"), result.getInteger("expires_in")); redisUtil.set(key, result.getString("suite_access_token"), result.getInteger("expires_in"));
return result.getString("suite_access_token");
} }
@Override @Override
public void savePermanentCode(String authCode) { public HealthAuth savePermanentCode(String authCode, String suiteAccessToken) {
//授权成功通知 //授权成功通知
Map<String, String> params = new HashMap<>(); Map<String, String> params = new HashMap<>();
params.put("auth_code", authCode); params.put("auth_code", authCode);
String result = RestTemplateUtil.postBody(WeiXinConstant.GET_PERMANENT_CODE, params); 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); log.info("获取永久授权返回:{}", result);
JSONObject json = JSONObject.parseObject(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); log.error("获取永久授权码异常:{}", result);
//TODO 异常如何处理 //TODO 异常如何处理
return; return null;
} }
HealthAuth auth = initAuth(json); HealthAuth auth = initAuth(json);
HealthAuthAgent agent = initAuthAgent(json); HealthAuthAgent agent = initAuthAgent(json);
@ -114,20 +151,146 @@ public class WeiXinService implements IWeiXinService {
if (agent != null) { if (agent != null) {
healthAuthAgentMapper.insertSelective(agent); healthAuthAgentMapper.insertSelective(agent);
} }
return auth;
} }
@Override @Override
public void initDepartment(String accessToken) { public void initDepartment(String accessToken) {
Map<String, Object> param = new HashMap<>(); Map<String, Object> param = new HashMap<>();
param.put("access_token", accessToken); param.put("access_token", accessToken);
List departmentList = (List) RestTemplateUtil.getForEntity(WeiXinConstant.DEPARTMENT_LIST, param, List.class); JSONObject result = (JSONObject) RestTemplateUtil.getForEntity(WeiXinConstant.DEPARTMENT_LIST, param, JSONObject.class);
log.info("部門信息:{}", departmentList); log.info("部門信息:{}", result);
if (!WeiXinConstant.pageResult(result)) {
//TODO 读取部门信息异常
return;
}
JSONArray departmentList = result.getJSONArray("department");
if (CollectionUtil.isEmpty(departmentList)) { if (CollectionUtil.isEmpty(departmentList)) {
return; return;
} }
List<Department> departments = new ArrayList<>(); List<Department> departments = new ArrayList<>();
departmentList.forEach(obj -> {
JSONObject json = (JSONObject) obj;
Department department = json.toJavaObject(Department.class);
departments.add(department);
});
insertBatchDepartment(departments);
//初始化員工信息
departments.forEach(department -> {
initEmployee(accessToken, department);
});
}
/**
* 初始化员工信息
* @param accessToken
* @param department
*/
private void initEmployee(String accessToken, Department department) {
// 查询员工信息
Map<String, Object> params = new HashMap<>();
params.put("access_token", accessToken);
params.put("department_id", department.getId());
params.put("fetch_child", 0);
JSONObject userResult = (JSONObject) RestTemplateUtil.getForEntity(WeiXinConstant.USER_LIST, params, JSONObject.class);
if (WeiXinConstant.pageResult(userResult)) {
log.error("查询员工信息异常:{},{}", params, userResult);
return;
}
JSONArray userlist = userResult.getJSONArray("userlist");
if (CollectionUtil.isEmpty(userlist)) {
return;
}
//解析员工信息
List<Employee> employees = new ArrayList<>();
List<DepartmentEmployee> des = new ArrayList<>();
userlist.forEach(obj -> {
JSONObject user = (JSONObject)obj;
Employee employee = user.toJavaObject(Employee.class);
employee.setId(snowflake.nextId());
employees.add(employee);
JSONArray departmentIds = user.getJSONArray("department");
JSONArray orders = user.getJSONArray("order");
for (int i = 0; i < departmentIds.size(); i++) {
DepartmentEmployee de = new DepartmentEmployee();
de.setId(snowflake.nextId());
de.setEmployeeId(employee.getId());
de.setDepartmentId((Long)departmentIds.get(0));
de.setSort(i);
des.add(de);
}
});
// 保存员工信息
insertBatchEmployee(employees, des);
}
private void insertBatchEmployee(List<Employee> employees, List<DepartmentEmployee> des) {
TransactionStatus status = getTransactionStatus();
int empSize = employees.size();
int deSize = des.size();
int once = 100;
for (int i = 0; i < empSize; i+=once) {
int end = i+once > empSize ? empSize : i+once;
try {
employeeDao.insertBatch(employees.subList(i, end));
//提交事务
transactionManager.commit( status );
} catch (TransactionException e) {
e.printStackTrace();
log.error("存储员工{}时发生异常:{}", employees.subList(i,end), e);
transactionManager.rollback(status);
}
}
for (int i = 0; i < deSize; i+=once) {
int end = i+once > deSize ? deSize : i+once;
try {
departmentEmployeeDao.insertBatch(des.subList(i, end));
//提交事务
transactionManager.commit( status );
} catch (TransactionException e) {
e.printStackTrace();
log.error("存儲部門员工{}時發發生異常:{}", des.subList(i,end), e);
transactionManager.rollback(status);
}
}
}
/**
* 批量保存部門信息
* @param departments
*/
private void insertBatchDepartment(List<Department> departments) {
TransactionStatus status = getTransactionStatus();
int size = departments.size();
int once = 100;
for (int i = 0; i < size; i+=once) {
int end = i+once > size ? size : i+once;
try {
departmentDao.insertBatch(departments.subList(i, end));
//提交事务
transactionManager.commit( status );
} catch (TransactionException e) {
e.printStackTrace();
log.error("存儲部門{}時發發生異常:{}", departments.subList(i,end), e);
transactionManager.rollback(status);
}
}
}
/**
* 手动开启事务获取事务状态
* @return
*/
private TransactionStatus getTransactionStatus() {
//开启手动事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// 事务隔离级别,开启新事务
def.setPropagationBehavior( TransactionDefinition.PROPAGATION_REQUIRES_NEW );
//获取事务状态,并开启事务,相当于transation.begin();
return transactionManager.getTransaction( def );
} }
/** /**

17
health/src/main/resources/mapper_dao/DepartmentDao.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ccsens.health.persist.dao.DepartmentDao">
<insert id="insertBatch" parameterType="ArrayList">
insert into t_department (id, name,
name_en, parentid, order
)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=BIGINT}, #{item.name,jdbcType=VARCHAR},#{item.nameEn,jdbcType=VARCHAR},
#{item.parentid,jdbcType=VARCHAR}, #{item.order,jdbcType=INTEGER}
)
</foreach>
</insert>
</mapper>

17
health/src/main/resources/mapper_dao/DepartmentEmployeeDao.xml

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ccsens.health.persist.dao.DepartmentEmployeeDao">
<insert id="insertBatch" parameterType="ArrayList">
insert into t_department_employee (id, department_id, employee_id,
order, sort
)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=BIGINT}, #{item.departmentId,jdbcType=BIGINT},
#{item.employeeId,jdbcType=BIGINT},
#{item.order,jdbcType=INTEGER}, #{item.sort,jdbcType=INTEGER})
</foreach>
</insert>
</mapper>

19
health/src/main/resources/mapper_dao/EmployeeDao.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ccsens.health.persist.dao.EmployeeDao">
<insert id="insertBatch" parameterType="ArrayList">
insert into t_employee (id, userid, name,
gender, status, address,
hide_mobile, english_name, tall_user_id
)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=BIGINT}, #{item.userid,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR},
#{item.gender,jdbcType=TINYINT}, #{item.status,jdbcType=TINYINT}, #{item.address,jdbcType=VARCHAR},
#{item.hideMobile,jdbcType=TINYINT}, #{item.englishName,jdbcType=VARCHAR}, #{item.tallUserId,jdbcType=BIGINT}
)
</foreach>
</insert>
</mapper>

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

@ -24,14 +24,16 @@ public class UserDto {
@ApiModelProperty("用户凭据|密码") @ApiModelProperty("用户凭据|密码")
private String credential; 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.") @NotNull(message = "client is required.")
private Integer client; 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.") @NotNull(message = "type is required.")
private Integer type; private Integer type;
@ApiModelProperty("登录信息") @ApiModelProperty("登录信息")
private Data data; private Data data;
@ApiModelProperty("通知消息")
private String redirect;
} }
@Data @Data

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

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

96
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.ObjectUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil; 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.ProjectDto;
import com.ccsens.tall.bean.dto.UserDto; import com.ccsens.tall.bean.dto.UserDto;
import com.ccsens.tall.bean.po.*; 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.tall.persist.dao.*;
import com.ccsens.util.*; import com.ccsens.util.*;
import com.ccsens.util.bean.wx.po.WxOauth2UserInfo; 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.exception.BaseException;
import com.ccsens.util.wx.WxGzhUtil; import com.ccsens.util.wx.WxGzhUtil;
import com.ccsens.util.wx.WxXcxUtil; import com.ccsens.util.wx.WxXcxUtil;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired; 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 org.xhtmlrenderer.css.parser.property.PrimitivePropertyBuilders;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -57,6 +62,8 @@ public class UserService implements IUserService {
private SysProjectDao sysProjectDao; private SysProjectDao sysProjectDao;
@Autowired @Autowired
private UserAttentionDao userAttentionDao; private UserAttentionDao userAttentionDao;
@Autowired
private HealthFeignClient healthFeignClient;
/** /**
@ -64,10 +71,10 @@ public class UserService implements IUserService {
*/ */
@Override @Override
public UserVo.UserSign signin(WebConstant.CLIENT_TYPE clientType, WebConstant.IDENTIFY_TYPE identifyType, 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; UserVo.UserSign userSignVo = null;
//1.登陆 //1.登陆
userSignVo = __signin(identifyType, identifier, credential); userSignVo = __signin(identifyType, identifier, credential, redirect);
if (ObjectUtil.isNotNull(userSignVo) && ObjectUtil.isNotNull(userSignVo.getAuthId())) { if (ObjectUtil.isNotNull(userSignVo) && ObjectUtil.isNotNull(userSignVo.getAuthId())) {
//2.添加登陆记录 //2.添加登陆记录
__addSigninRecord(clientType, clientIp, userSignVo.getAuthId()); __addSigninRecord(clientType, clientIp, userSignVo.getAuthId());
@ -76,8 +83,10 @@ public class UserService implements IUserService {
} }
private UserVo.UserSign __signin(WebConstant.IDENTIFY_TYPE identifyType, private UserVo.UserSign __signin(WebConstant.IDENTIFY_TYPE identifyType,
String identifier, String credential) throws Exception { String identifier, String credential, String redirect) throws Exception {
switch (identifyType) { switch (identifyType) {
case WxEnterprise:
return wxEnterpriseLogin(identifier, credential, redirect);
case Wxmp: case Wxmp:
credential = credential == null ? "old" : credential; credential = credential == null ? "old" : credential;
return wxmplogin(identifier,credential); return wxmplogin(identifier,credential);
@ -100,6 +109,33 @@ public class UserService implements IUserService {
return null; 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 { private UserVo.UserSign wxmplogin(String code,String gameType) throws Exception {
UserVo.UserSign userSignVo = null;
//0.获取openid //0.获取openid
WxXcxUtil.WechatUser wechatUser = WxXcxUtil.getUserInfo(code,gameType); WxXcxUtil.WechatUser wechatUser = WxXcxUtil.getUserInfo(code,gameType);
String openId = wechatUser.openid; String openId = wechatUser.openid;
String unionId = wechatUser.unionid; String unionId = wechatUser.unionid;
log.info("小程序登录,openid:{} ,unionId:{}", openId, 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; List<SysAuth> authList = null;
SysAuth theAuth = null; SysAuth theAuth = null;
if(ObjectUtil.isNotNull(openId)) { if(ObjectUtil.isNotNull(openId)) {
SysAuthExample authExample = new SysAuthExample(); SysAuthExample authExample = new SysAuthExample();
authExample.createCriteria().andIdentifyTypeEqualTo((byte) WebConstant.IDENTIFY_TYPE.Wxmp.value) authExample.createCriteria().andIdentifyTypeEqualTo(identifyType)
.andIdentifierEqualTo(openId); .andIdentifierEqualTo(openId);
authList = authDao.selectByExample(authExample); authList = authDao.selectByExample(authExample);
} }
@ -372,25 +425,31 @@ public class UserService implements IUserService {
sysAuthList = authDao.selectByExample(sysAuthExample); sysAuthList = authDao.selectByExample(sysAuthExample);
} }
if (CollectionUtil.isNotEmpty(sysAuthList)) { if (CollectionUtil.isNotEmpty(sysAuthList)) {
// SysAuth sysAuth = sysAuthList.get(0); if (identifyType == WebConstant.IDENTIFY_TYPE.Wxmp.value) {
//添加认证方式 //添加认证方式
theAuth = new SysAuth(); theAuth = new SysAuth();
theAuth.setId(snowflake.nextId()); theAuth.setId(snowflake.nextId());
theAuth.setUserId(sysAuthList.get(0).getUserId()); theAuth.setUserId(sysAuthList.get(0).getUserId());
theAuth.setIdentifyType((byte) WebConstant.IDENTIFY_TYPE.Wxmp.value); theAuth.setIdentifyType(identifyType);
theAuth.setIdentifier(openId); theAuth.setIdentifier(openId);
theAuth.setCredential(unionId); theAuth.setCredential(unionId);
authDao.insertSelective(theAuth); authDao.insertSelective(theAuth);
} else {
theAuth = sysAuthList.get(0);
}
} else { } else {
//新建用户并保存微信信息 //新建用户并保存微信信息
SysUser user = new SysUser(); SysUser user = new SysUser();
user.setId(snowflake.nextId()); user.setId(snowflake.nextId());
//企业微信获取详细用户信息,并绑定用户信息
getUserDetail(identifyType, param, user);
userDao.insertSelective(user); userDao.insertSelective(user);
//添加认证方式 //添加认证方式
theAuth = new SysAuth(); theAuth = new SysAuth();
theAuth.setId(snowflake.nextId()); theAuth.setId(snowflake.nextId());
theAuth.setUserId(user.getId()); theAuth.setUserId(user.getId());
theAuth.setIdentifyType((byte) WebConstant.IDENTIFY_TYPE.Wxmp.value); theAuth.setIdentifyType(identifyType);
theAuth.setIdentifier(openId); theAuth.setIdentifier(openId);
theAuth.setCredential(unionId); theAuth.setCredential(unionId);
authDao.insertSelective(theAuth); authDao.insertSelective(theAuth);
@ -416,6 +475,23 @@ public class UserService implements IUserService {
return userSignVo; 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.验证参数 //1.验证参数
switch (clientType) { switch (clientType) {
case Wxmp: case Wxmp:
case H5: case H5:
case Android: case Android:
case IOS: case IOS:
case WxEnterprise:
break; break;
default: default:
throw new UserLoginException(-1, String.format("Not supported client type: %1$d(%2$s)", throw new UserLoginException(-1, String.format("Not supported client type: %1$d(%2$s)",
clientType.value, clientType)); clientType.value, clientType));
} }
switch (identify_type) { switch (identify_type) {
case WxEnterprise:
case Wxmp: case Wxmp:
case OAUTH2_Wx: case OAUTH2_Wx:
case Wx_H5: case Wx_H5:
@ -86,7 +89,7 @@ public class UserController {
//2.调用业务方法(注册/添加登陆记录) //2.调用业务方法(注册/添加登陆记录)
UserVo.UserSign userSignVo = userService.signin( UserVo.UserSign userSignVo = userService.signin(
clientType, identify_type, identifier, credential, clientType, identify_type, identifier, credential,
ServletUtil.getClientIP(request)); ServletUtil.getClientIP(request), dto.getRedirect());
//3.生成token(access_token,refresh_token) //3.生成token(access_token,refresh_token)
if (ObjectUtil.isNotNull(userSignVo)) { if (ObjectUtil.isNotNull(userSignVo)) {

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

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

1
util/home

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

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

@ -96,7 +96,8 @@ public enum CodeEnum {
ALREADY_ATTENTION(79,"您已经关注了这个项目",true), ALREADY_ATTENTION(79,"您已经关注了这个项目",true),
NOT_EMPLOYEE(80,"未找到成员信息",true), NOT_EMPLOYEE(80,"未找到成员信息",true),
NOT_SITE(81,"未找到该场所",true), NOT_SITE(81,"未找到该场所",true),
ALREADY_REAL_AUTH(82,"您已经完成认证",true) ALREADY_REAL_AUTH(82,"您已经完成认证",true),
LACK_CONFIG(82,"缺少配置",true),
; ;
public CodeEnum addMsg(String msg){ 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 imgDomain;
public static String projectName; public static String projectName;
public static String contextPath; public static String contextPath;
public static String gatewayUrl;
@Value("${gatewayUrl:}")
public void setGatewayUrl(String gatewayUrl) {
PropUtil.gatewayUrl = gatewayUrl;
}
@Value("${file.path:}") @Value("${file.path:}")
public void setPath(String path) { public void setPath(String path) {
PropUtil.path = 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 { public enum CLIENT_TYPE {
Wxmp(0,"微信小程序"), H5(1,"网页"),Android(2 Wxmp(0,"微信小程序"), H5(1,"网页"),Android(2
,"安卓客户端"),IOS(3,"苹果客户端"); ,"安卓客户端"),IOS(3,"苹果客户端"),
WxEnterprise(4, "企业微信");
public int value; public int value;
public String phase; public String phase;
@ -170,7 +171,7 @@ public class WebConstant {
Wxmp(0,"微信小程序"), Phone(1,"电话") Wxmp(0,"微信小程序"), Phone(1,"电话")
, Email(2,"Email"), Account(3,"账号") , Email(2,"Email"), Account(3,"账号")
,OAUTH2_Wx(4,"微信公众号"),Wx_H5(5,"网页微信登陆") ,OAUTH2_Wx(4,"微信公众号"),Wx_H5(5,"网页微信登陆")
,OAUTH2_WeiBo(6,"微博"); ,OAUTH2_WeiBo(6,"微博"),WxEnterprise(7, "企业微信"),;
public int value; public int value;
public String phase; public String phase;
@ -188,6 +189,7 @@ public class WebConstant {
case 4: return OAUTH2_Wx; case 4: return OAUTH2_Wx;
case 5: return Wx_H5; case 5: return Wx_H5;
case 6: return OAUTH2_WeiBo; case 6: return OAUTH2_WeiBo;
case 7: return WxEnterprise;
default: return null; default: return null;
} }
} }

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

@ -1,10 +1,22 @@
package com.ccsens.util.enterprisewx; package com.ccsens.util.enterprisewx;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject; 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 * @author wu
*/ */
@Slf4j
public class WeiXinConstant { public class WeiXinConstant {
public static final String token = "4CxIpRDBWHMiePP3x6muNe4hRj"; public static final String token = "4CxIpRDBWHMiePP3x6muNe4hRj";
@ -16,10 +28,33 @@ public class WeiXinConstant {
public static final String secret= "HyhFPrD_7gObsQdX1RTTH6nDeJNduVKGuaF62zqmgYs"; public static final String secret= "HyhFPrD_7gObsQdX1RTTH6nDeJNduVKGuaF62zqmgYs";
public static final String ERR_CODE = "errcode"; public static final String ERR_CODE = "errcode";
public static final String ERR_MSG = "errmsg"; 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;
}
}
}
/** /**
* 获取永久授权 * 获取永久授权
*/ */
@ -27,7 +62,9 @@ public class WeiXinConstant {
public static final String GET_SUITE_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token"; public static final String GET_SUITE_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token";
public static final String GET_CORP_TOKEN = "https://qyapi.weixin.qq.com/cgi-bin/service/get_corp_token"; 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 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";
/** /**
* 获取第三方凭证 * 获取第三方凭证
@ -74,7 +111,56 @@ public class WeiXinConstant {
* @return * @return
*/ */
public static boolean pageResult(JSONObject result) { 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";
}
} }

1
util/src/main/java/com/ccsens/util/enterprisewx/dto/MessageDto.java

@ -16,6 +16,7 @@ public class MessageDto {
private String msg_signature; private String msg_signature;
private String timestamp; private String timestamp;
private String nonce; private String nonce;
//get方法返回
private String echostr; private String echostr;

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