From ee4d52e65a255c02744bfb30c259d1b8f61d441f Mon Sep 17 00:00:00 2001 From: link2fun <19241982+link2fun@users.noreply.github.com> Date: Thu, 6 Nov 2025 19:30:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=90=8C=E6=AD=A5=20=E5=A2=9E=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=A6=81=E7=94=A8=E7=A6=BB=E8=81=8C=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workweixin/WorkweixinUsersService.java | 71 ++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/maxkey-synchronizers/maxkey-synchronizer-workweixin/src/main/java/org/dromara/maxkey/synchronizer/workweixin/WorkweixinUsersService.java b/maxkey-synchronizers/maxkey-synchronizer-workweixin/src/main/java/org/dromara/maxkey/synchronizer/workweixin/WorkweixinUsersService.java index 8a64d41e7..ab098143c 100644 --- a/maxkey-synchronizers/maxkey-synchronizer-workweixin/src/main/java/org/dromara/maxkey/synchronizer/workweixin/WorkweixinUsersService.java +++ b/maxkey-synchronizers/maxkey-synchronizer-workweixin/src/main/java/org/dromara/maxkey/synchronizer/workweixin/WorkweixinUsersService.java @@ -58,20 +58,33 @@ public class WorkweixinUsersService extends AbstractSynchronizerService implemen try { // 获取前面已经拉取下来的微信部门同步记录 List synchroRelatedOrgList = synchroRelatedService.findOrgs(this.synchronizer); - Map fieldMap = getFieldMap(Long.parseLong(synchronizer.getId())); + // 加载同步器的历史数据 + Map userRelationHistoryMap = loadUserRelationHistory(); + // 获取同步器的字段映射 + Map fieldMap = getFieldMap(Long.parseLong(synchronizer.getId())); // 拿到微信用户Id映射后的MaxKey字段名称 String wxUserIdInMaxkeyField = getWxUserMappingField(fieldMap, "userid"); + boolean fetchFailed = false; for (SynchroRelated relatedOrg : synchroRelatedOrgList) { // 根据微信部门ID,拉取微信用户列表, 这里拉取的是直属员工 HttpRequestAdapter request = new HttpRequestAdapter(); String responseBody = request.get(String.format(USERS_URL, access_token, relatedOrg.getOriginId())); WorkWeixinUsersResponse usersResponse = JsonUtils.gsonStringToObject(responseBody, WorkWeixinUsersResponse.class); - _logger.trace("response : " + responseBody); + _logger.trace("response : {}", responseBody); + if (usersResponse == null || usersResponse.getErrcode() != 0 || usersResponse.getUserlist() == null) { + fetchFailed = true; + _logger.warn("[同步微信用户] 拉取部门 {} (originId={}) 用户失败, errcode={}, errmsg={}", + relatedOrg.getObjectName(), relatedOrg.getOriginId(), + usersResponse == null ? "null" : usersResponse.getErrcode(), + usersResponse == null ? "null" : usersResponse.getErrmsg()); + continue; + } for (WorkWeixinUsers wxUser : usersResponse.getUserlist()) { + userRelationHistoryMap.remove(wxUser.getUserid()); // 依次处理每个员工 // 根据员工信息,构建MaxKey用户信息 UserInfo maxkeyUserNew = buildUserInfoByFiledMap(wxUser, fieldMap); @@ -156,6 +169,12 @@ public class WorkweixinUsersService extends AbstractSynchronizerService implemen } } + if (fetchFailed) { + _logger.warn("[同步微信用户] 存在部门用户拉取失败,跳过缺失用户禁用流程。"); + return; + } + + disableMissingUsers(userRelationHistoryMap); } catch (Exception e) { _logger.error("[同步微信用户] 同步用户失败", e); } @@ -291,6 +310,54 @@ public class WorkweixinUsersService extends AbstractSynchronizerService implemen this.access_token = access_token; } + /** + * 加载当前同步器历史同步的企业微信用户映射,用于判定本次缺失用户。 + * + * @return 以企业微信用户 originId 为键的同步关系映射 + */ + private Map loadUserRelationHistory() { + Map _userRelationHistoryMap = new HashMap<>(); + List historyRecords = synchroRelatedService.find( + "instid = ? and syncId = ? and objecttype = ?", + new Object[]{synchronizer.getInstId(), synchronizer.getId(), UserInfo.CLASS_TYPE}, + new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR} + ); + if (historyRecords != null) { + for (SynchroRelated related : historyRecords) { + _userRelationHistoryMap.put(related.getOriginId(), related); + } + } + return _userRelationHistoryMap; + } + + /** + * 禁用本次企业微信未返回的历史同步用户,并将 userState 标记为 WITHDRAWN。 + * + * @param _userRelationHistoryMap 尚未在本次同步中匹配到的历史同步关系 + */ + private void disableMissingUsers(Map _userRelationHistoryMap) { + if (_userRelationHistoryMap.isEmpty()) { + _logger.info("[同步微信用户] 本次同步未发现需要禁用的历史用户。"); + return; + } + _logger.info("[同步微信用户] 发现 {} 个历史同步用户未出现在本次企业微信返回,开始禁用。", _userRelationHistoryMap.size()); + for (SynchroRelated orphanRelation : _userRelationHistoryMap.values()) { + UserInfo localUser = userInfoService.get(orphanRelation.getObjectId()); + if (localUser == null) { + _logger.warn("[同步微信用户] 历史同步用户 originId={} (objectId={}) 在本地不存在,跳过禁用。", orphanRelation.getOriginId(), orphanRelation.getObjectId()); + continue; + } + if (localUser.getStatus() == ConstsStatus.DISABLED && "WITHDRAWN".equals(localUser.getUserState())) { + _logger.debug("[同步微信用户] 用户 {} (originId={}) 已处于禁用且离职状态,跳过更新。", localUser.getUsername(), orphanRelation.getOriginId()); + continue; + } + localUser.setStatus(ConstsStatus.DISABLED); + localUser.setUserState("WITHDRAWN"); + userInfoService.update(localUser); + _logger.info("[同步微信用户] 用户 {} (originId={}) 已标记为禁用,userState=WITHDRAWN。", localUser.getUsername(), orphanRelation.getOriginId()); + } + } + public SyncJobConfigFieldService getSyncJobConfigFieldService() { return syncJobConfigFieldService; }