SynThirdInfoController.java 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. package jnpf.base.controller;
  2. import cn.dev33.satoken.annotation.SaCheckPermission;
  3. import cn.dev33.satoken.annotation.SaMode;
  4. import cn.hutool.core.collection.CollectionUtil;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.baomidou.dynamic.datasource.annotation.DSTransactional;
  7. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  8. import com.baomidou.mybatisplus.core.toolkit.StringUtils;
  9. import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
  10. import com.dingtalk.api.response.OapiV2UserListResponse;
  11. import io.swagger.v3.oas.annotations.Operation;
  12. import io.swagger.v3.oas.annotations.Parameter;
  13. import io.swagger.v3.oas.annotations.Parameters;
  14. import io.swagger.v3.oas.annotations.tags.Tag;
  15. import jakarta.validation.Valid;
  16. import jnpf.base.ActionResult;
  17. import jnpf.base.UserInfo;
  18. import jnpf.base.entity.SuperBaseEntity;
  19. import jnpf.base.entity.SysConfigEntity;
  20. import jnpf.base.model.synThirdInfo.PaginationSynThirdInfo;
  21. import jnpf.base.service.SysconfigService;
  22. import jnpf.base.util.SynDingTalkUtil;
  23. import jnpf.base.util.SynQyWebChatUtil;
  24. import jnpf.base.vo.PaginationVO;
  25. import jnpf.config.ConfigValueUtil;
  26. import jnpf.constant.MsgCode;
  27. import jnpf.exception.DataException;
  28. import jnpf.exception.WxErrorException;
  29. import jnpf.message.entity.SynThirdInfoEntity;
  30. import jnpf.message.model.SynThirdInfoVo;
  31. import jnpf.message.model.message.*;
  32. import jnpf.message.service.MessageService;
  33. import jnpf.message.service.SynThirdDingTalkService;
  34. import jnpf.message.service.SynThirdInfoService;
  35. import jnpf.message.service.SynThirdQyService;
  36. import jnpf.message.util.SynThirdConsts;
  37. import jnpf.message.util.SynThirdTotal;
  38. import jnpf.model.SocialsSysConfig;
  39. import jnpf.permission.entity.OrganizeEntity;
  40. import jnpf.permission.entity.UserEntity;
  41. import jnpf.permission.model.organize.OrganizeModel;
  42. import jnpf.permission.service.OrganizeService;
  43. import jnpf.permission.service.UserService;
  44. import jnpf.util.*;
  45. import jnpf.util.treeutil.SumTree;
  46. import jnpf.util.treeutil.newtreeutil.TreeDotUtils;
  47. import lombok.extern.slf4j.Slf4j;
  48. import org.springframework.beans.factory.annotation.Autowired;
  49. import org.springframework.transaction.annotation.Transactional;
  50. import org.springframework.web.bind.annotation.*;
  51. import java.text.ParseException;
  52. import java.util.ArrayList;
  53. import java.util.List;
  54. import java.util.Map;
  55. import java.util.stream.Collectors;
  56. /**
  57. * 第三方工具的公司-部门-用户同步表模型
  58. *
  59. * @author JNPF开发平台组
  60. * @version V3.1.0
  61. * @copyright 引迈信息技术有限公司
  62. * @date 2021/4/25 9:30
  63. */
  64. @Tag(name = "第三方信息同步", description = "SynThirdInfo")
  65. @RestController
  66. @RequestMapping("/api/system/SynThirdInfo")
  67. @Slf4j
  68. public class SynThirdInfoController extends SuperController<SynThirdInfoService, SynThirdInfoEntity> {
  69. public static final String SOCIALS_CONFIG = "SocialsConfig";
  70. public static final String QYH_DEPARTMENT = "qyhDepartment";
  71. public static final String DING_DEPARTMENT = "dingDepartment";
  72. @Autowired
  73. private SynThirdInfoService synThirdInfoService;
  74. @Autowired
  75. private SynThirdQyService synThirdQyService;
  76. @Autowired
  77. private SynThirdDingTalkService synThirdDingTalkService;
  78. @Autowired
  79. private OrganizeService organizeService;
  80. @Autowired
  81. private UserService userService;
  82. @Autowired
  83. private RedisUtil redisUtil;
  84. @Autowired
  85. private ConfigValueUtil configValueUtil;
  86. @Autowired
  87. private MessageService messageService;
  88. @Autowired
  89. private CacheKeyUtil cacheKeyUtil;
  90. @Autowired
  91. private SysconfigService sysconfigService;
  92. /**
  93. * 新增同步表信息
  94. *
  95. * @param synThirdInfoCrForm 新建模型
  96. * @return ignore
  97. */
  98. @Operation(summary = "新增同步表信息")
  99. @Parameters({
  100. @Parameter(name = "synThirdInfoCrForm", description = "同步信息模型", required = true)
  101. })
  102. @SaCheckPermission("sysConfig.parameter")
  103. @PostMapping
  104. @DSTransactional
  105. public ActionResult create(@RequestBody @Valid SynThirdInfoCrForm synThirdInfoCrForm) throws DataException {
  106. UserInfo userInfo = UserProvider.getUser();
  107. SynThirdInfoEntity entity = JsonUtil.getJsonToBean(synThirdInfoCrForm, SynThirdInfoEntity.class);
  108. entity.setCreatorUserId(userInfo.getUserId());
  109. entity.setCreatorTime(DateUtil.getNowDate());
  110. entity.setId(RandomUtil.uuId());
  111. synThirdInfoService.create(entity);
  112. return ActionResult.success(MsgCode.SU001.get());
  113. }
  114. /**
  115. * 获取同步表信息
  116. *
  117. * @param id 主键
  118. * @return ignore
  119. */
  120. @Operation(summary = "获取同步表信息")
  121. @Parameters({
  122. @Parameter(name = "id", description = "主键", required = true)
  123. })
  124. @SaCheckPermission("sysConfig.parameter")
  125. @GetMapping("/{id}")
  126. public SynThirdInfoEntity getInfo(@PathVariable("id") String id) {
  127. return synThirdInfoService.getInfo(id);
  128. }
  129. /**
  130. * 获取指定类型的同步对象
  131. *
  132. * @param thirdType 1:企业微信 2:钉钉
  133. * @param dataType 1:公司 2:部门 3:用户
  134. * @param id dataType对应的对象ID
  135. * @return ignore
  136. */
  137. @Operation(summary = "获取指定类型的同步对象")
  138. @GetMapping("/getInfoBySysObjId/{thirdType}/{dataType}/{id}")
  139. public SynThirdInfoEntity getInfoBySysObjId(@PathVariable("thirdType") String thirdType, @PathVariable("dataType") String dataType, @PathVariable("id") String id) {
  140. return synThirdInfoService.getInfoBySysObjId(thirdType, dataType, id);
  141. }
  142. /**
  143. * 更新同步表信息
  144. *
  145. * @param id 主键
  146. * @param synThirdInfoUpForm 修改对象
  147. * @return ignore
  148. * @throws DataException ignore
  149. */
  150. @Operation(summary = "更新同步表信息")
  151. @Parameters({
  152. @Parameter(name = "id", description = "主键", required = true),
  153. @Parameter(name = "synThirdInfoUpForm", description = "同步模型", required = true)
  154. })
  155. @SaCheckPermission("sysConfig.parameter")
  156. @PutMapping("/{id}")
  157. @DSTransactional
  158. public ActionResult update(@PathVariable("id") String id, @RequestBody @Valid SynThirdInfoUpForm synThirdInfoUpForm) throws DataException {
  159. SynThirdInfoEntity entity = synThirdInfoService.getInfo(id);
  160. UserInfo userInfo = UserProvider.getUser();
  161. if (entity != null) {
  162. SynThirdInfoEntity entityUpd = JsonUtil.getJsonToBean(synThirdInfoUpForm, SynThirdInfoEntity.class);
  163. entityUpd.setCreatorUserId(entity.getCreatorUserId());
  164. entityUpd.setCreatorTime(entity.getCreatorTime());
  165. entityUpd.setLastModifyUserId(userInfo.getUserId());
  166. entityUpd.setLastModifyTime(DateUtil.getNowDate());
  167. synThirdInfoService.update(id, entityUpd);
  168. return ActionResult.success(MsgCode.SU004.get());
  169. } else {
  170. return ActionResult.fail(MsgCode.FA002.get());
  171. }
  172. }
  173. /**
  174. * 删除同步表信息
  175. *
  176. * @param id 主键
  177. * @return ignore
  178. */
  179. @Operation(summary = "删除同步表信息")
  180. @Parameters({
  181. @Parameter(name = "id", description = "主键", required = true)
  182. })
  183. @SaCheckPermission("sysConfig.parameter")
  184. @DeleteMapping("/{id}")
  185. @DSTransactional
  186. public ActionResult delete(@PathVariable("id") String id) {
  187. SynThirdInfoEntity entity = synThirdInfoService.getInfo(id);
  188. if (entity != null) {
  189. synThirdInfoService.delete(entity);
  190. }
  191. return ActionResult.success(MsgCode.SU003.get());
  192. }
  193. /**
  194. * 获取第三方(如:企业微信、钉钉)的组织与用户同步统计信息
  195. *
  196. * @param thirdType 第三方类型(1:企业微信;2:钉钉)
  197. * @return ignore
  198. */
  199. @Operation(summary = "获取第三方(如:企业微信、钉钉)的组织与用户同步统计信息")
  200. @Parameters({
  201. @Parameter(name = "thirdType", description = "第三方类型(1:企业微信;2:钉钉)", required = true)
  202. })
  203. @SaCheckPermission("sysConfig.parameter")
  204. @GetMapping("/getSynThirdTotal/{thirdType}")
  205. public ActionResult<List<SynThirdTotal>> getSynThirdTotal(@PathVariable("thirdType") String thirdType) {
  206. List<SynThirdTotal> synTotalList = new ArrayList<>();
  207. synTotalList.add(synThirdInfoService.getSynTotal(thirdType, SynThirdConsts.DATA_TYPE_ORG));
  208. synTotalList.add(synThirdInfoService.getSynTotal(thirdType, SynThirdConsts.DATA_TYPE_USER));
  209. return ActionResult.success(synTotalList);
  210. }
  211. /**
  212. * 获取第三方(如:企业微信、钉钉)的组织或用户同步统计信息
  213. *
  214. * @param thirdType 第三方类型(1:企业微信;2:钉钉)
  215. * @param dataType 数据类型(1:组织(公司与部门);2:用户)
  216. * @return ignore
  217. */
  218. @Operation(summary = "获取第三方(如:企业微信、钉钉)的组织或用户同步统计信息")
  219. @Parameters({
  220. @Parameter(name = "thirdType", description = "第三方类型(1:企业微信;2:钉钉)", required = true),
  221. @Parameter(name = "dataType", description = "数据类型(1:组织(公司与部门);2:用户)", required = true)
  222. })
  223. @SaCheckPermission("sysConfig.parameter")
  224. @GetMapping("/getSynThirdTotal/{thirdType}/{dataType}")
  225. public SynThirdTotal getSynThirdTotal(@PathVariable("thirdType") String thirdType, @PathVariable("dataType") String dataType) {
  226. return synThirdInfoService.getSynTotal(thirdType, dataType);
  227. }
  228. //==================================企业微信的公司-部门-用户批量同步到本系统20220609==================================
  229. /**
  230. * 本地所有组织信息(包含公司和部门)同步到企业微信
  231. * 不带第三方错误定位判断的功能代码,只获取调用接口的返回信息 20210604
  232. * 应用密钥
  233. * @return ignore
  234. * @throws WxErrorException ignore
  235. */
  236. @Operation(summary = "本地所有组织信息(包含公司和部门)同步到企业微信")
  237. @Parameters({
  238. @Parameter(name = "type", description = "类型", required = true)
  239. })
  240. @SaCheckPermission("sysConfig.parameter")
  241. @GetMapping("/synAllOrganizeSysToQy")
  242. public ActionResult synAllOrganizeSysToQy(@RequestParam("type") String type
  243. , @RequestParam("departmentId") String departmentId) throws WxErrorException {
  244. if (StringUtils.isEmpty(departmentId)) {
  245. return ActionResult.fail(MsgCode.FA057.get());
  246. }
  247. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  248. String qyhDepartment = config.getQyhDepartment();
  249. Boolean isDepartChange = saveConfig(departmentId, qyhDepartment, QYH_DEPARTMENT);
  250. if (isDepartChange){
  251. qyhDepartment=departmentId;
  252. }
  253. if ("1".equals(type)) {
  254. //类型为1走企业微信组织信息同步到本地
  255. return this.synAllOrganizeQyToSys(qyhDepartment);
  256. }
  257. JSONObject retMsg = new JSONObject();
  258. String corpId = config.getQyhCorpId();
  259. // 向企业微信插入数据需要另外token(凭证密钥)
  260. String corpSecret = config.getQyhAgentSecret();
  261. if (StringUtil.isEmpty(qyhDepartment)) {
  262. return ActionResult.fail("同步组织配置未保存");
  263. }
  264. String access_token = "";
  265. try {
  266. // 获取Token值
  267. JSONObject tokenObject = SynQyWebChatUtil.getAccessToken(corpId, corpSecret);
  268. if (!tokenObject.getBoolean("code")) {
  269. return ActionResult.fail(MsgCode.SYS025.get());
  270. }
  271. access_token = tokenObject.getString("access_token");
  272. // 获取同步表、部门表的信息
  273. List<SynThirdInfoEntity> synThirdInfoList = synThirdInfoService.getList(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_ORG);
  274. List<OrganizeEntity> organizeEntitiesBind = synThirdInfoService.getOrganizeEntitiesBind(qyhDepartment);
  275. List<String> collect = organizeEntitiesBind.stream()
  276. .map(SuperBaseEntity.SuperIBaseEntity::getId)
  277. .distinct()
  278. .collect(Collectors.toList());
  279. List<SynThirdInfoEntity> collected = synThirdInfoList.stream()
  280. .filter(t -> !collect.contains(t.getSysObjId()))
  281. .collect(Collectors.toList());
  282. synThirdInfoList.removeAll(collected);
  283. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  284. for (OrganizeEntity organizeEntity : organizeEntitiesBind) {
  285. if (synThirdInfoList.stream().anyMatch(t -> t.getSysObjId().equals(organizeEntity.getId()))) {
  286. // 执行更新功能,token取应用密钥
  287. retMsg = synThirdQyService.updateDepartmentSysToQy(true, organizeEntity, access_token);
  288. } else {
  289. // 执行创建功能,token取应用密钥
  290. retMsg = synThirdQyService.createDepartmentSysToQy(true, organizeEntity, access_token);
  291. }
  292. }
  293. } catch (Exception e) {
  294. ActionResult.fail(e.toString());
  295. }
  296. //获取结果
  297. SynThirdTotal synThirdTotal = synThirdInfoService.getSynTotal(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_ORG);
  298. return ActionResult.success(synThirdTotal);
  299. }
  300. /**
  301. * 本地所有用户信息同步到企业微信
  302. * 不带第三方错误定位判断的功能代码,只获取调用接口的返回信息 20210604
  303. *
  304. * @return ignore
  305. * @throws WxErrorException ignore
  306. */
  307. @Operation(summary = "本地所有用户信息同步到企业微信")
  308. @Parameters({
  309. @Parameter(name = "type", description = "类型", required = true)
  310. })
  311. @SaCheckPermission("sysConfig.parameter")
  312. @GetMapping("/synAllUserSysToQy")
  313. public ActionResult synAllUserSysToQy(@RequestParam("type") String type) throws WxErrorException {
  314. if ("1".equals(type)) {
  315. //类型为1走企业微信用户同步到本地
  316. return this.synAllUserQyToSys();
  317. }
  318. JSONObject retMsg = new JSONObject();
  319. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  320. String corpToken = "";
  321. try {
  322. String corpId = config.getQyhCorpId();
  323. // 向企业微信插入数据需要另外token(凭证密钥)
  324. String corpSecret = config.getQyhCorpSecret();
  325. // 获取Token值
  326. JSONObject tokenObject = SynQyWebChatUtil.getAccessToken(corpId, corpSecret);
  327. if (!tokenObject.getBoolean("code")) {
  328. return ActionResult.fail(MsgCode.SYS025.get());
  329. }
  330. corpToken = tokenObject.getString("access_token");
  331. // 获取同步表、用户表的信息
  332. List<SynThirdInfoEntity> synThirdInfoList = synThirdInfoService
  333. .getList(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_USER);
  334. List<OrganizeEntity> organizeEntitiesBind = synThirdInfoService
  335. .getOrganizeEntitiesBind(config.getQyhDepartment());
  336. List<UserEntity> userEntities = userService.getListBySyn(organizeEntitiesBind.stream()
  337. .map(SuperBaseEntity.SuperIBaseEntity::getId).collect(Collectors.toList()), "");
  338. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  339. String needToken=this.getAgentAccessToken();
  340. for (UserEntity userEntity : userEntities) {
  341. if (synThirdInfoList.stream().noneMatch(t -> t.getSysObjId().equals(userEntity.getId()))) {
  342. // 执行创建功能
  343. retMsg = synThirdQyService.createUserSysToQy(true, userEntity, needToken);
  344. } else {
  345. // 执行更新功能
  346. retMsg = synThirdQyService.updateUserSysToQy(true, userEntity, needToken,corpToken);
  347. }
  348. }
  349. } catch (Exception e) {
  350. ActionResult.fail(e.toString());
  351. }
  352. //获取结果
  353. SynThirdTotal synThirdTotal = synThirdInfoService.getSynTotal(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_USER);
  354. return ActionResult.success(synThirdTotal);
  355. }
  356. private String getAgentAccessToken() {
  357. SocialsSysConfig socialsConfig = sysconfigService.getSocialsConfig();
  358. String corpId = socialsConfig.getQyhCorpId();
  359. String corpSecret = socialsConfig.getQyhAgentSecret();
  360. JSONObject tokenObject = SynQyWebChatUtil.getAccessToken(corpId, corpSecret);
  361. return tokenObject.getString("access_token");
  362. }
  363. //==================================企业微信的公司-部门-用户批量同步到本系统20220609==================================
  364. /**
  365. * 企业微信所有组织信息(包含公司和部门)同步到本系统
  366. * 通讯录密钥
  367. * @return ignore
  368. */
  369. @Operation(summary = "企业微信所有组织信息(包含公司和部门)同步到本系统")
  370. @SaCheckPermission("sysConfig.parameter")
  371. @GetMapping("/synAllOrganizeQyToSys")
  372. public ActionResult synAllOrganizeQyToSys(@RequestParam(value = "departmentId") String departmentId) {
  373. // 设置redis的key
  374. String synDing = "";
  375. UserInfo userInfo = UserProvider.getUser();
  376. if (configValueUtil.isMultiTenancy()) {
  377. synDing = userInfo.getTenantId() + "_" + userInfo.getUserId() + "_synAllOrganizeQyToSys";
  378. } else {
  379. synDing = userInfo.getUserId() + "_synAllOrganizeQyToSys";
  380. }
  381. // 如果redis中存在key说明同步正在进行
  382. if (redisUtil.exists(synDing)) {
  383. return ActionResult.fail(MsgCode.SYS026.get());
  384. }
  385. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  386. if (StringUtil.isEmpty(departmentId)) {
  387. return ActionResult.fail("同步组织配置未保存");
  388. }
  389. OrganizeEntity info = organizeService.getInfo(departmentId);
  390. if (info == null) {
  391. return ActionResult.fail("同步组织数据不存在");
  392. }
  393. // 获取Token值
  394. JSONObject tokenObject = SynQyWebChatUtil.getAccessToken(config.getQyhCorpId(), config.getQyhCorpSecret());
  395. if (!tokenObject.getBoolean("code")) {
  396. return ActionResult.fail(MsgCode.SYS025.get());
  397. }
  398. // 异步执行
  399. String finalSynDing = synDing;
  400. ThreadPoolExecutorUtil.getExecutor().execute(() -> {
  401. String userId = userInfo.getUserId();
  402. try {
  403. redisUtil.insert(finalSynDing, "true");
  404. String access_token = tokenObject.getString("access_token");
  405. List<QyWebChatDeptModel> QyDeptAllList = new ArrayList<>();
  406. // 获取同步表的信息
  407. List<SynThirdInfoEntity> synThirdInfoList = synThirdInfoService
  408. .getListByDepartment(SynThirdConsts.THIRD_TYPE_QY
  409. , SynThirdConsts.DATA_TYPE_ORG
  410. , config.getQyhDepartment());
  411. // 获取企业微信上的根目录部门(本系统的组织)
  412. String departId = SynThirdConsts.QY_ROOT_DEPT_ID;
  413. // 获取企业微信上的部门列表,需要通讯录密钥
  414. JSONObject retMsg = SynQyWebChatUtil.getDepartmentList(departId, access_token);
  415. QyDeptAllList = JsonUtil.getJsonToList(retMsg.get("department").toString(), QyWebChatDeptModel.class);
  416. Map<String, QyWebChatDeptModel> deptModelMap = QyDeptAllList.stream().collect(Collectors.toMap(t -> String.valueOf(t.getId()), dept -> dept));
  417. // 部门进行树结构化,固化上下层级序列化
  418. List<OrganizeModel> organizeModelList = QyDeptAllList.stream().map(t -> {
  419. OrganizeModel model = JsonUtil.getJsonToBean(t, OrganizeModel.class);
  420. model.setFullName(t.getName());
  421. model.setParentId(t.getParentid() + "");
  422. return model;
  423. }).collect(Collectors.toList());
  424. List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDot(organizeModelList);
  425. List<OrganizeListVO> listVO = JsonUtil.getJsonToList(trees, OrganizeListVO.class);
  426. // 转化成为按上下层级顺序排序的列表数据
  427. List<QyWebChatDeptModel> listByOrder = new ArrayList<>();
  428. for (OrganizeListVO organizeVo : listVO) {
  429. QyWebChatDeptModel entity = deptModelMap.get(organizeVo.getId());
  430. listByOrder.add(entity);
  431. SynQyWebChatUtil.getOrganizeTreeToList(organizeVo, deptModelMap, listByOrder);
  432. }
  433. List<OrganizeEntity> organizeEntitiesBind = synThirdInfoService.getOrganizeEntitiesBind(departmentId);
  434. List<String> collect = organizeEntitiesBind.stream()
  435. .map(SuperBaseEntity.SuperIBaseEntity::getId)
  436. .distinct()
  437. .collect(Collectors.toList());
  438. List<SynThirdInfoEntity> list = synThirdInfoService.getList(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_ORG);
  439. List<SynThirdInfoEntity> synThirdInfoEntities = list.stream()
  440. .filter(t -> !collect.contains(t.getSysObjId()))
  441. .distinct()
  442. .collect(Collectors.toList());
  443. //如果不存在在最高组织下,就删除
  444. if (CollectionUtil.isNotEmpty(synThirdInfoEntities)) {
  445. synThirdInfoService.removeBatchByIds(synThirdInfoEntities);
  446. }
  447. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  448. for (QyWebChatDeptModel qyWebChatDeptModel : listByOrder) {
  449. if (synThirdInfoList.stream().anyMatch(t -> t.getThirdObjId().equals(String.valueOf(qyWebChatDeptModel.getId())))) {
  450. // 执行本地更新功能
  451. synThirdQyService.updateDepartmentQyToSys(true, qyWebChatDeptModel, access_token);
  452. } else {
  453. // 执行本的创建功能
  454. synThirdQyService.createDepartmentQyToSys(true, qyWebChatDeptModel, access_token);
  455. }
  456. }
  457. } catch (Exception e) {
  458. log.error(finalSynDing + ",企业微信所有组织信息同步到本系统失败:" + e.getMessage());
  459. } finally {
  460. redisUtil.remove(finalSynDing);
  461. redisUtil.remove(cacheKeyUtil.getOrganizeList());
  462. List<String> toUserId = new ArrayList<>(1);
  463. toUserId.add(userId);
  464. messageService.sentMessage(toUserId, "企业微信所有组织信息同步到本系统", null, userInfo, 3, 1);
  465. redisUtil.remove(cacheKeyUtil.getOrganizeInfoList());
  466. }
  467. });
  468. return ActionResult.success(MsgCode.SYS026.get());
  469. }
  470. /**
  471. * 企业微信所有用户信息同步到本系统
  472. *
  473. * @return ignore
  474. */
  475. @Operation(summary = "企业微信所有用户信息同步到本系统")
  476. @SaCheckPermission("sysConfig.parameter")
  477. @GetMapping("/synAllUserQyToSys")
  478. @Transactional
  479. public ActionResult synAllUserQyToSys() {
  480. SocialsSysConfig socialsConfig = sysconfigService.getSocialsConfig();
  481. String qyhDepartment = socialsConfig.getQyhDepartment();
  482. // 设置redis的key
  483. String synDing = "";
  484. UserInfo userInfo = UserProvider.getUser();
  485. if (configValueUtil.isMultiTenancy()) {
  486. synDing = userInfo.getTenantId() + "_" + userInfo.getUserId() + "_synAllUserQyToSys";
  487. } else {
  488. synDing = userInfo.getUserId() + "_synAllUserQyToSys";
  489. }
  490. // 如果redis中存在key说明同步正在进行
  491. if (redisUtil.exists(synDing)) {
  492. return ActionResult.fail(MsgCode.SYS026.get());
  493. }
  494. // 获取已同步的部门信息
  495. List<SynThirdInfoEntity> synThirdOrgList = synThirdInfoService.getListByDepartment(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_ORG,qyhDepartment);
  496. List<String> dingDeptIdList = new ArrayList<>();
  497. if (CollectionUtil.isNotEmpty(synThirdOrgList)) {
  498. dingDeptIdList = synThirdOrgList
  499. .stream()
  500. .map(SynThirdInfoEntity::getThirdObjId)
  501. .filter(StringUtils::isNotBlank)
  502. .distinct().collect(Collectors.toList());
  503. } else {
  504. return ActionResult.fail(MsgCode.SYS027.get());
  505. }
  506. // 获取Token值
  507. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  508. JSONObject tokenObject = SynQyWebChatUtil.getAccessToken(config.getQyhCorpId(), config.getQyhCorpSecret());
  509. if (!tokenObject.getBoolean("code")) {
  510. return ActionResult.fail(MsgCode.SYS025.get());
  511. }
  512. // 异步执行
  513. String finalSynDing = synDing;
  514. ThreadPoolExecutorUtil.getExecutor().execute(() -> {
  515. String userId = userInfo.getUserId();
  516. try {
  517. redisUtil.insert(finalSynDing, "true");
  518. List<OapiV2UserListResponse.ListUserResponse> dingUserList = new ArrayList<>();
  519. List<QyWebChatUserModel> qyUserAllList = new ArrayList<>();
  520. String access_token = tokenObject.getString("access_token");
  521. // 获取企业微信的用户列表
  522. JSONObject retMsg = SynQyWebChatUtil.getUserList("1", "1", access_token);
  523. qyUserAllList = JsonUtil.getJsonToList(retMsg.get("userlist"), QyWebChatUserModel.class);
  524. // 得到企业微信信息
  525. List<SynThirdInfoEntity> synThirdInfoEntityList = synThirdInfoService
  526. .syncThirdInfoByType(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_USER, SynThirdConsts.THIRD_TYPE_QY);
  527. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  528. for (QyWebChatUserModel qyWebChatUserModel : qyUserAllList) {
  529. if (synThirdInfoEntityList.stream().noneMatch(t -> t.getThirdObjId().equals(qyWebChatUserModel.getUserid()))) {
  530. // 执行创建功能
  531. synThirdQyService.createUserQyToSys(true, qyWebChatUserModel, access_token);
  532. } else {
  533. // 执行更新功能
  534. synThirdQyService.updateUserQyToSystem(true, qyWebChatUserModel, access_token);
  535. }
  536. }
  537. } catch (Exception e) {
  538. e.printStackTrace();
  539. log.error("{},企业微信所有用户信息同步到本系统失败:{}", finalSynDing, e.getMessage());
  540. } finally {
  541. redisUtil.remove(finalSynDing);
  542. List<String> toUserId = new ArrayList<>(1);
  543. toUserId.add(userId);
  544. messageService.sentMessage(toUserId, "企业微信所有用户信息同步到本系统", null, userInfo, 3, 1);
  545. }
  546. });
  547. return ActionResult.success(MsgCode.SYS026.get());
  548. }
  549. @Operation(summary = "同步成功或失败数")
  550. @SaCheckPermission("sysConfig.parameter")
  551. @GetMapping("/getHandleNum")
  552. public ActionResult getHandleNum(PaginationSynThirdInfo pagination) {
  553. List<SynThirdInfoVo> synThirdInfoList = synThirdInfoService
  554. .getListJoin(pagination);
  555. synThirdInfoList=synThirdInfoList.stream()
  556. .filter(t->t.getLastModifyTime()!=null)
  557. .collect(Collectors.toList());
  558. PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
  559. return ActionResult.page(synThirdInfoList, paginationVO);
  560. }
  561. //==================================本系统的公司-部门-用户批量同步到钉钉==================================
  562. /**
  563. * 本地所有组织信息(包含公司和部门)同步到钉钉
  564. * 不带第三方错误定位判断的功能代码 20210604
  565. *
  566. * @return ignore
  567. */
  568. @Operation(summary = "本地所有组织信息(包含公司和部门)同步到钉钉")
  569. @Parameters({
  570. @Parameter(name = "type", description = "类型", required = true)
  571. })
  572. @SaCheckPermission("sysConfig.parameter")
  573. @GetMapping("/synAllOrganizeSysToDing")
  574. public ActionResult synAllOrganizeSysToDing(@RequestParam("type") String type
  575. ,@RequestParam("departmentId") String departmentId) {
  576. if (StringUtils.isEmpty(departmentId)) {
  577. return ActionResult.fail(MsgCode.FA057.get());
  578. }
  579. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  580. String dingDepartment = config.getDingDepartment();
  581. Boolean isDepartChange = saveConfig(departmentId, dingDepartment, DING_DEPARTMENT);
  582. if (isDepartChange){
  583. dingDepartment=departmentId;
  584. }
  585. if ("1".equals(type)) {
  586. //类型为1走钉钉组织部门信息同步到本地
  587. return this.synAllOrganizeDingToSys(dingDepartment);
  588. }
  589. JSONObject retMsg = new JSONObject();
  590. //获取配置
  591. String corpId = config.getDingSynAppKey();
  592. String corpSecret = config.getDingSynAppSecret();
  593. if (StringUtil.isEmpty(dingDepartment)) {
  594. return ActionResult.fail("同步组织配置未保存");
  595. }
  596. // 获取Token值
  597. JSONObject tokenObject = SynDingTalkUtil.getAccessToken(corpId, corpSecret);
  598. if (!tokenObject.getBoolean("code")) {
  599. return ActionResult.fail(MsgCode.SYS053.get());
  600. }
  601. String access_token = tokenObject.getString("access_token");
  602. //获取绑定部门的下级有序组织
  603. List<OrganizeEntity> listByOrder = synThirdInfoService.getOrganizeEntitiesBind(dingDepartment);
  604. try {
  605. List<SynThirdInfoEntity> synThirdInfoList = synThirdInfoService.getList(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_ORG);
  606. List<String> collect = listByOrder.stream()
  607. .map(SuperBaseEntity.SuperIBaseEntity::getId)
  608. .distinct()
  609. .collect(Collectors.toList());
  610. //筛选同步表有,但是公司表没有的数据
  611. List<SynThirdInfoEntity> collected = synThirdInfoList.stream()
  612. .filter(t -> !collect.contains(t.getSysObjId()))
  613. .collect(Collectors.toList());
  614. if (CollectionUtil.isNotEmpty(collected)) {
  615. for (SynThirdInfoEntity synThirdInfoEntity : collected) {
  616. //如果系统中组织不存在同步表,那将钉钉上的数据也删除
  617. retMsg = synThirdDingTalkService.deleteDepartmentSysToDing(true, synThirdInfoEntity.getId(), access_token);
  618. }
  619. }
  620. synThirdInfoList.removeAll(collected);
  621. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  622. for (OrganizeEntity organizeEntity : listByOrder) {
  623. if (synThirdInfoList.stream().anyMatch(t -> t.getSysObjId().equals(organizeEntity.getId()))) {
  624. // 执行更新功能
  625. retMsg = synThirdDingTalkService.updateDepartmentSysToDing(true, organizeEntity, access_token);
  626. } else {
  627. // 执行创建功能
  628. retMsg = synThirdDingTalkService.createDepartmentSysToDing(true, organizeEntity, access_token);
  629. }
  630. }
  631. } catch (Exception e) {
  632. ActionResult.fail(e.toString());
  633. }
  634. //获取结果
  635. SynThirdTotal synThirdTotal = synThirdInfoService.getSynTotal(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_ORG);
  636. return ActionResult.success(synThirdTotal);
  637. }
  638. private Boolean saveConfig(String departmentId, String dingDepartment, String department) {
  639. if (StringUtil.isNotEmpty(departmentId) && !departmentId.equals(dingDepartment)) {
  640. LambdaQueryWrapper<SysConfigEntity> wrapper = new LambdaQueryWrapper<>();
  641. wrapper.eq(SysConfigEntity::getCategory, SOCIALS_CONFIG);
  642. wrapper.eq(SysConfigEntity::getFkey, department);
  643. List<SysConfigEntity> list = sysconfigService.list(wrapper);
  644. SysConfigEntity configEntity = list.get(0);
  645. configEntity.setValue(departmentId);
  646. sysconfigService.updateById(configEntity);
  647. String cacheKey = cacheKeyUtil.getSocialsConfig();
  648. redisUtil.remove(cacheKey);
  649. return true;
  650. }
  651. return false;
  652. }
  653. /**
  654. * 本地所有用户信息同步到钉钉
  655. * 不带第三方错误定位判断的功能代码 20210604
  656. *
  657. * @return ignore
  658. */
  659. @Operation(summary = "本地所有用户信息同步到钉钉")
  660. @Parameters({
  661. @Parameter(name = "type", description = "类型", required = true)
  662. })
  663. @SaCheckPermission("sysConfig.parameter")
  664. @GetMapping("/synAllUserSysToDing")
  665. public ActionResult synAllUserSysToDing(@RequestParam("type") String type) throws ParseException {
  666. if ("1".equals(type)) {
  667. //类型为1走钉钉用户信息同步到本地
  668. return this.synAllUserDingToSys();
  669. }
  670. JSONObject retMsg = new JSONObject();
  671. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  672. String corpId = config.getDingSynAppKey();
  673. String corpSecret = config.getDingSynAppSecret();
  674. String dingDepartment = config.getDingDepartment();
  675. try {
  676. // 获取Token值
  677. JSONObject tokenObject = SynDingTalkUtil.getAccessToken(corpId, corpSecret);
  678. if (!tokenObject.getBoolean("code")) {
  679. return ActionResult.success(MsgCode.SYS053.get());
  680. }
  681. String access_token = tokenObject.getString("access_token");
  682. // 获取同步表、用户表的信息
  683. List<SynThirdInfoEntity> synThirdInfoList = synThirdInfoService.getList(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_USER);
  684. List<OrganizeEntity> organizeEntitiesBind = synThirdInfoService.getOrganizeEntitiesBind(dingDepartment);
  685. List<UserEntity> userEntities = userService.getList(organizeEntitiesBind.stream()
  686. .map(SuperBaseEntity.SuperIBaseEntity::getId).collect(Collectors.toList()), "");
  687. // 根据同步表、公司表进行比较,判断不存的执行删除
  688. for (SynThirdInfoEntity synThirdInfoEntity : synThirdInfoList) {
  689. if (userEntities.stream().noneMatch(t -> t.getId().equals(synThirdInfoEntity.getSysObjId()))) {
  690. // 执行删除操作
  691. retMsg = synThirdDingTalkService.deleteUserSysToDing(true, synThirdInfoEntity.getSysObjId(), access_token);
  692. }
  693. }
  694. // ||synThirdInfoList.stream()
  695. // .filter(t->t.getSysObjId().equals(userEntity.getId()))
  696. // .collect(Collectors.toList())
  697. // .get(0).getDescription().contains("40103")
  698. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  699. for (UserEntity userEntity : userEntities) {
  700. if (synThirdInfoList.stream()
  701. .noneMatch(t -> t.getSysObjId().equals(userEntity.getId()))
  702. ) {
  703. // 执行创建功能
  704. retMsg = synThirdDingTalkService.createUserSysToDing(true, userEntity, access_token);
  705. } else {
  706. // 执行更新功能
  707. retMsg = synThirdDingTalkService.updateUserSysToDing(true, userEntity, access_token);
  708. }
  709. }
  710. } catch (Exception e) {
  711. ActionResult.fail(e.toString());
  712. }
  713. //获取结果
  714. SynThirdTotal synThirdTotal = synThirdInfoService.getSynTotal(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_USER);
  715. return ActionResult.success(synThirdTotal);
  716. }
  717. //==================================钉钉的公司-部门-用户批量同步到本系统20220330==================================
  718. /**
  719. * 钉钉所有组织信息(包含公司和部门)同步到本系统
  720. * 不带第三方错误定位判断的功能代码 20220330
  721. *
  722. * @return ignore
  723. */
  724. @Operation(summary = "钉钉所有组织信息(包含公司和部门)同步到本系统")
  725. @SaCheckPermission("sysConfig.parameter")
  726. @GetMapping("/synAllOrganizeDingToSys")
  727. public ActionResult synAllOrganizeDingToSys(@RequestParam("departmentId") String departmentId) {
  728. // 设置redis的key
  729. String synDing = "";
  730. UserInfo userInfo = UserProvider.getUser();
  731. if (configValueUtil.isMultiTenancy()) {
  732. synDing = userInfo.getTenantId() + "_" + userInfo.getUserId() + "_synAllOrganizeDingToSys";
  733. } else {
  734. synDing = userInfo.getUserId() + "_synAllOrganizeDingToSys";
  735. }
  736. // 如果redis中存在key说明同步正在进行
  737. if (redisUtil.exists(synDing)) {
  738. return ActionResult.fail(MsgCode.SYS026.get());
  739. }
  740. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  741. if (StringUtil.isEmpty(departmentId)) {
  742. return ActionResult.fail("同步组织配置未保存");
  743. }
  744. OrganizeEntity info = organizeService.getInfo(departmentId);
  745. if (info == null) {
  746. return ActionResult.fail("同步组织数据不存在");
  747. }
  748. // 获取Token值
  749. JSONObject tokenObject = SynDingTalkUtil.getAccessToken(config.getDingSynAppKey(), config.getDingSynAppSecret());
  750. if (!tokenObject.getBoolean("code")) {
  751. return ActionResult.fail(MsgCode.SYS053.get());
  752. }
  753. // 异步执行
  754. String finalSynDing = synDing;
  755. ThreadPoolExecutorUtil.getExecutor().execute(() -> {
  756. String userId = userInfo.getUserId();
  757. String messText = "同步完成";
  758. try {
  759. redisUtil.insert(finalSynDing, "true");
  760. List<OapiV2DepartmentListsubResponse.DeptBaseResponse> DingDeptList = new ArrayList<>();
  761. String access_token = tokenObject.getString("access_token");
  762. // 获取钉钉上的部门列表
  763. JSONObject retMsg = SynDingTalkUtil.getDepartmentList(SynThirdConsts.DING_ROOT_DEPT_ID, access_token);
  764. if (!retMsg.getBoolean("code")) {
  765. throw new DataException(retMsg.getString("msg"));
  766. }
  767. DingDeptList = (List<OapiV2DepartmentListsubResponse.DeptBaseResponse>) retMsg.get("department");
  768. List<DingTalkDeptModel> dingDeptListVo = JsonUtil.getJsonToList(DingDeptList, DingTalkDeptModel.class);
  769. List<DingTalkDeptModel> DingDeptAllList = new ArrayList<>(dingDeptListVo);
  770. Map<String, DingTalkDeptModel> deptModelMap = DingDeptAllList.stream().collect(Collectors.toMap(t -> String.valueOf(t.getDeptId()), dept -> dept));
  771. // 部门进行树结构化,固化上下层级序列化
  772. List<OrganizeModel> organizeModelList = DingDeptAllList.stream().map(t -> {
  773. OrganizeModel model = JsonUtil.getJsonToBean(t, OrganizeModel.class);
  774. model.setFullName(t.getName());
  775. model.setCategory(t.getSourceIdentifier());
  776. model.setParentId(t.getParentId() + "");
  777. model.setDeptId(t.getDeptId() + "");
  778. model.setId(t.getDeptId() + "");
  779. model.setParentId(t.getParentId() + "");
  780. return model;
  781. }).collect(Collectors.toList());
  782. List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDot(organizeModelList);
  783. List<OrganizeListVO> listVO = JsonUtil.getJsonToList(trees, OrganizeListVO.class);
  784. // 转化成为按上下层级顺序排序的列表数据
  785. List<DingTalkDeptModel> listByOrder = new ArrayList<>();
  786. for (OrganizeListVO organizeVo : listVO) {
  787. DingTalkDeptModel entity = deptModelMap.get(organizeVo.getId());
  788. listByOrder.add(entity);
  789. SynDingTalkUtil.getOrganizeTreeToList(organizeVo, deptModelMap, listByOrder);
  790. }
  791. // 钉钉没有最高级得先插入一条最高级
  792. synThirdInfoService.initBaseDept(SynThirdConsts.DING_ROOT_DEPT_ID, access_token, SynThirdConsts.THIRD_TYPE_DING);
  793. // 获取同步表的信息
  794. List<SynThirdInfoEntity> synThirdInfoList = synThirdInfoService.getListByDepartment(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_ORG,departmentId);
  795. // List<SynThirdInfoEntity> synThirdInfoListAll = synThirdInfoService.getList(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_ORG);
  796. // // 根据同步表、公司表进行比较,判断不存的执行删除
  797. // synThirdInfoListAll.removeAll(synThirdInfoList);
  798. // for (SynThirdInfoEntity synThirdInfoEntity : synThirdInfoListAll) {
  799. // synThirdInfoService.delete(synThirdInfoEntity);
  800. // }
  801. // // 删除后需要重新获取数据
  802. // synThirdInfoList = synThirdInfoService.getList(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_ORG);
  803. List<String> sysDeptIds = synThirdInfoList.stream().map(SynThirdInfoEntity::getThirdObjId).collect(Collectors.toList());
  804. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  805. for (DingTalkDeptModel dingDeptEntity : listByOrder) {
  806. if (sysDeptIds.contains(String.valueOf(dingDeptEntity.getDeptId()))) {
  807. // 执行本地更新功能
  808. synThirdDingTalkService.updateDepartmentDingToSys(true, dingDeptEntity, access_token);
  809. } else {
  810. // 执行本的创建功能
  811. synThirdDingTalkService.createDepartmentDingToSys(true, dingDeptEntity, access_token);
  812. }
  813. }
  814. } catch (Exception e) {
  815. messText = e.getMessage();
  816. log.error("{},钉钉所有组织信息同步到本系统失败:{}", finalSynDing, e.getMessage());
  817. } finally {
  818. redisUtil.remove(finalSynDing);
  819. redisUtil.remove(cacheKeyUtil.getOrganizeList());
  820. List<String> toUserId = new ArrayList<>(1);
  821. toUserId.add(userId);
  822. messageService.sentMessage(toUserId, "钉钉所有组织信息同步到本系统", null, userInfo, 3, 1);
  823. }
  824. });
  825. return ActionResult.success(MsgCode.SYS026.get());
  826. }
  827. /**
  828. * 钉钉所有用户信息同步到本系统
  829. * 不带第三方错误定位判断的功能代码 20210604
  830. *
  831. * @return ignore
  832. */
  833. @Operation(summary = "钉钉所有用户信息同步到本系统")
  834. @SaCheckPermission("sysConfig.parameter")
  835. @GetMapping("/synAllUserDingToSys")
  836. @Transactional
  837. public ActionResult synAllUserDingToSys() {
  838. SocialsSysConfig socialsConfig = sysconfigService.getSocialsConfig();
  839. String dingDepartment = socialsConfig.getDingDepartment();
  840. // 设置redis的key
  841. String synDing = "";
  842. UserInfo userInfo = UserProvider.getUser();
  843. if (configValueUtil.isMultiTenancy()) {
  844. synDing = userInfo.getTenantId() + "_" + userInfo.getUserId() + "_synAllUserDingToSys";
  845. } else {
  846. synDing = userInfo.getUserId() + "_synAllUserDingToSys";
  847. }
  848. // 如果redis中存在key说明同步正在进行
  849. if (redisUtil.exists(synDing)) {
  850. return ActionResult.fail(MsgCode.SYS026.get());
  851. }
  852. // 获取已同步的部门信息
  853. List<SynThirdInfoEntity> synThirdOrgList = synThirdInfoService.getListByDepartment(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_ORG,dingDepartment);
  854. List<String> dingDeptIdList = new ArrayList<>();
  855. if (CollectionUtil.isNotEmpty(synThirdOrgList)) {
  856. dingDeptIdList = synThirdOrgList.stream().map(SynThirdInfoEntity::getThirdObjId)
  857. .filter(StringUtils::isNotBlank)
  858. .distinct().collect(Collectors.toList());
  859. } else {
  860. return ActionResult.fail(MsgCode.SYS028.get());
  861. }
  862. // 获取Token值
  863. SocialsSysConfig config = sysconfigService.getSocialsConfig();
  864. JSONObject tokenObject = SynDingTalkUtil.getAccessToken(config.getDingSynAppKey(), config.getDingSynAppSecret());
  865. if (!tokenObject.getBoolean("code")) {
  866. return ActionResult.fail(MsgCode.SYS053.get());
  867. }
  868. // 异步执行
  869. List<String> finalDingDeptIdList = dingDeptIdList;
  870. String finalSynDing = synDing;
  871. ThreadPoolExecutorUtil.getExecutor().execute(() -> {
  872. String userId = userInfo.getUserId();
  873. try {
  874. redisUtil.insert(finalSynDing, "true");
  875. List<OapiV2UserListResponse.ListUserResponse> dingUserList = new ArrayList<>();
  876. String access_token = tokenObject.getString("access_token");
  877. // 获取钉钉的用户列表
  878. JSONObject retMsg = SynDingTalkUtil.getUserDingList(finalDingDeptIdList, access_token);
  879. dingUserList = (List<OapiV2UserListResponse.ListUserResponse>) retMsg.get("userlist");
  880. // 获取同步表、用户表的信息
  881. List<SynThirdInfoEntity> synThirdInfoList = synThirdInfoService.syncThirdInfoByType(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_USER, SynThirdConsts.THIRD_TYPE_DING);
  882. // 根据公司表、同步表进行比较,决定执行创建、还是更新
  883. for (OapiV2UserListResponse.ListUserResponse dingUserModel : dingUserList) {
  884. if (synThirdInfoList.stream().noneMatch(t -> t.getThirdObjId().equals(dingUserModel.getUserid()))) {
  885. // 执行创建功能
  886. synThirdDingTalkService.createUserDingToSys(true, dingUserModel, access_token);
  887. } else {
  888. // 执行更新功能
  889. synThirdDingTalkService.updateUserDingToSystem(true, dingUserModel);
  890. }
  891. }
  892. } catch (Exception e) {
  893. log.error("{},钉钉所有用户信息同步到本系统失败:{}", finalSynDing, e.getMessage());
  894. } finally {
  895. redisUtil.remove(finalSynDing);
  896. List<String> toUserId = new ArrayList<>(1);
  897. toUserId.add(userId);
  898. messageService.sentMessage(toUserId, "钉钉所有用户信息同步到本系统", null, userInfo, 3, 1);
  899. }
  900. });
  901. return ActionResult.success(MsgCode.SYS026.get());
  902. }
  903. @Operation(summary = "解除同步")
  904. @SaCheckPermission(value = {"sysConfig.parameter", "integrationCenter.dingTalk"}, mode = SaMode.OR)
  905. @GetMapping("/clearAllSyn")
  906. @Transactional
  907. public ActionResult clearAllSyn(String type) {
  908. synThirdInfoService.clearAllSyn(Integer.valueOf(type));
  909. return ActionResult.success(MsgCode.SU005.get());
  910. }
  911. }