钉钉通讯录初始化到中台主数据

2024年9月4日11:04:04
This commit is contained in:
xiang2lin 2024-09-04 11:04:28 +08:00
parent eb733789bb
commit d8fcae24d8
8 changed files with 369 additions and 52 deletions

View File

@ -0,0 +1,111 @@
package com.hzya.frame.plugin.kjs.plugin;
import com.alibaba.fastjson.JSONObject;
import com.hzya.frame.base.PluginBaseEntity;
import com.hzya.frame.plugin.kjs.service.IDingTalkInitService;
import com.hzya.frame.web.entity.BaseResult;
import com.hzya.frame.web.entity.JsonResultEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description 钉钉组织架构初始化
* @Author xiangerlin
* @Date 2024/9/2 16:19
**/
public class DingTalkInitPluginInitializer extends PluginBaseEntity {
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private IDingTalkInitService dingTalkService;
/***
* 插件初始化方法
* @Author 👻👻👻👻👻👻👻👻 gjh
* @Date 2023-08-02 10:48
* @Param []
* @return void
**/
@Override
public void initialize() {
logger.info(getPluginLabel() + "執行初始化方法initialize()");
}
/****
* 插件销毁方法
* @author 👻👻👻👻👻👻👻👻 gjh
* @date 2023-08-02 10:48
* @return void
**/
@Override
public void destroy() {
logger.info(getPluginLabel() + "執行銷毀方法destroy()");
}
/****
* 插件的ID
* @author 👻👻👻👻👻👻👻👻 gjh
* @date 2023-08-02 10:48
* @return void
**/
@Override
public String getPluginId() {
return "kjsDingTalkInitPlugin";
}
/****
* 插件的名称
* @author 👻👻👻👻👻👻👻👻 gjh
* @date 2023-08-02 10:48
* @return void
**/
@Override
public String getPluginName() {
return "kjs钉钉部门人员初始化插件";
}
/****
* 插件的显示值
* @author 👻👻👻👻👻👻👻👻 gjh
* @date 2023-08-02 10:48
* @return void
**/
@Override
public String getPluginLabel() {
return "kjs钉钉部门人员初始化插件";
}
/***
* 插件类型 1场景插件
* @Author 👻👻👻👻👻👻👻👻 gjh
* @Date 2023-08-02 14:01
* @Param []
* @return java.lang.String
**/
@Override
public String getPluginType() {
return "1";
}
/***
* 执行业务代码
* @Author 👻👻👻👻👻👻👻👻 gjh
* @Date 2023-08-07 11:20
* @param requestJson 执行业务代码的参数
* @return void
**/
@Override
public JsonResultEntity executeBusiness(JSONObject requestJson) throws Exception {
logger.info("开始执行"+getPluginName()+requestJson.toString());
new Thread(()->{
String type = requestJson.getString("type");
Long deptId = requestJson.getLong("deptId");
if ("dept".equals(type)){
dingTalkService.deptInit(deptId);
}else if ("user".equals(type)){
dingTalkService.userInit(deptId);
}
}).start();
return BaseResult.getSuccessMessageEntity("成功");
}
}

View File

@ -10,8 +10,10 @@ import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.dingtalk.open.app.api.message.GenericOpenDingTalkEvent;
import com.hzya.frame.dingtalk.enums.OrgEventEnum;
import com.hzya.frame.dingtalk.service.IDingTalkService;
import com.hzya.frame.uuid.UUIDUtils;
import com.hzya.frame.web.entity.BaseResult;
import com.hzya.frame.web.entity.JsonResultEntity;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@ -19,9 +21,8 @@ import shade.com.alibaba.fastjson2.JSONArray;
import shade.com.alibaba.fastjson2.JSONObject;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Description 通讯录事件订阅消费者
@ -31,30 +32,30 @@ import java.util.Map;
public class GenericEventConsumer {
Logger logger = LoggerFactory.getLogger(getClass());
//中台应用
private static final String APPCODE = "800004";
private static final String URL = "http://127.0.0.1:9999/kangarooDataCenterV3/entranceController/externalCallInterface";
public static final String APPCODE = "800004";
public static final String URL = "http://127.0.0.1:9999/kangarooDataCenterV3/entranceController/externalCallInterface";
//中台 publicKey
private static final String PUBLICKEY = "ZJYAWb7lhAUTYqekPkU+uHJv1/ObJxb7dT7sD8HPRDGAgyhCe7eDIk+3zDUT+v578prj";
public static final String PUBLICKEY = "ZJYAWb7lhAUTYqekPkU+uHJv1/ObJxb7dT7sD8HPRDGAgyhCe7eDIk+3zDUT+v578prj";
//中台secretKey
private static final String SECRETKEY = "fviZnLBsQUAGF8w8FSOdJi7XlIm/XAZclMxRagDLfTyJFlvnIBF3w66Hrpfzs8cYj3JzOP8MtA1LSGvL+2BWG8c/o7DKi92S4mr3zcGearA=";
public static final String SECRETKEY = "fviZnLBsQUAGF8w8FSOdJi7XlIm/XAZclMxRagDLfTyJFlvnIBF3w66Hrpfzs8cYj3JzOP8MtA1LSGvL+2BWG8c/o7DKi92S4mr3zcGearA=";
//mdm通用新增接口编码
private static final String MDMADDCODE = "8000040022";
public static final String MDMADDCODE = "8000040022";
//mdm通用删除接口编码
private static final String MDMREMOVECODE = "8000040024";
public static final String MDMREMOVECODE = "8000040024";
//主数据人员钉钉档案编码
private static final String DDUSERMDMCODE = "10015";
public static final String DDUSERMDMCODE = "10015";
//主数据钉钉部门档案编码
private static final String DDDEPTMDMCODE = "10016";
public static final String DDDEPTMDMCODE = "10016";
//钉钉应用编码
private static final String DDAPPCODE = "800005";
public static final String DDAPPCODE = "800005";
//钉钉 publicKey
private static final String DDPUBLICKEY = "ZJYAn/EBWEhLUMezDLU4iZ1vTO9kc6pM6XrYLajnqnK60Q9Ce7eDIk+3zDUT+v578prj";
public static final String DDPUBLICKEY = "ZJYAn/EBWEhLUMezDLU4iZ1vTO9kc6pM6XrYLajnqnK60Q9Ce7eDIk+3zDUT+v578prj";
//钉钉secretKey
private static final String DDSECRETKEY = "ctMIYyauwoKSFeU4tg5gH1aWC/3OJK6HsKJrSR0oyDmdmdvRNgdoTzX0C1OQ+whrj3JzOP8MtA1LSGvL+2BWG8c/o7DKi92S4mr3zcGearA=";
public static final String DDSECRETKEY = "ctMIYyauwoKSFeU4tg5gH1aWC/3OJK6HsKJrSR0oyDmdmdvRNgdoTzX0C1OQ+whrj3JzOP8MtA1LSGvL+2BWG8c/o7DKi92S4mr3zcGearA=";
//获取钉钉用户详情接口编码
private static final String GETUSERAPPCODE="8000050001";
public static final String GETUSERAPPCODE="8000050001";
//获取钉钉部门详情接口编码
private static final String GETDETPAPPCODE="8000050002";
public static final String GETDETPAPPCODE="8000050002";
/**
* 消费通讯录事件订阅消息
*
@ -153,7 +154,7 @@ public class GenericEventConsumer {
}
//保存用户到mdm
private static String createUser(String userRes,String eventType) {
private String createUser(String userRes,String eventType) {
JsonResultEntity jsonResult = JSONObject.parseObject(userRes,JsonResultEntity.class);
if (jsonResult.isFlag()){
shade.com.alibaba.fastjson2.JSONObject attribute = (shade.com.alibaba.fastjson2.JSONObject) jsonResult.getAttribute();
@ -163,39 +164,73 @@ public class GenericEventConsumer {
String result = attribute.getString("result");
OapiV2UserGetResponse.UserGetResponse userInfo = com.alibaba.fastjson.JSONObject.parseObject(result,OapiV2UserGetResponse.UserGetResponse.class);
//OapiV2UserGetResponse.UserGetResponse userInfo = dingtalkService.getUserById(userIds.getString(i));
Map<String,Object> mdmMap = new LinkedHashMap<>();
mdmMap.put("mdmCode",DDUSERMDMCODE);
mdmMap.put("optionName","系统管理员");
Map<String,Object> userMap = new LinkedHashMap<>();
userMap.put("data_id", userInfo.getUserid());
userMap.put("unionid",userInfo.getUnionid());
userMap.put("userid",userInfo.getUserid());
userMap.put("name",userInfo.getName());
userMap.put("mobile",userInfo.getMobile());
userMap.put("job_number",userInfo.getJobNumber());
userMap.put("title",userInfo.getTitle());
userMap.put("email",userInfo.getEmail());
userMap.put("org_email",userInfo.getOrgEmail());
userMap.put("event_type",eventType);
userMap.put("dept_id_list",userInfo.getDeptIdList());
if (null != userInfo.getHiredDate()){
userMap.put("hired_date", DateUtil.date(userInfo.getHiredDate()));
}
mdmMap.put("mdm_dd_user",userMap);
//保存到人员主数据
Map<String, String> headerMap = MapBuilder.<String, String>create(true)
.put("apiCode", MDMADDCODE)//中台接口
.put("publicKey",DDPUBLICKEY)//钉钉应用
.put("secretKey",DDSECRETKEY)//钉钉应用
.put("appId",APPCODE)//中台应用
.build();
String body = HttpRequest.post(URL).addHeaders(headerMap).body(com.alibaba.fastjson.JSONObject.toJSONString(mdmMap)).timeout(60000).execute().body();
// return body;
createMdmUser(eventType, userInfo);
// return body;
}
}
return null;
}
public void createMdmUser(String eventType, OapiV2UserGetResponse.UserGetResponse userInfo) {
Map<String,Object> mdmMap = new LinkedHashMap<>();
mdmMap.put("mdmCode",DDUSERMDMCODE);
mdmMap.put("optionName","系统管理员");
Map<String,Object> userMap = new LinkedHashMap<>();
userMap.put("data_id", userInfo.getUserid());
userMap.put("unionid", userInfo.getUnionid());
userMap.put("userid", userInfo.getUserid());
userMap.put("name", userInfo.getName());
userMap.put("mobile", userInfo.getMobile());
userMap.put("job_number", userInfo.getJobNumber());
userMap.put("title", userInfo.getTitle());
userMap.put("email", userInfo.getEmail());
userMap.put("org_email", userInfo.getOrgEmail());
userMap.put("event_type", eventType);
userMap.put("dept_id_list", userInfo.getDeptIdList());
if (null != userInfo.getHiredDate()){
userMap.put("hired_date", DateUtil.format(DateUtil.date(userInfo.getHiredDate()),"yyyy-MM-dd"));
}
List<Map<String,Object>> postList = new LinkedList<>();
//处理职位信息
List<OapiV2UserGetResponse.DeptPosition> deptPositionList = userInfo.getDeptPositionList();
if (CollectionUtils.isNotEmpty(deptPositionList) && deptPositionList.size()>1){
//用stream方式给deptOrderList排序排序字段为order
List<OapiV2UserGetResponse.DeptOrder> deptOrderList = userInfo.getDeptOrderList();
// 使用Stream API对deptOrderList按order字段排序
List<OapiV2UserGetResponse.DeptOrder> sortedDeptOrderList = deptOrderList.stream()
.sorted(Comparator.comparing(OapiV2UserGetResponse.DeptOrder::getOrder))
.collect(Collectors.toList());
for (OapiV2UserGetResponse.DeptOrder deptOrder : sortedDeptOrderList) {
for (OapiV2UserGetResponse.DeptPosition deptPosition : deptPositionList) {
if (deptPosition.getDeptId().equals(deptOrder.getDeptId())){
Map<String,Object> positionMap = new LinkedHashMap<>();
positionMap.put("dept_id",deptPosition.getDeptId());
positionMap.put("title",deptPosition.getTitle());
postList.add(positionMap);
break;
}
}
}
}else if (CollectionUtils.isNotEmpty(deptPositionList) && deptPositionList.size() == 1){
OapiV2UserGetResponse.DeptPosition deptPosition = deptPositionList.get(0);
Map<String,Object> positionMap = new LinkedHashMap<>();
positionMap.put("dept_id",deptPosition.getDeptId());
positionMap.put("title",StrUtil.isEmpty(deptPosition.getTitle()) ? userInfo.getTitle():deptPosition.getTitle());
positionMap.put("data_id", UUIDUtils.getUUID());
postList.add(positionMap);
}
mdmMap.put("mdm_dd_user",userMap);
mdmMap.put("mdm_dd_user_position",postList);
//保存到人员主数据
Map<String, String> headerMap = MapBuilder.<String, String>create(true)
.put("apiCode", MDMADDCODE)//中台接口
.put("publicKey",DDPUBLICKEY)//钉钉应用
.put("secretKey",DDSECRETKEY)//钉钉应用
.put("appId",APPCODE)//中台应用
.build();
String body = HttpRequest.post(URL).addHeaders(headerMap).body(com.alibaba.fastjson.JSONObject.toJSONString(mdmMap)).timeout(60000).execute().body();
}
/**
* 保存部门到mdm
* @param deptRes

View File

@ -0,0 +1,23 @@
package com.hzya.frame.plugin.kjs.service;
/**
* @Description 钉钉部门人员初始化
* @Author xiangerlin
* @Date 2024/9/2 16:24
**/
public interface IDingTalkInitService {
/**
* 部门初始化仅初始化部门
* 这里只会用一次所以直接调用钉钉原生接口
* @return
*/
String deptInit(Long deptId);
/**
* 部门人员初始化
* 这里只会用一次所以直接调用钉钉原生接口
* @param deptId 部门id
* @return
*/
String userInit(Long deptId);
}

View File

@ -0,0 +1,135 @@
package com.hzya.frame.plugin.kjs.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.http.HttpRequest;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiV2DepartmentListsubRequest;
import com.dingtalk.api.request.OapiV2UserListRequest;
import com.dingtalk.api.response.OapiV2DepartmentGetResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.dingtalk.api.response.OapiV2UserListResponse;
import com.hzya.frame.dingtalk.enums.OrgEventEnum;
import com.hzya.frame.dingtalk.service.IDingTalkService;
import com.hzya.frame.dingtalk.util.DingTalkAccessToken;
import com.hzya.frame.plugin.kjs.service.GenericEventConsumer;
import com.hzya.frame.plugin.kjs.service.IDingTalkInitService;
import com.taobao.api.ApiException;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import java.util.*;
/**
* @Description 钉钉部门人员初始化
* @Author xiangerlin
* @Date 2024/9/2 16:24
**/
public class DingTalkInitServiceImpl implements IDingTalkInitService {
@Value("${dingtalk.appKey}")
private String appKey;
@Value("${dingtalk.appSecret}")
private String appSecret;
@Autowired
private IDingTalkService dingTalkService;
@Autowired
private GenericEventConsumer commonEventConsumer;
/**
* 部门初始化仅初始化部门
* 这里只会用一次所以直接调用钉钉原生接口
* @return
*/
@Override
public String deptInit(Long deptId) {
List<Long> deptIdList = new LinkedList<>();
List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptBaseResponseList = new LinkedList<>();
recursiveDept(deptId, appKey, appSecret,deptIdList,deptBaseResponseList);
System.out.println(deptIdList.size());
if (CollectionUtils.isNotEmpty(deptIdList) && deptIdList.size() == deptBaseResponseList.size()){
for (OapiV2DepartmentListsubResponse.DeptBaseResponse resp : deptBaseResponseList) {
Map<String,Object> mdmMap = new LinkedHashMap<>();
mdmMap.put("mdmCode",GenericEventConsumer.DDDEPTMDMCODE);
mdmMap.put("optionName","系统管理员");
Map<String,Object> deptMap = new LinkedHashMap<>();
deptMap.put("dept_id",resp.getDeptId());
deptMap.put("data_id",resp.getDeptId());
deptMap.put("name",resp.getName());
deptMap.put("parent_id",resp.getParentId());
mdmMap.put("mdm_dd_dept",deptMap);
//保存部门到主数据
Map<String, String> headerMap = MapBuilder.<String, String>create(true)
.put("apiCode", GenericEventConsumer.MDMADDCODE)//中台接口
.put("publicKey",GenericEventConsumer.DDPUBLICKEY)//钉钉应用
.put("secretKey",GenericEventConsumer.DDSECRETKEY)//钉钉应用
.put("appId",GenericEventConsumer.APPCODE)//中台应用
.build();
String body = HttpRequest.post(GenericEventConsumer.URL).addHeaders(headerMap).body(com.alibaba.fastjson.JSONObject.toJSONString(mdmMap)).timeout(60000).execute().body();
System.out.println(body);
}
}
return null;
}
private void queryPageUser(OapiV2UserListRequest req,List<OapiV2UserListResponse.ListUserResponse> userList) {
boolean hasMore = true;
do {
hasMore = false;
OapiV2UserListResponse.PageResult pageResult = dingTalkService.getUserListByDeptId(req, appKey, appSecret);
hasMore = pageResult.getHasMore();
req.setCursor(pageResult.getNextCursor());
userList.addAll(pageResult.getList());
}while (hasMore);
}
/**
* 人员初始化
* @param deptId 部门id
* @return
*/
@Override
public String userInit(Long deptId) {
List<Long> deptIdList = new LinkedList<>();
List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptBaseResponseList = new LinkedList<>();
recursiveDept(deptId, appKey, appSecret,deptIdList,deptBaseResponseList);
System.out.println(deptIdList.size());
if (CollectionUtils.isNotEmpty(deptIdList)){
for (Long id : deptIdList) {
List<OapiV2UserListResponse.ListUserResponse> userList = new LinkedList<>();
//查询部门下人员信息
OapiV2UserListRequest req = new OapiV2UserListRequest();
req.setDeptId(id);
req.setCursor(0L);
queryPageUser(req,userList);
if (CollectionUtils.isNotEmpty(userList)){
for (OapiV2UserListResponse.ListUserResponse resp : userList) {
//查询user详情
OapiV2UserGetResponse.UserGetResponse userGetResponse = dingTalkService.getUserById(resp.getUserid(), appKey, appSecret);
commonEventConsumer.createMdmUser(OrgEventEnum.USER_MODIFY_ORG.getCode(), userGetResponse);
}
}
}
}
return null;
}
private void recursiveDept(Long deptId,String appKey,String appSecret,List<Long> deptIdList,List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptBaseResponseList){
if (deptId.longValue() != 1L){
deptIdList.add(deptId);
}
//1查询部门档案
List<OapiV2DepartmentListsubResponse.DeptBaseResponse> deptList = dingTalkService.getDeptList(deptId, appKey, appSecret);
if (CollectionUtils.isNotEmpty(deptList)){
for (OapiV2DepartmentListsubResponse.DeptBaseResponse deptBaseResponse : deptList) {
System.out.println(deptBaseResponse.getName());
deptBaseResponseList.add(deptBaseResponse);
recursiveDept(deptBaseResponse.getDeptId(),appKey,appSecret,deptIdList,deptBaseResponseList);
}
}
}
}

View File

@ -5,19 +5,22 @@ logging:
root: info
encodings: UTF-8
file:
# 日志保存路径
path: /Users/apple/Desktop/log/local
# 日志保存路径
path: /Users/xiangerlin/work/app/logs/kjs
spring:
datasource:
dynamic:
datasource:
master:
url: jdbc:mysql://ufidahz.com.cn:9014/businesscenter?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowLoadLocalInfile=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=30000&socketTimeout=30000&autoReconnectForPools=true
url: jdbc:mysql://ufidahz.com.cn:9014/businesscenter_kjs?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowLoadLocalInfile=false&autoReconnect=true&failOverReadOnly=false&connectTimeout=30000&socketTimeout=30000&autoReconnectForPools=true
username: root
password: 62e4295b615a30dbf3b8ee96f41c820b
driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
savefile:
# 文件保存路径
path: /Users/apple/Desktop/log/local
zt:
url: http://127.0.0.1:9999/kangarooDataCenterV3/entranceController/externalCallInterface
# 文件保存路径
path: /Users/xiangerlin/work/app/file/kjs
dingtalk:
appKey: dingq3vbsswvyujiuwa7
appSecret: m4IRNcKQn-W9QBLERHWt0iW2hSirvxPS684xiNw-4QFMNg2gsBCur9T4QMvvAR4I
appId: dd39187a-079a-466c-b4b7-9ef3172e9e61
agentId: 3209295620 appkey:dingbltm9wszcl7hoxyg

View File

@ -3,4 +3,5 @@
<beans default-autowire="byName">
<bean name="deliveryOrderPluginInitializer" class="com.hzya.frame.plugin.kjs.plugin.DeliveryOrderPluginInitializer" />
<bean name="momOrderPluginInitializer" class="com.hzya.frame.plugin.kjs.plugin.MomOrderPluginInitializer" />
<bean name="dingTalkInitPluginInitializer" class="com.hzya.frame.plugin.kjs.plugin.DingTalkInitPluginInitializer" />
</beans>

View File

@ -5,4 +5,5 @@
<bean name="momOrderPluginServiceImpl" class="com.hzya.frame.plugin.kjs.service.impl.MomOrderPluginServiceImpl" />
<bean name="kjsPluginBaseService" class="com.hzya.frame.plugin.kjs.service.impl.KjsPluginBaseService" />
<bean name="genericEventConsumer" class="com.hzya.frame.plugin.kjs.service.GenericEventConsumer" />
<bean name="dingTalkInitServiceImpl" class="com.hzya.frame.plugin.kjs.service.impl.DingTalkInitServiceImpl" />
</beans>

View File

@ -15,6 +15,7 @@ import com.hzya.frame.cbs8.util.CbsAccessToken;
import com.hzya.frame.plugin.cbs8.plugin.PayApplyPluginInitializer;
import com.hzya.frame.plugin.cbs8.plugin.PayResultPluginInitializer;
import com.hzya.frame.plugin.cbs8.plugin.TransactionDetailPluginInitializer;
import com.hzya.frame.plugin.kjs.service.IDingTalkInitService;
import com.hzya.frame.plugin.seeyonExt.plugin.SeeyonExtPluginInitializer;
import com.hzya.frame.seeyon.cbs8.entity.PaymentEntity;
import com.hzya.frame.seeyon.cbs8.service.IPaymentService;
@ -65,7 +66,14 @@ public class temButtom {
private TransactionDetailPluginInitializer transactionDetailPluginInitializer;
@Autowired
private PayResultPluginInitializer payResultPluginInitializer;
@Autowired
private IDingTalkInitService dingTalkInitService;
@Test
public void dingTest(){
String s = dingTalkInitService.deptInit(1L);
}
@Test
public void cbs8PluginTest(){
try {