✨ Introducing new features. 支持企业微信组织 用户结构同步
This commit is contained in:
1 parent
5e80065d46
commit
92e20524bc
9 files changed
+415
-370
No files matched your search
@@ -27,7 +27,7 @@
|
||||
<sqlserver.version>8.4.1.jre8</sqlserver.version>
|
||||
<dm.version>8.1.2.79</dm.version>
|
||||
<swagger.core.version>1.5.22</swagger.core.version>
|
||||
<mp.weixin.version>4.2.0</mp.weixin.version>
|
||||
<mp.weixin.version>4.3.0</mp.weixin.version>
|
||||
<ijpay.version>2.8.0</ijpay.version>
|
||||
<groovy.version>3.0.3</groovy.version>
|
||||
<jsoup.version>1.13.1</jsoup.version>
|
||||
@@ -233,6 +233,11 @@
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
<version>${mp.weixin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-cp</artifactId>
|
||||
<version>${mp.weixin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-common</artifactId>
|
||||
|
||||
+10
@@ -90,4 +90,14 @@ public interface ErrorCodes {
|
||||
*/
|
||||
String SYS_APP_PHONE_UNREGISTERED = "sys.app.phone.unregistered";
|
||||
|
||||
/**
|
||||
* 企微调用接口错误
|
||||
*/
|
||||
String SYS_CONNECT_CP_DEPT_SYNC_ERROR = "sys.connect.cp.dept.sync.error";
|
||||
|
||||
/**
|
||||
* 企微调用接口错误
|
||||
*/
|
||||
String SYS_CONNECT_CP_USER_SYNC_ERROR = "sys.connect.cp.user.sync.error";
|
||||
|
||||
}
|
||||
@@ -3,22 +3,17 @@ sys.user.query.error=\u83B7\u53D6\u5F53\u524D\u7528\u6237\u4FE1\u606F\u5931\u8D2
|
||||
sys.user.import.succeed=\u7528\u6237\u5BFC\u5165\u6210\u529F\uFF0C\u9ED8\u8BA4\u5BC6\u7801\u4E3A\u624B\u673A\u53F7
|
||||
sys.user.username.existing={0} \u7528\u6237\u540D\u5DF2\u5B58\u5728
|
||||
sys.user.userInfo.empty={0} \u7528\u6237\u4FE1\u606F\u4E3A\u7A7A
|
||||
|
||||
sys.dept.deptName.inexistence={0} \u90E8\u95E8\u540D\u79F0\u4E0D\u5B58\u5728
|
||||
|
||||
sys.post.postName.inexistence={0} \u5C97\u4F4D\u540D\u79F0\u4E0D\u5B58\u5728
|
||||
sys.post.nameOrCode.existing={0} {1} \u5C97\u4F4D\u540D\u6216\u5C97\u4F4D\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728
|
||||
|
||||
sys.role.roleName.inexistence={0} \u89D2\u8272\u540D\u79F0\u4E0D\u5B58\u5728
|
||||
sys.role.nameOrCode.existing={0} {1} \u89D2\u8272\u540D\u6216\u89D2\u8272\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728
|
||||
|
||||
sys.param.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u53C2\u6570\u4E0D\u80FD\u5220\u9664
|
||||
sys.param.config.error={0} \u7CFB\u7EDF\u53C2\u6570\u914D\u7F6E\u9519\u8BEF
|
||||
|
||||
sys.menu.delete.existing=\u83DC\u5355\u542B\u6709\u4E0B\u7EA7\u4E0D\u80FD\u5220\u9664
|
||||
|
||||
sys.app.sms.often=\u9A8C\u8BC1\u7801\u53D1\u9001\u8FC7\u9891\u7E41
|
||||
sys.app.phone.unregistered={0} \u624B\u673A\u53F7\u672A\u6CE8\u518C
|
||||
|
||||
sys.dict.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u5220\u9664
|
||||
sys.dict.update.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u4FEE\u6539
|
||||
sys.connect.cp.dept.sync.error=\u83B7\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u90E8\u95E8\u5217\u8868\u5931\u8D25
|
||||
sys.connect.cp.user.sync.error=\u83B7\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u7528\u6237\u5217\u8868\u5931\u8D25
|
||||
+161
-162
@@ -19,171 +19,170 @@
|
||||
-->
|
||||
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
<version>4.3.0</version>
|
||||
</parent>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
<version>4.3.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-upms-biz</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>pigx-upms-biz</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<description>pigx 通用用户权限管理系统业务处理模块</description>
|
||||
<description>pigx 通用用户权限管理系统业务处理模块</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- mysql -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<!-- ojdbc8 -->
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc8</artifactId>
|
||||
</dependency>
|
||||
<!--PG-->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<!--mssql-->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
</dependency>
|
||||
<!--upms api、model 模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms-api</artifactId>
|
||||
</dependency>
|
||||
<!--日志处理-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-data</artifactId>
|
||||
</dependency>
|
||||
<!--swagger-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
</dependency>
|
||||
<!--文件系统-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-oss</artifactId>
|
||||
</dependency>
|
||||
<!--注册中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<!--配置中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<!--spring security 、oauth、jwt依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
</dependency>
|
||||
<!--XSS 安全过滤-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-xss</artifactId>
|
||||
</dependency>
|
||||
<!--支持动态路由配置 -->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gateway</artifactId>
|
||||
</dependency>
|
||||
<!--sentinel 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-sentinel</artifactId>
|
||||
</dependency>
|
||||
<!--路由控制-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- druid 连接池 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- cas sdk -->
|
||||
<dependency>
|
||||
<groupId>org.jasig.cas.client</groupId>
|
||||
<artifactId>cas-client-core</artifactId>
|
||||
<version>${cas.sdk.version}</version>
|
||||
</dependency>
|
||||
<!--新版api-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dingtalk</artifactId>
|
||||
<version>${dingtalk.version}</version>
|
||||
</dependency>
|
||||
<!--旧版api,新版api未包含全部的服务端API的产品能力-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||
<version>${dingtalk.old.version}</version>
|
||||
</dependency>
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!--undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencies>
|
||||
<!-- mysql -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
<!-- ojdbc8 -->
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc8</artifactId>
|
||||
</dependency>
|
||||
<!--PG-->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<!--mssql-->
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
</dependency>
|
||||
<!--upms api、model 模块-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms-api</artifactId>
|
||||
</dependency>
|
||||
<!--日志处理-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-data</artifactId>
|
||||
</dependency>
|
||||
<!--swagger-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
</dependency>
|
||||
<!--文件系统-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-oss</artifactId>
|
||||
</dependency>
|
||||
<!--注册中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<!--配置中心客户端-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
<!--spring security 、oauth、jwt依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
</dependency>
|
||||
<!--XSS 安全过滤-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-xss</artifactId>
|
||||
</dependency>
|
||||
<!--支持动态路由配置 -->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gateway</artifactId>
|
||||
</dependency>
|
||||
<!--sentinel 依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-sentinel</artifactId>
|
||||
</dependency>
|
||||
<!--路由控制-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- druid 连接池 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<!-- cas sdk -->
|
||||
<dependency>
|
||||
<groupId>org.jasig.cas.client</groupId>
|
||||
<artifactId>cas-client-core</artifactId>
|
||||
<version>${cas.sdk.version}</version>
|
||||
</dependency>
|
||||
<!--旧版api,新版api未包含全部的服务端API的产品能力-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||
<version>${dingtalk.old.version}</version>
|
||||
</dependency>
|
||||
<!--企业微信-->
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-cp</artifactId>
|
||||
</dependency>
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!--undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>**/*.xlsx</exclude>
|
||||
<exclude>**/*.xls</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
<includes>
|
||||
<include>**/*.xlsx</include>
|
||||
<include>**/*.xls</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>docker-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
<excludes>
|
||||
<exclude>**/*.xlsx</exclude>
|
||||
<exclude>**/*.xls</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
<includes>
|
||||
<include>**/*.xlsx</include>
|
||||
<include>**/*.xls</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
+2
-20
@@ -40,15 +40,6 @@ public class ConnectController {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步钉钉角色
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/sync/ding/role")
|
||||
public R syncRole() {
|
||||
return R.ok(connectService.syncDingRole());
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步钉钉部门
|
||||
* @return
|
||||
@@ -64,16 +55,7 @@ public class ConnectController {
|
||||
*/
|
||||
@PostMapping("/sync/cp/user")
|
||||
public R syncCpUser() {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步企微角色
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/sync/cp/role")
|
||||
public R syncCpRole() {
|
||||
return R.ok();
|
||||
return connectService.syncCpUser();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +64,7 @@ public class ConnectController {
|
||||
*/
|
||||
@PostMapping("/sync/cp/dept")
|
||||
public R syncCpDept() {
|
||||
return R.ok();
|
||||
return connectService.syncCpDept();
|
||||
}
|
||||
|
||||
}
|
||||
+15
-6
@@ -1,5 +1,7 @@
|
||||
package com.pig4cloud.pigx.admin.service;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2022/4/22
|
||||
@@ -8,11 +10,6 @@ package com.pig4cloud.pigx.admin.service;
|
||||
*/
|
||||
public interface ConnectService {
|
||||
|
||||
/**
|
||||
* 同步钉钉角色
|
||||
*/
|
||||
Boolean syncDingRole();
|
||||
|
||||
/**
|
||||
* 同步钉钉部门
|
||||
*/
|
||||
@@ -21,6 +18,18 @@ public interface ConnectService {
|
||||
/**
|
||||
* 同步钉钉用户
|
||||
*/
|
||||
Boolean syncDingUser(Long deptId);
|
||||
R syncDingUser(Long deptId);
|
||||
|
||||
/**
|
||||
* 同步企微部门
|
||||
* @return
|
||||
*/
|
||||
R<Boolean> syncCpDept();
|
||||
|
||||
/**
|
||||
* 同步企微用户
|
||||
* @return
|
||||
*/
|
||||
R<Boolean> syncCpUser();
|
||||
|
||||
}
|
||||
+208
-162
@@ -2,7 +2,6 @@ package com.pig4cloud.pigx.admin.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.extra.pinyin.PinyinUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -10,24 +9,43 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.dingtalk.api.DefaultDingTalkClient;
|
||||
import com.dingtalk.api.DingTalkClient;
|
||||
import com.dingtalk.api.request.*;
|
||||
import com.dingtalk.api.response.*;
|
||||
import com.pig4cloud.pigx.admin.api.entity.*;
|
||||
import com.dingtalk.api.request.OapiGettokenRequest;
|
||||
import com.dingtalk.api.request.OapiUserListidRequest;
|
||||
import com.dingtalk.api.request.OapiV2DepartmentListsubRequest;
|
||||
import com.dingtalk.api.request.OapiV2UserGetRequest;
|
||||
import com.dingtalk.api.response.OapiGettokenResponse;
|
||||
import com.dingtalk.api.response.OapiUserListidResponse;
|
||||
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
|
||||
import com.dingtalk.api.response.OapiV2UserGetResponse;
|
||||
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysDept;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
|
||||
import com.pig4cloud.pigx.admin.api.entity.SysUser;
|
||||
import com.pig4cloud.pigx.admin.mapper.SysSocialDetailsMapper;
|
||||
import com.pig4cloud.pigx.admin.service.*;
|
||||
import com.pig4cloud.pigx.admin.service.ConnectService;
|
||||
import com.pig4cloud.pigx.admin.service.SysDeptService;
|
||||
import com.pig4cloud.pigx.admin.service.SysUserService;
|
||||
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
|
||||
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
|
||||
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
|
||||
import com.pig4cloud.pigx.common.core.util.MsgUtils;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
|
||||
import me.chanjar.weixin.cp.bean.WxCpDepart;
|
||||
import me.chanjar.weixin.cp.bean.WxCpUser;
|
||||
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 互联平台实现
|
||||
@@ -45,91 +63,16 @@ public class ConnectServiceImpl implements ConnectService {
|
||||
|
||||
private final SysSocialDetailsMapper sysSocialDetailsMapper;
|
||||
|
||||
private final SysRoleService sysRoleService;
|
||||
|
||||
private final SysDeptService sysDeptService;
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
private final SysUserRoleService sysUserRoleService;
|
||||
|
||||
private String getDingAccessToken() {
|
||||
SysSocialDetails dingTalk = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
|
||||
.eq(SysSocialDetails::getType, LoginTypeEnum.dingtalk.getType()));
|
||||
|
||||
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_GET_TOKEN);
|
||||
OapiGettokenRequest request = new OapiGettokenRequest();
|
||||
request.setAppkey(dingTalk.getAppId());
|
||||
request.setAppsecret(dingTalk.getAppSecret());
|
||||
request.setHttpMethod(HttpMethod.GET.name());
|
||||
try {
|
||||
OapiGettokenResponse response = client.execute(request);
|
||||
return response.getAccessToken();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("调用钉钉异常", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步钉钉角色
|
||||
*
|
||||
* @link https://open.dingtalk.com/document/orgapp-server/obtains-a-list-of-enterprise-roles
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Boolean syncDingRole() {
|
||||
// 分页偏移量
|
||||
long offset = 0L;
|
||||
// 是否还有非同步的数据
|
||||
boolean hasMore;
|
||||
// 数据库中现有的角色
|
||||
List<SysRole> roleList = sysRoleService.list(Wrappers.emptyWrapper());
|
||||
// 钉钉同步过来的角色
|
||||
List<SysRole> insertRole = new LinkedList<>();
|
||||
|
||||
do {
|
||||
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_ROLE_URL);
|
||||
OapiRoleListRequest req = new OapiRoleListRequest();
|
||||
// 分页查询,默认分页20条
|
||||
req.setSize(2L);
|
||||
req.setOffset(offset);
|
||||
OapiRoleListResponse rsp = client.execute(req, getDingAccessToken());
|
||||
offset += req.getSize();
|
||||
|
||||
JSONObject result = JSONUtil.parseObj(rsp.getBody());
|
||||
JSONObject resultStr = result.getJSONObject("result");
|
||||
|
||||
hasMore = resultStr.get("hasMore", Boolean.class);
|
||||
List<JSONObject> list = resultStr.get("list", List.class);
|
||||
// 处理返回的数据
|
||||
List<SysRole> collect = list.stream().flatMap(
|
||||
(Function<JSONObject, Stream<JSONObject>>) item -> ((List<JSONObject>) item.get("roles")).stream())
|
||||
.filter(role -> roleList.stream().noneMatch(db -> db.getRoleName().equals(role.get("name"))))
|
||||
.map(role -> {
|
||||
SysRole sysRole = new SysRole();
|
||||
sysRole.setRoleId(Convert.toLong(role.get("id")));
|
||||
sysRole.setRoleCode(String.format("ROLE_DING_%s", Convert.toStr(role.get("id"))));
|
||||
sysRole.setRoleCode(PinyinUtil.getPinyin(Convert.toStr(role.get("name"))));
|
||||
sysRole.setRoleName(Convert.toStr(role.get("name")));
|
||||
return sysRole;
|
||||
}).collect(Collectors.toList());
|
||||
insertRole.addAll(collect);
|
||||
}
|
||||
while (hasMore);
|
||||
|
||||
// 保存到数据库中
|
||||
return sysRoleService.saveBatch(insertRole);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步钉钉部门
|
||||
*
|
||||
* @see <a href=
|
||||
* "https://open.dingtalk.com/document/orgapp-server/obtain-the-department-list-v2"/>
|
||||
* @return Boolean
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean syncDingDept() {
|
||||
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
|
||||
req.setDeptId(1L);
|
||||
@@ -152,6 +95,187 @@ public class ConnectServiceImpl implements ConnectService {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步部门下的钉钉用户
|
||||
* @param deptId 部门ID
|
||||
* @return R
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R syncDingUser(Long deptId) {
|
||||
// 数据库中现有用户
|
||||
List<SysUser> users = sysUserService.list(Wrappers.emptyWrapper());
|
||||
|
||||
String token = getDingAccessToken();
|
||||
|
||||
// 查询部门下的用户id列表
|
||||
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_DEPT_USERIDS_URL);
|
||||
OapiUserListidRequest req = new OapiUserListidRequest();
|
||||
req.setDeptId(deptId);
|
||||
OapiUserListidResponse rsp = client.execute(req, token);
|
||||
|
||||
JSONObject jsonObject = JSONUtil.parseObj(rsp.getBody());
|
||||
JSONObject result = jsonObject.getJSONObject("result");
|
||||
|
||||
if (result == null) {
|
||||
return R.ok();
|
||||
}
|
||||
List<String> useridList = result.get("userid_list", List.class);
|
||||
|
||||
// 查询用户详情
|
||||
for (String userid : useridList) {
|
||||
DingTalkClient userClient = new DefaultDingTalkClient(SecurityConstants.DING_USER_INFO_URL);
|
||||
OapiV2UserGetRequest userGetRequest = new OapiV2UserGetRequest();
|
||||
userGetRequest.setUserid(userid);
|
||||
OapiV2UserGetResponse userGetResponse = userClient.execute(userGetRequest, token);
|
||||
JSONObject userResult = JSONUtil.parseObj(userGetResponse.getBody());
|
||||
JSONObject userObj = JSONUtil.parseObj(userResult.get("result"));
|
||||
|
||||
boolean exist = users.stream().anyMatch(user -> user.getPhone().equals(userObj.getStr("mobile")));
|
||||
|
||||
if (exist) {
|
||||
log.info("用户已存在 {}", userid);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 用户部门信息
|
||||
JSONArray deptOrders = userObj.getJSONArray("dept_order_list");
|
||||
JSONObject deptInfo = (JSONObject) deptOrders.get(0);
|
||||
|
||||
// 用户信息
|
||||
UserDTO userDTO = new UserDTO();
|
||||
userDTO.setDeptId(Convert.toLong(deptInfo.get("dept_id")));
|
||||
userDTO.setAvatar(userObj.getStr("avatar"));
|
||||
userDTO.setUsername(userObj.getStr("mobile"));
|
||||
userDTO.setPhone(userObj.getStr("mobile"));
|
||||
userDTO.setNickname(userObj.getStr("nickname"));
|
||||
userDTO.setName(userObj.getStr("name"));
|
||||
userDTO.setEmail(userObj.getStr("email"));
|
||||
// 初始化密码为 手机号
|
||||
userDTO.setPassword(userObj.getStr("mobile"));
|
||||
sysUserService.saveUser(userDTO);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步企微部门
|
||||
* @return R
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<Boolean> syncCpDept() {
|
||||
WxCpService wxCpService = new WxCpServiceImpl();
|
||||
wxCpService.setWxCpConfigStorage(getCpConfig());
|
||||
|
||||
List<WxCpDepart> departList;
|
||||
try {
|
||||
departList = wxCpService.getDepartmentService().list(null);
|
||||
}
|
||||
catch (WxErrorException e) {
|
||||
log.error("获取企业微信部门列表失败", e);
|
||||
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR));
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(departList)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 数据库中现有的部门
|
||||
List<SysDept> deptList = sysDeptService.list(Wrappers.emptyWrapper());
|
||||
departList.stream()
|
||||
.filter(depart -> deptList.stream().noneMatch(sysDept -> depart.getName().equals(sysDept.getName())))
|
||||
.map(dept -> {
|
||||
SysDept sysDept = new SysDept();
|
||||
sysDept.setName(dept.getName());
|
||||
sysDept.setDeptId(dept.getId());
|
||||
sysDept.setParentId(dept.getParentId());
|
||||
sysDept.setSortOrder(dept.getOrder().intValue());
|
||||
return sysDept;
|
||||
}).forEach(sysDeptService::saveDept);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步企微用户
|
||||
* @return R
|
||||
*/
|
||||
@Override
|
||||
public R<Boolean> syncCpUser() {
|
||||
WxCpService wxCpService = new WxCpServiceImpl();
|
||||
wxCpService.setWxCpConfigStorage(getCpConfig());
|
||||
|
||||
List<WxCpUser> cpUserList;
|
||||
try {
|
||||
cpUserList = wxCpService.getUserService().listByDepartment(0L, true, 0);
|
||||
}
|
||||
catch (WxErrorException e) {
|
||||
log.error("获取企业微信用户列表失败", e);
|
||||
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR));
|
||||
}
|
||||
|
||||
if (CollUtil.isEmpty(cpUserList)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
// 系统原有用户
|
||||
List<SysUser> userList = sysUserService.list(Wrappers.emptyWrapper());
|
||||
|
||||
for (WxCpUser cpUser : cpUserList) {
|
||||
boolean exist = userList.stream().anyMatch(user -> user.getPhone().equals(cpUser.getMobile()));
|
||||
if (exist) {
|
||||
log.info("用户已存在跳过 {}", cpUser);
|
||||
continue;
|
||||
}
|
||||
|
||||
UserDTO user = new UserDTO();
|
||||
user.setUsername(cpUser.getMobile());
|
||||
user.setName(cpUser.getName());
|
||||
user.setDeptId(cpUser.getDepartIds()[0]);
|
||||
user.setEmail(cpUser.getEmail());
|
||||
user.setPhone(cpUser.getMobile());
|
||||
user.setAvatar(cpUser.getAvatar());
|
||||
// 初始化密码为 手机号
|
||||
user.setPassword(cpUser.getMobile());
|
||||
sysUserService.saveUser(user);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
private String getDingAccessToken() {
|
||||
SysSocialDetails dingTalk = sysSocialDetailsMapper.selectOne(Wrappers.<SysSocialDetails>lambdaQuery()
|
||||
.eq(SysSocialDetails::getType, LoginTypeEnum.dingtalk.getType()));
|
||||
|
||||
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_OLD_GET_TOKEN);
|
||||
OapiGettokenRequest request = new OapiGettokenRequest();
|
||||
request.setAppkey(dingTalk.getAppId());
|
||||
request.setAppsecret(dingTalk.getAppSecret());
|
||||
request.setHttpMethod(HttpMethod.GET.name());
|
||||
try {
|
||||
OapiGettokenResponse response = client.execute(request);
|
||||
return response.getAccessToken();
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("调用钉钉异常", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private WxCpDefaultConfigImpl getCpConfig() {
|
||||
WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
|
||||
config.setCorpId("wwdfd8cc3eb1127464"); // 设置微信企业号的appid
|
||||
config.setCorpSecret("mrJAJwC0msVJ0-F30Iwop6B-w8eledxD66l3flrjX5w"); // 设置微信企业号的app
|
||||
// corpSecret
|
||||
config.setAgentId(1000003); // 设置微信企业号应用ID
|
||||
config.setToken("lengleng"); // 设置微信企业号应用的token
|
||||
config.setAesKey("pc49WfQMwDg2tDwHHP8gfLN6fRjkgDzS4WkYCumZCF1"); // 设置微信企业号应用的EncodingAESKey
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前部门下的所有部门
|
||||
*/
|
||||
@@ -196,82 +320,4 @@ public class ConnectServiceImpl implements ConnectService {
|
||||
return sysDepts;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步部门下的钉钉用户
|
||||
*
|
||||
* @see <a href=
|
||||
* "https://open.dingtalk.com/document/isvapp-server/query-the-list-of-department-userids"/>
|
||||
* @see <a href=
|
||||
* "https://open.dingtalk.com/document/isvapp-server/query-user-details"/>
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Boolean syncDingUser(Long deptId) {
|
||||
// 数据库中现有用户
|
||||
List<SysUser> users = sysUserService.list(Wrappers.emptyWrapper());
|
||||
|
||||
String token = getDingAccessToken();
|
||||
|
||||
// 查询部门下的用户id列表
|
||||
DingTalkClient client = new DefaultDingTalkClient(SecurityConstants.DING_DEPT_USERIDS_URL);
|
||||
OapiUserListidRequest req = new OapiUserListidRequest();
|
||||
req.setDeptId(deptId);
|
||||
OapiUserListidResponse rsp = client.execute(req, token);
|
||||
|
||||
JSONObject jsonObject = JSONUtil.parseObj(rsp.getBody());
|
||||
JSONObject result = jsonObject.getJSONObject("result");
|
||||
|
||||
if (result == null) {
|
||||
return false;
|
||||
}
|
||||
List<String> useridList = result.get("userid_list", List.class);
|
||||
|
||||
// 查询用户详情
|
||||
for (String userid : useridList) {
|
||||
DingTalkClient userClient = new DefaultDingTalkClient(SecurityConstants.DING_USER_INFO_URL);
|
||||
OapiV2UserGetRequest userGetRequest = new OapiV2UserGetRequest();
|
||||
userGetRequest.setUserid(userid);
|
||||
OapiV2UserGetResponse userGetResponse = userClient.execute(userGetRequest, token);
|
||||
JSONObject userResult = JSONUtil.parseObj(userGetResponse.getBody());
|
||||
JSONObject userObj = JSONUtil.parseObj(userResult.get("result"));
|
||||
|
||||
boolean exist = users.stream().anyMatch(user -> user.getPhone().equals(userObj.getStr("mobile")));
|
||||
|
||||
if (exist) {
|
||||
log.info("用户已存在 {}", userid);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 用户部门信息
|
||||
JSONArray deptOrders = userObj.getJSONArray("dept_order_list");
|
||||
JSONObject deptInfo = (JSONObject) deptOrders.get(0);
|
||||
|
||||
// 用户信息
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setDeptId(Convert.toLong(deptInfo.get("dept_id")));
|
||||
sysUser.setAvatar(userObj.getStr("avatar"));
|
||||
sysUser.setUsername(userObj.getStr("mobile"));
|
||||
sysUser.setPhone(userObj.getStr("mobile"));
|
||||
sysUser.setNickname(userObj.getStr("nickname"));
|
||||
sysUser.setName(userObj.getStr("name"));
|
||||
sysUser.setEmail(userObj.getStr("email"));
|
||||
sysUserService.save(sysUser);
|
||||
|
||||
// 用户角色信息
|
||||
JSONArray roleList = userObj.getJSONArray("role_list");
|
||||
|
||||
if (roleList == null) {
|
||||
continue;
|
||||
}
|
||||
JSONObject roleInfo = (JSONObject) roleList.get(0);
|
||||
Long userRoleId = Convert.toLong(roleInfo.get("id"));
|
||||
SysUserRole sysUserRole = new SysUserRole();
|
||||
sysUserRole.setUserId(sysUser.getUserId());
|
||||
sysUserRole.setRoleId(userRoleId);
|
||||
sysUserRoleService.save(sysUserRole);
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
+11
-11
@@ -99,6 +99,17 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
return userPost;
|
||||
}).forEach(sysUserPostMapper::insert);
|
||||
});
|
||||
|
||||
// 如果角色为空,赋默认角色
|
||||
if (CollUtil.isEmpty(userDto.getRole())) {
|
||||
// 获取默认角色编码
|
||||
String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
|
||||
// 默认角色
|
||||
SysRole sysRole = sysRoleService
|
||||
.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, defaultRole));
|
||||
userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
|
||||
}
|
||||
|
||||
List<SysUserRole> userRoleList = userDto.getRole().stream().map(roleId -> {
|
||||
SysUserRole userRole = new SysUserRole();
|
||||
userRole.setUserId(sysUser.getUserId());
|
||||
@@ -356,17 +367,6 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
|
||||
return R.failed(message);
|
||||
}
|
||||
|
||||
// 获取默认角色编码
|
||||
String defaultRole = ParamResolver.getStr("USER_DEFAULT_ROLE");
|
||||
// 默认角色
|
||||
SysRole sysRole = sysRoleService.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, defaultRole));
|
||||
|
||||
if (sysRole == null) {
|
||||
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_PARAM_CONFIG_ERROR, "USER_DEFAULT_ROLE"));
|
||||
}
|
||||
|
||||
userDto.setRole(Collections.singletonList(sysRole.getRoleId()));
|
||||
return R.ok(saveUser(userDto));
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
<spring-boot-admin.version>2.6.6</spring-boot-admin.version>
|
||||
<captcha.version>1.2.7</captcha.version>
|
||||
<cas.sdk.version>3.6.4</cas.sdk.version>
|
||||
<dingtalk.version>1.3.40</dingtalk.version>
|
||||
<dingtalk.old.version>2.0.0</dingtalk.old.version>
|
||||
<swagger.fox.version>3.0.0</swagger.fox.version>
|
||||
<knife4j.version>2.0.9</knife4j.version>
|
||||
|
||||
Reference in new issue
Block a user