|
|
package com.dsideal.FengHuang.Util;
|
|
|
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.aliyun.dingtalkoauth2_1_0.models.*;
|
|
|
import com.aliyun.tea.TeaException;
|
|
|
import com.aspose.slides.Collections.ArrayList;
|
|
|
import com.dingtalk.api.DefaultDingTalkClient;
|
|
|
import com.dingtalk.api.DingTalkClient;
|
|
|
import com.dingtalk.api.request.*;
|
|
|
import com.dingtalk.api.response.*;
|
|
|
import com.jfinal.kit.Kv;
|
|
|
import com.jfinal.plugin.activerecord.Db;
|
|
|
import com.jfinal.plugin.activerecord.Record;
|
|
|
import com.jfinal.plugin.redis.Redis;
|
|
|
import com.taobao.api.ApiException;
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
public class DingTalkUtil {
|
|
|
/**
|
|
|
* 使用 Token 初始化账号Client
|
|
|
*
|
|
|
* @return Client
|
|
|
* @throws Exception
|
|
|
*/
|
|
|
private static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
|
|
|
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
|
|
|
config.protocol = "https";
|
|
|
config.regionId = "central";
|
|
|
return new com.aliyun.dingtalkoauth2_1_0.Client(config);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
功能:获取钉钉的AccessToken
|
|
|
作者:黄海
|
|
|
时间:2023-06-06
|
|
|
*/
|
|
|
public static String getAccessToken(String appKey, String appSecret) throws Exception {
|
|
|
final String KEY = "DingTalkAccessToken";
|
|
|
if (!Redis.use().exists(KEY)) {
|
|
|
String accessToken = null;
|
|
|
com.aliyun.dingtalkoauth2_1_0.Client client = createClient();
|
|
|
com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
|
|
|
.setAppKey(appKey)
|
|
|
.setAppSecret(appSecret);
|
|
|
try {
|
|
|
GetAccessTokenResponse res = client.getAccessToken(getAccessTokenRequest);
|
|
|
accessToken = res.getBody().getAccessToken();
|
|
|
} catch (TeaException err) {
|
|
|
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
|
|
}
|
|
|
} catch (Exception _err) {
|
|
|
TeaException err = new TeaException(_err.getMessage(), _err);
|
|
|
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
|
|
}
|
|
|
}
|
|
|
Redis.use().setex(KEY, 5400, accessToken);//5400:一个半小时过期
|
|
|
return accessToken;
|
|
|
} else {
|
|
|
return Redis.use().get(KEY);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
功能:获取钉钉的JsApiToken->ticket
|
|
|
作者:黄海
|
|
|
时间:2023-06-06
|
|
|
*/
|
|
|
public static String getJsApiToken(String access_token) throws Exception {
|
|
|
final String KEY = "DingTalkJsApiToken";
|
|
|
if (!Redis.use().exists(KEY)) {
|
|
|
String jsApiToken = null;
|
|
|
com.aliyun.dingtalkoauth2_1_0.Client client = createClient();
|
|
|
com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders createJsapiTicketHeaders = new com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders();
|
|
|
createJsapiTicketHeaders.xAcsDingtalkAccessToken = access_token;
|
|
|
try {
|
|
|
CreateJsapiTicketResponse res = client.createJsapiTicketWithOptions(createJsapiTicketHeaders, new com.aliyun.teautil.models.RuntimeOptions());
|
|
|
jsApiToken = res.getBody().getJsapiTicket();
|
|
|
} catch (TeaException err) {
|
|
|
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
|
|
}
|
|
|
} catch (Exception _err) {
|
|
|
TeaException err = new TeaException(_err.getMessage(), _err);
|
|
|
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
|
|
}
|
|
|
}
|
|
|
Redis.use().setex(KEY, 5400, jsApiToken);//5400:一个半小时过期
|
|
|
return jsApiToken;
|
|
|
} else {
|
|
|
return Redis.use().get(KEY);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
功能:获取钉钉的SsoToken
|
|
|
作者:黄海
|
|
|
时间:2023-06-06
|
|
|
*/
|
|
|
public static String getSsoToken(String corpId, String ssoSecret) throws Exception {
|
|
|
final String KEY = "DingTalkSsoToken";
|
|
|
if (!Redis.use().exists(KEY)) {
|
|
|
String ssoToken = null;
|
|
|
com.aliyun.dingtalkoauth2_1_0.Client client = createClient();
|
|
|
GetSsoAccessTokenRequest getSsoAccessTokenRequest = new GetSsoAccessTokenRequest()
|
|
|
.setCorpid(corpId)
|
|
|
.setSsoSecret(ssoSecret);
|
|
|
try {
|
|
|
GetSsoAccessTokenResponse res = client.getSsoAccessToken(getSsoAccessTokenRequest);
|
|
|
ssoToken = res.getBody().getAccessToken();
|
|
|
} catch (TeaException err) {
|
|
|
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
|
|
}
|
|
|
} catch (Exception _err) {
|
|
|
TeaException err = new TeaException(_err.getMessage(), _err);
|
|
|
if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
|
|
|
}
|
|
|
}
|
|
|
Redis.use().setex(KEY, 5400, ssoToken);//5400:一个半小时过期
|
|
|
return ssoToken;
|
|
|
} else {
|
|
|
return Redis.use().get(KEY);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 功能:获取单个人员信息
|
|
|
*
|
|
|
* @param access_token
|
|
|
* @param userId
|
|
|
* @return
|
|
|
*/
|
|
|
public static String getPerson(String access_token, String userId) {
|
|
|
try {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
|
|
|
OapiV2UserGetRequest req = new OapiV2UserGetRequest();
|
|
|
req.setUserid(userId);
|
|
|
req.setLanguage("zh_CN");
|
|
|
OapiV2UserGetResponse rsp = client.execute(req, access_token);
|
|
|
return rsp.getBody();
|
|
|
} catch (ApiException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
//TODO 未完成
|
|
|
public static String getPersonToken(String appKey, String appSecret) throws Exception {
|
|
|
com.aliyun.dingtalkoauth2_1_0.Client client = createClient();
|
|
|
GetUserTokenRequest getUserTokenRequest = new GetUserTokenRequest()
|
|
|
.setClientId(appKey)
|
|
|
.setClientSecret(appSecret)
|
|
|
//.setCode("abcd")
|
|
|
.setRefreshToken("abcd")
|
|
|
.setGrantType("authorization_code");
|
|
|
try {
|
|
|
GetUserTokenResponse res = client.getUserToken(getUserTokenRequest);
|
|
|
System.out.println(res.getBody().getAccessToken());
|
|
|
System.out.println(res.getBody().getRefreshToken());
|
|
|
} catch (TeaException err) {
|
|
|
System.out.println(err);
|
|
|
} catch (Exception _err) {
|
|
|
System.out.println(_err);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 功能:创建部门
|
|
|
*
|
|
|
* @param access_token
|
|
|
* @throws ApiException
|
|
|
*/
|
|
|
public static long createDept(String access_token, String deptName, long parentId, long orderId) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/create");
|
|
|
OapiV2DepartmentCreateRequest req = new OapiV2DepartmentCreateRequest();
|
|
|
req.setParentId(parentId);
|
|
|
req.setOrder(orderId);
|
|
|
req.setName(deptName);
|
|
|
OapiV2DepartmentCreateResponse rsp = client.execute(req, access_token);
|
|
|
JSONObject jo = JSONObject.parseObject(rsp.getBody());
|
|
|
if (jo.getLong("errcode") > 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
return jo.getJSONObject("result").getLong("dept_id");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 功能:删除部门
|
|
|
*
|
|
|
* @param access_token
|
|
|
* @param deptId
|
|
|
* @throws ApiException
|
|
|
*/
|
|
|
public static void delDept(String access_token, long deptId) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/delete");
|
|
|
OapiV2DepartmentDeleteRequest req = new OapiV2DepartmentDeleteRequest();
|
|
|
req.setDeptId(deptId);
|
|
|
OapiV2DepartmentDeleteResponse rsp = client.execute(req, access_token);
|
|
|
//System.out.println(rsp.getBody());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 功能:更新部门信息
|
|
|
*
|
|
|
* @param access_token
|
|
|
* @param deptId
|
|
|
* @param deptName
|
|
|
* @param orderId
|
|
|
* @throws ApiException
|
|
|
*/
|
|
|
public static void updateDept(String access_token, long deptId, String deptName, long orderId) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/update");
|
|
|
OapiV2DepartmentUpdateRequest req = new OapiV2DepartmentUpdateRequest();
|
|
|
req.setDeptId(deptId);
|
|
|
req.setOrder(orderId);
|
|
|
req.setName(deptName);
|
|
|
req.setLanguage("zh_CN");
|
|
|
OapiV2DepartmentUpdateResponse rsp = client.execute(req, access_token);
|
|
|
//System.out.println(rsp.getBody());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 功能:获取部门列表
|
|
|
*
|
|
|
* @param access_token
|
|
|
* @throws ApiException
|
|
|
*/
|
|
|
public static List<Kv> deptList = new ArrayList();
|
|
|
|
|
|
public static void getDeptList(String access_token, long dept_id) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
|
|
|
OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
|
|
|
req.setDeptId(dept_id);
|
|
|
req.setLanguage("zh_CN");
|
|
|
OapiV2DepartmentListsubResponse rsp = client.execute(req, access_token);
|
|
|
JSONObject jo = JSONObject.parseObject(rsp.getBody());
|
|
|
JSONArray ja = jo.getJSONArray("result");
|
|
|
if (ja == null) return;
|
|
|
for (int i = 0; i < ja.size(); i++) {
|
|
|
JSONObject j = ja.getJSONObject(i);
|
|
|
Kv kv = Kv.create();
|
|
|
long childDeptId = j.getLongValue("dept_id");
|
|
|
kv.set("dept_id", childDeptId);
|
|
|
kv.set("name", j.getString("name"));
|
|
|
//kv.set("parent_id", j.getLongValue("parent_id"));
|
|
|
deptList.add(kv);
|
|
|
getDeptList(access_token, childDeptId);//递归
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 功能:创建人员
|
|
|
*
|
|
|
* @param access_token
|
|
|
* @param deptId
|
|
|
* @param userId
|
|
|
* @param personName
|
|
|
* @param tel
|
|
|
* @param zhiWei
|
|
|
* @throws ApiException
|
|
|
*/
|
|
|
public static void createPerson(String access_token, String deptId, String userId, String personName, String tel, String zhiWei) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/create");
|
|
|
OapiV2UserCreateRequest req = new OapiV2UserCreateRequest();
|
|
|
req.setUserid(userId);
|
|
|
req.setName(personName);
|
|
|
req.setMobile(tel);
|
|
|
req.setTitle(zhiWei);
|
|
|
req.setDeptIdList(deptId);
|
|
|
OapiV2UserCreateResponse rsp = client.execute(req, access_token);
|
|
|
//System.out.println(rsp.getBody());
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 功能:删除人员
|
|
|
*
|
|
|
* @param access_token
|
|
|
* @param userId
|
|
|
* @throws ApiException
|
|
|
*/
|
|
|
public static void delPerson(String access_token, String userId) throws ApiException {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/delete");
|
|
|
OapiV2UserDeleteRequest req = new OapiV2UserDeleteRequest();
|
|
|
req.setUserid(userId);
|
|
|
OapiV2UserDeleteResponse rsp = client.execute(req, access_token);
|
|
|
//System.out.println(rsp.getBody());
|
|
|
}
|
|
|
|
|
|
|
|
|
public static void writeDtDeptId(int orgId, String value) {
|
|
|
String sql = "update t_base_organization set dingtalk_dept_id=? where org_id=?";
|
|
|
Db.update(sql, value, orgId);
|
|
|
}
|
|
|
|
|
|
public static long getDtDeptId(int org_id) {
|
|
|
String sql = "select dingtalk_dept_id from t_base_organization where org_id=?";
|
|
|
Record r = Db.findFirst(sql, org_id);
|
|
|
if (r.get("dingtalk_dept_id") == null) return 1;
|
|
|
return r.get("dingtalk_dept_id");
|
|
|
}
|
|
|
|
|
|
public static Record getOrgByOrgName(String org_name) {
|
|
|
String sql = "select org_id,org_name,sort_id from t_base_organization where org_name = ?";
|
|
|
return Db.findFirst(sql, org_name);
|
|
|
}
|
|
|
|
|
|
public static List<Record> getOrgList(int orgId) {
|
|
|
// 学校及学校下的部门
|
|
|
String sql = "select org_id,org_name,parent_id,sort_id,dingtalk_dept_id from t_base_organization where bureau_id=? and org_id<>bureau_id order by org_id";
|
|
|
List<Record> list = Db.find(sql, orgId);
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
public static void importYptOrg(String accessToken, int orgId) throws ApiException {
|
|
|
//1、读取云平台数据,创建学校
|
|
|
/*
|
|
|
需要先手动执行,对表增加一列,记录钉钉的部门ID号:
|
|
|
ALTER TABLE `dsideal_db`.`t_base_organization`
|
|
|
ADD COLUMN `dingtalk_dept_id` bigint NULL COMMENT '钉钉中的部门ID' AFTER `zydz`,
|
|
|
ADD INDEX(`dingtalk_dept_id`);
|
|
|
*/
|
|
|
|
|
|
//单位需要清空一下这个属性,有枣没枣都打一下子
|
|
|
writeDtDeptId(orgId, null);
|
|
|
|
|
|
// 学校及学校下的部门
|
|
|
List<Record> list = getOrgList(orgId);
|
|
|
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
|
orgId = list.get(i).getInt("org_id");
|
|
|
int parentId = list.get(i).getInt("parent_id");
|
|
|
if (parentId == -1) parentId = orgId;
|
|
|
String dept_name = list.get(i).getStr("org_name");
|
|
|
long dingtalk_dept_id = getDtDeptId(parentId);
|
|
|
long sortId = list.get(i).getLong("sort_id");
|
|
|
//创建
|
|
|
long dt_dept_id = DingTalkUtil.createDept(accessToken, dept_name, dingtalk_dept_id, sortId);
|
|
|
//回写
|
|
|
writeDtDeptId(orgId, String.valueOf(dt_dept_id));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public static JSONObject getDeptInfo(String access_token, long deptId) {
|
|
|
JSONObject jo;
|
|
|
try {
|
|
|
DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
|
|
|
OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
|
|
|
req.setDeptId(deptId);
|
|
|
req.setLanguage("zh_CN");
|
|
|
OapiV2DepartmentGetResponse rsp = client.execute(req, access_token);
|
|
|
jo = JSONObject.parseObject(rsp.getBody());
|
|
|
} catch (Exception err) {
|
|
|
jo = JSONObject.parseObject(err.toString());
|
|
|
}
|
|
|
return jo;
|
|
|
}
|
|
|
|
|
|
public static void syncOrg(String accessToken, String orgName) throws ApiException {
|
|
|
Record rOrg = getOrgByOrgName(orgName);
|
|
|
int bureauId = rOrg.getInt("org_id");
|
|
|
int sortId = rOrg.getInt("sort_id");
|
|
|
//获取部门信息
|
|
|
deptList.clear();
|
|
|
//获取数据库中记录的钉钉端的dept_id,但不一定准确存在,需要继续判断一下
|
|
|
long DT_BureauId = getDtDeptId(bureauId);
|
|
|
|
|
|
JSONObject jRes = getDeptInfo(accessToken, DT_BureauId);
|
|
|
if (jRes.getLong("errcode") > 0) {
|
|
|
DT_BureauId = createDept(accessToken, orgName, 1, sortId);
|
|
|
writeDtDeptId(bureauId, String.valueOf(DT_BureauId));//记得要回写
|
|
|
CommonUtil.Print("单位名称:" + orgName + "不存在!已创建!");
|
|
|
} else {
|
|
|
CommonUtil.Print("单位名称:" + orgName + "已存在,保留!");
|
|
|
}
|
|
|
//获取下属部门的列表
|
|
|
getDeptList(accessToken, DT_BureauId);
|
|
|
|
|
|
// 云平台->集合A,钉钉->集合B
|
|
|
// (1) x在A中存在,在B中也存在,内容也一致:不处理
|
|
|
// (2) x在A中存在,在B中也存在,内容不一致:更新处理
|
|
|
// (3) x在A中存在,在B中不存在,新增
|
|
|
// (4) x在A中不存在,在B中存在,删除
|
|
|
|
|
|
Set<Long> keysOfA = new HashSet<>();
|
|
|
Map<Long, JSONObject> mapOfA = new HashMap<>();
|
|
|
Set<Long> keysOfB = new HashSet<>();
|
|
|
Map<Long, JSONObject> mapOfB = new HashMap<>();
|
|
|
//A:钉钉
|
|
|
for (int i = 0; i < deptList.size(); i++) {
|
|
|
long deptId = deptList.get(i).getLong("dept_id");
|
|
|
String org_name = deptList.get(i).getStr("name");
|
|
|
keysOfA.add(deptId);
|
|
|
JSONObject jo = new JSONObject();
|
|
|
jo.put("org_name", org_name);
|
|
|
mapOfA.put(deptId, jo);
|
|
|
}
|
|
|
//B:云平台
|
|
|
List<Record> list = getOrgList(bureauId);
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
|
if (list.get(i).get("dingtalk_dept_id") != null) {
|
|
|
long deptId = list.get(i).getLong("dingtalk_dept_id");
|
|
|
String org_name = list.get(i).getStr("org_name");
|
|
|
sortId = list.get(i).getInt("sort_id");
|
|
|
int org_id = list.get(i).getInt("org_id");
|
|
|
int parentId = list.get(i).getInt("parent_id");
|
|
|
keysOfB.add(deptId);
|
|
|
|
|
|
JSONObject jo = new JSONObject();
|
|
|
jo.put("org_id", org_id);
|
|
|
jo.put("org_name", org_name);
|
|
|
jo.put("sort_id", sortId);
|
|
|
jo.put("parent_id", parentId);
|
|
|
mapOfB.put(deptId, jo);
|
|
|
}
|
|
|
}
|
|
|
//在A不在B
|
|
|
for (Long key : keysOfA) {
|
|
|
if (!keysOfB.contains(key)) {
|
|
|
// key只存在于A中
|
|
|
// 删除
|
|
|
CommonUtil.Print("发现钉钉中多出的dept_id:" + key + ",将删除掉...");
|
|
|
delDept(accessToken, key);
|
|
|
} else {
|
|
|
// key在A和B中都存在
|
|
|
String aName = mapOfA.get(key).getString("org_name");
|
|
|
String bName = mapOfB.get(key).getString("org_name");
|
|
|
int sId = mapOfB.get(key).getInteger("sort_id");
|
|
|
if (aName.equals(bName)) {
|
|
|
CommonUtil.Print("发现钉钉与云平台间部门名称一致,不需要修改,aName=" + aName + ",bName=" + bName);
|
|
|
continue;
|
|
|
}
|
|
|
CommonUtil.Print("发现钉钉与云平台间部门名称不一致,将修改,aName=" + aName + ",bName=" + bName);
|
|
|
updateDept(accessToken, key, bName, sId);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//在B不在A
|
|
|
for (Long key : keysOfB) {
|
|
|
if (!keysOfA.contains(key)) {
|
|
|
// key只存在于B中
|
|
|
// 增加
|
|
|
String org_name = mapOfB.get(key).getString("org_name");
|
|
|
System.out.println(org_name);
|
|
|
int sId = mapOfB.get(key).getInteger("sort_id");
|
|
|
int parentId = mapOfB.get(key).getInteger("parent_id");
|
|
|
int org_id = mapOfB.get(key).getInteger("org_id");
|
|
|
//这个部门是在哪个部门下的
|
|
|
long dingTalkParentDeptId = getDtDeptId(parentId);
|
|
|
long dt_dept_id = createDept(accessToken, org_name, dingTalkParentDeptId, sId);
|
|
|
writeDtDeptId(org_id, String.valueOf(dt_dept_id));
|
|
|
CommonUtil.Print("成功创建部门:" + org_name);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public static List<Record> getPersonList(int bureau_id) {
|
|
|
String sql = "select t1.person_id,t1.person_name,t2.dingtalk_dept_id from t_base_person as t1 " +
|
|
|
"inner join t_base_organization as t2 on t1.org_id=t2.org_id " +
|
|
|
" where t1.bureau_id=? and t1.b_use=1";
|
|
|
return Db.find(sql, bureau_id);
|
|
|
}
|
|
|
|
|
|
}
|