package com.dsideal.FengHuang.DingTalk; import cn.binarywang.tools.generator.ChineseMobileNumberGenerator; import cn.hutool.core.util.PhoneUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenRequest; import com.aliyun.dingtalkoauth2_1_0.models.GetUserTokenResponse; 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.dsideal.FengHuang.Util.CommonUtil; import com.jfinal.kit.Kv; import com.jfinal.kit.StrKit; import com.jfinal.plugin.activerecord.Record; import com.taobao.api.ApiException; import java.util.*; public class OrgPerson { /** * 功能:创建部门 * * @param access_token * @throws ApiException */ public static long createDept(String access_token, String deptName, long parentId, long orderId, boolean isRoot) 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); if (isRoot) { req.setOuterDept(true); req.setOuterDeptOnlySelf(true); } 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")); deptList.add(kv); getDeptList(access_token, childDeptId);//递归 } } public static void delAllDept(String access_token) throws ApiException { for (int i = 0; i < deptList.size(); i++) { delDept(access_token, deptList.get(i).getLong("dept_id")); CommonUtil.Print("成功删除部门:"+deptList.get(i).getStr("name")); } } 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, Record rOrg) throws ApiException { String orgName = rOrg.getStr("org_name"); int bureau_id = rOrg.getInt("org_id"); int sort_id = rOrg.getInt("sort_id"); //获取数据库中记录的钉钉端的dept_id,但不一定准确存在,需要继续判断一下 long dingtalk_dept_id = Model.getDtDeptId(bureau_id); JSONObject jRes = getDeptInfo(accessToken, dingtalk_dept_id); if (jRes.getLong("errcode") > 0) { dingtalk_dept_id = createDept(accessToken, orgName, 1, sort_id, true); Model.writeDtDeptId(bureau_id, String.valueOf(dingtalk_dept_id));//记得要回写 CommonUtil.Print("单位名称:" + orgName + "不存在!已创建!"); } else { CommonUtil.Print("单位名称:" + orgName + "已存在,保留!"); //获取下属部门的列表 getDeptList(accessToken, dingtalk_dept_id); } // 云平台->集合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 = Model.getOrgList(bureau_id); 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"); sort_id = 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", sort_id); 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 = Model.getDtDeptId(parentId); long dt_dept_id = createDept(accessToken, org_name, dingTalkParentDeptId, sId, false); Model.writeDtDeptId(org_id, String.valueOf(dt_dept_id)); CommonUtil.Print("成功创建部门:" + org_name); } } //重新获取下属部门的列表,使得后续的代码不再获取部门列表 getDeptList(accessToken, dingtalk_dept_id); } /** * 功能:创建人员 * * @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 updatePerson(String access_token, String person_id, String person_name) throws ApiException { DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/update"); OapiV2UserUpdateRequest req = new OapiV2UserUpdateRequest(); req.setUserid(person_id); req.setName(person_name); OapiV2UserUpdateResponse rsp = client.execute(req, access_token); System.out.println(rsp.getBody()); } public static List personList = new ArrayList(); public static void getDeptPerson(String access_token, long dept_id) throws ApiException { DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listsimple"); long next_cursor = 0; while (true) { OapiUserListsimpleRequest req = new OapiUserListsimpleRequest(); req.setDeptId(dept_id); req.setCursor(next_cursor); req.setSize(10L); req.setOrderField("modify_desc"); req.setContainAccessLimit(false); req.setLanguage("zh_CN"); OapiUserListsimpleResponse rsp = client.execute(req, access_token); JSONObject jo = JSONObject.parseObject(rsp.getBody()); JSONArray ja = jo.getJSONObject("result").getJSONArray("list"); if (ja == null) return; for (int i = 0; i < ja.size(); i++) { JSONObject j = ja.getJSONObject(i); Kv kv = Kv.create(); String userid = j.getString("userid"); String name = j.getString("name"); kv.set("userid", userid); kv.set("name", name); personList.add(kv); } if (jo.getJSONObject("result").getBoolean("has_more")) next_cursor = jo.getJSONObject("result").getLong("next_cursor"); else break; } } public static void getBureauPerson(String access_token, long dept_id) throws ApiException { personList.clear(); getDeptPerson(access_token, dept_id); for (int i = 0; i < deptList.size(); i++) { getDeptPerson(access_token, deptList.get(i).getInt("dept_id")); } } public static void delBureauPerson(String accessToken, Record rOrg) throws ApiException { int dingtalk_dept_id = rOrg.getInt("dingtalk_dept_id"); getBureauPerson(accessToken, dingtalk_dept_id); for (int i = 0; i < personList.size(); i++) { String userid = personList.get(i).getStr("userid"); String person_name = personList.get(i).getStr("name"); delPerson(accessToken, userid); CommonUtil.Print("成功删除:" + person_name); } } /** * 功能:同步人员信息 * * @param accessToken * @param rOrg * @throws ApiException */ public static void syncPerson(String accessToken, Record rOrg) throws ApiException { int bureauId = rOrg.getInt("org_id"); //获取数据库中记录的钉钉端的dept_id,但不一定准确存在,需要继续判断一下 long DT_BureauId = Model.getDtDeptId(bureauId); getBureauPerson(accessToken, DT_BureauId); Set keysOfA = new HashSet<>(); Map mapOfA = new HashMap<>(); Set keysOfB = new HashSet<>(); Map mapOfB = new HashMap<>(); //A:钉钉 for (int i = 0; i < personList.size(); i++) { String userid = personList.get(i).getStr("userid"); String name = personList.get(i).getStr("name"); keysOfA.add(userid); JSONObject jo = new JSONObject(); jo.put("person_id", userid); jo.put("person_name", name); mapOfA.put(userid, jo); } //B:云平台 List list = Model.getDeptPerson(bureauId); for (int i = 0; i < list.size(); i++) { Record r = list.get(i); int person_id = r.getInt("person_id"); String person_name = r.getStr("person_name"); long dingtalk_dept_id = r.getLong("dingtalk_dept_id"); String tel = r.getStr("tel"); if (StrKit.isBlank(tel) || !PhoneUtil.isMobile(tel)) { tel = ChineseMobileNumberGenerator.getInstance().generate();//生成一个随机临时测试用的手机号 tel = "14" + tel.substring(2);//以14段开头,避开已存在的号码 } keysOfB.add(String.valueOf(person_id)); JSONObject jo = new JSONObject(); jo.put("person_id", person_id); jo.put("person_name", person_name); jo.put("dingtalk_dept_id", dingtalk_dept_id); jo.put("tel", tel); mapOfB.put(String.valueOf(person_id), jo); } //在A不在B for (String key : keysOfA) { if (!keysOfB.contains(key)) { // key只存在于A中 // 删除 CommonUtil.Print("发现钉钉中多出的user_id:" + key + ",将删除掉..."); delPerson(accessToken, key); } else { // key在A和B中都存在 String aName = mapOfA.get(key).getString("person_name"); String bName = mapOfB.get(key).getString("person_name"); if (!aName.equals(bName)) { updatePerson(accessToken, key, mapOfB.get(key).getString("person_name")); CommonUtil.Print("发现钉钉与云平台间部门人员姓名不一致,将修改,person_name=" + mapOfB.get(key).getString("person_name")); } else { CommonUtil.Print("钉钉与云平台间部门人员姓名一致,无需修改,person_name=" + mapOfB.get(key).getString("person_name")); } } } //在B不在A for (String key : keysOfB) { if (!keysOfA.contains(key)) { // key只存在于B中 // 增加 String person_id = mapOfB.get(key).getString("person_id"); String person_name = mapOfB.get(key).getString("person_name"); String tel = mapOfB.get(key).getString("tel"); long deptId = mapOfB.get(key).getLong("dingtalk_dept_id"); createPerson(accessToken, String.valueOf(deptId), person_id, person_name, tel, "教师"); CommonUtil.Print("成功加入人员:" + person_name); } } } /** * 功能:获取单个人员信息 * * @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 = Common.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; } }