Преглед на файлове

feature: 同步功能完善(待测试)
1.教职工同步完善

luo.yibo@datuai.com преди 1 година
родител
ревизия
2854c955ca
променени са 27 файла, в които са добавени 1038 реда и са изтрити 155 реда
  1. 1 0
      ruoyi-api/pom.xml
  2. 31 0
      ruoyi-api/ruoyi-api-sync/pom.xml
  3. 15 0
      ruoyi-api/ruoyi-api-sync/src/main/java/org/dromara/sync/api/RemoteKafkaSyncService.java
  4. 153 0
      ruoyi-api/ruoyi-api-sync/src/main/java/org/dromara/sync/api/domain/bo/RemoteConsumeBo.java
  5. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java
  6. 0 136
      ruoyi-server/ruoyi-server-base/src/main/java/org/dromara/server/base/service/dept/strategy/impl/HrDeptStrategyImpl.java
  7. 0 1
      ruoyi-server/ruoyi-server-base/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  8. 6 0
      ruoyi-server/ruoyi-server-mqdata/pom.xml
  9. 13 5
      ruoyi-server/ruoyi-server-mqdata/src/main/java/org/dromara/server/mq/event/kafka/impl/cloud/TeacherEventStrategyImpl.java
  10. 6 0
      ruoyi-server/ruoyi-server-sync/pom.xml
  11. 1 1
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/CreateHttpRequest.java
  12. 1 1
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/SyncGraduateService.java
  13. 2 2
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/SyncHrService.java
  14. 1 1
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/SyncTrainService.java
  15. 35 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/kafka/SyncKafkaService.java
  16. 3 3
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/controller/SyncHand.java
  17. 7 4
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/controller/SyncTest.java
  18. 135 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/domain/SysDept.java
  19. 127 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/domain/bo/SysDeptBo.java
  20. 144 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/domain/vo/SysDeptVo.java
  21. 28 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/dubbo/RemoteKafkaSyncServiceImpl.java
  22. 13 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/mapper/SysDeptMapper.java
  23. 28 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/IDeptService.java
  24. 119 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/impl/DeptServiceImpl.java
  25. 30 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/strategy/dept/ISyncDeptStrategy.java
  26. 131 0
      ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/strategy/dept/impl/HrDeptStrategyImpl.java
  27. 7 0
      ruoyi-server/ruoyi-server-sync/src/main/resources/mapper/SysDeptMapper.xml

+ 1 - 0
ruoyi-api/pom.xml

@@ -16,6 +16,7 @@
         <module>ruoyi-api-backstage</module>
         <module>ruoyi-api-consume</module>
         <module>ruoyi-api-hotel</module>
+        <module>ruoyi-api-sync</module>
     </modules>
 
     <artifactId>ruoyi-api</artifactId>

+ 31 - 0
ruoyi-api/ruoyi-api-sync/pom.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-api</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-api-sync</artifactId>
+
+    <description>
+        ruoyi-api-sync 一卡通同步接口服务模块
+    </description>
+
+    <dependencies>
+
+        <!-- RuoYi Common Core-->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-json</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 15 - 0
ruoyi-api/ruoyi-api-sync/src/main/java/org/dromara/sync/api/RemoteKafkaSyncService.java

@@ -0,0 +1,15 @@
+package org.dromara.sync.api;
+
+import cn.hutool.json.JSONObject;
+
+/**
+ * @ClassName RemoteKafkaSyncService
+ * @Description TODO
+ * @Author luoyibo
+ * @Date 2025-01-24 07:36
+ * @Version 1.0
+ * @since jdk17
+ */
+public interface RemoteKafkaSyncService {
+    void syncTeacherDept(JSONObject data);
+}

+ 153 - 0
ruoyi-api/ruoyi-api-sync/src/main/java/org/dromara/sync/api/domain/bo/RemoteConsumeBo.java

@@ -0,0 +1,153 @@
+package org.dromara.consume.api.domain.bo;
+
+import lombok.Data;
+import org.dromara.common.core.enums.CreditTypeEnum;
+import org.dromara.common.core.enums.SystemUseTypeEnum;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * name: ConsumeBo
+ * package: org.dromara.backstage.consumption.domain.bo
+ * description: 消费业务对象,和消费相关的业务都使用此业务对象
+ *             属性可能会根据业务动态调整,最早的业务是错扣补款业务
+ * date: 2024-09-04 08:53:02 08:53
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+@Data
+public class RemoteConsumeBo implements Serializable {
+    @Serial
+    private static final long serialVersionUID = 3387823485152734748L;
+
+    //region 消费业务基础属性
+    /**
+     * 人员账户Id
+     */
+    private Long userId;
+    /**
+     * 账户流水号
+     */
+    private Long userNo;
+
+    /**
+     * 学/工号
+     */
+    private String userNumb;
+
+    /**
+     * 人员姓名
+     */
+    private String realName;
+
+    /**
+     * 卡流水号
+     */
+    private Long cardNo;
+
+    /**
+     * 物理卡号
+     */
+    private Long factoryId;
+    /**
+     * 钱包代码
+     */
+    private String bagType;
+
+    /**
+     * 消费金额
+     */
+    private BigDecimal consumeMoney;
+
+    /**
+     * 消费钱包余额
+     */
+    private BigDecimal balance;
+    /**
+     * 消费日期
+     */
+    private Date consumeDate;
+
+    /**
+     * 设备机号
+     */
+    private Long termNo;
+
+    /**
+     * 机器流水号
+     */
+    private Long termRecordId;
+    /**
+     * 餐类Id
+     */
+    private Long mealType;
+
+    /**
+     * 消费明细记录Id
+     */
+    private String consumeId;
+
+    /**
+     * 记录Id
+     */
+    private Long recordId;
+    /**
+     * 消费记录标志位?
+     */
+    private Long recordStatus;
+
+    /**
+     * 状态标识(记录消费类型?)
+     */
+    private Integer statusFlag;
+    /**
+     * 系统使用类型
+     */
+    private SystemUseTypeEnum useType;
+    /**
+     * 操作员Id
+     */
+    private Long operatorId;
+    /**
+     * 操作员姓名
+     */
+    private String operatorName;
+
+    /**
+     * 交易类型
+     */
+    private CreditTypeEnum creditType;
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+    /**
+     * 防伪验证码(记录消费模式的中文信息)
+     */
+    private String digitalSign;
+
+    /**
+     * 原始消费记录Id
+     */
+    private String originalId;
+    //endregion
+
+    //region 错扣补款属性
+    /**
+     * 补款日期
+     */
+    private Date fillDate;
+
+    /**
+     * 操作金额
+     */
+    private BigDecimal operatorMoney;
+    //endregion
+}

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java

@@ -77,7 +77,7 @@ public class RemoteDeptServiceImpl implements RemoteDeptService {
      */
     @Override
     public RemoteDeptVo selectDeptByOtherId(String otherId, String tenantId) {
-        SysDeptVo deptVo = sysDeptService.selectVoByOtherId(otherId);
+        SysDeptVo deptVo = sysDeptService.selectVoByOtherId(otherId,tenantId);
         return MapstructUtils.convert(deptVo, RemoteDeptVo.class);
     }
 

+ 0 - 136
ruoyi-server/ruoyi-server-base/src/main/java/org/dromara/server/base/service/dept/strategy/impl/HrDeptStrategyImpl.java

@@ -1,136 +0,0 @@
-package org.dromara.server.base.service.dept.strategy.impl;
-
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.util.ObjUtil;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.constant.DefaultConstants;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.json.utils.JsonUtils;
-import org.dromara.server.base.service.dept.SyncRemoteDeptService;
-import org.dromara.server.base.service.dept.strategy.ISyncDeptStrategy;
-import org.dromara.server.common.constant.SyncResourceConstants;
-import org.dromara.server.common.domain.bo.ResourceDept;
-import org.dromara.system.api.domain.bo.RemoteDeptBo;
-import org.dromara.system.api.domain.vo.RemoteDeptVo;
-import org.springframework.stereotype.Service;
-
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * name: HrDeptStrategyImpl
- * package: org.dromara.server.base.dept.service.strategy.impl
- * description: 人事部门同步处理策略
- * date: 2024-10-18 14:40:23 14:40
- *
- * @author luoyibo
- * @version 0.1
- * @since JDK 1.8
- */
-@Slf4j
-@RequiredArgsConstructor
-@Service(SyncResourceConstants.HR_DEPT)
-public class HrDeptStrategyImpl implements ISyncDeptStrategy {
-    private final SyncRemoteDeptService syncRemoteDeptService;
-
-    @Override
-    public void syncDept(List<ResourceDept> deptList) {
-        List<String> syncMessage = new ArrayList<>();
-        deptList.forEach(resourceDept -> {
-            R<Object> result = syncDept(resourceDept);
-            if (result.getCode() == R.SUCCESS) {
-                syncMessage.add(MessageFormat.format("[同步部门成功]-[{0}]", JsonUtils.toJsonString(resourceDept)));
-            } else {
-                syncMessage.add(MessageFormat.format("[同步部门失败]-[{0}]-[{1}]", JsonUtils.toJsonString(resourceDept), result.getMsg()));
-            }
-        });
-        syncMessage.forEach(System.out::println);
-    }
-
-    @Override
-    public void syncDelDept(List<ResourceDept> deptList) {
-        List<String> syncDelMessage = new ArrayList<>();
-        deptList.forEach(resourceDept -> {
-            R<Object>result = syncRemoteDeptService.deleteDeptByOtherId(resourceDept.getDept_id());
-
-            if (result.getCode() == R.SUCCESS) {
-                syncDelMessage.add(MessageFormat.format("[同步删除部门成功]-[{0}]", JsonUtils.toJsonString(resourceDept)));
-            } else {
-                syncDelMessage.add(MessageFormat.format("[同步删除部门失败]-[{0}]-[{1}]", JsonUtils.toJsonString(resourceDept), result.getMsg()));
-            }
-        });
-        syncDelMessage.forEach(System.out::println);
-    }
-
-    /**
-     * 单个部门处理
-     *
-     * @param resourceDept 源部门
-     * @return 入库部门模型
-     */
-    public R<Object> syncDept(ResourceDept resourceDept) {
-        try {
-            String tenantId = resourceDept.getTenantId();
-            String otherId = resourceDept.getDept_id();
-            String parentId = resourceDept.getParent_id();
-            // 获取同步的部门在一卡通系统中对应的部门
-            RemoteDeptVo remoteDeptVo = syncRemoteDeptService.selectDeptByOtherId(otherId, tenantId);
-            // 获取同步的部门在一卡通系统中对应的父部门
-            RemoteDeptVo remoteParentDeptVo = syncRemoteDeptService.selectDeptByOtherId(parentId, tenantId);
-            // 组装写库的部门业务对象
-            RemoteDeptBo remoteDeptBo = setRemoteDeptBo(resourceDept, remoteDeptVo, remoteParentDeptVo);
-            if (remoteDeptVo != null) {
-                // 已存在此部门,更新
-                return syncRemoteDeptService.updateDept(remoteDeptBo);
-            } else {
-                return syncRemoteDeptService.insertDept(remoteDeptBo);
-            }
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-            return R.fail(e.getMessage());
-        }
-    }
-
-    /**
-     * 同步部门预处理
-     *
-     * @param resourceDept       源部门
-     * @param remoteDeptVo       一卡通系统对应部门
-     * @param remoteParentDeptVo 一卡通系统对应父部门
-     * @return 部门业务对象
-     */
-    private RemoteDeptBo setRemoteDeptBo(ResourceDept resourceDept, RemoteDeptVo remoteDeptVo, RemoteDeptVo remoteParentDeptVo) {
-        String deptNum = resourceDept.getDept_num();
-        String tenantId = resourceDept.getTenantId();
-        RemoteDeptBo remoteDeptBo;
-        if (ObjUtil.isEmpty(remoteDeptVo)) {
-            remoteDeptBo = new RemoteDeptBo();
-            // 业中同步的部门默认类型为03-部门
-            remoteDeptBo.setDeptType(DefaultConstants.DEPT_DEPT_TYPE);
-            remoteDeptBo.setCreateBy(resourceDept.getOperatorId());
-        } else {
-            remoteDeptBo = BeanUtil.copyProperties(remoteDeptVo, RemoteDeptBo.class);
-            remoteDeptBo.setUpdateBy(resourceDept.getOperatorId());
-        }
-        remoteDeptBo.setDeptName(resourceDept.getDept_name());
-        remoteDeptBo.setOtherId(resourceDept.getDept_id());
-        if (StringUtils.isNotEmpty(tenantId)) {
-            remoteDeptBo.setTenantId(tenantId);
-        }
-        if (remoteParentDeptVo != null) {
-            remoteDeptBo.setParentId(remoteParentDeptVo.getDeptId());
-        } else {
-            // 如果同步的部门的父部门在系统中不存在,则父部门为学校
-            if (!remoteDeptBo.getDeptId().equals(DefaultConstants.ROOT_DEPT_ID)) {
-                remoteDeptBo.setParentId(DefaultConstants.ROOT_DEPT_ID);
-            }
-        }
-        if (StringUtils.isNotEmpty(deptNum)) {
-            remoteDeptBo.setOrderNum(Integer.valueOf(deptNum));
-        }
-        return remoteDeptBo;
-    }
-}

+ 0 - 1
ruoyi-server/ruoyi-server-base/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -1,6 +1,5 @@
 org.dromara.server.base.service.dept.SyncRemoteDeptService
 org.dromara.server.base.service.dept.strategy.SyncDeptStrategyContent
-org.dromara.server.base.service.dept.strategy.impl.HrDeptStrategyImpl
 org.dromara.server.base.service.dept.strategy.impl.GraduateClassStrategyImpl
 org.dromara.server.base.service.dept.strategy.impl.TrainClassStrategyImpl
 org.dromara.server.base.service.user.SyncRemoteUserService

+ 6 - 0
ruoyi-server/ruoyi-server-mqdata/pom.xml

@@ -128,6 +128,12 @@
             <version>2.2.0</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-sync</artifactId>
+            <version>2.2.0</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
     <build>

+ 13 - 5
ruoyi-server/ruoyi-server-mqdata/src/main/java/org/dromara/server/mq/event/kafka/impl/cloud/TeacherEventStrategyImpl.java

@@ -3,6 +3,7 @@ package org.dromara.server.mq.event.kafka.impl.cloud;
 import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.message.kafka.constant.EventSenderConstants;
 import org.dromara.common.message.kafka.constant.EventTypeConstants;
 import org.dromara.server.base.service.dept.strategy.SyncDeptStrategyContent;
@@ -12,6 +13,7 @@ import org.dromara.server.common.constant.SyncResourceConstants;
 import org.dromara.server.common.domain.bo.ResourceDept;
 import org.dromara.server.common.domain.bo.ResourcePerson;
 import org.dromara.server.mq.event.kafka.IYktEventStrategy;
+import org.dromara.sync.api.RemoteKafkaSyncService;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -31,13 +33,17 @@ public class TeacherEventStrategyImpl implements IYktEventStrategy {
     private final SyncDeptStrategyContent syncDeptStrategyContent;
     private final SyncUserStrategyContent syncUserStrategyContent;
 
+    @DubboReference
+    private final RemoteKafkaSyncService remoteKafkaSyncService;
+
     @Override
     public void doMsgHandle(String eventType, Object msg) throws Exception {
         switch (eventType) {
             case EventTypeConstants.DEPT_ADD -> {
-                List<ResourceDept> resourceDeptlist = TeacherUtils.getSyncDept(JSONUtil.parseObj(msg));
-                log.info("[处理业务中台->云端部门增加请求]-[部门信息:{}]", JSONUtil.toJsonStr(resourceDeptlist));
-                syncDeptStrategyContent.syncDept(resourceDeptlist, SyncResourceConstants.HR_DEPT);
+                // List<ResourceDept> resourceDeptlist = TeacherUtils.getSyncDept(JSONUtil.parseObj(msg));
+                 log.info("[处理业务中台->云端部门增加请求]-[部门信息:{}]", JSONUtil.toJsonStr(msg));
+                remoteKafkaSyncService.syncTeacherDept(JSONUtil.parseObj(msg));
+                // syncDeptStrategyContent.syncDept(resourceDeptlist, SyncResourceConstants.HR_DEPT);
             }
             case EventTypeConstants.DEPT_EDIT -> {
                 List<ResourceDept> resourceDeptlist = TeacherUtils.getSyncDept(JSONUtil.parseObj(msg));
@@ -45,7 +51,7 @@ public class TeacherEventStrategyImpl implements IYktEventStrategy {
                 syncDeptStrategyContent.syncDept(resourceDeptlist, SyncResourceConstants.HR_DEPT);
             }
             case EventTypeConstants.DEPT_DEL -> {
-                List<ResourceDept> resourceDeptlist = TeacherUtils.getSyncDept(JSONUtil.parseObj(msg));
+                List<ResourceDept> resourceDeptlist = TeacherUtils.getSycDeleteDept(JSONUtil.parseObj(msg));
                 log.info("[处理业务中台->云端部门删除请求]-[部门信息:{}]", JSONUtil.toJsonStr(resourceDeptlist));
                 syncDeptStrategyContent.syncDelDept(resourceDeptlist, SyncResourceConstants.HR_DEPT);
             }
@@ -60,7 +66,9 @@ public class TeacherEventStrategyImpl implements IYktEventStrategy {
                 syncUserStrategyContent.syncUser(resourcePersonList, SyncResourceConstants.TEACHER);
             }
             case EventTypeConstants.TEACHER_DEL -> {
-
+                List<ResourcePerson> resourcePersonList = TeacherUtils.getSyncDeleteTeahcer(JSONUtil.parseObj(msg));
+                log.info("[处理业务中台->云端人员删除请求]-[人员信息:{}]", JSONUtil.toJsonStr(resourcePersonList));
+                syncUserStrategyContent.syncDelUser(resourcePersonList, SyncResourceConstants.TEACHER);
             }
         }
     }

+ 6 - 0
ruoyi-server/ruoyi-server-sync/pom.xml

@@ -113,6 +113,12 @@
             <version>2.2.0</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-sync</artifactId>
+            <version>2.2.0</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
     <build>

+ 1 - 1
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/CreateHttpRequest.java → ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/CreateHttpRequest.java

@@ -1,4 +1,4 @@
-package org.dromara.server.sync.service;
+package org.dromara.server.sync.business.full;
 
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpUtil;

+ 1 - 1
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/SyncGraduateService.java → ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/SyncGraduateService.java

@@ -1,4 +1,4 @@
-package org.dromara.server.sync.service;
+package org.dromara.server.sync.business.full;
 
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;

+ 2 - 2
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/SyncHrService.java → ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/SyncHrService.java

@@ -1,4 +1,4 @@
-package org.dromara.server.sync.service;
+package org.dromara.server.sync.business.full;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.HttpRequest;
@@ -10,7 +10,7 @@ import org.dromara.common.core.config.DefaultConfig;
 import org.dromara.common.core.constant.DefaultConstants;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.SpringUtils;
-import org.dromara.server.base.service.dept.strategy.ISyncDeptStrategy;
+import org.dromara.server.sync.strategy.dept.ISyncDeptStrategy;
 import org.dromara.server.base.service.user.strategy.ISyncUserStrategy;
 import org.dromara.server.common.constant.SyncResourceConstants;
 import org.dromara.server.common.domain.bo.ResourceDept;

+ 1 - 1
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/SyncTrainService.java → ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/full/SyncTrainService.java

@@ -1,4 +1,4 @@
-package org.dromara.server.sync.service;
+package org.dromara.server.sync.business.full;
 
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;

+ 35 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/business/kafka/SyncKafkaService.java

@@ -0,0 +1,35 @@
+package org.dromara.server.sync.business.kafka;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.server.base.util.TeacherUtils;
+import org.dromara.server.common.constant.SyncResourceConstants;
+import org.dromara.server.common.domain.bo.ResourceDept;
+import org.springframework.stereotype.Service;
+import org.dromara.server.sync.strategy.dept.ISyncDeptStrategy;
+import java.util.List;
+
+/**
+ * @ClassName SyncKafkaService
+ * @Description TODO
+ * @Author luoyibo
+ * @Date 2025-01-23 20:59
+ * @Version 1.0
+ * @since jdk17
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class SyncKafkaService {
+
+    public void syncTeacherDept(JSONObject data) {
+        List<ResourceDept> resourceDeptlist = TeacherUtils.getSyncDept(data);
+        log.info("[业中同步测试->部门同步]-[部门信息:{}]", JSONUtil.toJsonStr(resourceDeptlist));
+        ISyncDeptStrategy syncDeptStrategy = SpringUtils.getBean(SyncResourceConstants.HR_DEPT, ISyncDeptStrategy.class);
+        syncDeptStrategy.syncDept(resourceDeptlist);
+    }
+
+}

+ 3 - 3
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/controller/SyncHand.java

@@ -2,9 +2,9 @@ package org.dromara.server.sync.controller;
 
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
-import org.dromara.server.sync.service.SyncGraduateService;
-import org.dromara.server.sync.service.SyncHrService;
-import org.dromara.server.sync.service.SyncTrainService;
+import org.dromara.server.sync.business.full.SyncGraduateService;
+import org.dromara.server.sync.business.full.SyncHrService;
+import org.dromara.server.sync.business.full.SyncTrainService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;

+ 7 - 4
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/controller/SyncTest.java

@@ -13,6 +13,7 @@ import org.dromara.server.base.util.TrainUtils;
 import org.dromara.server.common.constant.SyncResourceConstants;
 import org.dromara.server.common.domain.bo.ResourceDept;
 import org.dromara.server.common.domain.bo.ResourcePerson;
+import org.dromara.server.sync.business.kafka.SyncKafkaService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -35,6 +36,7 @@ import java.util.Map;
 public class SyncTest {
     private final SyncDeptStrategyContent syncDeptStrategyContent;
     private final SyncUserStrategyContent syncUserStrategyContent;
+    private final SyncKafkaService syncKafkaService;
 
     /**
      * 培训班同步测试
@@ -123,10 +125,11 @@ public class SyncTest {
      * @return 同步测试
      */
     @GetMapping("/sync/teacher/dept")
-    public R<Void> syncTeacherDept(@RequestBody Map<String, Object> data) {
-        List<ResourceDept> resourceDeptlist = TeacherUtils.getSyncDept(JSONUtil.parseObj(data));
-        log.info("[业中同步测试->部门同步]-[部门信息:{}]", JSONUtil.toJsonStr(resourceDeptlist));
-        syncDeptStrategyContent.syncDept(resourceDeptlist, SyncResourceConstants.HR_DEPT);
+    public R<Void> syncTeacherDept(@RequestBody Map<String, String> data) {
+        syncKafkaService.syncTeacherDept(JSONUtil.parseObj(data));
+        // List<ResourceDept> resourceDeptlist = TeacherUtils.getSyncDept(JSONUtil.parseObj(data));
+        // log.info("[业中同步测试->部门同步]-[部门信息:{}]", JSONUtil.toJsonStr(resourceDeptlist));
+        // syncDeptStrategyContent.syncDept(resourceDeptlist, SyncResourceConstants.HR_DEPT);
 
         return R.ok();
     }

+ 135 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/domain/SysDept.java

@@ -0,0 +1,135 @@
+package org.dromara.server.sync.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.tenant.core.TenantEntity;
+
+import java.io.Serial;
+import java.util.Date;
+
+
+/**
+ * 部门表 t_sys_dept
+ *
+ * @author Lion Li
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("t_sys_dept")
+public class SysDept extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 部门ID
+     */
+    @TableId(value = "dept_id")
+    private Long deptId;
+
+    /**
+     * 父部门ID
+     */
+    private Long parentId;
+
+    /**
+     * 部门名称
+     */
+    private String deptName;
+
+    /**
+     * 部门类别编码
+     */
+    private String deptType;
+
+    /**
+     * 显示顺序
+     */
+    private Integer orderNum;
+
+    /**
+     * 传真号码
+     */
+    private String fax;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 部门状态:0正常,1停用
+     */
+    private String status;
+
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 主管部门
+     */
+    private Long superDept;
+
+    /**
+     * 主管岗位
+     */
+    private Long superJob;
+
+    /**
+     * 唯一标识
+     */
+    private String otherId;
+
+    /**
+     * 开班日期
+     */
+    private Date beginDate;
+
+    /**
+     * 结业日期
+     */
+    private Date endDate;
+
+    /**
+     * 报到日期
+     */
+    private Date checkDate;
+
+    /**
+     * 是否自主选房
+     */
+    private String chooseRoom;
+
+    /**
+     * 是否就餐
+     */
+    private String canEat;
+
+    /**
+     * 是否先缴费再报到
+     */
+    private String payCheck;
+
+    /**
+     * 缴费开始日期
+     */
+    private Date payBegin;
+
+    /**
+     * 缴费结束日期
+     */
+    private Date payEnd;
+
+
+}

+ 127 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/domain/bo/SysDeptBo.java

@@ -0,0 +1,127 @@
+package org.dromara.server.sync.domain.bo;
+
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.server.sync.domain.SysDept;
+
+import java.util.Date;
+
+/**
+ * 部门业务对象 t_sys_dept
+ *
+ * @author Michelle.Chung
+ */
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SysDept.class, reverseConvertGenerate = false)
+public class SysDeptBo extends BaseEntity {
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 父部门ID
+     */
+    private Long parentId;
+
+    /**
+     * 部门名称
+     */
+    @NotBlank(message = "部门名称不能为空")
+    @Size(min = 0, max = 30, message = "部门名称长度不能超过{max}个字符")
+    private String deptName;
+
+    /**
+     * 部门类别编码
+     */
+    @Size(min = 0, max = 100, message = "部门类别编码长度不能超过{max}个字符")
+    private String deptType;
+
+    /**
+     * 显示顺序
+     */
+    @NotNull(message = "显示顺序不能为空")
+    private Integer orderNum;
+
+    /**
+     * 联系电话
+     */
+    @Size(min = 0, max = 11, message = "联系电话长度不能超过{max}个字符")
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    @Email(message = "邮箱格式不正确")
+    @Size(min = 0, max = 50, message = "邮箱长度不能超过{max}个字符")
+    private String email;
+
+    /**
+     * 部门状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 唯一标识
+     */
+    private String otherId;
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+    /**
+     * 开班日期
+     */
+    private Date beginDate;
+
+    /**
+     * 结业日期
+     */
+    private Date endDate;
+
+    /**
+     * 报到日期
+     */
+    private Date checkDate;
+
+    /**
+     * 是否自主选房
+     */
+    private String chooseRoom;
+
+    /**
+     * 是否就餐
+     */
+    private String canEat;
+
+    /**
+     * 是否先缴费再报到
+     */
+    private String payCheck;
+
+    /**
+     * 缴费开始日期
+     */
+    private Date payBegin;
+
+    /**
+     * 缴费结束日期
+     */
+    private Date payEnd;
+
+    /**
+     * 部门状态
+     */
+    private String delFlag;
+}

+ 144 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/domain/vo/SysDeptVo.java

@@ -0,0 +1,144 @@
+package org.dromara.server.sync.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.server.sync.domain.SysDept;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 部门视图对象 t_sys_dept
+ *
+ * @author Michelle.Chung
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SysDept.class)
+public class SysDeptVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 父部门id
+     */
+    private Long parentId;
+
+    /**
+     * 父部门名称
+     */
+    private String parentName;
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 部门名称
+     */
+    private String deptName;
+
+    /**
+     * 部门类别编码
+     */
+    private String deptType;
+
+    /**
+     * 显示顺序
+     */
+    private Integer orderNum;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 部门状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建者
+     */
+    private Long createBy;
+
+    /**
+     * 更新者
+     */
+    private Long updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+    /**
+     * 唯一标识
+     */
+    private String otherId;
+
+    /**
+     * 开班日期
+     */
+    private Date beginDate;
+
+    /**
+     * 结业日期
+     */
+    private Date endDate;
+
+    /**
+     * 报到日期
+     */
+    private Date checkDate;
+
+    /**
+     * 是否自主选房
+     */
+    private String chooseRoom;
+
+    /**
+     * 是否就餐
+     */
+    private String canEat;
+
+    /**
+     * 是否先缴费再报到
+     */
+    private String payCheck;
+
+    /**
+     * 缴费开始日期
+     */
+    private Date payBegin;
+
+    /**
+     * 缴费结束日期
+     */
+    private Date payEnd;
+}

+ 28 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/dubbo/RemoteKafkaSyncServiceImpl.java

@@ -0,0 +1,28 @@
+package org.dromara.server.sync.dubbo;
+
+import cn.hutool.json.JSONObject;
+import lombok.RequiredArgsConstructor;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.dromara.server.sync.business.kafka.SyncKafkaService;
+import org.dromara.sync.api.RemoteKafkaSyncService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @ClassName RemoteKafkaSyncServiceImpl
+ * @Description TODO
+ * @Author luoyibo
+ * @Date 2025-01-24 07:42
+ * @Version 1.0
+ * @since jdk17
+ */
+
+@Service
+@DubboService
+@RequiredArgsConstructor
+public class RemoteKafkaSyncServiceImpl implements RemoteKafkaSyncService {
+    private final SyncKafkaService syncKafkaService;
+    @Override
+    public void syncTeacherDept(JSONObject data) {
+        syncKafkaService.syncTeacherDept(data);
+    }
+}

+ 13 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/mapper/SysDeptMapper.java

@@ -0,0 +1,13 @@
+package org.dromara.server.sync.mapper;
+
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.dromara.server.sync.domain.SysDept;
+import org.dromara.server.sync.domain.vo.SysDeptVo;
+
+/**
+ * 部门管理 数据层
+ *
+ * @author Lion Li
+ */
+public interface SysDeptMapper extends BaseMapperPlus<SysDept, SysDeptVo> {
+}

+ 28 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/IDeptService.java

@@ -0,0 +1,28 @@
+package org.dromara.server.sync.service;
+
+import org.dromara.common.core.domain.R;
+import org.dromara.server.sync.domain.bo.SysDeptBo;
+import org.dromara.server.sync.domain.vo.SysDeptVo;
+
+/**
+ * @ClassName IDeptService
+ * @Description 部门服务接口
+ * @Author luoyibo
+ * @Date 2025-01-23 21:31
+ * @Version 1.0
+ * @since jdk17
+ */
+public interface IDeptService {
+
+    SysDeptVo selectByOtherId(String otherId, String tenantId);
+
+    SysDeptVo selectByRootId(String tenantId);
+
+    R<SysDeptVo> insertReturnDept(SysDeptBo bo);
+
+    R<SysDeptVo> updateReturnDept(SysDeptBo bo);
+
+    Boolean insertDept(SysDeptBo bo);
+
+    Boolean updateDept(SysDeptBo bo);
+}

+ 119 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/service/impl/DeptServiceImpl.java

@@ -0,0 +1,119 @@
+package org.dromara.server.sync.service.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.server.sync.domain.SysDept;
+import org.dromara.server.sync.domain.bo.SysDeptBo;
+import org.dromara.server.sync.domain.vo.SysDeptVo;
+import org.dromara.server.sync.mapper.SysDeptMapper;
+import org.dromara.server.sync.service.IDeptService;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+
+/**
+ * @ClassName DeptServiceImpl
+ * @Description 部门服务接口实现
+ * @Author luoyibo
+ * @Date 2025-01-23 21:33
+ * @Version 1.0
+ * @since jdk17
+ */
+@Service
+@RequiredArgsConstructor
+public class DeptServiceImpl implements IDeptService {
+    private final SysDeptMapper deptMapper;
+
+    @Override
+    public SysDeptVo selectByOtherId(String otherId, String tenantId) {
+        return TenantHelper.ignore(
+            () -> deptMapper.selectVoOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getOtherId, otherId).eq(SysDept::getTenantId, tenantId)));
+
+    }
+
+    @Override
+    public SysDeptVo selectByRootId(String tenantId) {
+        return TenantHelper.ignore(
+            () -> deptMapper.selectVoOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getParentId, 0L).eq(SysDept::getTenantId, tenantId)));
+    }
+
+    @Override
+    public Boolean insertDept(SysDeptBo bo) {
+        SysDept entity = MapstructUtils.convert(bo, SysDept.class);
+        if (bo.getOrderNum() == null || bo.getOrderNum() == 0) {
+            Objects.requireNonNull(entity).setOrderNum(this.getMaxLevelOrderNumb(bo.getParentId()));
+        }
+        Objects.requireNonNull(entity).setAncestors(getAncestors(bo.getParentId()));
+        int iCount = TenantHelper.ignore(
+            () -> deptMapper.insert(entity));
+        if (iCount > 0) {
+            bo.setDeptId(entity.getDeptId());
+        }
+        return iCount > 0;
+    }
+
+    @Override
+    public Boolean updateDept(SysDeptBo bo) {
+        SysDept entity = MapstructUtils.convert(bo, SysDept.class);
+        SysDept old = TenantHelper.ignore(
+            () -> deptMapper.selectById(bo.getDeptId()));
+        if (entity != null && ObjectUtil.notEqual(entity.getParentId(), old.getParentId())) {
+            // 上级部门变了,要更新祖级列表
+            entity.setAncestors(getAncestors(entity.getParentId()));
+        }
+        int iCount = TenantHelper.ignore(
+            () -> deptMapper.updateById(entity));
+
+        return iCount > 0;
+    }
+
+    @Override
+    public R<SysDeptVo> insertReturnDept(SysDeptBo bo) {
+        Boolean result = this.insertDept(bo);
+        if (result) {
+            return R.ok(TenantHelper.ignore(
+                () -> deptMapper.selectVoById(bo.getDeptId())));
+        }
+        return R.fail();
+    }
+
+    @Override
+    public R<SysDeptVo> updateReturnDept(SysDeptBo bo) {
+        Boolean result = this.updateDept(bo);
+        if (result) {
+            return R.ok(TenantHelper.ignore(
+                () -> deptMapper.selectVoById(bo.getDeptId())));
+        }
+        return R.fail();
+    }
+
+
+    private String getAncestors(Long parentId) {
+        if (ObjectUtil.equals(parentId, 0L)) {
+            return "0";
+        }
+        SysDept parent = TenantHelper.ignore(
+            () -> deptMapper.selectById(parentId));
+
+        return parent.getAncestors() + StringUtils.SEPARATOR + parentId;
+    }
+
+    private Integer getMaxLevelOrderNumb(Long deptId) {
+        QueryWrapper<SysDept> qw = new QueryWrapper<>();
+        qw.select("max(order_num) as order_num");
+        qw.eq("parent_id", deptId);
+        qw.lt("order_num", 999);
+
+        SysDept dept = TenantHelper.ignore(()->deptMapper.selectOne(qw));
+        if (dept == null) {
+            return 1;
+        }
+        return dept.getOrderNum() + 1;
+    }
+}

+ 30 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/strategy/dept/ISyncDeptStrategy.java

@@ -0,0 +1,30 @@
+package org.dromara.server.sync.strategy.dept;
+
+import org.dromara.server.common.domain.bo.ResourceDept;
+
+import java.util.List;
+
+/**
+ * name: IDoDeptStrategy
+ * package: org.dromara.server.base.dept.service.strategy
+ * description: 部门同步写入策略
+ * date: 2024-10-18 14:17:38 14:17
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+public interface ISyncDeptStrategy {
+    /**
+     * 处理部门的部门数据(增加、修改)
+     *
+     * @param deptList 部门数据
+     */
+    void syncDept(List<ResourceDept> deptList);
+
+    /**
+     * 同步删除部门数据
+     * @param deptList 部门列表
+     */
+    void syncDelDept(List<ResourceDept> deptList);
+}

+ 131 - 0
ruoyi-server/ruoyi-server-sync/src/main/java/org/dromara/server/sync/strategy/dept/impl/HrDeptStrategyImpl.java

@@ -0,0 +1,131 @@
+package org.dromara.server.sync.strategy.dept.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.ObjectUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.json.utils.JsonUtils;
+import org.dromara.server.base.service.dept.SyncRemoteDeptService;
+import org.dromara.server.common.constant.SyncResourceConstants;
+import org.dromara.server.common.domain.bo.ResourceDept;
+import org.dromara.server.sync.domain.bo.SysDeptBo;
+import org.dromara.server.sync.domain.vo.SysDeptVo;
+import org.dromara.server.sync.service.IDeptService;
+import org.dromara.server.sync.strategy.dept.ISyncDeptStrategy;
+import org.springframework.stereotype.Service;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * name: HrDeptStrategyImpl
+ * package: org.dromara.server.base.dept.service.strategy.impl
+ * description: 人事部门同步处理策略
+ * date: 2024-10-18 14:40:23 14:40
+ *
+ * @author luoyibo
+ * @version 0.1
+ * @since JDK 1.8
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service(SyncResourceConstants.HR_DEPT)
+public class HrDeptStrategyImpl implements ISyncDeptStrategy {
+    private final SyncRemoteDeptService syncRemoteDeptService;
+    private final IDeptService deptService;
+
+    @Override
+    public void syncDept(List<ResourceDept> deptList) {
+        List<String> syncMessage = new ArrayList<>();
+        deptList.forEach(resourceDept -> {
+            R<Void> result = syncDept(resourceDept);
+            if (result.getCode() == R.SUCCESS) {
+                syncMessage.add(MessageFormat.format("[同步部门成功]-[{0}]", JsonUtils.toJsonString(resourceDept)));
+            } else {
+                syncMessage.add(MessageFormat.format("[同步部门失败]-[{0}]-[{1}]", JsonUtils.toJsonString(resourceDept), result.getMsg()));
+            }
+        });
+        syncMessage.forEach(System.out::println);
+    }
+
+    @Override
+    public void syncDelDept(List<ResourceDept> deptList) {
+        List<String> syncDelMessage = new ArrayList<>();
+        deptList.forEach(resourceDept -> {
+            R<Object> result = syncRemoteDeptService.deleteDeptByOtherId(resourceDept.getDept_id());
+
+            if (result.getCode() == R.SUCCESS) {
+                syncDelMessage.add(MessageFormat.format("[同步删除部门成功]-[{0}]", JsonUtils.toJsonString(resourceDept)));
+            } else {
+                syncDelMessage.add(MessageFormat.format("[同步删除部门失败]-[{0}]-[{1}]", JsonUtils.toJsonString(resourceDept), result.getMsg()));
+            }
+        });
+        syncDelMessage.forEach(System.out::println);
+    }
+
+    /**
+     * 单个部门处理
+     *
+     * @param resourceDept 源部门
+     * @return 入库部门模型
+     */
+    public R<Void> syncDept(ResourceDept resourceDept) {
+        try {
+            String deptNum = resourceDept.getDept_num();
+            String tenantId = resourceDept.getTenantId();
+            String otherId = resourceDept.getDept_id();
+            // 获取同步的部门在一卡通系统中对应的部门
+            SysDeptVo deptVo = deptService.selectByOtherId(otherId, tenantId);
+            SysDeptBo deptBo;
+            if (ObjUtil.isEmpty(deptVo)) {
+                deptBo = new SysDeptBo();
+                if (resourceDept.getParent_id().equals("0")) {
+                    deptBo.setDeptType("01");
+                } else {
+                    deptBo.setDeptType("03");
+                }
+                deptBo.setTenantId(tenantId);
+                deptBo.setCreateBy(resourceDept.getOperatorId());
+            } else {
+                deptBo = BeanUtil.copyProperties(deptVo, SysDeptBo.class);
+                deptBo.setUpdateBy(resourceDept.getOperatorId());
+            }
+            if (StringUtils.isNotEmpty(deptNum)) {
+                deptBo.setOrderNum(Integer.valueOf(deptNum));
+            }
+            deptBo.setDeptName(resourceDept.getDept_name());
+            deptBo.setOtherId(resourceDept.getDept_id());
+            deptBo.setParentId(getParentId(resourceDept));
+
+            Boolean result;
+            if(ObjectUtil.isEmpty(deptVo)) {
+                result =  deptService.insertDept(deptBo);
+            } else {
+                result =  deptService.updateDept(deptBo);
+            }
+
+            return  result ?R.ok():R.fail();
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            return R.fail(e.getMessage());
+        }
+    }
+
+    private Long getParentId(ResourceDept resourceDept) {
+        String tenantId = resourceDept.getTenantId();
+        String parentId = resourceDept.getParent_id();
+        if (ObjectUtil.equals(parentId, "0")) {
+            return 0L;
+        }
+        SysDeptVo parentVo = deptService.selectByOtherId(parentId, tenantId);
+        if (ObjectUtil.isEmpty(parentVo)) {
+            // 如果父部门为空则设置为根部门
+            parentVo = deptService.selectByRootId(tenantId);
+        }
+        return parentVo.getDeptId();
+    }
+}

+ 7 - 0
ruoyi-server/ruoyi-server-sync/src/main/resources/mapper/SysDeptMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.server.sync.mapper.SysDeptMapper">
+
+</mapper>