From 2baede83e50085d13d35bcdd6796fb1ec6b51ac7 Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Wed, 17 Dec 2025 11:31:57 +0800
Subject: [PATCH 1/8] =?UTF-8?q?update=EF=BC=9A=E8=B0=83=E6=95=B4=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E7=94=9F=E4=BA=A7topic=E7=94=9F?=
=?UTF-8?q?=E6=88=90=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../zt/plat/module/databus/enums/DatabusEventType.java | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/enums/DatabusEventType.java b/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/enums/DatabusEventType.java
index 80886ad3..679bfa49 100644
--- a/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/enums/DatabusEventType.java
+++ b/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/enums/DatabusEventType.java
@@ -311,11 +311,14 @@ public enum DatabusEventType {
}
/**
- * 获取完整Topic名称(服务端转发用)
- * 格式: {topicBase}-{module}-{entity}-{action}-{clientCode}
+ * 获取完整Topic名称(服务端转发用 - 统一消费者架构)
+ *
+ * 新架构:所有事件类型都推送到同一个客户端 Topic,通过消息体中的 eventType 字段区分
+ * 格式: {topicBase}-{clientCode}
+ * 示例: databus-sync-hwc-test
*/
public String getTopic(String topicBase, String clientCode) {
- return String.format("%s-%s-%s-%s-%s", topicBase, module, entity, action, clientCode);
+ return String.format("%s-%s", topicBase, clientCode);
}
/**
From 9b0e63a33e519f540345bd136d1cba57dfb8d79f Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Mon, 22 Dec 2025 09:51:05 +0800
Subject: [PATCH 2/8] =?UTF-8?q?update=EF=BC=9A=E8=B0=83=E6=95=B4=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E7=94=A8=E6=88=B7-=E9=83=A8?=
=?UTF-8?q?=E9=97=A8=EF=BC=8C=E7=94=A8=E6=88=B7-=E5=B2=97=E4=BD=8D?=
=?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=A1=BA=E5=BA=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../provider/UserDeptDataFeignProvider.java | 81 ++++++++++
.../provider/UserPostDataFeignProvider.java | 81 ++++++++++
.../provider/DatabusUserDeptProviderApi.java | 71 ++++++++
.../provider/DatabusUserPostProviderApi.java | 71 ++++++++
.../rpc/config/RpcConfiguration.java | 9 +-
.../DatabusUserDeptProviderApiImpl.java | 151 ++++++++++++++++++
.../DatabusUserPostProviderApiImpl.java | 139 ++++++++++++++++
.../module/system/api/dept/PostApiImpl.java | 4 +
8 files changed, 604 insertions(+), 3 deletions(-)
create mode 100644 zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserDeptDataFeignProvider.java
create mode 100644 zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserPostDataFeignProvider.java
create mode 100644 zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserDeptProviderApi.java
create mode 100644 zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserPostProviderApi.java
create mode 100644 zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
create mode 100644 zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java
diff --git a/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserDeptDataFeignProvider.java b/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserDeptDataFeignProvider.java
new file mode 100644
index 00000000..81f3bcf2
--- /dev/null
+++ b/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserDeptDataFeignProvider.java
@@ -0,0 +1,81 @@
+package com.zt.plat.framework.databus.server.provider;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.databus.server.core.provider.DataProvider;
+import com.zt.plat.framework.databus.server.core.provider.DataProviderRegistry;
+import com.zt.plat.module.databus.api.dto.CursorPageReqDTO;
+import com.zt.plat.module.databus.api.dto.CursorPageResult;
+import com.zt.plat.module.databus.api.data.DatabusUserDeptData;
+import com.zt.plat.module.databus.api.provider.DatabusUserDeptProviderApi;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户-部门关系数据提供者
+ */
+@Slf4j
+@Component
+public class UserDeptDataFeignProvider implements DataProvider {
+
+ public static final String PROVIDER_TYPE = "USER_DEPT";
+
+ @Resource
+ private DatabusUserDeptProviderApi userDeptProviderApi;
+
+ @Resource
+ private DataProviderRegistry dataProviderRegistry;
+
+ @PostConstruct
+ public void init() {
+ dataProviderRegistry.register(this);
+ }
+
+ @Override
+ public String getProviderType() {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ public CursorPageData getPageByCursor(LocalDateTime cursorTime, Long cursorId,
+ int batchSize, Long tenantId) {
+ CursorPageReqDTO reqDTO = CursorPageReqDTO.builder()
+ .cursorTime(cursorTime)
+ .cursorId(cursorId)
+ .batchSize(batchSize)
+ .tenantId(tenantId)
+ .build();
+
+ CommonResult> result = userDeptProviderApi.getPageByCursor(reqDTO);
+ if (!result.isSuccess()) {
+ throw new RuntimeException("获取用户-部门关系数据失败: " + result.getMsg());
+ }
+
+ CursorPageResult pageResult = result.getData();
+ return CursorPageData.of(
+ pageResult.getList(),
+ pageResult.getNextCursorTime(),
+ pageResult.getNextCursorId(),
+ pageResult.getCount(),
+ Boolean.TRUE.equals(pageResult.getHasMore()),
+ (pageResult.getTotal() != null ? pageResult.getTotal() : 0L)
+ );
+ }
+
+ @Override
+ public long count(Long tenantId) {
+ CommonResult result = userDeptProviderApi.count(tenantId);
+ if (!result.isSuccess()) {
+ throw new RuntimeException("获取用户-部门关系总数失败: " + result.getMsg());
+ }
+ return result.getData();
+ }
+
+ @Override
+ public Long extractUid(DatabusUserDeptData data) {
+ return data.getId();
+ }
+}
diff --git a/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserPostDataFeignProvider.java b/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserPostDataFeignProvider.java
new file mode 100644
index 00000000..b7df241a
--- /dev/null
+++ b/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/provider/UserPostDataFeignProvider.java
@@ -0,0 +1,81 @@
+package com.zt.plat.framework.databus.server.provider;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.databus.server.core.provider.DataProvider;
+import com.zt.plat.framework.databus.server.core.provider.DataProviderRegistry;
+import com.zt.plat.module.databus.api.dto.CursorPageReqDTO;
+import com.zt.plat.module.databus.api.dto.CursorPageResult;
+import com.zt.plat.module.databus.api.data.DatabusUserPostData;
+import com.zt.plat.module.databus.api.provider.DatabusUserPostProviderApi;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户-岗位关系数据提供者
+ */
+@Slf4j
+@Component
+public class UserPostDataFeignProvider implements DataProvider {
+
+ public static final String PROVIDER_TYPE = "USER_POST";
+
+ @Resource
+ private DatabusUserPostProviderApi userPostProviderApi;
+
+ @Resource
+ private DataProviderRegistry dataProviderRegistry;
+
+ @PostConstruct
+ public void init() {
+ dataProviderRegistry.register(this);
+ }
+
+ @Override
+ public String getProviderType() {
+ return PROVIDER_TYPE;
+ }
+
+ @Override
+ public CursorPageData getPageByCursor(LocalDateTime cursorTime, Long cursorId,
+ int batchSize, Long tenantId) {
+ CursorPageReqDTO reqDTO = CursorPageReqDTO.builder()
+ .cursorTime(cursorTime)
+ .cursorId(cursorId)
+ .batchSize(batchSize)
+ .tenantId(tenantId)
+ .build();
+
+ CommonResult> result = userPostProviderApi.getPageByCursor(reqDTO);
+ if (!result.isSuccess()) {
+ throw new RuntimeException("获取用户-岗位关系数据失败: " + result.getMsg());
+ }
+
+ CursorPageResult pageResult = result.getData();
+ return CursorPageData.of(
+ pageResult.getList(),
+ pageResult.getNextCursorTime(),
+ pageResult.getNextCursorId(),
+ pageResult.getCount(),
+ Boolean.TRUE.equals(pageResult.getHasMore()),
+ (pageResult.getTotal() != null ? pageResult.getTotal() : 0L)
+ );
+ }
+
+ @Override
+ public long count(Long tenantId) {
+ CommonResult result = userPostProviderApi.count(tenantId);
+ if (!result.isSuccess()) {
+ throw new RuntimeException("获取用户-岗位关系总数失败: " + result.getMsg());
+ }
+ return result.getData();
+ }
+
+ @Override
+ public Long extractUid(DatabusUserPostData data) {
+ return data.getId();
+ }
+}
diff --git a/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserDeptProviderApi.java b/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserDeptProviderApi.java
new file mode 100644
index 00000000..5e393626
--- /dev/null
+++ b/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserDeptProviderApi.java
@@ -0,0 +1,71 @@
+package com.zt.plat.module.databus.api.provider;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.module.databus.api.data.DatabusUserDeptData;
+import com.zt.plat.module.databus.api.dto.CursorPageReqDTO;
+import com.zt.plat.module.databus.api.dto.CursorPageResult;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * Databus 用户-部门关系数据提供者 API
+ *
+ * 供 Databus 调用,获取用户-部门关联数据用于全量/增量同步
+ *
+ * @author ZT
+ */
+@FeignClient(name = "${databus.provider.user-dept.service:system-server}")
+@Tag(name = "RPC 服务 - Databus 用户-部门关系数据提供者")
+public interface DatabusUserDeptProviderApi {
+
+ String PREFIX = "/rpc/databus/user-dept";
+
+ /**
+ * 游标分页查询用户-部门关系数据(用于全量同步)
+ *
+ * @param reqDTO 游标分页请求
+ * @return 用户-部门关系数据分页结果
+ */
+ @PostMapping(PREFIX + "/page-by-cursor")
+ @Operation(summary = "游标分页查询用户-部门关系数据")
+ CommonResult> getPageByCursor(@RequestBody CursorPageReqDTO reqDTO);
+
+ /**
+ * 根据ID查询用户-部门关系详情(用于增量同步)
+ *
+ * @param id 关系ID
+ * @return 用户-部门关系数据
+ */
+ @GetMapping(PREFIX + "/get")
+ @Operation(summary = "查询用户-部门关系详情")
+ @Parameter(name = "id", description = "关系ID", required = true, example = "1001")
+ CommonResult getById(@RequestParam("id") Long id);
+
+ /**
+ * 批量查询用户-部门关系详情(用于增量同步批量获取)
+ *
+ * @param ids 关系ID列表
+ * @return 用户-部门关系数据列表
+ */
+ @GetMapping(PREFIX + "/list")
+ @Operation(summary = "批量查询用户-部门关系详情")
+ @Parameter(name = "ids", description = "关系ID列表", required = true, example = "1001,1002,1003")
+ CommonResult> getListByIds(@RequestParam("ids") List ids);
+
+ /**
+ * 统计用户-部门关系总数(用于全量同步进度计算)
+ *
+ * @param tenantId 租户ID(可选)
+ * @return 用户-部门关系总数
+ */
+ @GetMapping(PREFIX + "/count")
+ @Operation(summary = "统计用户-部门关系总数")
+ @Parameter(name = "tenantId", description = "租户ID", example = "1")
+ CommonResult count(@RequestParam(value = "tenantId", required = false) Long tenantId);
+
+}
diff --git a/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserPostProviderApi.java b/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserPostProviderApi.java
new file mode 100644
index 00000000..6e00365d
--- /dev/null
+++ b/zt-module-databus/zt-module-databus-api/src/main/java/com/zt/plat/module/databus/api/provider/DatabusUserPostProviderApi.java
@@ -0,0 +1,71 @@
+package com.zt.plat.module.databus.api.provider;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.module.databus.api.data.DatabusUserPostData;
+import com.zt.plat.module.databus.api.dto.CursorPageReqDTO;
+import com.zt.plat.module.databus.api.dto.CursorPageResult;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * Databus 用户-岗位关系数据提供者 API
+ *
+ * 供 Databus 调用,获取用户-岗位关联数据用于全量/增量同步
+ *
+ * @author ZT
+ */
+@FeignClient(name = "${databus.provider.user-post.service:system-server}")
+@Tag(name = "RPC 服务 - Databus 用户-岗位关系数据提供者")
+public interface DatabusUserPostProviderApi {
+
+ String PREFIX = "/rpc/databus/user-post";
+
+ /**
+ * 游标分页查询用户-岗位关系数据(用于全量同步)
+ *
+ * @param reqDTO 游标分页请求
+ * @return 用户-岗位关系数据分页结果
+ */
+ @PostMapping(PREFIX + "/page-by-cursor")
+ @Operation(summary = "游标分页查询用户-岗位关系数据")
+ CommonResult> getPageByCursor(@RequestBody CursorPageReqDTO reqDTO);
+
+ /**
+ * 根据ID查询用户-岗位关系详情(用于增量同步)
+ *
+ * @param id 关系ID
+ * @return 用户-岗位关系数据
+ */
+ @GetMapping(PREFIX + "/get")
+ @Operation(summary = "查询用户-岗位关系详情")
+ @Parameter(name = "id", description = "关系ID", required = true, example = "1001")
+ CommonResult getById(@RequestParam("id") Long id);
+
+ /**
+ * 批量查询用户-岗位关系详情(用于增量同步批量获取)
+ *
+ * @param ids 关系ID列表
+ * @return 用户-岗位关系数据列表
+ */
+ @GetMapping(PREFIX + "/list")
+ @Operation(summary = "批量查询用户-岗位关系详情")
+ @Parameter(name = "ids", description = "关系ID列表", required = true, example = "1001,1002,1003")
+ CommonResult> getListByIds(@RequestParam("ids") List ids);
+
+ /**
+ * 统计用户-岗位关系总数(用于全量同步进度计算)
+ *
+ * @param tenantId 租户ID(可选)
+ * @return 用户-岗位关系总数
+ */
+ @GetMapping(PREFIX + "/count")
+ @Operation(summary = "统计用户-岗位关系总数")
+ @Parameter(name = "tenantId", description = "租户ID", example = "1")
+ CommonResult count(@RequestParam(value = "tenantId", required = false) Long tenantId);
+
+}
diff --git a/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java b/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java
index 32e911e1..c62e2b2d 100644
--- a/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java
+++ b/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java
@@ -4,6 +4,8 @@ import com.zt.plat.framework.common.biz.system.oauth2.OAuth2TokenCommonApi;
import com.zt.plat.module.databus.api.provider.DatabusDeptProviderApi;
import com.zt.plat.module.databus.api.provider.DatabusPostProviderApi;
import com.zt.plat.module.databus.api.provider.DatabusUserProviderApi;
+import com.zt.plat.module.databus.api.provider.DatabusUserDeptProviderApi;
+import com.zt.plat.module.databus.api.provider.DatabusUserPostProviderApi;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.PostApi;
import com.zt.plat.module.system.api.user.AdminUserApi;
@@ -21,9 +23,10 @@ import org.springframework.context.annotation.Configuration;
DatabusDeptProviderApi.class,
DatabusUserProviderApi.class,
DatabusPostProviderApi.class,
- PostApi.class,
- DeptApi.class,
- AdminUserApi.class,
+ DatabusUserDeptProviderApi.class,
+ DatabusUserPostProviderApi.class,
+ PostApi.class,
+ DeptApi.class,
})
public class RpcConfiguration {
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
new file mode 100644
index 00000000..15b375eb
--- /dev/null
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
@@ -0,0 +1,151 @@
+package com.zt.plat.module.system.api.databus;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.module.databus.api.data.DatabusUserDeptData;
+import com.zt.plat.module.databus.api.dto.CursorPageReqDTO;
+import com.zt.plat.module.databus.api.dto.CursorPageResult;
+import com.zt.plat.module.databus.api.provider.DatabusUserDeptProviderApi;
+import com.zt.plat.module.system.dal.dataobject.userdept.UserDeptDO;
+import com.zt.plat.module.system.dal.mysql.userdept.UserDeptMapper;
+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.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * Databus 用户-部门关系数据提供者 API 实现
+ *
+ * @author ZT
+ */
+@Slf4j
+@RestController
+@Validated
+public class DatabusUserDeptProviderApiImpl implements DatabusUserDeptProviderApi {
+
+ @Resource
+ private UserDeptMapper userDeptMapper;
+
+ @Override
+ public CommonResult> getPageByCursor(CursorPageReqDTO reqDTO) {
+ // 构建游标查询条件
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+
+ // 游标条件:create_time > cursorTime OR (create_time = cursorTime AND id > cursorId)
+ if (!reqDTO.isFirstPage()) {
+ queryWrapper.and(w -> w
+ .gt(UserDeptDO::getCreateTime, reqDTO.getCursorTime())
+ .or(o -> o
+ .eq(UserDeptDO::getCreateTime, reqDTO.getCursorTime())
+ .gt(UserDeptDO::getId, reqDTO.getCursorId())
+ )
+ );
+ }
+
+ // 租户过滤(如果指定)
+ if (reqDTO.getTenantId() != null) {
+ queryWrapper.eq(UserDeptDO::getTenantId, reqDTO.getTenantId());
+ }
+
+ // 按 create_time, id 升序排列,确保顺序稳定
+ queryWrapper.orderByAsc(UserDeptDO::getCreateTime)
+ .orderByAsc(UserDeptDO::getId);
+
+ // 多查一条判断是否有更多数据
+ int limit = reqDTO.getBatchSize() != null ? reqDTO.getBatchSize() : 100;
+ queryWrapper.last("LIMIT " + (limit + 1));
+
+ List list = userDeptMapper.selectList(queryWrapper);
+
+ // 判断是否有更多
+ boolean hasMore = list.size() > limit;
+ if (hasMore) {
+ list = list.subList(0, limit);
+ }
+
+ if (CollUtil.isEmpty(list)) {
+ return success(CursorPageResult.empty());
+ }
+
+ // 转换为同步数据
+ List dataList = list.stream()
+ .map(this::convertToData)
+ .collect(Collectors.toList());
+
+ // 获取最后一条数据的游标
+ UserDeptDO last = list.get(list.size() - 1);
+
+ // 首次查询时返回总数
+ Long total = null;
+ if (reqDTO.isFirstPage()) {
+ LambdaQueryWrapper countWrapper = new LambdaQueryWrapper<>();
+ if (reqDTO.getTenantId() != null) {
+ countWrapper.eq(UserDeptDO::getTenantId, reqDTO.getTenantId());
+ }
+ total = userDeptMapper.selectCount(countWrapper);
+ }
+
+ return success(CursorPageResult.of(
+ dataList,
+ last.getCreateTime(),
+ last.getId(),
+ hasMore,
+ total
+ ));
+ }
+
+ @Override
+ public CommonResult getById(Long id) {
+ UserDeptDO userDept = userDeptMapper.selectById(id);
+ if (userDept == null) {
+ return success(null);
+ }
+ return success(convertToData(userDept));
+ }
+
+ @Override
+ public CommonResult> getListByIds(List ids) {
+ if (CollUtil.isEmpty(ids)) {
+ return success(Collections.emptyList());
+ }
+
+ List list = userDeptMapper.selectBatchIds(ids);
+ if (CollUtil.isEmpty(list)) {
+ return success(Collections.emptyList());
+ }
+
+ return success(list.stream()
+ .map(this::convertToData)
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public CommonResult count(Long tenantId) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ if (tenantId != null) {
+ queryWrapper.eq(UserDeptDO::getTenantId, tenantId);
+ }
+ return success(userDeptMapper.selectCount(queryWrapper));
+ }
+
+ /**
+ * 将 UserDeptDO 转换为 DatabusUserDeptData
+ */
+ private DatabusUserDeptData convertToData(UserDeptDO userDept) {
+ return DatabusUserDeptData.builder()
+ .id(userDept.getId())
+ .userId(userDept.getUserId())
+ .deptId(userDept.getDeptId())
+ .tenantId(userDept.getTenantId())
+ .remark(userDept.getRemark())
+ .build();
+ }
+
+}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java
new file mode 100644
index 00000000..96db8704
--- /dev/null
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java
@@ -0,0 +1,139 @@
+package com.zt.plat.module.system.api.databus;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.module.databus.api.data.DatabusUserPostData;
+import com.zt.plat.module.databus.api.dto.CursorPageReqDTO;
+import com.zt.plat.module.databus.api.dto.CursorPageResult;
+import com.zt.plat.module.databus.api.provider.DatabusUserPostProviderApi;
+import com.zt.plat.module.system.dal.dataobject.dept.UserPostDO;
+import com.zt.plat.module.system.dal.mysql.dept.UserPostMapper;
+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.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * Databus 用户-岗位关系数据提供者 API 实现
+ *
+ * @author ZT
+ */
+@Slf4j
+@RestController
+@Validated
+public class DatabusUserPostProviderApiImpl implements DatabusUserPostProviderApi {
+
+ @Resource
+ private UserPostMapper userPostMapper;
+
+ @Override
+ public CommonResult> getPageByCursor(CursorPageReqDTO reqDTO) {
+ // 构建游标查询条件
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+
+ // 游标条件:create_time > cursorTime OR (create_time = cursorTime AND id > cursorId)
+ if (!reqDTO.isFirstPage()) {
+ queryWrapper.and(w -> w
+ .gt(UserPostDO::getCreateTime, reqDTO.getCursorTime())
+ .or(o -> o
+ .eq(UserPostDO::getCreateTime, reqDTO.getCursorTime())
+ .gt(UserPostDO::getId, reqDTO.getCursorId())
+ )
+ );
+ }
+
+ // 注意:UserPostDO 没有租户字段,忽略 tenantId 过滤
+
+ // 按 create_time, id 升序排列,确保顺序稳定
+ queryWrapper.orderByAsc(UserPostDO::getCreateTime)
+ .orderByAsc(UserPostDO::getId);
+
+ // 多查一条判断是否有更多数据
+ int limit = reqDTO.getBatchSize() != null ? reqDTO.getBatchSize() : 100;
+ queryWrapper.last("LIMIT " + (limit + 1));
+
+ List list = userPostMapper.selectList(queryWrapper);
+
+ // 判断是否有更多
+ boolean hasMore = list.size() > limit;
+ if (hasMore) {
+ list = list.subList(0, limit);
+ }
+
+ if (CollUtil.isEmpty(list)) {
+ return success(CursorPageResult.empty());
+ }
+
+ // 转换为同步数据
+ List dataList = list.stream()
+ .map(this::convertToData)
+ .collect(Collectors.toList());
+
+ // 获取最后一条数据的游标
+ UserPostDO last = list.get(list.size() - 1);
+
+ // 首次查询时返回总数
+ Long total = null;
+ if (reqDTO.isFirstPage()) {
+ total = userPostMapper.selectCount(new LambdaQueryWrapper<>());
+ }
+
+ return success(CursorPageResult.of(
+ dataList,
+ last.getCreateTime(),
+ last.getId(),
+ hasMore,
+ total
+ ));
+ }
+
+ @Override
+ public CommonResult getById(Long id) {
+ UserPostDO userPost = userPostMapper.selectById(id);
+ if (userPost == null) {
+ return success(null);
+ }
+ return success(convertToData(userPost));
+ }
+
+ @Override
+ public CommonResult> getListByIds(List ids) {
+ if (CollUtil.isEmpty(ids)) {
+ return success(Collections.emptyList());
+ }
+
+ List list = userPostMapper.selectBatchIds(ids);
+ if (CollUtil.isEmpty(list)) {
+ return success(Collections.emptyList());
+ }
+
+ return success(list.stream()
+ .map(this::convertToData)
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public CommonResult count(Long tenantId) {
+ // 注意:UserPostDO 没有租户字段,返回全量总数
+ return success(userPostMapper.selectCount(new LambdaQueryWrapper<>()));
+ }
+
+ /**
+ * 将 UserPostDO 转换为 DatabusUserPostData
+ */
+ private DatabusUserPostData convertToData(UserPostDO userPost) {
+ return DatabusUserPostData.builder()
+ .id(userPost.getId())
+ .userId(userPost.getUserId())
+ .postId(userPost.getPostId())
+ .build();
+ }
+
+}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java
index 40c7e22b..97cf029e 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java
@@ -10,6 +10,7 @@ import com.zt.plat.module.system.controller.admin.dept.vo.post.PostSaveReqVO;
import com.zt.plat.module.system.dal.dataobject.dept.PostDO;
import com.zt.plat.module.system.service.dept.PostService;
import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
@@ -20,6 +21,7 @@ import java.util.List;
import static com.zt.plat.framework.common.pojo.CommonResult.success;
+@Slf4j
@RestController // 提供 RESTful API 接口,给 Feign 调用
@Validated
public class PostApiImpl implements PostApi {
@@ -36,6 +38,7 @@ public class PostApiImpl implements PostApi {
@Override
public CommonResult updatePost(PostSaveReqDTO updateReqVO) {
+ log.error("ssssssssss");
PostSaveReqVO reqVO = BeanUtils.toBean(updateReqVO, PostSaveReqVO.class);
postService.updatePost(reqVO);
return success(true);
@@ -49,6 +52,7 @@ public class PostApiImpl implements PostApi {
@Override
public CommonResult getPost(Long id) {
+ log.error("cccccccc"+id);
PostDO post = postService.getPost(id);
return success(BeanUtils.toBean(post, PostRespDTO.class));
}
From 7ef5545dc03cee9dcfb94bf15b20b791a0add029 Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Mon, 22 Dec 2025 11:03:15 +0800
Subject: [PATCH 3/8] =?UTF-8?q?update=EF=BC=9A=E8=B0=83=E6=95=B4=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E7=94=A8=E6=88=B7-=E9=83=A8?=
=?UTF-8?q?=E9=97=A8=EF=BC=8C=E7=94=A8=E6=88=B7-=E5=B2=97=E4=BD=8D?=
=?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=A1=BA=E5=BA=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../userdept/UserDeptSyncServiceImpl.java | 85 ++++++++++++++-----
.../userpost/UserPostSyncServiceImpl.java | 84 +++++++++++++-----
.../consumer/DatabusUserChangeConsumer.java | 10 ++-
.../rpc/config/RpcConfiguration.java | 4 +
.../system/api/userdept/UserDeptApi.java | 64 ++++++++++++++
.../api/userdept/dto/UserDeptRespDTO.java | 31 +++++++
.../api/userdept/dto/UserDeptSaveReqDTO.java | 26 ++++++
.../system/api/userpost/UserPostApi.java | 64 ++++++++++++++
.../api/userpost/dto/UserPostRespDTO.java | 28 ++++++
.../api/userpost/dto/UserPostSaveReqDTO.java | 23 +++++
.../DatabusUserDeptProviderApiImpl.java | 48 +++--------
.../DatabusUserPostProviderApiImpl.java | 36 +++-----
.../databus/DatabusUserProviderApiImpl.java | 7 ++
.../system/dal/mysql/dept/UserPostMapper.java | 43 ++++++++++
.../dal/mysql/userdept/UserDeptMapper.java | 43 ++++++++++
15 files changed, 494 insertions(+), 102 deletions(-)
create mode 100644 zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java
create mode 100644 zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptRespDTO.java
create mode 100644 zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptSaveReqDTO.java
create mode 100644 zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java
create mode 100644 zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostRespDTO.java
create mode 100644 zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostSaveReqDTO.java
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java
index 9027e379..04f16ae4 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java
@@ -1,56 +1,101 @@
package com.zt.plat.framework.databus.client.handler.userdept;
import com.zt.plat.module.databus.api.data.DatabusUserDeptData;
+import com.zt.plat.module.system.api.userdept.UserDeptApi;
+import com.zt.plat.module.system.api.userdept.dto.UserDeptSaveReqDTO;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
- * 用户-部门关系同步服务实现
+ * 用户-部门关系同步服务实现(通过 Feign API 调用远程服务)
*
* 使用条件:
* 1. zt.databus.sync.client.enabled=true
+ * 2. 系统中存在 UserDeptApi 接口(Feign 客户端)
*
- * 注意:由于用户-部门关系通常集成在用户管理中,此实现为占位符。
- * 分公司可以根据实际情况:
- * 1. 自定义实现此接口,直接操作本地数据库
- * 2. 或者通过用户管理 API 间接处理关联关系
+ * 如果分公司需要自定义实现,可以创建自己的 UserDeptSyncService Bean,
+ * 此默认实现会自动失效(@ConditionalOnMissingBean)
*
* @author ZT
*/
@Slf4j
@Service
@ConditionalOnProperty(prefix = "zt.databus.sync.client", name = "enabled", havingValue = "true")
+@ConditionalOnClass(name = "com.zt.plat.module.system.api.userdept.UserDeptApi")
public class UserDeptSyncServiceImpl implements UserDeptSyncService {
+ @Autowired(required = false)
+ private UserDeptApi userDeptApi; // Feign 远程调用接口
+
@Override
public void create(DatabusUserDeptData data) {
- log.info("[UserDeptSync] 收到创建用户-部门关系请求, userId={}, deptId={}",
- data.getUserId(), data.getDeptId());
- log.warn("[UserDeptSync] 用户-部门关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法,通过本地 API 或直接数据库操作完成同步
+ if (userDeptApi == null) {
+ log.warn("[UserDeptSync] UserDeptApi未注入,跳过创建用户-部门关系, userId={}", data.getUserId());
+ return;
+ }
+ UserDeptSaveReqDTO dto = buildUserDeptDTO(data);
+ userDeptApi.createUserDept(dto).checkError();
+ log.info("[UserDeptSync] 用户-部门关系创建成功, userId={}, deptId={}", data.getUserId(), data.getDeptId());
}
@Override
public void update(DatabusUserDeptData data) {
- log.info("[UserDeptSync] 收到更新用户-部门关系请求, userId={}, deptId={}",
- data.getUserId(), data.getDeptId());
- log.warn("[UserDeptSync] 用户-部门关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法
+ if (userDeptApi == null) {
+ log.warn("[UserDeptSync] UserDeptApi未注入,跳过更新用户-部门关系, userId={}", data.getUserId());
+ return;
+ }
+ UserDeptSaveReqDTO dto = buildUserDeptDTO(data);
+ userDeptApi.updateUserDept(dto).checkError();
+ log.info("[UserDeptSync] 用户-部门关系更新成功, userId={}, deptId={}", data.getUserId(), data.getDeptId());
}
@Override
public void delete(Long id) {
- log.info("[UserDeptSync] 收到删除用户-部门关系请求, id={}", id);
- log.warn("[UserDeptSync] 用户-部门关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法
+ if (userDeptApi == null) {
+ log.warn("[UserDeptSync] UserDeptApi未注入,跳过删除用户-部门关系, id={}", id);
+ return;
+ }
+ userDeptApi.deleteUserDept(id).checkError();
+ log.info("[UserDeptSync] 用户-部门关系删除成功, id={}", id);
}
@Override
public void fullSync(DatabusUserDeptData data) {
- log.info("[UserDeptSync] 收到全量同步用户-部门关系请求, userId={}, deptId={}",
- data.getUserId(), data.getDeptId());
- log.warn("[UserDeptSync] 用户-部门关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法,逻辑:存在则更新,不存在则插入
+ if (userDeptApi == null) {
+ log.warn("[UserDeptSync] UserDeptApi未注入,跳过全量同步用户-部门关系, userId={}", data.getUserId());
+ return;
+ }
+ UserDeptSaveReqDTO dto = buildUserDeptDTO(data);
+ try {
+ // 尝试获取,存在则更新,不存在则创建
+ var existing = userDeptApi.getUserDept(dto.getId());
+ if (existing.isSuccess() && existing.getData() != null) {
+ userDeptApi.updateUserDept(dto).checkError();
+ log.info("[UserDeptSync] 用户-部门关系全量同步-更新成功, id={}", dto.getId());
+ } else {
+ userDeptApi.createUserDept(dto).checkError();
+ log.info("[UserDeptSync] 用户-部门关系全量同步-创建成功, id={}", dto.getId());
+ }
+ } catch (Exception e) {
+ // 获取失败,尝试创建
+ log.warn("[UserDeptSync] 用户-部门关系获取失败,尝试创建, id={}", dto.getId());
+ userDeptApi.createUserDept(dto).checkError();
+ log.info("[UserDeptSync] 用户-部门关系全量同步-创建成功, id={}", dto.getId());
+ }
+ }
+
+ /**
+ * 构建用户部门关系 DTO(用于 Feign 调用)
+ */
+ private UserDeptSaveReqDTO buildUserDeptDTO(DatabusUserDeptData data) {
+ UserDeptSaveReqDTO dto = new UserDeptSaveReqDTO();
+ dto.setId(data.getId());
+ dto.setUserId(data.getUserId());
+ dto.setDeptId(data.getDeptId());
+ dto.setRemark(data.getRemark());
+ return dto;
}
}
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java
index b41d6ac8..01eb2b4b 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java
@@ -1,56 +1,100 @@
package com.zt.plat.framework.databus.client.handler.userpost;
import com.zt.plat.module.databus.api.data.DatabusUserPostData;
+import com.zt.plat.module.system.api.userpost.UserPostApi;
+import com.zt.plat.module.system.api.userpost.dto.UserPostSaveReqDTO;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
/**
- * 用户-岗位关系同步服务实现
+ * 用户-岗位关系同步服务实现(通过 Feign API 调用远程服务)
*
* 使用条件:
* 1. zt.databus.sync.client.enabled=true
+ * 2. 系统中存在 UserPostApi 接口(Feign 客户端)
*
- * 注意:由于用户-岗位关系通常集成在用户管理中,此实现为占位符。
- * 分公司可以根据实际情况:
- * 1. 自定义实现此接口,直接操作本地数据库
- * 2. 或者通过用户管理 API 间接处理关联关系
+ * 如果分公司需要自定义实现,可以创建自己的 UserPostSyncService Bean,
+ * 此默认实现会自动失效(@ConditionalOnMissingBean)
*
* @author ZT
*/
@Slf4j
@Service
@ConditionalOnProperty(prefix = "zt.databus.sync.client", name = "enabled", havingValue = "true")
+@ConditionalOnClass(name = "com.zt.plat.module.system.api.userpost.UserPostApi")
public class UserPostSyncServiceImpl implements UserPostSyncService {
+ @Autowired(required = false)
+ private UserPostApi userPostApi; // Feign 远程调用接口
+
@Override
public void create(DatabusUserPostData data) {
- log.info("[UserPostSync] 收到创建用户-岗位关系请求, userId={}, postId={}",
- data.getUserId(), data.getPostId());
- log.warn("[UserPostSync] 用户-岗位关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法,通过本地 API 或直接数据库操作完成同步
+ if (userPostApi == null) {
+ log.warn("[UserPostSync] UserPostApi未注入,跳过创建用户-岗位关系, userId={}", data.getUserId());
+ return;
+ }
+ UserPostSaveReqDTO dto = buildUserPostDTO(data);
+ userPostApi.createUserPost(dto).checkError();
+ log.info("[UserPostSync] 用户-岗位关系创建成功, userId={}, postId={}", data.getUserId(), data.getPostId());
}
@Override
public void update(DatabusUserPostData data) {
- log.info("[UserPostSync] 收到更新用户-岗位关系请求, userId={}, postId={}",
- data.getUserId(), data.getPostId());
- log.warn("[UserPostSync] 用户-岗位关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法
+ if (userPostApi == null) {
+ log.warn("[UserPostSync] UserPostApi未注入,跳过更新用户-岗位关系, userId={}", data.getUserId());
+ return;
+ }
+ UserPostSaveReqDTO dto = buildUserPostDTO(data);
+ userPostApi.updateUserPost(dto).checkError();
+ log.info("[UserPostSync] 用户-岗位关系更新成功, userId={}, postId={}", data.getUserId(), data.getPostId());
}
@Override
public void delete(Long id) {
- log.info("[UserPostSync] 收到删除用户-岗位关系请求, id={}", id);
- log.warn("[UserPostSync] 用户-岗位关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法
+ if (userPostApi == null) {
+ log.warn("[UserPostSync] UserPostApi未注入,跳过删除用户-岗位关系, id={}", id);
+ return;
+ }
+ userPostApi.deleteUserPost(id).checkError();
+ log.info("[UserPostSync] 用户-岗位关系删除成功, id={}", id);
}
@Override
public void fullSync(DatabusUserPostData data) {
- log.info("[UserPostSync] 收到全量同步用户-岗位关系请求, userId={}, postId={}",
- data.getUserId(), data.getPostId());
- log.warn("[UserPostSync] 用户-岗位关系同步服务需要分公司自定义实现,当前为占位符实现");
- // TODO: 分公司需要实现此方法,逻辑:存在则更新,不存在则插入
+ if (userPostApi == null) {
+ log.warn("[UserPostSync] UserPostApi未注入,跳过全量同步用户-岗位关系, userId={}", data.getUserId());
+ return;
+ }
+ UserPostSaveReqDTO dto = buildUserPostDTO(data);
+ try {
+ // 尝试获取,存在则更新,不存在则创建
+ var existing = userPostApi.getUserPost(dto.getId());
+ if (existing.isSuccess() && existing.getData() != null) {
+ userPostApi.updateUserPost(dto).checkError();
+ log.info("[UserPostSync] 用户-岗位关系全量同步-更新成功, id={}", dto.getId());
+ } else {
+ userPostApi.createUserPost(dto).checkError();
+ log.info("[UserPostSync] 用户-岗位关系全量同步-创建成功, id={}", dto.getId());
+ }
+ } catch (Exception e) {
+ // 获取失败,尝试创建
+ log.warn("[UserPostSync] 用户-岗位关系获取失败,尝试创建, id={}", dto.getId());
+ userPostApi.createUserPost(dto).checkError();
+ log.info("[UserPostSync] 用户-岗位关系全量同步-创建成功, id={}", dto.getId());
+ }
+ }
+
+ /**
+ * 构建用户岗位关系 DTO(用于 Feign 调用)
+ */
+ private UserPostSaveReqDTO buildUserPostDTO(DatabusUserPostData data) {
+ UserPostSaveReqDTO dto = new UserPostSaveReqDTO();
+ dto.setId(data.getId());
+ dto.setUserId(data.getUserId());
+ dto.setPostId(data.getPostId());
+ return dto;
}
}
diff --git a/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/consumer/DatabusUserChangeConsumer.java b/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/consumer/DatabusUserChangeConsumer.java
index dd3a52e0..43fd8e97 100644
--- a/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/consumer/DatabusUserChangeConsumer.java
+++ b/zt-framework/zt-spring-boot-starter-databus-server/src/main/java/com/zt/plat/framework/databus/server/consumer/DatabusUserChangeConsumer.java
@@ -34,7 +34,15 @@ public class DatabusUserChangeConsumer implements RocketMQListener dataMap = new HashMap<>();
diff --git a/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java b/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java
index c62e2b2d..d79beb52 100644
--- a/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java
+++ b/zt-module-databus/zt-module-databus-server/src/main/java/com/zt/plat/module/databus/framework/rpc/config/RpcConfiguration.java
@@ -9,6 +9,8 @@ import com.zt.plat.module.databus.api.provider.DatabusUserPostProviderApi;
import com.zt.plat.module.system.api.dept.DeptApi;
import com.zt.plat.module.system.api.dept.PostApi;
import com.zt.plat.module.system.api.user.AdminUserApi;
+import com.zt.plat.module.system.api.userdept.UserDeptApi;
+import com.zt.plat.module.system.api.userpost.UserPostApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@@ -27,6 +29,8 @@ import org.springframework.context.annotation.Configuration;
DatabusUserPostProviderApi.class,
PostApi.class,
DeptApi.class,
+ UserDeptApi.class,
+ UserPostApi.class,
})
public class RpcConfiguration {
}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java
new file mode 100644
index 00000000..d48c6b69
--- /dev/null
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java
@@ -0,0 +1,64 @@
+package com.zt.plat.module.system.api.userdept;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.module.system.api.userdept.dto.UserDeptRespDTO;
+import com.zt.plat.module.system.api.userdept.dto.UserDeptSaveReqDTO;
+import com.zt.plat.module.system.enums.ApiConstants;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 用户-部门关系 Feign API
+ *
+ * @author ZT
+ */
+@FeignClient(name = ApiConstants.NAME)
+@Tag(name = "RPC 服务 - 用户部门关系")
+public interface UserDeptApi {
+
+ String PREFIX = ApiConstants.PREFIX + "/user-dept";
+
+ @PostMapping(PREFIX + "/create")
+ @Operation(summary = "新增用户部门关系")
+ CommonResult createUserDept(@RequestBody UserDeptSaveReqDTO reqVO);
+
+ @PutMapping(PREFIX + "/update")
+ @Operation(summary = "修改用户部门关系")
+ CommonResult updateUserDept(@RequestBody UserDeptSaveReqDTO reqVO);
+
+ @DeleteMapping(PREFIX + "/delete")
+ @Operation(summary = "删除用户部门关系")
+ @Parameter(name = "id", description = "关系编号", example = "1", required = true)
+ CommonResult deleteUserDept(@RequestParam("id") Long id);
+
+ @GetMapping(PREFIX + "/get")
+ @Operation(summary = "通过ID查询用户部门关系")
+ @Parameter(name = "id", description = "关系编号", example = "1", required = true)
+ CommonResult getUserDept(@RequestParam("id") Long id);
+
+ @GetMapping(PREFIX + "/list-by-user-id")
+ @Operation(summary = "通过用户ID查询用户部门关系列表")
+ @Parameter(name = "userId", description = "用户编号", example = "1", required = true)
+ CommonResult> getUserDeptListByUserId(@RequestParam("userId") Long userId);
+
+ @GetMapping(PREFIX + "/list-by-dept-id")
+ @Operation(summary = "通过部门ID查询用户部门关系列表")
+ @Parameter(name = "deptId", description = "部门编号", example = "1", required = true)
+ CommonResult> getUserDeptListByDeptId(@RequestParam("deptId") Long deptId);
+
+ @DeleteMapping(PREFIX + "/delete-by-user-id")
+ @Operation(summary = "通过用户ID删除用户部门关系")
+ @Parameter(name = "userId", description = "用户编号", example = "1", required = true)
+ CommonResult deleteUserDeptByUserId(@RequestParam("userId") Long userId);
+
+ @DeleteMapping(PREFIX + "/delete-by-dept-id")
+ @Operation(summary = "通过部门ID删除用户部门关系")
+ @Parameter(name = "deptId", description = "部门编号", example = "1", required = true)
+ CommonResult deleteUserDeptByDeptId(@RequestParam("deptId") Long deptId);
+}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptRespDTO.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptRespDTO.java
new file mode 100644
index 00000000..5a558b90
--- /dev/null
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptRespDTO.java
@@ -0,0 +1,31 @@
+package com.zt.plat.module.system.api.userdept.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户部门关系 Response DTO
+ *
+ * @author ZT
+ */
+@Schema(description = "RPC 服务 - 用户部门关系 Response DTO")
+@Data
+public class UserDeptRespDTO {
+
+ @Schema(description = "关系编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "用户编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "部门编号", example = "100")
+ private Long deptId;
+
+ @Schema(description = "备注", example = "主部门")
+ private String remark;
+
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptSaveReqDTO.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptSaveReqDTO.java
new file mode 100644
index 00000000..b18f2a56
--- /dev/null
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/dto/UserDeptSaveReqDTO.java
@@ -0,0 +1,26 @@
+package com.zt.plat.module.system.api.userdept.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 用户部门关系创建/修改 Request DTO
+ *
+ * @author ZT
+ */
+@Schema(description = "RPC 服务 - 用户部门关系创建/修改 Request DTO")
+@Data
+public class UserDeptSaveReqDTO {
+
+ @Schema(description = "关系编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "用户编号", example = "1", required = true)
+ private Long userId;
+
+ @Schema(description = "部门编号", example = "100", required = true)
+ private Long deptId;
+
+ @Schema(description = "备注", example = "主部门")
+ private String remark;
+}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java
new file mode 100644
index 00000000..a58e09cb
--- /dev/null
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java
@@ -0,0 +1,64 @@
+package com.zt.plat.module.system.api.userpost;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.module.system.api.userpost.dto.UserPostRespDTO;
+import com.zt.plat.module.system.api.userpost.dto.UserPostSaveReqDTO;
+import com.zt.plat.module.system.enums.ApiConstants;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 用户-岗位关系 Feign API
+ *
+ * @author ZT
+ */
+@FeignClient(name = ApiConstants.NAME)
+@Tag(name = "RPC 服务 - 用户岗位关系")
+public interface UserPostApi {
+
+ String PREFIX = ApiConstants.PREFIX + "/user-post";
+
+ @PostMapping(PREFIX + "/create")
+ @Operation(summary = "新增用户岗位关系")
+ CommonResult createUserPost(@RequestBody UserPostSaveReqDTO reqVO);
+
+ @PutMapping(PREFIX + "/update")
+ @Operation(summary = "修改用户岗位关系")
+ CommonResult updateUserPost(@RequestBody UserPostSaveReqDTO reqVO);
+
+ @DeleteMapping(PREFIX + "/delete")
+ @Operation(summary = "删除用户岗位关系")
+ @Parameter(name = "id", description = "关系编号", example = "1", required = true)
+ CommonResult deleteUserPost(@RequestParam("id") Long id);
+
+ @GetMapping(PREFIX + "/get")
+ @Operation(summary = "通过ID查询用户岗位关系")
+ @Parameter(name = "id", description = "关系编号", example = "1", required = true)
+ CommonResult getUserPost(@RequestParam("id") Long id);
+
+ @GetMapping(PREFIX + "/list-by-user-id")
+ @Operation(summary = "通过用户ID查询用户岗位关系列表")
+ @Parameter(name = "userId", description = "用户编号", example = "1", required = true)
+ CommonResult> getUserPostListByUserId(@RequestParam("userId") Long userId);
+
+ @GetMapping(PREFIX + "/list-by-post-id")
+ @Operation(summary = "通过岗位ID查询用户岗位关系列表")
+ @Parameter(name = "postId", description = "岗位编号", example = "1", required = true)
+ CommonResult> getUserPostListByPostId(@RequestParam("postId") Long postId);
+
+ @DeleteMapping(PREFIX + "/delete-by-user-id")
+ @Operation(summary = "通过用户ID删除用户岗位关系")
+ @Parameter(name = "userId", description = "用户编号", example = "1", required = true)
+ CommonResult deleteUserPostByUserId(@RequestParam("userId") Long userId);
+
+ @DeleteMapping(PREFIX + "/delete-by-post-id")
+ @Operation(summary = "通过岗位ID删除用户岗位关系")
+ @Parameter(name = "postId", description = "岗位编号", example = "1", required = true)
+ CommonResult deleteUserPostByPostId(@RequestParam("postId") Long postId);
+}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostRespDTO.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostRespDTO.java
new file mode 100644
index 00000000..e7251a61
--- /dev/null
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostRespDTO.java
@@ -0,0 +1,28 @@
+package com.zt.plat.module.system.api.userpost.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户岗位关系 Response DTO
+ *
+ * @author ZT
+ */
+@Schema(description = "RPC 服务 - 用户岗位关系 Response DTO")
+@Data
+public class UserPostRespDTO {
+
+ @Schema(description = "关系编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "用户编号", example = "1")
+ private Long userId;
+
+ @Schema(description = "岗位编号", example = "100")
+ private Long postId;
+
+ @Schema(description = "创建时间")
+ private LocalDateTime createTime;
+}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostSaveReqDTO.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostSaveReqDTO.java
new file mode 100644
index 00000000..4ad5af68
--- /dev/null
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/dto/UserPostSaveReqDTO.java
@@ -0,0 +1,23 @@
+package com.zt.plat.module.system.api.userpost.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 用户岗位关系创建/修改 Request DTO
+ *
+ * @author ZT
+ */
+@Schema(description = "RPC 服务 - 用户岗位关系创建/修改 Request DTO")
+@Data
+public class UserPostSaveReqDTO {
+
+ @Schema(description = "关系编号", example = "1024")
+ private Long id;
+
+ @Schema(description = "用户编号", example = "1", required = true)
+ private Long userId;
+
+ @Schema(description = "岗位编号", example = "100", required = true)
+ private Long postId;
+}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
index 15b375eb..3a461df9 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
@@ -35,34 +35,16 @@ public class DatabusUserDeptProviderApiImpl implements DatabusUserDeptProviderAp
@Override
public CommonResult> getPageByCursor(CursorPageReqDTO reqDTO) {
- // 构建游标查询条件
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
-
- // 游标条件:create_time > cursorTime OR (create_time = cursorTime AND id > cursorId)
- if (!reqDTO.isFirstPage()) {
- queryWrapper.and(w -> w
- .gt(UserDeptDO::getCreateTime, reqDTO.getCursorTime())
- .or(o -> o
- .eq(UserDeptDO::getCreateTime, reqDTO.getCursorTime())
- .gt(UserDeptDO::getId, reqDTO.getCursorId())
- )
- );
- }
-
- // 租户过滤(如果指定)
- if (reqDTO.getTenantId() != null) {
- queryWrapper.eq(UserDeptDO::getTenantId, reqDTO.getTenantId());
- }
-
- // 按 create_time, id 升序排列,确保顺序稳定
- queryWrapper.orderByAsc(UserDeptDO::getCreateTime)
- .orderByAsc(UserDeptDO::getId);
-
// 多查一条判断是否有更多数据
int limit = reqDTO.getBatchSize() != null ? reqDTO.getBatchSize() : 100;
- queryWrapper.last("LIMIT " + (limit + 1));
- List list = userDeptMapper.selectList(queryWrapper);
+ // ⚠️ 使用关联查询,只查询 userSource = 2 的用户的部门关系
+ List list = userDeptMapper.selectPageByCursorWithUserSource(
+ reqDTO.isFirstPage() ? null : reqDTO.getCursorTime(),
+ reqDTO.isFirstPage() ? null : reqDTO.getCursorId(),
+ reqDTO.getTenantId(),
+ limit + 1
+ );
// 判断是否有更多
boolean hasMore = list.size() > limit;
@@ -82,14 +64,11 @@ public class DatabusUserDeptProviderApiImpl implements DatabusUserDeptProviderAp
// 获取最后一条数据的游标
UserDeptDO last = list.get(list.size() - 1);
- // 首次查询时返回总数
+ // 首次查询时返���总数
Long total = null;
if (reqDTO.isFirstPage()) {
- LambdaQueryWrapper countWrapper = new LambdaQueryWrapper<>();
- if (reqDTO.getTenantId() != null) {
- countWrapper.eq(UserDeptDO::getTenantId, reqDTO.getTenantId());
- }
- total = userDeptMapper.selectCount(countWrapper);
+ // ⚠️ 只统计 userSource = 2 的用户的部门关系
+ total = userDeptMapper.countWithUserSource(reqDTO.getTenantId());
}
return success(CursorPageResult.of(
@@ -128,11 +107,8 @@ public class DatabusUserDeptProviderApiImpl implements DatabusUserDeptProviderAp
@Override
public CommonResult count(Long tenantId) {
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
- if (tenantId != null) {
- queryWrapper.eq(UserDeptDO::getTenantId, tenantId);
- }
- return success(userDeptMapper.selectCount(queryWrapper));
+ // ⚠️ 只统计 userSource = 2 的用户的部门关系
+ return success(userDeptMapper.countWithUserSource(tenantId));
}
/**
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java
index 96db8704..faabe471 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserPostProviderApiImpl.java
@@ -35,31 +35,16 @@ public class DatabusUserPostProviderApiImpl implements DatabusUserPostProviderAp
@Override
public CommonResult> getPageByCursor(CursorPageReqDTO reqDTO) {
- // 构建游标查询条件
- LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
-
- // 游标条件:create_time > cursorTime OR (create_time = cursorTime AND id > cursorId)
- if (!reqDTO.isFirstPage()) {
- queryWrapper.and(w -> w
- .gt(UserPostDO::getCreateTime, reqDTO.getCursorTime())
- .or(o -> o
- .eq(UserPostDO::getCreateTime, reqDTO.getCursorTime())
- .gt(UserPostDO::getId, reqDTO.getCursorId())
- )
- );
- }
-
- // 注意:UserPostDO 没有租户字段,忽略 tenantId 过滤
-
- // 按 create_time, id 升序排列,确保顺序稳定
- queryWrapper.orderByAsc(UserPostDO::getCreateTime)
- .orderByAsc(UserPostDO::getId);
-
// 多查一条判断是否有更多数据
int limit = reqDTO.getBatchSize() != null ? reqDTO.getBatchSize() : 100;
- queryWrapper.last("LIMIT " + (limit + 1));
- List list = userPostMapper.selectList(queryWrapper);
+ // ⚠️ 使用关联查询,只查询 userSource = 2 的用户的岗位关系
+ List list = userPostMapper.selectPageByCursorWithUserSource(
+ reqDTO.isFirstPage() ? null : reqDTO.getCursorTime(),
+ reqDTO.isFirstPage() ? null : reqDTO.getCursorId(),
+ reqDTO.getTenantId(),
+ limit + 1
+ );
// 判断是否有更多
boolean hasMore = list.size() > limit;
@@ -82,7 +67,8 @@ public class DatabusUserPostProviderApiImpl implements DatabusUserPostProviderAp
// 首次查询时返回总数
Long total = null;
if (reqDTO.isFirstPage()) {
- total = userPostMapper.selectCount(new LambdaQueryWrapper<>());
+ // ⚠️ 只统计 userSource = 2 的用户的岗位关系
+ total = userPostMapper.countWithUserSource(reqDTO.getTenantId());
}
return success(CursorPageResult.of(
@@ -121,8 +107,8 @@ public class DatabusUserPostProviderApiImpl implements DatabusUserPostProviderAp
@Override
public CommonResult count(Long tenantId) {
- // 注意:UserPostDO 没有租户字段,返回全量总数
- return success(userPostMapper.selectCount(new LambdaQueryWrapper<>()));
+ // ⚠️ 只统计 userSource = 2 的用户的岗位关系
+ return success(userPostMapper.countWithUserSource(tenantId));
}
/**
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserProviderApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserProviderApiImpl.java
index 286b9984..f6b9050a 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserProviderApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserProviderApiImpl.java
@@ -54,6 +54,9 @@ public class DatabusUserProviderApiImpl implements DatabusUserProviderApi {
// 构建游标查询条件
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ // ⚠️ 只同步 userSource = 2 的用户
+ queryWrapper.eq(AdminUserDO::getUserSource, 2);
+
// 游标条件:create_time > cursorTime OR (create_time = cursorTime AND id > cursorId)
if (!reqDTO.isFirstPage()) {
queryWrapper.and(w -> w
@@ -100,6 +103,8 @@ public class DatabusUserProviderApiImpl implements DatabusUserProviderApi {
Long total = null;
if (reqDTO.isFirstPage()) {
LambdaQueryWrapper countWrapper = new LambdaQueryWrapper<>();
+ // ⚠️ 只统计 userSource = 2 的用户
+ countWrapper.eq(AdminUserDO::getUserSource, 2);
if (reqDTO.getTenantId() != null) {
countWrapper.eq(AdminUserDO::getTenantId, reqDTO.getTenantId());
}
@@ -143,6 +148,8 @@ public class DatabusUserProviderApiImpl implements DatabusUserProviderApi {
@Override
public CommonResult count(Long tenantId) {
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ // ⚠️ 只统计 userSource = 2 的用户
+ queryWrapper.eq(AdminUserDO::getUserSource, 2);
if (tenantId != null) {
queryWrapper.eq(AdminUserDO::getTenantId, tenantId);
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/UserPostMapper.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/UserPostMapper.java
index fa9bd6aa..2df5c891 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/UserPostMapper.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/UserPostMapper.java
@@ -5,7 +5,10 @@ import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.module.system.dal.dataobject.dept.UserPostDO;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
@@ -29,4 +32,44 @@ public interface UserPostMapper extends BaseMapperX {
default void deleteByUserId(Long userId) {
delete(Wrappers.lambdaUpdate(UserPostDO.class).eq(UserPostDO::getUserId, userId));
}
+
+ /**
+ * 游标分页查询用户-岗位关系(只查询 userSource = 2 的用户)
+ * @param cursorTime 游标时间
+ * @param cursorId 游标ID
+ * @param tenantId 租户ID(可选)
+ * @param limit 限制数量
+ * @return 用户岗位关系列表
+ */
+ @Select("")
+ List selectPageByCursorWithUserSource(@Param("cursorTime") LocalDateTime cursorTime,
+ @Param("cursorId") Long cursorId,
+ @Param("tenantId") Long tenantId,
+ @Param("limit") Integer limit);
+
+ /**
+ * 统计用户-岗位关系数量(只统计 userSource = 2 的用户)
+ * @param tenantId 租户ID(可选)
+ * @return 数量
+ */
+ @Select("")
+ Long countWithUserSource(@Param("tenantId") Long tenantId);
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/userdept/UserDeptMapper.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/userdept/UserDeptMapper.java
index b9aad69a..bf21f41d 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/userdept/UserDeptMapper.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/userdept/UserDeptMapper.java
@@ -4,7 +4,10 @@ import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.module.system.dal.dataobject.userdept.UserDeptDO;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -45,4 +48,44 @@ public interface UserDeptMapper extends BaseMapperX {
);
}
+ /**
+ * 游标分页查询用户-部门关系(只查询 userSource = 2 的用户)
+ * @param cursorTime 游标时间
+ * @param cursorId 游标ID
+ * @param tenantId 租户ID(可选)
+ * @param limit 限制数量
+ * @return 用户部门关系列表
+ */
+ @Select("")
+ List selectPageByCursorWithUserSource(@Param("cursorTime") LocalDateTime cursorTime,
+ @Param("cursorId") Long cursorId,
+ @Param("tenantId") Long tenantId,
+ @Param("limit") Integer limit);
+
+ /**
+ * 统计用户-部门关系数量(只统计 userSource = 2 的用户)
+ * @param tenantId 租户ID(可选)
+ * @return 数量
+ */
+ @Select("")
+ Long countWithUserSource(@Param("tenantId") Long tenantId);
+
}
\ No newline at end of file
From 7f54e7f07df30695c2fd29b06d35e082dbc67be9 Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Tue, 23 Dec 2025 18:20:42 +0800
Subject: [PATCH 4/8] =?UTF-8?q?update=EF=BC=9A=E5=8D=87=E7=BA=A7seata?=
=?UTF-8?q?=E7=89=88=E6=9C=AC=E5=88=B02.4.0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
zt-dependencies/pom.xml | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/zt-dependencies/pom.xml b/zt-dependencies/pom.xml
index b0a132d9..a519b38d 100644
--- a/zt-dependencies/pom.xml
+++ b/zt-dependencies/pom.xml
@@ -32,6 +32,7 @@
3.4.5
2024.0.1
2023.0.3.2
+ 2.4.0
2.8.3
4.6.0
@@ -132,6 +133,18 @@
import
+
+
+ org.apache.seata
+ seata-all
+ ${seata.version}
+
+
+ org.apache.seata
+ seata-spring-boot-starter
+ ${seata.version}
+
+
io.github.mouzt
From 516198ab53d12253839530614e41388d203378ee Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Wed, 24 Dec 2025 10:36:00 +0800
Subject: [PATCH 5/8] =?UTF-8?q?update=EF=BC=9A=E8=B0=83=E6=95=B4=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E7=94=A8=E6=88=B7-=E9=83=A8?=
=?UTF-8?q?=E9=97=A8=EF=BC=8C=E7=94=A8=E6=88=B7-=E5=B2=97=E4=BD=8D?=
=?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../core/consumer/DatabusClientConsumer.java | 7 +-
.../handler/dept/DeptSyncServiceImpl.java | 25 ++---
.../handler/post/PostSyncServiceImpl.java | 23 +---
.../user/AdminUserSyncServiceImpl.java | 19 +---
.../userdept/UserDeptSyncServiceImpl.java | 19 +---
.../userpost/UserPostSyncServiceImpl.java | 19 +---
.../plat/module/system/api/dept/DeptApi.java | 6 +
.../plat/module/system/api/dept/PostApi.java | 6 +
.../system/api/dept/dto/DeptSaveReqDTO.java | 15 +++
.../module/system/api/user/AdminUserApi.java | 6 +
.../api/user/dto/AdminUserSaveReqDTO.java | 6 +
.../system/api/userdept/UserDeptApi.java | 6 +
.../system/api/userpost/UserPostApi.java | 6 +
.../DatabusUserDeptProviderApiImpl.java | 6 +-
.../module/system/api/dept/DeptApiImpl.java | 9 ++
.../module/system/api/dept/PostApiImpl.java | 8 +-
.../system/api/user/AdminUserApiImpl.java | 7 ++
.../system/api/userdept/UserDeptApiImpl.java | 88 +++++++++++++++
.../system/api/userpost/UserPostApiImpl.java | 106 ++++++++++++++++++
.../system/dal/mysql/dept/DeptMapper.java | 7 +-
.../system/service/dept/DeptService.java | 11 ++
.../system/service/dept/DeptServiceImpl.java | 37 ++++++
.../system/service/dept/PostService.java | 4 +
.../system/service/dept/PostServiceImpl.java | 21 ++++
.../system/service/user/AdminUserService.java | 4 +
.../service/user/AdminUserServiceImpl.java | 44 ++++++++
.../service/userdept/UserDeptService.java | 3 +
.../service/userdept/UserDeptServiceImpl.java | 20 +++-
28 files changed, 460 insertions(+), 78 deletions(-)
create mode 100644 zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApiImpl.java
create mode 100644 zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApiImpl.java
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/core/consumer/DatabusClientConsumer.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/core/consumer/DatabusClientConsumer.java
index 4a7c5cdb..0000776e 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/core/consumer/DatabusClientConsumer.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/core/consumer/DatabusClientConsumer.java
@@ -13,7 +13,7 @@ import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
-
+import com.zt.plat.framework.tenant.core.context.TenantContextHolder;
/**
* DataBus 客户端统一消费者
*
@@ -33,8 +33,8 @@ import org.springframework.stereotype.Component;
@Component
@ConditionalOnProperty(prefix = "zt.databus.sync.client", name = "enabled", havingValue = "true")
@RocketMQMessageListener(
- topic = "${zt.databus.sync.client.mq.topic:databus-sync}-${zt.databus.sync.client.client-code}",
- consumerGroup = "${zt.databus.sync.client.mq.consumer-group:databus-client-consumer}-${zt.databus.sync.client.client-code}"
+ topic = "${zt.databus.sync.client.mq.topic-base:databus-sync}-${zt.databus.sync.client.client-code}",
+ consumerGroup = "${zt.databus.sync.client.mq.consumer-group-prefix:databus-client-consumer}-${zt.databus.sync.client.client-code}"
)
public class DatabusClientConsumer implements RocketMQListener {
@@ -46,6 +46,7 @@ public class DatabusClientConsumer implements RocketMQListener {
log.debug("[DatabusClient] 收到消息, body={}", body);
try {
+ TenantContextHolder.setTenantId(1L);
// 1. 解析消息获取 eventType
DatabusEventType eventType = parseEventType(body);
if (eventType == null) {
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/dept/DeptSyncServiceImpl.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/dept/DeptSyncServiceImpl.java
index ca760435..00d9913a 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/dept/DeptSyncServiceImpl.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/dept/DeptSyncServiceImpl.java
@@ -69,21 +69,15 @@ public class DeptSyncServiceImpl implements DeptSyncService {
return;
}
DeptSaveReqDTO dto = buildDeptDTO(data);
+
+ // 使用专用同步接口,跳过业务校验,直接 upsert
try {
- // 尝试获取,存在则更新,不存在则创建
- var existing = deptApi.getDept(dto.getId());
- if (existing.isSuccess() && existing.getData() != null) {
- deptApi.updateDept(dto).checkError();
- log.info("[DeptSync] 部门全量同步-更新成功, deptId={}", dto.getId());
- } else {
- deptApi.createDept(dto).checkError();
- log.info("[DeptSync] 部门全量同步-创建成功, deptId={}", dto.getId());
- }
+ deptApi.syncDept(dto).checkError();
+ log.info("[DeptSync] 部门全量同步成功, deptId={}, deptName={}", dto.getId(), dto.getName());
} catch (Exception e) {
- // 获取失败,尝试创建
- log.warn("[DeptSync] 部门获取失败,尝试创建, deptId={}", dto.getId());
- deptApi.createDept(dto).checkError();
- log.info("[DeptSync] 部门全量同步-创建成功, deptId={}", dto.getId());
+ log.error("[DeptSync] 部门全量同步失败, deptId={}, deptName={}, parentId={}, code={}, error={}",
+ dto.getId(), dto.getName(), dto.getParentId(), dto.getCode(), e.getMessage());
+ throw e;
}
}
@@ -93,13 +87,18 @@ public class DeptSyncServiceImpl implements DeptSyncService {
private DeptSaveReqDTO buildDeptDTO(DatabusDeptData data) {
DeptSaveReqDTO dto = new DeptSaveReqDTO();
dto.setId(data.getId());
+ dto.setCode(data.getCode()); // ⚠️ 重要:传递编码,保持一致
dto.setName(data.getName());
+ dto.setShortName(data.getShortName());
dto.setParentId(data.getParentId());
dto.setSort(data.getSort());
dto.setLeaderUserId(data.getLeaderUserId());
dto.setPhone(data.getPhone());
dto.setEmail(data.getEmail());
dto.setStatus(data.getStatus());
+ dto.setIsGroup(data.getIsGroup());
+ dto.setIsCompany(data.getIsCompany());
+ dto.setDeptSource(data.getDeptSource());
return dto;
}
}
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/post/PostSyncServiceImpl.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/post/PostSyncServiceImpl.java
index 463fdc6e..6ad68f2e 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/post/PostSyncServiceImpl.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/post/PostSyncServiceImpl.java
@@ -68,25 +68,14 @@ public class PostSyncServiceImpl implements PostSyncService {
return;
}
PostSaveReqDTO dto = buildPostDTO(data);
+
try {
- // 尝试获取,存在则更新,不存在则创建
- var existing = postApi.getPost(dto.getId());
- if (existing.isSuccess() && existing.getData() != null) {
- postApi.updatePost(dto).checkError();
- log.info("[PostSync] 岗位全量同步-更新成功, postId={}, postName={}", dto.getId(), dto.getName());
- } else {
- postApi.createPost(dto).checkError();
- log.info("[PostSync] 岗位全量同步-创建成功, postId={}, postName={}", dto.getId(), dto.getName());
- }
+ postApi.syncPost(dto).checkError();
+ log.info("[PostSync] 岗位全量同步成功, postId={}, postName={}", dto.getId(), dto.getName());
} catch (Exception e) {
- // 获取失败,尝试创建
- try {
- postApi.createPost(dto).checkError();
- log.info("[PostSync] 岗位全量同步-创建成功, postId={}, postName={}", dto.getId(), dto.getName());
- } catch (Exception createEx) {
- log.error("[PostSync] 岗位全量同步失败, postId={}, postName={}", dto.getId(), dto.getName(), createEx);
- throw createEx;
- }
+ log.error("[PostSync] 岗位全量同步失败, postId={}, postName={}, code={}, error={}",
+ dto.getId(), dto.getName(), dto.getCode(), e.getMessage());
+ throw e;
}
}
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/user/AdminUserSyncServiceImpl.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/user/AdminUserSyncServiceImpl.java
index d40cfd51..a0b239df 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/user/AdminUserSyncServiceImpl.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/user/AdminUserSyncServiceImpl.java
@@ -72,21 +72,14 @@ public class AdminUserSyncServiceImpl implements AdminUserSyncService {
return;
}
AdminUserSaveReqDTO dto = buildUserDTO(data);
+
try {
- // 尝试获取,存在则更新,不存在则创建
- var existing = adminUserApi.getUser(dto.getId());
- if (existing.isSuccess() && existing.getData() != null) {
- adminUserApi.updateUser(dto).checkError();
- log.info("[UserSync] 用户全量同步-更新成功, userId={}", dto.getId());
- } else {
- adminUserApi.createUser(dto).checkError();
- log.info("[UserSync] 用户全量同步-创建成功, userId={}", dto.getId());
- }
+ adminUserApi.syncUser(dto).checkError();
+ log.info("[UserSync] 用户全量同步成功, userId={}, username={}", dto.getId(), dto.getUsername());
} catch (Exception e) {
- // 获取失败,尝试创建
- log.warn("[UserSync] 用户获取失败,尝试创建, userId={}", dto.getId());
- adminUserApi.createUser(dto).checkError();
- log.info("[UserSync] 用户全量同步-创建成功, userId={}", dto.getId());
+ log.error("[UserSync] 用户全量同步失败, userId={}, username={}, error={}",
+ dto.getId(), dto.getUsername(), e.getMessage());
+ throw e;
}
}
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java
index 04f16ae4..36914af0 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userdept/UserDeptSyncServiceImpl.java
@@ -70,20 +70,13 @@ public class UserDeptSyncServiceImpl implements UserDeptSyncService {
}
UserDeptSaveReqDTO dto = buildUserDeptDTO(data);
try {
- // 尝试获取,存在则更新,不存在则创建
- var existing = userDeptApi.getUserDept(dto.getId());
- if (existing.isSuccess() && existing.getData() != null) {
- userDeptApi.updateUserDept(dto).checkError();
- log.info("[UserDeptSync] 用户-部门关系全量同步-更新成功, id={}", dto.getId());
- } else {
- userDeptApi.createUserDept(dto).checkError();
- log.info("[UserDeptSync] 用户-部门关系全量同步-创建成功, id={}", dto.getId());
- }
+ userDeptApi.syncUserDept(dto).checkError();
+ log.info("[UserDeptSync] 用户-部门关系全量同步成功, id={}, userId={}, deptId={}",
+ dto.getId(), dto.getUserId(), dto.getDeptId());
} catch (Exception e) {
- // 获取失败,尝试创建
- log.warn("[UserDeptSync] 用户-部门关系获取失败,尝试创建, id={}", dto.getId());
- userDeptApi.createUserDept(dto).checkError();
- log.info("[UserDeptSync] 用户-部门关系全量同步-创建成功, id={}", dto.getId());
+ log.error("[UserDeptSync] 用户-部门关系全量同步失败, id={}, userId={}, deptId={}, error={}",
+ dto.getId(), dto.getUserId(), dto.getDeptId(), e.getMessage());
+ throw e;
}
}
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java
index 01eb2b4b..47251092 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java
+++ b/zt-framework/zt-spring-boot-starter-databus-client/src/main/java/com/zt/plat/framework/databus/client/handler/userpost/UserPostSyncServiceImpl.java
@@ -70,20 +70,13 @@ public class UserPostSyncServiceImpl implements UserPostSyncService {
}
UserPostSaveReqDTO dto = buildUserPostDTO(data);
try {
- // 尝试获取,存在则更新,不存在则创建
- var existing = userPostApi.getUserPost(dto.getId());
- if (existing.isSuccess() && existing.getData() != null) {
- userPostApi.updateUserPost(dto).checkError();
- log.info("[UserPostSync] 用户-岗位关系全量同步-更新成功, id={}", dto.getId());
- } else {
- userPostApi.createUserPost(dto).checkError();
- log.info("[UserPostSync] 用户-岗位关系全量同步-创建成功, id={}", dto.getId());
- }
+ userPostApi.syncUserPost(dto).checkError();
+ log.info("[UserPostSync] 用户-岗位关系全量同步成功, id={}, userId={}, postId={}",
+ dto.getId(), dto.getUserId(), dto.getPostId());
} catch (Exception e) {
- // 获取失败,尝试创建
- log.warn("[UserPostSync] 用户-岗位关系获取失败,尝试创建, id={}", dto.getId());
- userPostApi.createUserPost(dto).checkError();
- log.info("[UserPostSync] 用户-岗位关系全量同步-创建成功, id={}", dto.getId());
+ log.error("[UserPostSync] 用户-岗位关系全量同步失败, id={}, userId={}, postId={}, error={}",
+ dto.getId(), dto.getUserId(), dto.getPostId(), e.getMessage());
+ throw e;
}
}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/DeptApi.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/DeptApi.java
index eea5499e..abc53972 100644
--- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/DeptApi.java
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/DeptApi.java
@@ -86,4 +86,10 @@ public interface DeptApi {
@Parameter(name = "userId", description = "用户编号", example = "1", required = true)
CommonResult> getCompanyDeptInfoListByUserId(@RequestParam("userId") Long userId);
+ // ========== 数据同步专用接口 ==========
+
+ @PostMapping(PREFIX + "/sync")
+ @Operation(summary = "同步部门")
+ CommonResult syncDept(@RequestBody DeptSaveReqDTO syncReqDTO);
+
}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/PostApi.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/PostApi.java
index fed71544..4ef8bd45 100644
--- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/PostApi.java
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/PostApi.java
@@ -64,4 +64,10 @@ public interface PostApi {
return CollectionUtils.convertMap(list, PostRespDTO::getId);
}
+ // ========== 数据同步专用接口 ==========
+
+ @PostMapping(PREFIX + "/sync")
+ @Operation(summary = "同步岗位")
+ CommonResult syncPost(@RequestBody PostSaveReqDTO syncReqDTO);
+
}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/dto/DeptSaveReqDTO.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/dto/DeptSaveReqDTO.java
index fbb311cc..b01a712d 100644
--- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/dto/DeptSaveReqDTO.java
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/dept/dto/DeptSaveReqDTO.java
@@ -15,9 +15,15 @@ public class DeptSaveReqDTO {
@Schema(description = "部门编号", example = "1024")
private Long 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 Long parentId;
@@ -36,6 +42,15 @@ public class DeptSaveReqDTO {
@Schema(description = "状态,见 CommonStatusEnum 枚举0 开启 1 关闭", example = "0")
private Integer status;
+ @Schema(description = "是否集团", example = "false")
+ private Boolean isGroup;
+
+ @Schema(description = "是否公司", example = "false")
+ private Boolean isCompany;
+
+ @Schema(description = "部门来源类型", example = "1")
+ private Integer deptSource;
+
@Schema(description = "外部系统标识,用于建立编码映射", example = "ERP")
private String externalSystemCode;
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/AdminUserApi.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/AdminUserApi.java
index 02443415..293608b8 100644
--- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/AdminUserApi.java
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/AdminUserApi.java
@@ -104,6 +104,12 @@ public interface AdminUserApi extends AutoTransable {
@Parameter(name = "ids", description = "用户编号数组", example = "3,5", required = true)
CommonResult validateUserList(@RequestParam("ids") Collection ids);
+ // ========== 数据同步专用接口 ==========
+
+ @PostMapping(PREFIX + "/sync")
+ @Operation(summary = "同步用户")
+ CommonResult syncUser(@RequestBody AdminUserSaveReqDTO syncReqDTO);
+
@Override
@FeignIgnore
default List selectByIds(List> ids) {
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserSaveReqDTO.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserSaveReqDTO.java
index 4e4a30c2..691f5204 100644
--- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserSaveReqDTO.java
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/user/dto/AdminUserSaveReqDTO.java
@@ -50,4 +50,10 @@ public class AdminUserSaveReqDTO {
@Schema(description = "密码", example = "123456")
private String password;
+ @Schema(description = "工号", example = "A00123")
+ private String workcode;
+
+ @Schema(description = "用户来源类型", example = "1")
+ private Integer userSource;
+
}
\ No newline at end of file
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java
index d48c6b69..050216ae 100644
--- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApi.java
@@ -61,4 +61,10 @@ public interface UserDeptApi {
@Operation(summary = "通过部门ID删除用户部门关系")
@Parameter(name = "deptId", description = "部门编号", example = "1", required = true)
CommonResult deleteUserDeptByDeptId(@RequestParam("deptId") Long deptId);
+
+ // ========== 数据同步专用接口 ==========
+
+ @PostMapping(PREFIX + "/sync")
+ @Operation(summary = "同步用户部门关系")
+ CommonResult syncUserDept(@RequestBody UserDeptSaveReqDTO syncReqDTO);
}
diff --git a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java
index a58e09cb..d72e4706 100644
--- a/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java
+++ b/zt-module-system/zt-module-system-api/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApi.java
@@ -61,4 +61,10 @@ public interface UserPostApi {
@Operation(summary = "通过岗位ID删除用户岗位关系")
@Parameter(name = "postId", description = "岗位编号", example = "1", required = true)
CommonResult deleteUserPostByPostId(@RequestParam("postId") Long postId);
+
+ // ========== 数据同步专用接口 ==========
+
+ @PostMapping(PREFIX + "/sync")
+ @Operation(summary = "同步用户岗位关系")
+ CommonResult syncUserPost(@RequestBody UserPostSaveReqDTO syncReqDTO);
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
index 3a461df9..efbe2e1d 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/databus/DatabusUserDeptProviderApiImpl.java
@@ -38,7 +38,7 @@ public class DatabusUserDeptProviderApiImpl implements DatabusUserDeptProviderAp
// 多查一条判断是否有更多数据
int limit = reqDTO.getBatchSize() != null ? reqDTO.getBatchSize() : 100;
- // ⚠️ 使用关联查询,只查询 userSource = 2 的用户的部门关系
+ // 查询用户部门关系
List list = userDeptMapper.selectPageByCursorWithUserSource(
reqDTO.isFirstPage() ? null : reqDTO.getCursorTime(),
reqDTO.isFirstPage() ? null : reqDTO.getCursorId(),
@@ -67,7 +67,7 @@ public class DatabusUserDeptProviderApiImpl implements DatabusUserDeptProviderAp
// 首次查询时返���总数
Long total = null;
if (reqDTO.isFirstPage()) {
- // ⚠️ 只统计 userSource = 2 的用户的部门关系
+ // 统计用户部门关系
total = userDeptMapper.countWithUserSource(reqDTO.getTenantId());
}
@@ -107,7 +107,7 @@ public class DatabusUserDeptProviderApiImpl implements DatabusUserDeptProviderAp
@Override
public CommonResult count(Long tenantId) {
- // ⚠️ 只统计 userSource = 2 的用户的部门关系
+ // 统计用户部门关系
return success(userDeptMapper.countWithUserSource(tenantId));
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/DeptApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/DeptApiImpl.java
index d06b79a6..bed2d2b6 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/DeptApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/DeptApiImpl.java
@@ -107,4 +107,13 @@ public class DeptApiImpl implements DeptApi {
return success(BeanUtils.toBean(companyDeptInfos, CompanyDeptInfoRespDTO.class));
}
+ // ========== 数据同步专用接口 ==========
+
+ @Override
+ public CommonResult syncDept(DeptSaveReqDTO syncReqDTO) {
+ DeptSaveReqVO reqVO = BeanUtils.toBean(syncReqDTO, DeptSaveReqVO.class);
+ deptService.syncDept(reqVO);
+ return success(true);
+ }
+
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java
index 97cf029e..bb760ec4 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/dept/PostApiImpl.java
@@ -38,7 +38,6 @@ public class PostApiImpl implements PostApi {
@Override
public CommonResult updatePost(PostSaveReqDTO updateReqVO) {
- log.error("ssssssssss");
PostSaveReqVO reqVO = BeanUtils.toBean(updateReqVO, PostSaveReqVO.class);
postService.updatePost(reqVO);
return success(true);
@@ -76,4 +75,11 @@ public class PostApiImpl implements PostApi {
return success(BeanUtils.toBean(list, PostRespDTO.class));
}
+ @Override
+ public CommonResult syncPost(PostSaveReqDTO syncReqDTO) {
+ PostSaveReqVO reqVO = BeanUtils.toBean(syncReqDTO, PostSaveReqVO.class);
+ postService.syncPost(reqVO);
+ return success(true);
+ }
+
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/user/AdminUserApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/user/AdminUserApiImpl.java
index a80db06e..523e432a 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/user/AdminUserApiImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/user/AdminUserApiImpl.java
@@ -149,4 +149,11 @@ public class AdminUserApiImpl implements AdminUserApi {
return success(true);
}
+ @Override
+ public CommonResult syncUser(AdminUserSaveReqDTO syncReqDTO) {
+ UserSaveReqVO reqVO = BeanUtils.toBean(syncReqDTO, UserSaveReqVO.class);
+ userService.syncUser(reqVO);
+ return success(true);
+ }
+
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApiImpl.java
new file mode 100644
index 00000000..91b30187
--- /dev/null
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userdept/UserDeptApiImpl.java
@@ -0,0 +1,88 @@
+package com.zt.plat.module.system.api.userdept;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.common.util.object.BeanUtils;
+import com.zt.plat.module.system.api.userdept.dto.UserDeptRespDTO;
+import com.zt.plat.module.system.api.userdept.dto.UserDeptSaveReqDTO;
+import com.zt.plat.module.system.dal.dataobject.userdept.UserDeptDO;
+import com.zt.plat.module.system.service.userdept.UserDeptService;
+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.List;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * 用户-部门关系 API 实现类
+ *
+ * @author ZT
+ */
+@Slf4j
+@RestController
+@Validated
+public class UserDeptApiImpl implements UserDeptApi {
+
+ @Resource
+ private UserDeptService userDeptService;
+
+ @Override
+ public CommonResult createUserDept(UserDeptSaveReqDTO reqVO) {
+ UserDeptDO userDept = BeanUtils.toBean(reqVO, UserDeptDO.class);
+ Long id = userDeptService.createUserDept(userDept);
+ return success(id);
+ }
+
+ @Override
+ public CommonResult updateUserDept(UserDeptSaveReqDTO reqVO) {
+ UserDeptDO userDept = BeanUtils.toBean(reqVO, UserDeptDO.class);
+ userDeptService.updateUserDept(userDept);
+ return success(true);
+ }
+
+ @Override
+ public CommonResult deleteUserDept(Long id) {
+ userDeptService.deleteUserDept(id);
+ return success(true);
+ }
+
+ @Override
+ public CommonResult getUserDept(Long id) {
+ UserDeptDO userDept = userDeptService.getUserDept(id);
+ return success(BeanUtils.toBean(userDept, UserDeptRespDTO.class));
+ }
+
+ @Override
+ public CommonResult> getUserDeptListByUserId(Long userId) {
+ List list = userDeptService.getValidUserDeptListByUserIds(List.of(userId));
+ return success(BeanUtils.toBean(list, UserDeptRespDTO.class));
+ }
+
+ @Override
+ public CommonResult> getUserDeptListByDeptId(Long deptId) {
+ List list = userDeptService.getValidUserDeptListByDeptIds(List.of(deptId));
+ return success(BeanUtils.toBean(list, UserDeptRespDTO.class));
+ }
+
+ @Override
+ public CommonResult deleteUserDeptByUserId(Long userId) {
+ userDeptService.deleteUserDeptByUserId(userId);
+ return success(true);
+ }
+
+ @Override
+ public CommonResult deleteUserDeptByDeptId(Long deptId) {
+ // 需要实现此方法,暂时返回成功
+ return success(true);
+ }
+
+ @Override
+ public CommonResult syncUserDept(UserDeptSaveReqDTO syncReqDTO) {
+ UserDeptDO userDept = BeanUtils.toBean(syncReqDTO, UserDeptDO.class);
+ userDeptService.syncUserDept(userDept);
+ return success(true);
+ }
+
+}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApiImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApiImpl.java
new file mode 100644
index 00000000..1ee2db26
--- /dev/null
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/api/userpost/UserPostApiImpl.java
@@ -0,0 +1,106 @@
+package com.zt.plat.module.system.api.userpost;
+
+import com.zt.plat.framework.common.pojo.CommonResult;
+import com.zt.plat.framework.common.util.object.BeanUtils;
+import com.zt.plat.module.system.api.userpost.dto.UserPostRespDTO;
+import com.zt.plat.module.system.api.userpost.dto.UserPostSaveReqDTO;
+import com.zt.plat.module.system.dal.dataobject.dept.UserPostDO;
+import com.zt.plat.module.system.dal.mysql.dept.UserPostMapper;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+import static com.zt.plat.framework.common.pojo.CommonResult.success;
+
+/**
+ * 用户-岗位关系 API 实现类
+ *
+ * @author ZT
+ */
+@Slf4j
+@RestController
+@Validated
+public class UserPostApiImpl implements UserPostApi {
+
+ @Resource
+ private UserPostMapper userPostMapper;
+
+ @Override
+ public CommonResult createUserPost(UserPostSaveReqDTO reqVO) {
+ UserPostDO userPost = BeanUtils.toBean(reqVO, UserPostDO.class);
+ userPostMapper.insert(userPost);
+ return success(userPost.getId());
+ }
+
+ @Override
+ public CommonResult updateUserPost(UserPostSaveReqDTO reqVO) {
+ UserPostDO userPost = BeanUtils.toBean(reqVO, UserPostDO.class);
+ userPostMapper.updateById(userPost);
+ return success(true);
+ }
+
+ @Override
+ public CommonResult deleteUserPost(Long id) {
+ userPostMapper.deleteById(id);
+ return success(true);
+ }
+
+ @Override
+ public CommonResult getUserPost(Long id) {
+ UserPostDO userPost = userPostMapper.selectById(id);
+ return success(BeanUtils.toBean(userPost, UserPostRespDTO.class));
+ }
+
+ @Override
+ public CommonResult> getUserPostListByUserId(Long userId) {
+ List list = userPostMapper.selectListByUserId(userId);
+ return success(BeanUtils.toBean(list, UserPostRespDTO.class));
+ }
+
+ @Override
+ public CommonResult> getUserPostListByPostId(Long postId) {
+ List list = userPostMapper.selectListByPostIds(List.of(postId));
+ return success(BeanUtils.toBean(list, UserPostRespDTO.class));
+ }
+
+ @Override
+ public CommonResult deleteUserPostByUserId(Long userId) {
+ userPostMapper.deleteByUserId(userId);
+ return success(true);
+ }
+
+ @Override
+ public CommonResult deleteUserPostByPostId(Long postId) {
+ userPostMapper.delete(UserPostDO::getPostId, postId);
+ return success(true);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public CommonResult syncUserPost(UserPostSaveReqDTO syncReqDTO) {
+ if (syncReqDTO.getId() == null) {
+ return success(false);
+ }
+
+ UserPostDO existing = userPostMapper.selectById(syncReqDTO.getId());
+ UserPostDO userPost = BeanUtils.toBean(syncReqDTO, UserPostDO.class);
+
+ if (existing != null) {
+ userPostMapper.updateById(userPost);
+ log.info("[syncUserPost] 用户岗位关系同步-更新成功, id={}, userId={}, postId={}",
+ userPost.getId(), userPost.getUserId(), userPost.getPostId());
+ } else {
+ userPostMapper.insert(userPost);
+ log.info("[syncUserPost] 用户岗位关系同步-创建成功, id={}, userId={}, postId={}",
+ userPost.getId(), userPost.getUserId(), userPost.getPostId());
+ }
+
+ return success(true);
+ }
+
+}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/DeptMapper.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/DeptMapper.java
index fbd7c2c0..b030665c 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/DeptMapper.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/dal/mysql/dept/DeptMapper.java
@@ -124,12 +124,17 @@ public interface DeptMapper extends BaseMapperX {
/**
* 根据部门编码查询部门
+ *
+ * 注意:如果存在多条相同编码的记录,只返回第一条
*
* @param code 部门编码
* @return 部门信息
*/
default DeptDO selectByCode(String code) {
- return selectOne(DeptDO::getCode, code);
+ List list = selectList(new LambdaQueryWrapperX()
+ .eq(DeptDO::getCode, code)
+ .last("LIMIT 1"));
+ return CollUtil.isNotEmpty(list) ? list.get(0) : null;
}
/**
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptService.java
index c97510df..3996eef8 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptService.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/DeptService.java
@@ -174,4 +174,15 @@ public interface DeptService {
* @return 部门列表
*/
List searchDeptTree(String keyword);
+
+ /**
+ * 回填缺失的部门编码(不触发事件)。
+ *
+ * @param deptIds 需要回填的部门 ID 列表
+ */
+ void backfillMissingCodesWithoutEvent(Collection deptIds);
+
+ // ========== 数据同步专用接口 ==========
+
+ void syncDept(DeptSaveReqVO syncReqVO);
}
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 7a4e6bbe..edfb3267 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
@@ -802,4 +802,41 @@ public class DeptServiceImpl implements DeptService {
}
}
+ // ========== 数据同步专用接口 ==========
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ @CacheEvict(cacheNames = RedisKeyConstants.DEPT_CHILDREN_ID_LIST, allEntries = true)
+ @DataPermission(enable = false)
+ public void syncDept(DeptSaveReqVO syncReqVO) {
+ if (syncReqVO.getId() == null) {
+ log.warn("[syncDept] 同步部门失败,ID 不能为空");
+ return;
+ }
+ // 标准化父部门 ID
+ syncReqVO.setParentId(normalizeParentId(syncReqVO.getParentId()));
+ // 默认部门来源
+ if (syncReqVO.getDeptSource() == null) {
+ syncReqVO.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
+ }
+
+ // 检查部门是否存在
+ DeptDO existingDept = deptMapper.selectById(syncReqVO.getId());
+
+ // 转换为 DO
+ DeptDO dept = BeanUtils.toBean(syncReqVO, DeptDO.class);
+
+ if (existingDept != null) {
+ // 部门存在,执行更新
+ deptMapper.updateById(dept);
+ log.info("[syncDept] 部门同步-更新成功, deptId={}, deptName={}", dept.getId(), dept.getName());
+ } else {
+ // 部门不存在,执行插入
+ deptMapper.insert(dept);
+ log.info("[syncDept] 部门同步-创建成功, deptId={}, deptName={}", dept.getId(), dept.getName());
+ }
+
+ // 注意:不发布变更事件,避免循环同步
+ }
+
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostService.java
index 4ece87ea..153c7fd3 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostService.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostService.java
@@ -89,4 +89,8 @@ public interface PostService {
*/
Long getOrCreatePostByName(String postName);
+ // ========== 数据同步专用接口 ==========
+
+ void syncPost(PostSaveReqVO syncReqVO);
+
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostServiceImpl.java
index ff0aa7b4..9dcf31e2 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostServiceImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/dept/PostServiceImpl.java
@@ -191,4 +191,25 @@ public class PostServiceImpl implements PostService {
return createPost(createReqVO);
}
+
+ // ========== 数据同步专用接口 ==========
+
+ @Override
+ public void syncPost(PostSaveReqVO syncReqVO) {
+ if (syncReqVO.getId() == null) {
+ return;
+ }
+
+ PostDO existingPost = postMapper.selectById(syncReqVO.getId());
+ PostDO post = BeanUtils.toBean(syncReqVO, PostDO.class);
+
+ if (existingPost != null) {
+ postMapper.updateById(post);
+ } else {
+ if (post.getStatus() == null) {
+ post.setStatus(CommonStatusEnum.ENABLE.getStatus());
+ }
+ postMapper.insert(post);
+ }
+ }
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserService.java
index 967f3161..4244e9cf 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserService.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserService.java
@@ -208,4 +208,8 @@ public interface AdminUserService {
*/
boolean isPasswordMatch(AdminUserDO user, String rawPassword);
+ // ========== 数据同步专用接口 ==========
+
+ void syncUser(UserSaveReqVO syncReqVO);
+
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserServiceImpl.java
index b9126216..1fb85004 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserServiceImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/user/AdminUserServiceImpl.java
@@ -725,4 +725,48 @@ public class AdminUserServiceImpl implements AdminUserService {
return StrUtil.isNotBlank(value) && value.startsWith("$2");
}
+ // ========== 数据同步专用接口 ==========
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void syncUser(UserSaveReqVO syncReqVO) {
+ if (syncReqVO.getId() == null) {
+ log.warn("[syncUser] 同步用户失败,ID 不能为空");
+ return;
+ }
+
+ // 检查用户是否存在
+ AdminUserDO existingUser = userMapper.selectById(syncReqVO.getId());
+
+ // 转换为 DO(只同步用户主表,不处理关联关系)
+ AdminUserDO user = BeanUtils.toBean(syncReqVO, AdminUserDO.class);
+ user.setDeptIds(null); // 部门关联单独同步
+ user.setPostIds(null); // 岗位关联单独同步
+
+ if (existingUser != null) {
+ // 用户存在,执行更新(不更新密码)
+ user.setPassword(null);
+ userMapper.updateById(user);
+ log.info("[syncUser] 用户同步-更新成功, userId={}, username={}", user.getId(), user.getUsername());
+ } else {
+ // 用户不存在,执行插入
+ // 设置默认状态
+ if (user.getStatus() == null) {
+ user.setStatus(CommonStatusEnum.ENABLE.getStatus());
+ }
+ // 设置默认用户来源
+ if (user.getUserSource() == null) {
+ user.setUserSource(UserSourceEnum.EXTERNAL.getSource());
+ }
+ // 如果没有密码,设置默认密码
+ if (StrUtil.isBlank(user.getPassword())) {
+ user.setPassword(passwordEncoder.encode("123456"));
+ }
+ userMapper.insert(user);
+ log.info("[syncUser] 用户同步-创建成功, userId={}, username={}", user.getId(), user.getUsername());
+ }
+
+ // 注意:不发布变更事件,避免循环同步
+ }
+
}
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java
index 378637eb..26c728b7 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptService.java
@@ -76,5 +76,8 @@ public interface UserDeptService {
*/
void batchCreateUserDept(List createReqVOList);
+ // ========== 数据同步专用接口 ==========
+
+ void syncUserDept(UserDeptDO syncReqVO);
}
\ No newline at end of file
diff --git a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java
index 3b699c91..8c71a020 100644
--- a/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java
+++ b/zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/service/userdept/UserDeptServiceImpl.java
@@ -155,4 +155,22 @@ public class UserDeptServiceImpl implements UserDeptService {
}
}
-}
\ No newline at end of file
+ // ========== 数据同步专用接口 ==========
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void syncUserDept(UserDeptDO syncReqVO) {
+ if (syncReqVO.getId() == null) {
+ return;
+ }
+
+ UserDeptDO existing = userDeptMapper.selectById(syncReqVO.getId());
+
+ if (existing != null) {
+ userDeptMapper.updateById(syncReqVO);
+ } else {
+ userDeptMapper.insert(syncReqVO);
+ }
+ }
+
+}
From 01847264d5770fa453e5bfb74d0f8e2046ad1703 Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Wed, 24 Dec 2025 10:41:51 +0800
Subject: [PATCH 6/8] =?UTF-8?q?update=EF=BC=9A=E8=B0=83=E6=95=B4=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E7=94=A8=E6=88=B7-=E9=83=A8?=
=?UTF-8?q?=E9=97=A8=EF=BC=8C=E7=94=A8=E6=88=B7-=E5=B2=97=E4=BD=8D?=
=?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
zt-framework/zt-spring-boot-starter-databus-client/pom.xml | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/zt-framework/zt-spring-boot-starter-databus-client/pom.xml b/zt-framework/zt-spring-boot-starter-databus-client/pom.xml
index 08e8dcc8..ce35f87e 100644
--- a/zt-framework/zt-spring-boot-starter-databus-client/pom.xml
+++ b/zt-framework/zt-spring-boot-starter-databus-client/pom.xml
@@ -46,14 +46,12 @@
com.zt.plat
zt-spring-boot-starter-mq
-
-
com.zt.plat
- zt-spring-boot-starter-redis
+ zt-spring-boot-starter-biz-tenant
-
+
org.springframework.boot
spring-boot-starter-web
From 8823e316a0124d5daa677373e75c49c85535df81 Mon Sep 17 00:00:00 2001
From: hewencai <2357300448@qq.com>
Date: Wed, 24 Dec 2025 10:42:18 +0800
Subject: [PATCH 7/8] =?UTF-8?q?update=EF=BC=9A=E8=B0=83=E6=95=B4=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E7=94=A8=E6=88=B7-=E9=83=A8?=
=?UTF-8?q?=E9=97=A8=EF=BC=8C=E7=94=A8=E6=88=B7-=E5=B2=97=E4=BD=8D?=
=?UTF-8?q?=E5=90=8C=E6=AD=A5=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
zt-module-databus/zt-module-databus-server/pom.xml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/zt-module-databus/zt-module-databus-server/pom.xml b/zt-module-databus/zt-module-databus-server/pom.xml
index e94168ad..ceec001c 100644
--- a/zt-module-databus/zt-module-databus-server/pom.xml
+++ b/zt-module-databus/zt-module-databus-server/pom.xml
@@ -185,6 +185,11 @@
4.12.0
test
+
+ com.zt.plat
+ zt-spring-boot-starter-databus-client
+ ${revision}
+
From 89a047d28bd6861a6b7ebbac793306c212b924c4 Mon Sep 17 00:00:00 2001
From: chenbowen
Date: Wed, 24 Dec 2025 14:30:03 +0800
Subject: [PATCH 8/8] =?UTF-8?q?1.=20=E6=8F=90=E5=8D=87=20infra=20=E5=8F=AF?=
=?UTF-8?q?=E4=BB=A5=E4=B8=8A=E4=BC=A0=E7=9A=84=E9=99=84=E4=BB=B6=E5=A4=A7?=
=?UTF-8?q?=E5=B0=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/resources/application.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/zt-module-infra/zt-module-infra-server/src/main/resources/application.yaml b/zt-module-infra/zt-module-infra-server/src/main/resources/application.yaml
index bbf43124..73104a95 100644
--- a/zt-module-infra/zt-module-infra-server/src/main/resources/application.yaml
+++ b/zt-module-infra/zt-module-infra-server/src/main/resources/application.yaml
@@ -32,8 +32,8 @@ spring:
servlet:
# 文件上传相关配置项
multipart:
- max-file-size: 16MB # 单个文件大小
- max-request-size: 32MB # 设置总上传的文件大小
+ max-file-size: 128MB # 单个文件大小
+ max-request-size: 512MB # 设置总上传的文件大小
# Jackson 配置项
jackson: