From 12ba2cf75692f235dbfadb45cf1f5a5afa0641af Mon Sep 17 00:00:00 2001 From: chenbowen Date: Wed, 26 Nov 2025 10:42:24 +0800 Subject: [PATCH] =?UTF-8?q?iwork=20=E4=BA=BA=E5=91=98=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/api/user/dto/AdminUserRespDTO.java | 3 + .../iwork/IWorkIntegrationController.java | 10 +++- .../iwork/vo/IWorkHrDepartmentPageRespVO.java | 8 +-- .../iwork/vo/IWorkHrSubcompanyPageRespVO.java | 10 ++-- .../system/service/dept/DeptServiceImpl.java | 60 ++++++++++++------- .../integration/iwork/IWorkSyncService.java | 7 ++- .../iwork/impl/IWorkSyncProcessorImpl.java | 25 +++----- .../iwork/impl/IWorkSyncServiceImpl.java | 8 ++- 8 files changed, 77 insertions(+), 54 deletions(-) diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserRespDTO.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserRespDTO.java index 497f40d5..60fada58 100644 --- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserRespDTO.java +++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserRespDTO.java @@ -14,6 +14,9 @@ public class AdminUserRespDTO implements VO { @Schema(description = "用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long id; + @Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "zhangsan") + private String username; + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小王") private String nickname; diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java index c8472f03..e968b2c0 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/IWorkIntegrationController.java @@ -114,17 +114,23 @@ public class IWorkIntegrationController { // ----------------- 同步到本地 ----------------- @PostMapping("/hr/full-sync") - @Operation(summary = "手动触发 iWork 组织/人员全量同步") + @Operation(summary = "手动触发 iWork 组织/人员同步") public CommonResult fullSync(@Valid @RequestBody IWorkFullSyncReqVO reqVO) { return success(syncService.fullSync(reqVO)); } @PostMapping("/hr/departments/full-sync") - @Operation(summary = "手动触发 iWork 部门全量同步") + @Operation(summary = "手动触发 iWork 部门同步") public CommonResult fullSyncDepartments(@Valid @RequestBody IWorkFullSyncReqVO reqVO) { return success(syncService.fullSyncDepartments(reqVO)); } + @PostMapping("/hr/subcompanies/full-sync") + @Operation(summary = "手动触发 iWork 分部同步") + public CommonResult fullSyncSubcompanies(@Valid @RequestBody IWorkFullSyncReqVO reqVO) { + return success(syncService.fullSyncSubcompanies(reqVO)); + } + @PostMapping("/hr/job-titles/full-sync") @Operation(summary = "手动触发 iWork 岗位全量同步") public CommonResult fullSyncJobTitles(@Valid @RequestBody IWorkFullSyncReqVO reqVO) { diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrDepartmentPageRespVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrDepartmentPageRespVO.java index 6a250b6e..212a09c3 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrDepartmentPageRespVO.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrDepartmentPageRespVO.java @@ -159,13 +159,9 @@ public class IWorkHrDepartmentPageRespVO { private String supsubcomname; @Schema(description = "父部门 ID") - @JsonProperty("parentdeptid") + @JsonProperty("supdepid") @JsonDeserialize(using = LenientIntegerDeserializer.class) - private Integer parentdeptid; - - @Schema(description = "父部门名称") - @JsonProperty("parentdeptname") - private String parentdeptname; + private Integer supdepid; @Schema(description = "层级路径") @JsonProperty("alllevel") diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrSubcompanyPageRespVO.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrSubcompanyPageRespVO.java index fdbda82a..7a500d01 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrSubcompanyPageRespVO.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/integration/iwork/vo/IWorkHrSubcompanyPageRespVO.java @@ -5,11 +5,10 @@ import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.zt.plat.module.system.service.integration.iwork.jackson.LenientIntegerDeserializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import com.zt.plat.module.system.service.integration.iwork.jackson.LenientIntegerDeserializer; - import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -50,9 +49,10 @@ public class IWorkHrSubcompanyPageRespVO { @Schema(description = "分部信息") public static class Subcompany { - @Schema(description = "分部唯一 ID") - @JsonProperty("subcompanyid1") - private Integer subcompanyid1; + @Schema(description = "部门 ID(iWork 主键)") + @JsonProperty("id") + @JsonDeserialize(using = LenientIntegerDeserializer.class) + private Integer id; @Schema(description = "分部编码") @JsonProperty("subcompanycode") diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java index 0370d1bf..0d1da94f 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptServiceImpl.java @@ -74,16 +74,23 @@ public class DeptServiceImpl implements DeptService { // 校验部门名的唯一性 validateDeptNameUnique(null, createReqVO.getParentId(), createReqVO.getName()); // 生成并校验部门编码 - Long effectiveParentId = normalizeParentId(createReqVO.getParentId()); - boolean isTopLevel = Objects.equals(effectiveParentId, DeptDO.PARENT_ID_ROOT); - String resolvedCode; - if (isTopLevel) { - resolvedCode = resolveTopLevelCode(null, createReqVO.getCode()); + boolean isIWorkSource = Objects.equals(createReqVO.getDeptSource(), DeptSourceEnum.IWORK.getSource()); + if (isIWorkSource) { + // iWork 来源直接使用提供的编码,不再生成 + String providedCode = StrUtil.blankToDefault(createReqVO.getCode(), null); + createReqVO.setCode(providedCode); } else { - resolvedCode = generateDeptCode(effectiveParentId); - validateDeptCodeUnique(null, resolvedCode); + Long effectiveParentId = normalizeParentId(createReqVO.getParentId()); + boolean isTopLevel = Objects.equals(effectiveParentId, DeptDO.PARENT_ID_ROOT); + String resolvedCode; + if (isTopLevel) { + resolvedCode = resolveTopLevelCode(null, createReqVO.getCode()); + } else { + resolvedCode = generateDeptCode(effectiveParentId); + validateDeptCodeUnique(null, resolvedCode); + } + createReqVO.setCode(resolvedCode); } - createReqVO.setCode(resolvedCode); // 插入部门 DeptDO dept = BeanUtils.toBean(createReqVO, DeptDO.class); @@ -110,28 +117,35 @@ public class DeptServiceImpl implements DeptService { // 校验部门名的唯一性 validateDeptNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName()); // 如果上级发生变化,需要重新生成编码并同步子级 + boolean isIWorkSource = Objects.equals(originalDept.getDeptSource(), DeptSourceEnum.IWORK.getSource()); Long newParentId = normalizeParentId(updateReqVO.getParentId()); Long oldParentId = normalizeParentId(originalDept.getParentId()); boolean parentChanged = !Objects.equals(newParentId, oldParentId); - if (parentChanged) { - String newCode; - if (Objects.equals(newParentId, DeptDO.PARENT_ID_ROOT)) { - newCode = resolveTopLevelCode(updateReqVO.getId(), updateReqVO.getCode()); - } else { - newCode = generateDeptCode(updateReqVO.getParentId()); - validateDeptCodeUnique(updateReqVO.getId(), newCode); - } - updateReqVO.setCode(newCode); + if (isIWorkSource) { + // iWork 来源直接使用提供的编码,不再生成 + String providedCode = StrUtil.blankToDefault(updateReqVO.getCode(), null); + updateReqVO.setCode(providedCode); } else { - if (Objects.equals(newParentId, DeptDO.PARENT_ID_ROOT)) { - String requestedCode = updateReqVO.getCode(); - if (StrUtil.isNotBlank(requestedCode) && !StrUtil.equals(requestedCode.trim(), originalDept.getCode())) { - updateReqVO.setCode(resolveTopLevelCode(updateReqVO.getId(), requestedCode)); + if (parentChanged) { + String newCode; + if (Objects.equals(newParentId, DeptDO.PARENT_ID_ROOT)) { + newCode = resolveTopLevelCode(updateReqVO.getId(), updateReqVO.getCode()); + } else { + newCode = generateDeptCode(updateReqVO.getParentId()); + validateDeptCodeUnique(updateReqVO.getId(), newCode); + } + updateReqVO.setCode(newCode); + } else { + if (Objects.equals(newParentId, DeptDO.PARENT_ID_ROOT)) { + String requestedCode = updateReqVO.getCode(); + if (StrUtil.isNotBlank(requestedCode) && !StrUtil.equals(requestedCode.trim(), originalDept.getCode())) { + updateReqVO.setCode(resolveTopLevelCode(updateReqVO.getId(), requestedCode)); + } else { + updateReqVO.setCode(originalDept.getCode()); + } } else { updateReqVO.setCode(originalDept.getCode()); } - } else { - updateReqVO.setCode(originalDept.getCode()); } } diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkSyncService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkSyncService.java index 566ec028..af7ca75a 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkSyncService.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/IWorkSyncService.java @@ -16,10 +16,15 @@ public interface IWorkSyncService { IWorkFullSyncRespVO fullSync(IWorkFullSyncReqVO reqVO); /** - * 仅同步部门(会自动包含依赖的分部) + * 仅同步部门 */ IWorkFullSyncRespVO fullSyncDepartments(IWorkFullSyncReqVO reqVO); + /** + * 仅同步分部 + */ + IWorkFullSyncRespVO fullSyncSubcompanies(IWorkFullSyncReqVO reqVO); + /** * 仅同步岗位 */ diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java index 2a16b410..1983d537 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncProcessorImpl.java @@ -28,14 +28,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; @Slf4j @@ -72,12 +65,12 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { while (iterator.hasNext()) { IWorkHrSubcompanyPageRespVO.Subcompany sub = iterator.next(); if (shouldSkipByCanceled(sub.getCanceled(), options)) { - logSkip("分部", sub.getSubcompanyid1(), "iWork 标记为失效且当前不同步失效记录"); + logSkip("分部", sub.getId(), "iWork 标记为失效且当前不同步失效记录"); result.increaseSkipped(); iterator.remove(); continue; } - Integer externalId = sub.getSubcompanyid1(); + Integer externalId = sub.getId(); if (externalId == null) { log.warn("[iWork] 分部缺少标识,跳过:{}", sub.getSubcompanyname()); result.increaseFailed(); @@ -95,7 +88,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { options); applyDeptOutcome(result, outcome, "分部", sub.getSubcompanyname()); } catch (Exception ex) { - log.error("[iWork] 同步分部失败: id={} name={}", sub.getSubcompanyid1(), sub.getSubcompanyname(), ex); + log.error("[iWork] 同步分部失败: id={} name={}", sub.getId(), sub.getSubcompanyname(), ex); result.increaseFailed(); result.withMessage("同步分部失败: " + ex.getMessage()); } @@ -108,7 +101,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { } if (!queue.isEmpty()) { for (IWorkHrSubcompanyPageRespVO.Subcompany remaining : queue) { - log.warn("[iWork] 分部因父级缺失未同步: id={} name={}", remaining.getSubcompanyid1(), remaining.getSubcompanyname()); + log.warn("[iWork] 分部因父级缺失未同步: id={} name={}", remaining.getId(), remaining.getSubcompanyname()); result.increaseFailed(); } } @@ -397,7 +390,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { DeptSaveReqVO req = new DeptSaveReqVO(); req.setId(deptId); req.setName(limitLength(StrUtil.blankToDefault(data.getSubcompanyname(), "未命名分部"), 30)); - req.setShortName(limitLength(data.getSubcompanyname(), 20)); +// req.setShortName(limitLength(data.getSubcompanyname(), 20)); req.setCode(trimToNull(data.getSubcompanycode())); req.setParentId(parentId == null ? DeptDO.PARENT_ID_ROOT : parentId); req.setSort(defaultSort(data.getShoworder())); @@ -415,7 +408,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { DeptSaveReqVO req = new DeptSaveReqVO(); req.setId(deptId); req.setName(limitLength(StrUtil.blankToDefault(data.getDepartmentname(), "未命名部门"), 30)); - req.setShortName(limitLength(StrUtil.blankToDefault(data.getDepartmentmark(), data.getDepartmentname()), 20)); +// req.setShortName(limitLength(StrUtil.blankToDefault(data.getDepartmentmark(), data.getDepartmentname()), 20)); req.setCode(trimToNull(data.getDepartmentcode())); req.setParentId(parentId == null ? DeptDO.PARENT_ID_ROOT : parentId); req.setSort(defaultSort(data.getShoworder())); @@ -472,8 +465,8 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor { } private ParentHolder resolveDepartmentParent(IWorkHrDepartmentPageRespVO.Department dept) { - Long parentDeptId = toLong(dept.getParentdeptid()); - if (parentDeptId != null) { + Long parentDeptId = toLong(dept.getSupdepid()); + if (parentDeptId != null && parentDeptId > 0) { return new ParentHolder(parentDeptId); } Long subcompanyId = toLong(dept.getSubcompanyid1()); diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncServiceImpl.java index 073c2507..ef237e2d 100644 --- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncServiceImpl.java +++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/integration/iwork/impl/IWorkSyncServiceImpl.java @@ -37,6 +37,11 @@ public class IWorkSyncServiceImpl implements IWorkSyncService { return runFullSync(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.DEPARTMENT)); } + @Override + public IWorkFullSyncRespVO fullSyncSubcompanies(IWorkFullSyncReqVO reqVO) { + return runFullSync(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.SUBCOMPANY)); + } + @Override public IWorkFullSyncRespVO fullSyncJobTitles(IWorkFullSyncReqVO reqVO) { return runFullSync(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.JOB_TITLE)); @@ -56,6 +61,7 @@ public class IWorkSyncServiceImpl implements IWorkSyncService { boolean syncUsers = scopes.contains(IWorkSyncEntityTypeEnum.USER); boolean syncDepartments = scopes.contains(IWorkSyncEntityTypeEnum.DEPARTMENT); boolean syncSubcompanies = scopes.contains(IWorkSyncEntityTypeEnum.SUBCOMPANY); + boolean syncJobTitle = scopes.contains(IWorkSyncEntityTypeEnum.JOB_TITLE); int processedPages = 0; IWorkSyncProcessor.SyncOptions options = buildFullSyncOptions(reqVO); if (syncSubcompanies) { @@ -64,7 +70,7 @@ public class IWorkSyncServiceImpl implements IWorkSyncService { if (syncDepartments) { processedPages += executeDepartmentFullSync(reqVO, options, respVO.getDepartmentStat(), batchStats); } - if (scopes.contains(IWorkSyncEntityTypeEnum.JOB_TITLE)) { + if (syncJobTitle) { processedPages += executeJobTitleFullSync(reqVO, options, respVO.getJobTitleStat(), batchStats); } if (syncUsers) {