Merge remote-tracking branch 'base-version/main' into dev
This commit is contained in:
@@ -13,7 +13,6 @@ import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.zt.plat.module.system.api.esp;
|
||||
|
||||
import com.zt.plat.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.framework.common.util.object.ObjectUtils;
|
||||
import com.zt.plat.module.system.api.dept.dto.DeptSaveReqDTO;
|
||||
import com.zt.plat.module.system.api.esp.dto.EspDto;
|
||||
import com.zt.plat.module.system.service.dept.IEspService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@RestController
|
||||
@Validated
|
||||
public class EspApiImpl implements EspApi {
|
||||
|
||||
|
||||
@Resource
|
||||
private IEspService deptService;
|
||||
@Override
|
||||
public CommonResult<List<EspDto>> pushMsg(DeptSaveReqDTO syncReqDTO)
|
||||
{
|
||||
if(Objects.isNull(syncReqDTO) || null == syncReqDTO.getId())
|
||||
{
|
||||
return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
|
||||
"ID不能为空");
|
||||
}
|
||||
return CommonResult.success(deptService.pushMsg(syncReqDTO));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.zt.plat.module.system.controller.admin.dept;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.CommonResult;
|
||||
import com.zt.plat.framework.common.pojo.PageResult;
|
||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.EspPageReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.EspSaveRespVo;
|
||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptPushMsgDO;
|
||||
import com.zt.plat.module.system.service.dept.DeptService;
|
||||
import com.zt.plat.module.system.service.dept.IEspService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 部门推送消息")
|
||||
@RestController
|
||||
@RequestMapping("/system/esp")
|
||||
@Validated
|
||||
public class EspController
|
||||
{
|
||||
|
||||
@Resource
|
||||
private IEspService espService;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建部门推送消息")
|
||||
@PreAuthorize("@ss.hasPermission('system:esp-external-code:create')")
|
||||
public CommonResult<Long> create(@Valid @RequestBody EspSaveRespVo createReqVO) {
|
||||
Long id = espService.createDeptPushMsg(createReqVO);
|
||||
return success(id);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改部门推送消息")
|
||||
@PreAuthorize("@ss.hasPermission('system:esp-external-code:update')")
|
||||
public CommonResult<Boolean> update(@Valid @RequestBody EspSaveRespVo updateReqVO) {
|
||||
espService.updateDeptPushMsg(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除部门推送消息")
|
||||
@PreAuthorize("@ss.hasPermission('system:esp-external-code:delete')")
|
||||
public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
|
||||
espService.deleteDeptPushMsg(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获取部门推送消息详情")
|
||||
@PreAuthorize("@ss.hasPermission('system:esp-external-code:query')")
|
||||
public CommonResult<EspSaveRespVo> get(@RequestParam("id") Long id) {
|
||||
DeptPushMsgDO entity = espService.getDeptPushMsgDetails(id);
|
||||
EspSaveRespVo respVO = BeanUtils.toBean(entity, EspSaveRespVo.class);
|
||||
fillDeptInfo(List.of(respVO));
|
||||
return success(respVO);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "分页查询部门推送消息")
|
||||
@PreAuthorize("@ss.hasPermission('system:esp-external-code:query')")
|
||||
public CommonResult<PageResult<EspSaveRespVo>> page(@Valid EspPageReqVO reqVO) {
|
||||
PageResult<DeptPushMsgDO> pageResult = espService.getDeptExternalCodePage(reqVO);
|
||||
PageResult<EspSaveRespVo> result = BeanUtils.toBean(pageResult, EspSaveRespVo.class);
|
||||
fillDeptInfo(result.getList());
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-dept")
|
||||
@Operation(summary = "根据部门部门推送消息")
|
||||
@Parameter(name = "deptId", description = "部门编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:esp-external-code:query')")
|
||||
public CommonResult<List<EspSaveRespVo>> listByDept(@RequestParam("deptId") Long deptId) {
|
||||
List<DeptPushMsgDO> list = espService.getPushMsgByDeptId(deptId);
|
||||
List<EspSaveRespVo> respList = BeanUtils.toBean(list, EspSaveRespVo.class);
|
||||
fillDeptInfo(respList);
|
||||
return success(respList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void fillDeptInfo(List<EspSaveRespVo> list) {
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
Set<Long> deptIds = list.stream()
|
||||
.map(EspSaveRespVo::getDeptId)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
if (CollectionUtils.isEmpty(deptIds)) {
|
||||
return;
|
||||
}
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptList(deptIds).stream()
|
||||
.collect(Collectors.toMap(DeptDO::getId, dept -> dept, (left, right) -> left));
|
||||
list.forEach(item -> {
|
||||
DeptDO dept = deptMap.get(item.getDeptId());
|
||||
if (dept != null) {
|
||||
item.setDeptName(dept.getName());
|
||||
item.setDeptCode(dept.getCode());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Schema(description = "管理后台 - 部门外部组织编码映射分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EspPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "部门编号", example = "1024")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "外部系统标识", example = "ERP")
|
||||
private String systemCode;
|
||||
|
||||
@Schema(description = "外部组织编码", example = "100200")
|
||||
private String externalDeptCode;
|
||||
|
||||
@Schema(description = "状态", example = "0")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 部门外消息推送创建/修改 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EspSaveRespVo extends DeptExternalCodeBaseVO {
|
||||
|
||||
@Schema(description = "映射编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "所属部门名称", example = "技术部")
|
||||
private String deptName;
|
||||
|
||||
@Schema(description = "所属部门编码", example = "DEPT_001")
|
||||
private String deptCode;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "最后更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(description = "是否发送消息")
|
||||
private Integer isSendMsg;
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.zt.plat.module.system.controller.admin.integration.iwork.vo.*;
|
||||
import com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationService;
|
||||
import com.zt.plat.module.system.service.integration.iwork.IWorkOrgRestService;
|
||||
import com.zt.plat.module.system.service.integration.iwork.IWorkSyncService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
@@ -18,9 +19,7 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 提供统一 iWork 流程能力的管理端接口。
|
||||
*/
|
||||
@@ -29,6 +28,7 @@ import static com.zt.plat.framework.common.pojo.CommonResult.success;
|
||||
@RequestMapping("/system/integration/iwork")
|
||||
@RequiredArgsConstructor
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class IWorkIntegrationController {
|
||||
|
||||
private final IWorkIntegrationService integrationService;
|
||||
@@ -139,6 +139,17 @@ public class IWorkIntegrationController {
|
||||
return success(syncService.fullSyncUsers(reqVO));
|
||||
}
|
||||
|
||||
// ----------------- 根据ID同步到本地 -----------------
|
||||
|
||||
@PostMapping("/syncById")
|
||||
@Operation(summary = "根据ID触发 iWork 同步公司")
|
||||
public CommonResult<IWorkFullSyncRespVO> syncById(@Valid @RequestBody IWorkSyncByIdReqVO reqVO) {
|
||||
|
||||
log.error("IWork集成后端手动录入syncById{}",reqVO);
|
||||
return success(syncService.manuallySyncData(reqVO));
|
||||
}
|
||||
|
||||
|
||||
private ResponseEntity<String> buildOaResponse(IWorkOaRawResponse resp) {
|
||||
if (resp == null) {
|
||||
return ResponseEntity.internalServerError().body("OA 响应为空");
|
||||
|
||||
@@ -56,4 +56,8 @@ public class IWorkFullSyncReqVO {
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.zt.plat.module.system.controller.admin.integration.iwork.vo;
|
||||
|
||||
import com.zt.plat.module.system.enums.integration.IWorkSyncEntityTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* iWork 手动同步请求
|
||||
*/
|
||||
@Data
|
||||
public class IWorkSyncByIdReqVO {
|
||||
|
||||
|
||||
@Schema(description = "起始页码,从 1 开始", example = "1")
|
||||
@Min(1)
|
||||
private Integer startPage = 1;
|
||||
|
||||
@Schema(description = "最大处理页数,null 表示处理至 iWork 返回的末页", example = "10")
|
||||
@Min(1)
|
||||
private Integer maxPages;
|
||||
|
||||
@Schema(description = "每次分页从 iWork 拉取的记录数", example = "100")
|
||||
@Min(1)
|
||||
@Max(500)
|
||||
private Integer pageSize = 100;
|
||||
|
||||
@Schema(description = "同步范围列表,默认同步全部。可选:subcompany、department、jobTitle、user")
|
||||
private List<String> scopes;
|
||||
|
||||
@Schema(description = "是否包含已失效(canceled=1)的记录", example = "false")
|
||||
private Boolean includeCanceled = Boolean.FALSE;
|
||||
|
||||
@Schema(description = "是否允许更新已存在的本地实体", example = "false")
|
||||
private Boolean allowUpdate = Boolean.FALSE;
|
||||
|
||||
|
||||
@Schema(description = "指定同步记录的 iWork ID。传入后仅同步对应记录", example = "12345")
|
||||
@NotBlank(message = "ID不能为空")
|
||||
private String id;
|
||||
|
||||
@Schema(description = "部门编码", example = "ZT001")
|
||||
private String code;
|
||||
|
||||
@Schema(description = "部门名称", example = "ZT")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "部门简称", example = "技术")
|
||||
private String shortName;
|
||||
|
||||
@Schema(description = "父部门 ID", example = "1024")
|
||||
private String parentId;
|
||||
|
||||
@Schema(description = "负责人的用户编号", example = "2048")
|
||||
private String leaderUserId;
|
||||
|
||||
@Schema(description = "联系电话", example = "15601691000")
|
||||
private String phone;
|
||||
|
||||
@Schema(description = "邮箱", example = "zt@iocoder.cn")
|
||||
private String email;
|
||||
|
||||
@Schema(description = "状态,见 CommonStatusEnum 枚举0 开启 1 关闭", example = "0")
|
||||
private Integer status;
|
||||
|
||||
private Long tenantId;
|
||||
|
||||
@Schema(description = "是否公司", example = "false")
|
||||
private boolean isCompany;
|
||||
|
||||
@Schema(description = "是否集团", example = "false")
|
||||
private boolean isGroup;
|
||||
|
||||
private boolean hasChildren;
|
||||
|
||||
|
||||
public Set<IWorkSyncEntityTypeEnum> resolveScopes() {
|
||||
EnumSet<IWorkSyncEntityTypeEnum> defaults = EnumSet.allOf(IWorkSyncEntityTypeEnum.class);
|
||||
if (scopes == null || scopes.isEmpty()) {
|
||||
return defaults;
|
||||
}
|
||||
Set<IWorkSyncEntityTypeEnum> resolved = scopes.stream()
|
||||
.map(IWorkSyncEntityTypeEnum::fromCode)
|
||||
.filter(java.util.Objects::nonNull)
|
||||
.collect(Collectors.toCollection(() -> EnumSet.noneOf(IWorkSyncEntityTypeEnum.class)));
|
||||
if (resolved.isEmpty()) {
|
||||
return defaults;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.zt.plat.module.system.dal.dataobject.dept;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||
import com.zt.plat.framework.tenant.core.db.TenantBaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 部门推送消息 DO
|
||||
*/
|
||||
@TableName("system_dept_push_msg")
|
||||
@KeySequence("system_dept_push_msg_seq")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DeptPushMsgDO extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* 主键编号
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 本系统部门 ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 外部系统标识
|
||||
*/
|
||||
private String systemCode;
|
||||
|
||||
/**
|
||||
* 外部系统组织编码
|
||||
*/
|
||||
private String externalDeptCode;
|
||||
|
||||
/**
|
||||
* 外部系统组织名称
|
||||
*/
|
||||
private String externalDeptName;
|
||||
|
||||
/**
|
||||
* 映射状态
|
||||
* 枚举 {@link CommonStatusEnum}
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 是否发送消息
|
||||
*/
|
||||
private Integer isSendMsg;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.zt.plat.module.system.dal.mysql.dept;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.PageResult;
|
||||
import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.zt.plat.module.system.api.dept.dto.DeptSaveReqDTO;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.EspPageReqVO;
|
||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptPushMsgDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import java.util.List;
|
||||
/**
|
||||
* 部门推送消息接口Mapper
|
||||
*/
|
||||
@Mapper
|
||||
public interface EspMapper extends BaseMapperX<DeptPushMsgDO> {
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param reqVO 消息推送VO
|
||||
* @return PageResult
|
||||
*/
|
||||
default PageResult<DeptPushMsgDO> selectPage(EspPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<DeptPushMsgDO>()
|
||||
.eqIfPresent(DeptPushMsgDO::getDeptId,reqVO.getDeptId())
|
||||
.eqIfPresent(DeptPushMsgDO::getSystemCode, reqVO.getSystemCode())
|
||||
.likeIfPresent(DeptPushMsgDO::getExternalDeptCode, reqVO.getExternalDeptCode())
|
||||
.eqIfPresent(DeptPushMsgDO::getStatus, reqVO.getStatus())
|
||||
.orderByDesc(DeptPushMsgDO::getId));
|
||||
}
|
||||
|
||||
|
||||
default DeptPushMsgDO selectBySystemCodeAndDeptId(String systemCode, Long deptId) {
|
||||
return selectOne(new LambdaQueryWrapperX<DeptPushMsgDO>()
|
||||
.eq(DeptPushMsgDO::getSystemCode, systemCode)
|
||||
.eq(DeptPushMsgDO::getDeptId, deptId));
|
||||
}
|
||||
|
||||
default DeptPushMsgDO selectBySystemCodeAndExternalCode(String systemCode, String externalDeptCode) {
|
||||
return selectOne(new LambdaQueryWrapperX<DeptPushMsgDO>()
|
||||
.eq(DeptPushMsgDO::getSystemCode, systemCode)
|
||||
.eq(DeptPushMsgDO::getExternalDeptCode, externalDeptCode));
|
||||
}
|
||||
|
||||
default List<DeptPushMsgDO> selectListByDeptId(Long deptId) {
|
||||
return selectList(DeptPushMsgDO::getDeptId, deptId);
|
||||
}
|
||||
|
||||
default int deleteByDeptId(Long deptId) {
|
||||
return delete(DeptPushMsgDO::getDeptId, deptId);
|
||||
}
|
||||
|
||||
default List<DeptPushMsgDO> selectListBySystemCode(String systemCode) {
|
||||
return selectList(DeptPushMsgDO::getSystemCode, systemCode);
|
||||
}
|
||||
|
||||
@Select("SELECT ID,DEPT_ID, SYSTEM_CODE,EXTERNAL_DEPT_CODE,EXTERNAL_DEPT_NAME,STATUS,REMARK,TENANT_ID,CREATOR,CREATE_TIME,UPDATER,UPDATE_TIME" +
|
||||
"FROM" +
|
||||
"SYSTEM_DEPT_PUSH_MSG" +
|
||||
"WHERE" +
|
||||
" ID = #{id} AND IS_SEND_MSG = '0' AND DELETED = '0' ")
|
||||
List<DeptPushMsgDO> selectpushMsg(@Param("syncReqDTO") DeptSaveReqDTO syncReqDTO);
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
package com.zt.plat.module.system.service.dept;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||
import com.zt.plat.framework.common.pojo.PageResult;
|
||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||
import com.zt.plat.module.system.api.dept.dto.DeptSaveReqDTO;
|
||||
import com.zt.plat.module.system.api.esp.dto.EspDto;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.EspPageReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.EspSaveRespVo;
|
||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
|
||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptPushMsgDO;
|
||||
import com.zt.plat.module.system.dal.mysql.dept.DeptMapper;
|
||||
import com.zt.plat.module.system.dal.mysql.dept.EspMapper;
|
||||
import com.zt.plat.module.system.dal.redis.RedisKeyConstants;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.seata.common.result.Result;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.zt.plat.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* 部门推送消息接口ServiceImpl实现类
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class EspServiceImpl implements IEspService {
|
||||
|
||||
@Resource
|
||||
private EspMapper espMapper;
|
||||
@Resource
|
||||
private DeptMapper deptMapper;
|
||||
@Resource
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@Override
|
||||
@CacheEvict(cacheNames = RedisKeyConstants.DEPT_EXTERNAL_CODE_LIST, key = "#createReqVO.deptId", beforeInvocation = false)
|
||||
public Long createDeptPushMsg(EspSaveRespVo createReqVO) {
|
||||
|
||||
//请求校验
|
||||
normalizeRequest(createReqVO);
|
||||
//冲突禁用-映射
|
||||
disableActiveMappingIfConflict(createReqVO.getDeptId(), createReqVO.getSystemCode(), createReqVO.getExternalDeptCode());
|
||||
validateForCreateOrUpdate(null, createReqVO.getDeptId(), createReqVO.getSystemCode(),
|
||||
createReqVO.getExternalDeptCode());
|
||||
|
||||
DeptPushMsgDO entity = BeanUtils.toBean(createReqVO, DeptPushMsgDO.class);
|
||||
if (entity.getStatus() == null) {
|
||||
entity.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}
|
||||
entity.setIsSendMsg(0);
|
||||
espMapper.insert(entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDeptPushMsg(EspSaveRespVo updateReqVO) {
|
||||
normalizeRequest(updateReqVO);
|
||||
DeptPushMsgDO exists = validateExists(updateReqVO.getId());
|
||||
disableActiveMappingIfConflict(updateReqVO.getDeptId(), updateReqVO.getSystemCode(), updateReqVO.getExternalDeptCode());
|
||||
validateForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getDeptId(), updateReqVO.getSystemCode(),
|
||||
updateReqVO.getExternalDeptCode());
|
||||
|
||||
DeptPushMsgDO updateObj = BeanUtils.toBean(updateReqVO, DeptPushMsgDO.class);
|
||||
// 保持原有的状态默认值逻辑
|
||||
if (updateObj.getStatus() == null) {
|
||||
updateObj.setStatus(exists.getStatus() == null ? CommonStatusEnum.ENABLE.getStatus() : exists.getStatus());
|
||||
}
|
||||
updateObj.setIsSendMsg(updateReqVO.getIsSendMsg());
|
||||
espMapper.updateById(updateObj);
|
||||
evictCacheSafely(exists.getDeptId());
|
||||
evictCacheSafely(updateObj.getDeptId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDeptPushMsg(Long id) {
|
||||
DeptPushMsgDO exists = validateExists(id);
|
||||
espMapper.deleteById(id);
|
||||
evictCacheSafely(exists.getDeptId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeptPushMsgDO getDeptPushMsgDetails(Long id) {
|
||||
return espMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<DeptPushMsgDO> getDeptExternalCodePage(EspPageReqVO reqVO) {
|
||||
|
||||
return espMapper.selectPage(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = RedisKeyConstants.DEPT_EXTERNAL_CODE_LIST, key = "#deptId")
|
||||
public List<DeptPushMsgDO> getPushMsgByDeptId(Long deptId) {
|
||||
return espMapper.selectListByDeptId(deptId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EspDto> pushMsg(DeptSaveReqDTO syncReqDTO) {
|
||||
|
||||
return BeanUtils.toBean(espMapper.selectpushMsg(syncReqDTO), EspDto.class);
|
||||
}
|
||||
|
||||
private DeptPushMsgDO validateExists(Long id) {
|
||||
if (id == null) {
|
||||
throw exception(DEPT_EXTERNAL_RELATION_NOT_EXISTS);
|
||||
}
|
||||
DeptPushMsgDO entity = espMapper.selectById(id);
|
||||
if (entity == null) {
|
||||
throw exception(DEPT_EXTERNAL_RELATION_NOT_EXISTS);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void validateForCreateOrUpdate(Long id, Long deptId, String systemCode, String externalDeptCode) {
|
||||
|
||||
// 校验部门存在
|
||||
DeptDO dept = deptMapper.selectById(deptId);
|
||||
if (dept == null) {
|
||||
throw exception(DEPT_NOT_FOUND);
|
||||
}
|
||||
String normalizedSystemCode = StrUtil.blankToDefault(systemCode, null);
|
||||
String normalizedExternalCode = StrUtil.blankToDefault(externalDeptCode, null);
|
||||
|
||||
// 校验同一系统下部门唯一
|
||||
if (StrUtil.isNotBlank(normalizedSystemCode)) {
|
||||
DeptPushMsgDO sameDept = espMapper
|
||||
.selectBySystemCodeAndDeptId(normalizedSystemCode, deptId);
|
||||
if (sameDept != null && (id == null || !sameDept.getId().equals(id))) {
|
||||
throw exception(DEPT_EXTERNAL_RELATION_EXISTS, normalizedSystemCode);
|
||||
}
|
||||
}
|
||||
// 校验同一系统下外部编码唯一
|
||||
if (StrUtil.isNotBlank(normalizedSystemCode) && StrUtil.isNotBlank(normalizedExternalCode)) {
|
||||
DeptPushMsgDO sameExternal = espMapper
|
||||
.selectBySystemCodeAndExternalCode(normalizedSystemCode, normalizedExternalCode);
|
||||
if (sameExternal != null && (id == null || !sameExternal.getId().equals(id))) {
|
||||
boolean sameDept = Objects.equals(deptId, sameExternal.getDeptId());
|
||||
boolean activeConflict = !sameDept && CommonStatusEnum.isEnable(sameExternal.getStatus());
|
||||
if (activeConflict) {
|
||||
throw exception(DEPT_EXTERNAL_CODE_DUPLICATE, normalizedSystemCode, normalizedExternalCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void normalizeRequest(EspSaveRespVo reqVO) {
|
||||
if (reqVO == null) {
|
||||
return;
|
||||
}
|
||||
if (StrUtil.isNotBlank(reqVO.getSystemCode())) {
|
||||
reqVO.setSystemCode(reqVO.getSystemCode().trim());
|
||||
}
|
||||
if (StrUtil.isNotBlank(reqVO.getExternalDeptCode())) {
|
||||
reqVO.setExternalDeptCode(reqVO.getExternalDeptCode().trim());
|
||||
}
|
||||
if (reqVO.getStatus() == null) {
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
private void disableActiveMappingIfConflict(Long targetDeptId, String systemCode, String externalDeptCode) {
|
||||
String normalizedSystem = StrUtil.trimToNull(systemCode);
|
||||
String normalizedExternal = StrUtil.trimToNull(externalDeptCode);
|
||||
if (StrUtil.hasEmpty(normalizedSystem, normalizedExternal) || targetDeptId == null) {
|
||||
return;
|
||||
}
|
||||
DeptPushMsgDO existing = espMapper.selectBySystemCodeAndExternalCode(normalizedSystem, normalizedExternal);
|
||||
if (existing == null) {
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(existing.getDeptId(), targetDeptId)) {
|
||||
return;
|
||||
}
|
||||
if (CommonStatusEnum.isEnable(existing.getStatus())) {
|
||||
DeptPushMsgDO update = new DeptPushMsgDO();
|
||||
update.setId(existing.getId());
|
||||
update.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
espMapper.updateById(update);
|
||||
evictCacheSafely(existing.getDeptId());
|
||||
}
|
||||
}
|
||||
|
||||
private void evictCacheSafely(Long deptId) {
|
||||
|
||||
if (deptId == null || cacheManager == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (cacheManager.getCache(RedisKeyConstants.DEPT_EXTERNAL_CODE_LIST) != null) {
|
||||
cacheManager.getCache(RedisKeyConstants.DEPT_EXTERNAL_CODE_LIST).evict(deptId);
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// 缓存失效失败不影响主流程
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.zt.plat.module.system.service.dept;
|
||||
|
||||
import com.zt.plat.framework.common.pojo.PageResult;
|
||||
import com.zt.plat.module.system.api.dept.dto.DeptSaveReqDTO;
|
||||
import com.zt.plat.module.system.api.esp.dto.EspDto;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.EspPageReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.EspSaveRespVo;
|
||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptPushMsgDO;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门推送消息 Service 接口
|
||||
*/
|
||||
public interface IEspService {
|
||||
|
||||
/**
|
||||
* 创建映射关系
|
||||
* @param createReqVO 创建请求
|
||||
* @return 新增记录编号
|
||||
*/
|
||||
Long createDeptPushMsg(EspSaveRespVo createReqVO);
|
||||
|
||||
/**
|
||||
* 更新映射关系
|
||||
* @param updateReqVO 更新请求
|
||||
*/
|
||||
void updateDeptPushMsg(EspSaveRespVo updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除映射关系
|
||||
* @param id 记录编号
|
||||
*/
|
||||
void deleteDeptPushMsg(Long id);
|
||||
|
||||
/**
|
||||
* 获取映射详情
|
||||
*/
|
||||
DeptPushMsgDO getDeptPushMsgDetails(Long id);
|
||||
|
||||
/**
|
||||
* 分页查询映射
|
||||
*/
|
||||
PageResult<DeptPushMsgDO> getDeptExternalCodePage(EspPageReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 根据部门推送消息
|
||||
*/
|
||||
List<DeptPushMsgDO> getPushMsgByDeptId(Long deptId);
|
||||
|
||||
|
||||
/**
|
||||
* 推送部门数据到外部系统
|
||||
* @param syncReqDTO 同步请求
|
||||
*/
|
||||
List<EspDto> pushMsg(DeptSaveReqDTO syncReqDTO);
|
||||
|
||||
}
|
||||
@@ -19,19 +19,19 @@ public interface IWorkSyncProcessor {
|
||||
|
||||
BatchResult syncSubcompanies(List<IWorkHrSubcompanyPageRespVO.Subcompany> data,
|
||||
SyncOptions options);
|
||||
|
||||
// 同步子公司
|
||||
BatchResult syncSubcompanies(List<IWorkHrSubcompanyPageRespVO.Subcompany> data,
|
||||
SyncOptions options,
|
||||
DeptSyncContext context);
|
||||
|
||||
BatchResult syncDepartments(List<IWorkHrDepartmentPageRespVO.Department> data, SyncOptions options);
|
||||
|
||||
// 同步部门
|
||||
BatchResult syncDepartments(List<IWorkHrDepartmentPageRespVO.Department> data,
|
||||
SyncOptions options,
|
||||
DeptSyncContext context);
|
||||
|
||||
// 同步岗位
|
||||
BatchResult syncJobTitles(List<IWorkHrJobTitlePageRespVO.JobTitle> data, SyncOptions options);
|
||||
|
||||
// 同步用户
|
||||
BatchResult syncUsers(List<IWorkHrUserPageRespVO.User> data, SyncOptions options);
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,9 @@ package com.zt.plat.module.system.service.integration.iwork;
|
||||
|
||||
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkFullSyncReqVO;
|
||||
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkFullSyncRespVO;
|
||||
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkSyncByIdReqVO;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* iWork 组织/人员同步服务
|
||||
@@ -28,4 +31,8 @@ public interface IWorkSyncService {
|
||||
*/
|
||||
IWorkFullSyncRespVO fullSyncUsers(IWorkFullSyncReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 手动同步
|
||||
*/
|
||||
IWorkFullSyncRespVO manuallySyncData(@Valid IWorkSyncByIdReqVO list);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
public BatchResult syncSubcompanies(List<IWorkHrSubcompanyPageRespVO.Subcompany> data, SyncOptions options) {
|
||||
return syncSubcompanies(data, options, null);
|
||||
}
|
||||
|
||||
//1、同步子公司
|
||||
@Override
|
||||
public BatchResult syncSubcompanies(List<IWorkHrSubcompanyPageRespVO.Subcompany> data,
|
||||
SyncOptions options,
|
||||
@@ -154,7 +154,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//2、同步部门
|
||||
@Override
|
||||
public BatchResult syncDepartments(List<IWorkHrDepartmentPageRespVO.Department> data, SyncOptions options) {
|
||||
return syncDepartments(data, options, null);
|
||||
@@ -272,7 +272,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
result.merge(syncDepartmentsInternal(Collections.emptyList(), options, context, true));
|
||||
return result;
|
||||
}
|
||||
|
||||
//TODO 3、同步岗位
|
||||
@Override
|
||||
public BatchResult syncJobTitles(List<IWorkHrJobTitlePageRespVO.JobTitle> data, SyncOptions options) {
|
||||
List<IWorkHrJobTitlePageRespVO.JobTitle> records = CollUtil.emptyIfNull(data);
|
||||
@@ -310,7 +310,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//TODO 4、同步用户
|
||||
@Override
|
||||
public BatchResult syncUsers(List<IWorkHrUserPageRespVO.User> data, SyncOptions options) {
|
||||
List<IWorkHrUserPageRespVO.User> records = CollUtil.emptyIfNull(data);
|
||||
@@ -377,7 +377,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//TODO
|
||||
private DeptSyncOutcome upsertDept(Long deptId,
|
||||
DeptSaveReqVO desired,
|
||||
boolean disabled,
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.zt.plat.module.system.service.integration.iwork.IWorkSyncService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
@@ -34,32 +35,59 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
private final IWorkSyncProcessor syncProcessor;
|
||||
private final DeptService deptService;
|
||||
|
||||
/**
|
||||
* 同步部门
|
||||
*/
|
||||
@Override
|
||||
public IWorkFullSyncRespVO fullSyncDepartments(IWorkFullSyncReqVO reqVO) {
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅同步人员(会自动包含依赖的分部、部门)
|
||||
*/
|
||||
@Override
|
||||
public IWorkFullSyncRespVO fullSyncUsers(IWorkFullSyncReqVO reqVO) {
|
||||
return runFullSync(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.USER));
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动同步
|
||||
*/
|
||||
@Transactional
|
||||
@Override
|
||||
public IWorkFullSyncRespVO manuallySyncData(IWorkSyncByIdReqVO reqVO) {
|
||||
return manuallySyncData(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.USER));
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量同步方法
|
||||
* @param reqVO 请求参数
|
||||
* @param scopes 同步范围
|
||||
* @return 响应对象
|
||||
*/
|
||||
private IWorkFullSyncRespVO runFullSync(IWorkFullSyncReqVO reqVO, Set<IWorkSyncEntityTypeEnum> scopes) {
|
||||
IWorkFullSyncRespVO respVO = new IWorkFullSyncRespVO();
|
||||
IWorkFullSyncRespVO respVO = new IWorkFullSyncRespVO();//1 初始化响应对象:创建响应VO并设置分页大小和批次统计列表
|
||||
respVO.setPageSize(reqVO.getPageSize());
|
||||
List<IWorkSyncBatchStatVO> batchStats = new ArrayList<>();
|
||||
respVO.setBatches(batchStats);
|
||||
|
||||
//2 解析同步范围:根据传入的scopes确定需要同步的实体类型(用户、部门、分部、岗位)
|
||||
boolean syncUsers = scopes.contains(IWorkSyncEntityTypeEnum.USER);
|
||||
boolean syncDepartments = scopes.contains(IWorkSyncEntityTypeEnum.DEPARTMENT);
|
||||
boolean syncSubcompanies = scopes.contains(IWorkSyncEntityTypeEnum.SUBCOMPANY);
|
||||
@@ -69,18 +97,20 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
IWorkSyncProcessor.DeptSyncContext deptSyncContext = (syncDepartments || syncSubcompanies)
|
||||
? new IWorkSyncProcessor.DeptSyncContext()
|
||||
: null;
|
||||
if (syncSubcompanies) {
|
||||
//3 按类型执行同步:依次执行分部、部门、岗位、用户的分页同步操作
|
||||
if (syncSubcompanies) { //公司
|
||||
processedPages += executeSubcompanyFullSync(reqVO, options, respVO.getSubcompanyStat(), batchStats, deptSyncContext);
|
||||
}
|
||||
if (syncDepartments) {
|
||||
if (syncDepartments) { //部门
|
||||
processedPages += executeDepartmentFullSync(reqVO, options, respVO.getDepartmentStat(), batchStats, deptSyncContext);
|
||||
}
|
||||
if (syncJobTitle) {
|
||||
if (syncJobTitle) { // 岗位
|
||||
processedPages += executeJobTitleFullSync(reqVO, options, respVO.getJobTitleStat(), batchStats);
|
||||
}
|
||||
if (syncUsers) {
|
||||
if (syncUsers) { //人员
|
||||
processedPages += executeUserFullSync(reqVO, options, respVO.getUserStat(), batchStats);
|
||||
}
|
||||
//4、处理部门上下文:对部门和分部同步进行特殊处理,包括刷新待处理数据和补全部门编码
|
||||
if (deptSyncContext != null) {
|
||||
IWorkSyncProcessor.BatchResult flushResult = syncProcessor.flushDeptPending(deptSyncContext, options);
|
||||
updateStat(respVO.getDepartmentStat(), flushResult, 0);
|
||||
@@ -92,6 +122,9 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
return respVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量执行子公司全量同步
|
||||
*/
|
||||
private int executeSubcompanyFullSync(IWorkFullSyncReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
@@ -103,7 +136,7 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
query.setPagesize(pageSize);
|
||||
applyQueryConditions(query, reqVO);
|
||||
IWorkHrSubcompanyPageRespVO pageResp = orgRestService.listSubcompanies(query);
|
||||
ensureIWorkSuccess("拉取分部", pageResp.isSuccess(), pageResp.getMessage());
|
||||
ensureIWorkSuccess("拉取分部", pageResp.isSuccess(), pageResp.getMessage());// IWork执行成功
|
||||
List<IWorkHrSubcompanyPageRespVO.Subcompany> dataList = CollUtil.emptyIfNull(pageResp.getDataList());
|
||||
IWorkSyncProcessor.BatchResult result = syncProcessor.syncSubcompanies(dataList, options, context);
|
||||
updateStat(stat, result, dataList.size());
|
||||
@@ -111,6 +144,9 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行部门全量同步
|
||||
*/
|
||||
private int executeDepartmentFullSync(IWorkFullSyncReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
@@ -130,6 +166,9 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行岗位全量同步
|
||||
*/
|
||||
private int executeJobTitleFullSync(IWorkFullSyncReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
@@ -148,6 +187,9 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行用户全量同步
|
||||
*/
|
||||
private int executeUserFullSync(IWorkFullSyncReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
@@ -193,6 +235,12 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
return processedPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新统计
|
||||
* @param stat 统计
|
||||
* @param result 结果
|
||||
* @param pulled 拉取数量
|
||||
*/
|
||||
private void updateStat(IWorkSyncEntityStatVO stat, IWorkSyncProcessor.BatchResult result, int pulled) {
|
||||
stat.incrementPulled(pulled);
|
||||
stat.incrementCreated(result.getCreated());
|
||||
@@ -201,6 +249,11 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
stat.incrementFailed(result.getFailed());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询条件
|
||||
* @param query 查询条件
|
||||
* @param reqVO 请求
|
||||
*/
|
||||
private void applyQueryConditions(IWorkOrgBaseQueryReqVO query, IWorkFullSyncReqVO reqVO) {
|
||||
if (query == null || reqVO == null) {
|
||||
return;
|
||||
@@ -216,6 +269,9 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
params.put("id", reqVO.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 全量同步
|
||||
*/
|
||||
private IWorkSyncProcessor.SyncOptions buildFullSyncOptions(IWorkFullSyncReqVO reqVO) {
|
||||
boolean includeCanceled = Boolean.TRUE.equals(reqVO.getIncludeCanceled());
|
||||
boolean allowUpdate = Boolean.TRUE.equals(reqVO.getAllowUpdate());
|
||||
@@ -237,4 +293,197 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
|
||||
private record BatchExecution(IWorkSyncProcessor.BatchResult result, int totalPulled) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据ID同步
|
||||
*/
|
||||
private IWorkFullSyncRespVO manuallySyncData(IWorkSyncByIdReqVO reqVO, Set<IWorkSyncEntityTypeEnum> scopes) {
|
||||
|
||||
//1 初始化响应对象:创建响应VO并设置分页大小和批次统计列表
|
||||
IWorkFullSyncRespVO respVO = new IWorkFullSyncRespVO();
|
||||
List<IWorkSyncBatchStatVO> batchStats = new ArrayList<>();
|
||||
respVO.setBatches(batchStats);
|
||||
//2 解析同步范围:根据传入的scopes确定需要同步的实体类型(用户、部门、分部、岗位)
|
||||
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 = manualSync(reqVO);
|
||||
IWorkSyncProcessor.DeptSyncContext deptSyncContext = (syncDepartments || syncSubcompanies)
|
||||
? new IWorkSyncProcessor.DeptSyncContext()
|
||||
: null;
|
||||
//3 按类型执行同步:依次执行分部、部门、岗位、用户的分页同步操作
|
||||
if (syncSubcompanies) {
|
||||
processedPages += runManualFullSyncForSubsidiaries(reqVO, options, respVO.getSubcompanyStat(), batchStats, deptSyncContext);//分部统计信息
|
||||
}
|
||||
if (syncDepartments) {
|
||||
processedPages += departments(reqVO, options, respVO.getDepartmentStat(), batchStats, deptSyncContext);//部门统计信息
|
||||
}
|
||||
if (syncJobTitle) {
|
||||
processedPages += syncPositionsManually(reqVO, options, respVO.getJobTitleStat(), batchStats);//岗位统计信息
|
||||
}
|
||||
if (syncUsers) {
|
||||
processedPages += syncUsers(reqVO, options, respVO.getUserStat(), batchStats);//用户统计信息
|
||||
}
|
||||
//4、处理部门上下文:对部门和分部同步进行特殊处理,包括刷新待处理数据和补全部门编码
|
||||
if (deptSyncContext != null) {
|
||||
IWorkSyncProcessor.BatchResult flushResult = syncProcessor.flushDeptPending(deptSyncContext, options);
|
||||
updateStat(respVO.getDepartmentStat(), flushResult, 0);//部门统计信息
|
||||
if (CollUtil.isNotEmpty(deptSyncContext.getPlaceholderDeptIds())) {
|
||||
deptService.backfillMissingCodesWithoutEvent(deptSyncContext.getPlaceholderDeptIds());
|
||||
}
|
||||
}
|
||||
respVO.setProcessedPages(processedPages);
|
||||
return respVO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 手动同步
|
||||
*/
|
||||
private IWorkSyncProcessor.SyncOptions manualSync(IWorkSyncByIdReqVO reqVO) {
|
||||
boolean includeCanceled = Boolean.TRUE.equals(reqVO.getIncludeCanceled());
|
||||
boolean allowUpdate = Boolean.TRUE.equals(reqVO.getAllowUpdate());
|
||||
return IWorkSyncProcessor.SyncOptions.custom(includeCanceled, allowUpdate, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 手动执行子公司全量同步f
|
||||
*/
|
||||
private int runManualFullSyncForSubsidiaries(IWorkSyncByIdReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
List<IWorkSyncBatchStatVO> batches,
|
||||
IWorkSyncProcessor.DeptSyncContext context) {
|
||||
return paged(reqVO, IWorkSyncEntityTypeEnum.SUBCOMPANY, batches, (page, pageSize) -> {
|
||||
IWorkSubcompanyQueryReqVO query = new IWorkSubcompanyQueryReqVO();
|
||||
query.setCurpage(page);
|
||||
query.setPagesize(pageSize);
|
||||
applyQuery(query, reqVO);//查询条件
|
||||
IWorkHrSubcompanyPageRespVO pageResp = orgRestService.listSubcompanies(query);
|
||||
ensureIWorkSuccess("拉取分部", pageResp.isSuccess(), pageResp.getMessage());// IWork执行成功
|
||||
List<IWorkHrSubcompanyPageRespVO.Subcompany> dataList = CollUtil.emptyIfNull(pageResp.getDataList());
|
||||
IWorkSyncProcessor.BatchResult result = syncProcessor.syncSubcompanies(dataList, options, context);
|
||||
updateStat(stat, result, dataList.size());
|
||||
return new BatchExecution(result, dataList.size());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询条件
|
||||
* @param query 查询条件
|
||||
* @param reqVO 请求
|
||||
*/
|
||||
private void applyQuery(IWorkOrgBaseQueryReqVO query, IWorkSyncByIdReqVO reqVO) {
|
||||
if (query == null || reqVO == null) {
|
||||
return;
|
||||
}
|
||||
if (StrUtil.isBlank(reqVO.getId())) {
|
||||
return;
|
||||
}
|
||||
Map<String, Object> params = query.getParams();
|
||||
if (params == null) {
|
||||
params = new HashMap<>();
|
||||
query.setParams(params);
|
||||
}
|
||||
params.put("id", reqVO.getId());
|
||||
}
|
||||
|
||||
|
||||
private int paged(IWorkSyncByIdReqVO reqVO,
|
||||
IWorkSyncEntityTypeEnum type,
|
||||
List<IWorkSyncBatchStatVO> batches,
|
||||
PageExecutor executor) {
|
||||
int startPage = reqVO.getStartPage() == null ? 1 : reqVO.getStartPage();
|
||||
int pageSize = reqVO.getPageSize() == null ? 100 : reqVO.getPageSize();
|
||||
int pagesLimit = reqVO.getMaxPages() == null ? Integer.MAX_VALUE : reqVO.getMaxPages();
|
||||
int processedPages = 0;
|
||||
for (int page = startPage; processedPages < pagesLimit; page++) {
|
||||
BatchExecution execution = executor.execute(page, pageSize);
|
||||
if (execution == null || execution.totalPulled == 0) {
|
||||
break;
|
||||
}
|
||||
processedPages++;
|
||||
IWorkSyncBatchStatVO batchStat = new IWorkSyncBatchStatVO();
|
||||
batchStat.setEntityType(type);
|
||||
batchStat.setPageNumber(page);
|
||||
batchStat.setPulled(execution.totalPulled);
|
||||
batchStat.setCreated(execution.result.getCreated());
|
||||
batchStat.setSkippedExisting(execution.result.getSkipped());
|
||||
batchStat.setDisabled(execution.result.getDisabled());
|
||||
batchStat.setFailed(execution.result.getFailed());
|
||||
batches.add(batchStat);
|
||||
}
|
||||
return processedPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动执行部门同步
|
||||
*/
|
||||
private int departments(IWorkSyncByIdReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
List<IWorkSyncBatchStatVO> batches,
|
||||
IWorkSyncProcessor.DeptSyncContext context) {
|
||||
return paged(reqVO, IWorkSyncEntityTypeEnum.DEPARTMENT, batches, (page, pageSize) -> {
|
||||
IWorkDepartmentQueryReqVO query = new IWorkDepartmentQueryReqVO();
|
||||
query.setCurpage(page);
|
||||
query.setPagesize(pageSize);
|
||||
applyQuery(query, reqVO);
|
||||
IWorkHrDepartmentPageRespVO pageResp = orgRestService.listDepartments(query);
|
||||
ensureIWorkSuccess("拉取部门", pageResp.isSuccess(), pageResp.getMessage());
|
||||
List<IWorkHrDepartmentPageRespVO.Department> dataList = CollUtil.emptyIfNull(pageResp.getDataList());
|
||||
IWorkSyncProcessor.BatchResult result = syncProcessor.syncDepartments(dataList, options, context);
|
||||
updateStat(stat, result, dataList.size());
|
||||
return new BatchExecution(result, dataList.size());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 手动执行岗位同步
|
||||
*/
|
||||
private int syncPositionsManually(IWorkSyncByIdReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
List<IWorkSyncBatchStatVO> batches) {
|
||||
return paged(reqVO, IWorkSyncEntityTypeEnum.JOB_TITLE, batches, (page, pageSize) -> {
|
||||
IWorkJobTitleQueryReqVO query = new IWorkJobTitleQueryReqVO();
|
||||
query.setCurpage(page);
|
||||
query.setPagesize(pageSize);
|
||||
applyQuery(query, reqVO);
|
||||
IWorkHrJobTitlePageRespVO pageResp = orgRestService.listJobTitles(query);
|
||||
ensureIWorkSuccess("拉取岗位", pageResp.isSuccess(), pageResp.getMessage());
|
||||
List<IWorkHrJobTitlePageRespVO.JobTitle> dataList = CollUtil.emptyIfNull(pageResp.getDataList());
|
||||
IWorkSyncProcessor.BatchResult result = syncProcessor.syncJobTitles(dataList, options);
|
||||
updateStat(stat, result, dataList.size());
|
||||
return new BatchExecution(result, dataList.size());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动执行用户同步
|
||||
*/
|
||||
private int syncUsers(IWorkSyncByIdReqVO reqVO,
|
||||
IWorkSyncProcessor.SyncOptions options,
|
||||
IWorkSyncEntityStatVO stat,
|
||||
List<IWorkSyncBatchStatVO> batches) {
|
||||
return paged(reqVO, IWorkSyncEntityTypeEnum.USER, batches, (page, pageSize) -> {
|
||||
IWorkUserQueryReqVO query = new IWorkUserQueryReqVO();
|
||||
query.setCurpage(page);
|
||||
query.setPagesize(pageSize);
|
||||
applyQuery(query, reqVO);
|
||||
IWorkHrUserPageRespVO pageResp = orgRestService.listUsers(query);
|
||||
ensureIWorkSuccess("拉取人员", pageResp.isSuccess(), pageResp.getMessage());
|
||||
List<IWorkHrUserPageRespVO.User> dataList = CollUtil.emptyIfNull(pageResp.getDataList());
|
||||
IWorkSyncProcessor.BatchResult result = syncProcessor.syncUsers(dataList, options);
|
||||
updateStat(stat, result, dataList.size());
|
||||
return new BatchExecution(result, dataList.size());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user