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 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 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 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 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 keysOfA = new HashSet<>(); Map mapOfA = new HashMap<>(); Set keysOfB = new HashSet<>(); Map 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 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 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); } }