Merge branch 'dev' into test
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -69,7 +69,7 @@
|
|||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>3.0.33</revision>
|
<revision>3.0.34</revision>
|
||||||
<!-- Maven 相关 -->
|
<!-- Maven 相关 -->
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
|
|||||||
14
sql/dm/部门添加编码、简称字段.sql
Normal file
14
sql/dm/部门添加编码、简称字段.sql
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- 达梦8数据库DDL脚本
|
||||||
|
-- 为 system_dept 表添加 code 和 short_name 字段
|
||||||
|
|
||||||
|
-- 添加部门编码字段
|
||||||
|
ALTER TABLE system_dept ADD COLUMN code VARCHAR(50);
|
||||||
|
|
||||||
|
-- 添加部门简称字段
|
||||||
|
ALTER TABLE system_dept ADD COLUMN short_name VARCHAR(20);
|
||||||
|
|
||||||
|
-- 添加字段注释
|
||||||
|
COMMENT ON COLUMN system_dept.code IS '部门编码';
|
||||||
|
COMMENT ON COLUMN system_dept.short_name IS '部门简称';
|
||||||
|
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>3.0.33</revision>
|
<revision>3.0.34</revision>
|
||||||
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
|
||||||
<!-- 统一依赖管理 -->
|
<!-- 统一依赖管理 -->
|
||||||
<spring.boot.version>3.4.5</spring.boot.version>
|
<spring.boot.version>3.4.5</spring.boot.version>
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ public class DeptRespDTO {
|
|||||||
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
|
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "研发部")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "部门编码", example = "XXXXXXX")
|
||||||
|
private String code;
|
||||||
|
|
||||||
@Schema(description = "父部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "父部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
private Long parentId;
|
private Long parentId;
|
||||||
|
|
||||||
|
|||||||
@@ -105,18 +105,18 @@ public class DeptController {
|
|||||||
@GetMapping("/top-level-list")
|
@GetMapping("/top-level-list")
|
||||||
@Operation(summary = "获取顶级部门列表", description = "用于懒加载,只返回没有父部门的顶级部门")
|
@Operation(summary = "获取顶级部门列表", description = "用于懒加载,只返回没有父部门的顶级部门")
|
||||||
@PreAuthorize("@ss.hasPermission('system:dept:query')")
|
@PreAuthorize("@ss.hasPermission('system:dept:query')")
|
||||||
public CommonResult<List<DeptSimpleRespVO>> getTopLevelDeptList() {
|
public CommonResult<List<DeptRespVO>> getTopLevelDeptList() {
|
||||||
List<DeptDO> list = deptService.getTopLevelDeptList();
|
List<DeptDO> list = deptService.getTopLevelDeptList();
|
||||||
return success(BeanUtils.toBean(list, DeptSimpleRespVO.class));
|
return success(BeanUtils.toBean(list, DeptRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/children")
|
@GetMapping("/children")
|
||||||
@Operation(summary = "根据父部门ID获取子部门列表", description = "用于懒加载,根据父部门ID返回直接子部门")
|
@Operation(summary = "根据父部门ID获取子部门列表", description = "用于懒加载,根据父部门ID返回直接子部门")
|
||||||
@Parameter(name = "parentId", description = "父部门ID", required = true, example = "1024")
|
@Parameter(name = "parentId", description = "父部门ID", required = true, example = "1024")
|
||||||
@PreAuthorize("@ss.hasPermission('system:dept:query')")
|
@PreAuthorize("@ss.hasPermission('system:dept:query')")
|
||||||
public CommonResult<List<DeptSimpleRespVO>> getChildrenDeptList(@RequestParam("parentId") Long parentId) {
|
public CommonResult<List<DeptRespVO>> getChildrenDeptList(@RequestParam("parentId") Long parentId) {
|
||||||
List<DeptDO> list = deptService.getDirectChildDeptList(parentId);
|
List<DeptDO> list = deptService.getDirectChildDeptList(parentId);
|
||||||
return success(BeanUtils.toBean(list, DeptSimpleRespVO.class));
|
return success(BeanUtils.toBean(list, DeptRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ public class DeptSaveReqVO {
|
|||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "部门编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "DEPT_001")
|
@Schema(description = "部门编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "DEPT_001")
|
||||||
@NotBlank(message = "部门编码不能为空")
|
|
||||||
@Size(max = 50, message = "部门编码长度不能超过 50 个字符")
|
@Size(max = 50, message = "部门编码长度不能超过 50 个字符")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,4 +60,36 @@ public class SyncLogController {
|
|||||||
return success(success);
|
return success(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch-rerun")
|
||||||
|
@Operation(summary = "根据服务类型批量重跑异常的同步接口")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:sync-log:batch-rerun')")
|
||||||
|
public CommonResult<Integer> batchRerunByServiceName(
|
||||||
|
@RequestParam("serviceName") String serviceName,
|
||||||
|
@RequestParam(value = "batchSize", defaultValue = "200") Integer batchSize) {
|
||||||
|
// 参数校验
|
||||||
|
if (batchSize > 500) {
|
||||||
|
throw new IllegalArgumentException("批次大小不能超过500");
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer count = syncLogService.markForBatchRerun(serviceName, batchSize);
|
||||||
|
return success(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/batch-rerun/progress")
|
||||||
|
@Operation(summary = "查询批量重跑进度")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:sync-log:query')")
|
||||||
|
public CommonResult<Map<String, Object>> getBatchRerunProgress(
|
||||||
|
@RequestParam("serviceName") String serviceName) {
|
||||||
|
Map<String, Object> progress = syncLogService.getBatchRerunProgress(serviceName);
|
||||||
|
return success(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch-rerun/pause")
|
||||||
|
@Operation(summary = "暂停批量重跑(将重试中状态重置为原失败状态)")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:sync-log:batch-rerun')")
|
||||||
|
public CommonResult<Integer> pauseBatchRerun(@RequestParam("serviceName") String serviceName) {
|
||||||
|
Integer count = syncLogService.pauseBatchRerun(serviceName);
|
||||||
|
return success(count);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ public enum SyncLogStatusEnum {
|
|||||||
SIGNATURE_VERIFY_FAILED(2, "签名验证失败"),
|
SIGNATURE_VERIFY_FAILED(2, "签名验证失败"),
|
||||||
AUTH_FAILED(3, "认证失败"),
|
AUTH_FAILED(3, "认证失败"),
|
||||||
BUSINESS_FAILED(4, "业务处理失败"),
|
BUSINESS_FAILED(4, "业务处理失败"),
|
||||||
SYSTEM_ERROR(5, "系统异常");
|
SYSTEM_ERROR(5, "系统异常"),
|
||||||
|
RETRYING(6, "重试中"),
|
||||||
|
RETRY_FAILED(7, "重试失败");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态码
|
* 状态码
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.job.sync;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||||
|
import cn.iocoder.yudao.module.system.service.sync.SyncLogService;
|
||||||
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步日志自动标记重试任务
|
||||||
|
*
|
||||||
|
* 该任务定期扫描失败状态的同步日志记录,自动标记为"重试中"状态
|
||||||
|
* 实现完全自动化的重试闭环
|
||||||
|
*
|
||||||
|
* @author ZT
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class SyncLogAutoMarkRetryJob {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SyncLogService syncLogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动标记重试任务
|
||||||
|
*
|
||||||
|
* 建议配置执行频率:每5分钟执行一次
|
||||||
|
* cron表达式:0 0/5 * * * ?
|
||||||
|
*
|
||||||
|
* 该任务会按服务类型自动标记失败记录为重试状态:
|
||||||
|
* 1. 优先处理SYSTEM_ERROR状态的记录
|
||||||
|
* 2. 然后处理其他失败状态的记录
|
||||||
|
* 3. 每次每种服务类型最多标记100条记录
|
||||||
|
*/
|
||||||
|
@XxlJob("syncLogAutoMarkRetryJob")
|
||||||
|
@TenantJob
|
||||||
|
public void execute() {
|
||||||
|
log.info("[syncLogAutoMarkRetryJob][开始执行同步日志自动标记重试任务]");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 定义需要处理的服务类型
|
||||||
|
String[] serviceNames = {
|
||||||
|
"OrgCreateService",
|
||||||
|
"OrgUpdateService",
|
||||||
|
"OrgDeleteService",
|
||||||
|
"UserCreateService",
|
||||||
|
"UserUpdateService",
|
||||||
|
"UserDeleteService"
|
||||||
|
};
|
||||||
|
|
||||||
|
int totalMarkedCount = 0;
|
||||||
|
|
||||||
|
// 为每种服务类型自动标记重试
|
||||||
|
for (String serviceName : serviceNames) {
|
||||||
|
try {
|
||||||
|
// 每种服务类型最多标记100条记录,避免一次性处理过多
|
||||||
|
Integer markedCount = syncLogService.autoMarkForRetry(serviceName, 100);
|
||||||
|
totalMarkedCount += markedCount;
|
||||||
|
|
||||||
|
if (markedCount > 0) {
|
||||||
|
log.info("[syncLogAutoMarkRetryJob][服务类型 {} 自动标记了 {} 条记录为重试状态]",
|
||||||
|
serviceName, markedCount);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[syncLogAutoMarkRetryJob][处理服务类型 {} 时发生异常]", serviceName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalMarkedCount > 0) {
|
||||||
|
log.info("[syncLogAutoMarkRetryJob][自动标记重试任务执行完成,总共标记了 {} 条记录]", totalMarkedCount);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[syncLogAutoMarkRetryJob][自动标记重试任务执行异常]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package cn.iocoder.yudao.module.system.job.sync;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||||
|
import cn.iocoder.yudao.module.system.service.sync.SyncLogService;
|
||||||
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步日志批量重跑任务
|
||||||
|
*
|
||||||
|
* 该任务定期扫描状态为"重试中"的同步日志记录,进行分批重跑处理
|
||||||
|
*
|
||||||
|
* @author ZT
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class SyncLogBatchRerunJob {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SyncLogService syncLogService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行批量重跑任务
|
||||||
|
*
|
||||||
|
* 建议配置执行频率:每30秒执行一次
|
||||||
|
* cron表达式:0/30 * * * * ?
|
||||||
|
*/
|
||||||
|
@XxlJob("syncLogBatchRerunJob")
|
||||||
|
@TenantJob
|
||||||
|
public void execute() {
|
||||||
|
log.info("[syncLogBatchRerunJob][开始执行同步日志批量重跑任务]");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 执行批量重跑处理,每次处理50条记录
|
||||||
|
int processedCount = syncLogService.processBatchRerun(50);
|
||||||
|
|
||||||
|
if (processedCount > 0) {
|
||||||
|
log.info("[syncLogBatchRerunJob][批量重跑任务执行完成,处理了 {} 条记录]", processedCount);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("[syncLogBatchRerunJob][批量重跑任务执行异常]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user