6-18 - bug修复

master
tianxinlei 2026-06-18 17:49:06 +08:00
parent d0640c72c3
commit 10c425c1d3
21 changed files with 320 additions and 95 deletions

View File

@ -71,6 +71,9 @@ CREATE TABLE `safety_accountability_task_list_issue` (
`execute_user_id` bigint DEFAULT NULL COMMENT '执行人员ID',
`issue_status` tinyint DEFAULT '0' COMMENT '下发状态0-未下发 1-已下发',
`issue_time` datetime DEFAULT NULL COMMENT '下发时间',
`issue_corp_id` bigint DEFAULT NULL COMMENT '下发公司ID',
`issue_department_id` bigint DEFAULT NULL COMMENT '下发部门ID',
`issue_user_id` bigint DEFAULT NULL COMMENT '下发人员ID',
`period_start_time` datetime DEFAULT NULL COMMENT '执行周期开始时间',
`period_end_time` datetime DEFAULT NULL COMMENT '执行周期结束时间',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态1-进行中 2-已完成 3-已关闭',

View File

@ -0,0 +1,53 @@
package com.zcloud.safetyDutyList.job;
import com.jjb.saas.framework.job.Job;
import com.jjb.saas.framework.job.annotation.JobRegister;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zcloud.safetyDutyList.api.tasklist.TaskListServiceI;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* -
* <p>
* 10cron = "0 0 0 1 * ?"
* <p>
*
* ///
*
* <p>
* Job TaskListServiceI TaskListServiceImpl FeedbackExceptionCheckExe Gateway
* <p>
* COLAJobExe
*/
@RequiredArgsConstructor
@Component
@Slf4j
public class SendTodoMessageJob implements Job {
/** 安全责任清单服务接口,用于调用定时任务业务方法 */
private final TaskListServiceI taskListService;
/**
*
* <p>
* XXL-Job
* SUCCESSFAIL
*/
@Override
@JobRegister(cron = "0 0 8 1 * ?", jobDesc = "安全责任清单-发送待办消息", triggerStatus = 1)
@XxlJob("com.zcloud.safetyDutyList.job.SendTodoMessageJob")
public ReturnT<String> execute(String param) {
log.info("【安全责任清单】开始执行发送待办消息定时任务");
try {
taskListService.sendTodoMessage();
log.info("【安全责任清单】发送待办消息任务执行完成");
} catch (Exception e) {
log.error("【安全责任清单】发送待办消息定时任务执行异常", e);
return new ReturnT<>(ReturnT.FAIL_CODE, e.getMessage());
}
return ReturnT.SUCCESS;
}
}

View File

@ -57,12 +57,6 @@ public class TaskListController {
return taskListService.switchFlag(cmd);
}
@ApiOperation("关闭清单")
@PostMapping("/close")
public SingleResponse close(@Validated @RequestBody TaskListCloseCmd cmd) {
return taskListService.close(cmd);
}
@ApiOperation("任务下发")
@PostMapping("/issue")
public SingleResponse issue(@Validated @RequestBody TaskListIssueCmd cmd) {

View File

@ -36,4 +36,10 @@ public class TaskListIssueController {
public SingleResponse<TaskListIssueCO> getByTaskIssueId(@PathVariable String taskIssueId) {
return taskListService.getIssueByTaskIssueId(taskIssueId);
}
@ApiOperation("关闭任务 - 清单下发记录详情")
@GetMapping("close/{taskIssueId}")
public SingleResponse closeTaskIssueId(@PathVariable String taskIssueId) {
return taskListService.close(taskIssueId);
}
}

View File

@ -52,7 +52,11 @@ public class FeedbackAddExe {
}
FeedbackE feedbackE = new FeedbackE();
if (StringUtil.isNotBlank(cmd.getFeedbackId())) {
feedbackE.setFeedbackId(cmd.getFeedbackId());
}else {
feedbackE.init();
}
feedbackE.setTaskDetailId(executionE.getTaskDetailId());
feedbackE.setTaskExecutionId(executionE.getTaskExecutionId());
feedbackE.setTaskListId(executionE.getTaskListId());

View File

@ -0,0 +1,86 @@
package com.zcloud.safetyDutyList.command.tasklist;
import com.zcloud.safetyDutyList.domain.enums.TaskStatusEnum;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.*;
import com.zcloud.safetyDutyList.domain.model.tasklist.*;
import com.zcloud.safetyDutyList.domain.util.FeedbackCycleUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
/**
* 2
* <p>
* 10
* <p>
*
* 1. task_status=1 feedback_cycle_type
* 2.
*
* feedback_cycle_type=1
* feedback_cycle_type=2
* feedback_cycle_type=36
* feedback_cycle_type=4
*/
@Slf4j
@Component
@AllArgsConstructor
public class SendTodoMessageExe {
private final TaskListIssueGateway taskListIssueGateway;
private final TaskExecutionGateway taskExecutionGateway;
private final TaskDetailGateway taskDetailGateway;
private final FeedbackGateway feedbackGateway;
@Scheduled(cron = "0 0 0 1 * ?")
@Transactional(rollbackFor = Exception.class)
public void execute() {
log.info("【定时任务3】开始发送待办消息...");
List<TaskListIssueE> issuedList = taskListIssueGateway.listIssuedWithPeriod();
if (issuedList == null || issuedList.isEmpty()) {
log.info("【定时任务3】无下发记录需要发送待办");
return;
}
for (TaskListIssueE issueE : issuedList) {
List<TaskExecutionE> executionList = taskExecutionGateway.listByTaskIssueId(issueE.getTaskIssueId());
if (executionList == null) continue;
for (TaskExecutionE executionE : executionList) {
// 不是进行中就返回
if (!TaskStatusEnum.IN_PROGRESS.getCode().equals(executionE.getTaskStatus())) continue;
// 获取任务详情
TaskDetailE detailE = taskDetailGateway.getByTaskDetailId(executionE.getTaskDetailId());
if (detailE == null || detailE.getFeedbackCycleType() == null) continue;
// 反馈周期枚举: 1每月 2每季度 3每半年 4
Integer feedbackCycleType = detailE.getFeedbackCycleType();
// 首周期判断:如果当前仍处于清单的首个反馈周期内,跳过检测
if (!FeedbackCycleUtil.isFirstCycle(feedbackCycleType, issueE.getPeriodStartTime())) {
continue;
}
String currentCycleFlag = FeedbackCycleUtil.generatePeriodFlag(feedbackCycleType, LocalDateTime.now());
// 检查阶段内是否有反馈记录
List<FeedbackE> feedbackList = feedbackGateway.listByTaskExecutionIdAndPeriodFlag(
executionE.getTaskExecutionId(), currentCycleFlag);
if (feedbackList != null && !feedbackList.isEmpty()) {
// 周期内存在反馈
continue;
}
// todo 发送待办消息
}
}
log.info("【定时任务3】待办消息发送完成");
}
}

View File

@ -2,6 +2,7 @@ package com.zcloud.safetyDutyList.command.tasklist;
import com.alibaba.cola.exception.BizException;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskDetailGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListIssueGateway;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskDetailE;
import com.zcloud.safetyDutyList.dto.clientobject.tasklist.TaskDetailCO;
import com.zcloud.safetyDutyList.dto.tasklist.TaskDetailSaveBatchCmd;
@ -26,6 +27,7 @@ import java.util.stream.Collectors;
public class TaskDetailSaveBatchExe {
private final TaskDetailGateway taskDetailGateway;
private final TaskDetailRepository taskDetailRepository;
private final TaskListIssueGateway taskListIssueGateway;
@Transactional(rollbackFor = Exception.class)
public List<TaskDetailCO> execute(List<TaskDetailSaveBatchCmd> cmds) {
@ -35,6 +37,11 @@ public class TaskDetailSaveBatchExe {
// 获取已存在的任务详情列表
String taskListId = cmds.get(0).getTaskListId();
if (taskListIssueGateway.isIssued(taskListId)) {
throw new BizException("清单已下发,禁止修改");
}
List<TaskDetailE> existDetails = taskDetailGateway.listByTaskListId(taskListId);
Map<Long, TaskDetailE> existDetailMap = existDetails.stream()

View File

@ -1,71 +0,0 @@
package com.zcloud.safetyDutyList.command.tasklist;
import com.alibaba.cola.exception.BizException;
import com.zcloud.safetyDutyList.domain.enums.TaskStatusEnum;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskExecutionGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListIssueGateway;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskExecutionE;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskListE;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskListIssueE;
import com.zcloud.safetyDutyList.dto.tasklist.TaskListCloseCmd;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
/**
*
* <p>
*
* 1.
* 2.
* 3.
* 4.
*/
@Component
@AllArgsConstructor
public class TaskListCloseExe {
private final TaskListGateway taskListGateway;
private final TaskListIssueGateway taskListIssueGateway;
private final TaskExecutionGateway taskExecutionGateway;
@Transactional(rollbackFor = Exception.class)
public void execute(TaskListCloseCmd cmd) {
// 1. 关闭清单模板
TaskListE listE = taskListGateway.getByTaskListId(cmd.getTaskListId());
if (listE == null) {
throw new BizException("清单不存在");
}
listE.setStatus(TaskStatusEnum.CLOSED.getCode());
boolean res = taskListGateway.update(listE);
if (!res) {
throw new BizException("关闭清单失败");
}
// 2. 关闭该清单下所有进行中的下发记录
List<TaskListIssueE> issueList = taskListIssueGateway.listByTaskListId(cmd.getTaskListId());
if (issueList != null) {
for (TaskListIssueE issueE : issueList) {
if (TaskStatusEnum.IN_PROGRESS.getCode().equals(issueE.getStatus())) {
issueE.setStatus(TaskStatusEnum.CLOSED.getCode());
issueE.setCloseTime(LocalDateTime.now());
taskListIssueGateway.update(issueE);
}
// 3. 关闭该下发记录下所有进行中的任务执行记录
List<TaskExecutionE> executionList = taskExecutionGateway.listByTaskIssueId(issueE.getTaskIssueId());
if (executionList != null) {
for (TaskExecutionE executionE : executionList) {
if (TaskStatusEnum.IN_PROGRESS.getCode().equals(executionE.getTaskStatus())) {
executionE.setTaskStatus(TaskStatusEnum.CLOSED.getCode());
taskExecutionGateway.update(executionE);
}
}
}
}
}
}
}

View File

@ -0,0 +1,73 @@
package com.zcloud.safetyDutyList.command.tasklist;
import com.alibaba.cola.exception.BizException;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.safetyDutyList.domain.enums.TaskStatusEnum;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskExecutionGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListIssueGateway;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskExecutionE;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskListIssueE;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
/**
*
* <p>
*
* 1.
* 2.
* 3.
* 4.
*/
@Component
@AllArgsConstructor
public class TaskListIssueCloseExe {
private final TaskListGateway taskListGateway;
private final TaskListIssueGateway taskListIssueGateway;
private final TaskExecutionGateway taskExecutionGateway;
@Transactional(rollbackFor = Exception.class)
public void execute(String taskIssueId) {
// 1. 关闭清单模板
TaskListIssueE issueE = taskListIssueGateway.getByTaskIssueId(taskIssueId);
if (issueE == null) {
throw new BizException("清单下发记录不存在");
}
SSOUser ssoUser = AuthContext.getCurrentUser();
if (ssoUser == null) {
throw new BizException("用户未登录");
}
if (issueE.getIssueUserId() == null) {
throw new BizException("清单下发记录未指定下发人");
}
if (!Objects.equals(issueE.getIssueUserId(), ssoUser.getUserId())) {
throw new BizException("用户无权限关闭该清单下发记录");
}
issueE.setStatus(TaskStatusEnum.CLOSED.getCode());
issueE.setCloseTime(LocalDateTime.now());
boolean res = taskListIssueGateway.update(issueE);
if (!res) {
throw new BizException("关闭清单下发记录失败");
}
// 3. 关闭该下发记录下所有进行中的任务执行记录
List<TaskExecutionE> executionList = taskExecutionGateway.listByTaskIssueId(issueE.getTaskIssueId());
if (executionList != null) {
for (TaskExecutionE executionE : executionList) {
if (TaskStatusEnum.IN_PROGRESS.getCode().equals(executionE.getTaskStatus())) {
executionE.setTaskStatus(TaskStatusEnum.CLOSED.getCode());
taskExecutionGateway.update(executionE);
}
}
}
}
}

View File

@ -1,6 +1,8 @@
package com.zcloud.safetyDutyList.command.tasklist;
import com.alibaba.cola.exception.BizException;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.safetyDutyList.domain.enums.SwitchFlagEnum;
import com.zcloud.safetyDutyList.domain.enums.TaskStatusEnum;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskDetailGateway;
@ -39,6 +41,12 @@ public class TaskListIssueExe {
@Transactional(rollbackFor = Exception.class)
public void execute(TaskListIssueCmd cmd) {
SSOUser ssoUser = AuthContext.getCurrentUser();
if (ssoUser == null) {
throw new BizException("用户未登录");
}
TaskListE taskListE = taskListGateway.getInfoByTaskListId(cmd.getTaskListId());
if (taskListE == null) {
throw new BizException("任务清单不存在");
@ -53,12 +61,15 @@ public class TaskListIssueExe {
}
// 1. 处理周期时间
LocalDateTime startTime = cmd.getPeriodStartTime()
.withDayOfMonth(1)
.with(LocalTime.MIN);
LocalDateTime endTime = cmd.getPeriodEndTime()
.withDayOfMonth(cmd.getPeriodEndTime().toLocalDate().lengthOfMonth())
.with(LocalTime.of(23, 59, 59));
LocalDateTime startTime = cmd.getPeriodStartTime().atDay(1).atStartOfDay();
LocalDateTime endTime = cmd.getPeriodEndTime().atEndOfMonth().atTime(23, 59, 59);
// LocalDateTime startTime = cmd.getPeriodStartTime()
// .withDayOfMonth(1)
// .with(LocalTime.MIN);
// LocalDateTime endTime = cmd.getPeriodEndTime()
// .withDayOfMonth(cmd.getPeriodEndTime().toLocalDate().lengthOfMonth())
// .with(LocalTime.of(23, 59, 59));
// 2. 创建清单下发记录
TaskListIssueE issueE = new TaskListIssueE();
@ -69,6 +80,9 @@ public class TaskListIssueExe {
issueE.setExecuteUserId(cmd.getExecuteUserId());
issueE.setIssueStatus(1);
issueE.setIssueTime(LocalDateTime.now());
issueE.setIssueCorpId(ssoUser.getTenantId());
issueE.setIssueDepartmentId(ssoUser.getOrgId());
issueE.setIssueUserId(ssoUser.getUserId());
issueE.setPeriodStartTime(startTime);
issueE.setPeriodEndTime(endTime);
issueE.setStatus(TaskStatusEnum.IN_PROGRESS.getCode());

View File

@ -4,6 +4,7 @@ import com.alibaba.cola.exception.BizException;
import com.zcloud.safetyDutyList.domain.enums.TaskStatusEnum;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskDetailGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListGateway;
import com.zcloud.safetyDutyList.domain.gateway.tasklist.TaskListIssueGateway;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskDetailE;
import com.zcloud.safetyDutyList.domain.model.tasklist.TaskListE;
import com.zcloud.safetyDutyList.dto.clientobject.tasklist.TaskListCO;
@ -33,6 +34,7 @@ import java.util.List;
@AllArgsConstructor
public class TaskListUpdateExe {
private final TaskListGateway taskListGateway;
private final TaskListIssueGateway taskListIssueGateway;
@Transactional(rollbackFor = Exception.class)
public Boolean execute(TaskListUpdateCmd cmd) {
@ -40,6 +42,12 @@ public class TaskListUpdateExe {
if (existE == null) {
throw new BizException("任务清单不存在");
}
// 已经下发的任务,禁止修改
if (taskListIssueGateway.isIssued(existE.getTaskListId())) {
throw new BizException("任务清单已下发,禁止修改");
}
BeanUtils.copyProperties(cmd, existE);
boolean res = taskListGateway.update(existE);
if (!res) {

View File

@ -35,8 +35,8 @@ public class TaskListServiceImpl implements TaskListServiceI {
private final TaskListRemoveExe taskListRemoveExe;
/** 清单开关切换执行器 */
private final TaskListSwitchExe taskListSwitchExe;
/** 清单关闭执行器 */
private final TaskListCloseExe taskListCloseExe;
/** 清单下发关闭执行器 */
private final TaskListIssueCloseExe taskListIssueCloseExe;
/** 清单下发执行器 */
private final TaskListIssueExe taskListIssueExe;
/** 任务详情保存执行器 */
@ -71,6 +71,8 @@ public class TaskListServiceImpl implements TaskListServiceI {
private final TaskListStatusUpdateExe taskListStatusUpdateExe;
/** 反馈异常检测执行器定时任务2 */
private final FeedbackExceptionCheckExe feedbackExceptionCheckExe;
/** 发送代办执行器 */
private final SendTodoMessageExe sendTodoMessageExe;
@Override
public PageResponse<TaskListCO> listPage(TaskListPageQry qry) {
@ -113,8 +115,8 @@ public class TaskListServiceImpl implements TaskListServiceI {
}
@Override
public SingleResponse close(TaskListCloseCmd cmd) {
taskListCloseExe.execute(cmd);
public SingleResponse close(String taskIssueId) {
taskListIssueCloseExe.execute(taskIssueId);
return SingleResponse.buildSuccess();
}
@ -261,4 +263,14 @@ public class TaskListServiceImpl implements TaskListServiceI {
public void checkFeedbackException() {
feedbackExceptionCheckExe.execute();
}
/**
* 2
* <p>
* FeedbackExceptionCheckExe
*/
@Override
public void sendTodoMessage() {
sendTodoMessageExe.execute();
}
}

View File

@ -78,10 +78,9 @@ public interface TaskListServiceI {
/**
*
*
* @param cmd
* @return
*/
SingleResponse close(TaskListCloseCmd cmd);
SingleResponse close(String taskIssueId);
/**
*
@ -283,4 +282,12 @@ public interface TaskListServiceI {
* FeedbackExceptionCheckJob
*/
void checkFeedbackException();
/**
* 3
* <p>
*
* FeedbackExceptionCheckJob
*/
void sendTodoMessage();
}

View File

@ -46,6 +46,12 @@ public class TaskListIssueCO extends ClientObject {
@ApiModelProperty(value = "下发时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime issueTime;
@ApiModelProperty(value = "下发公司")
private Long issueCorpId;
@ApiModelProperty(value = "下发部门")
private Long issueDepartmentId;
@ApiModelProperty(value = "下发人员")
private Long issueUserId;
@ApiModelProperty(value = "执行周期开始时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime periodStartTime;

View File

@ -25,6 +25,9 @@ public class FeedbackAddCmd implements Serializable {
@NotEmpty(message = "任务执行ID不能为空")
private String taskExecutionId;
@ApiModelProperty(value = "反馈ID", required = true)
private String feedbackId;
@ApiModelProperty(value = "反馈内容", required = true)
@NotEmpty(message = "反馈内容不能为空")
private String feedbackContent;

View File

@ -16,7 +16,7 @@ import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TaskListCloseCmd implements Serializable {
public class TaskIssueCloseCmd implements Serializable {
@ApiModelProperty(value = "清单业务ID", required = true)
@NotEmpty(message = "清单业务ID不能为空")
private String taskListId;

View File

@ -10,6 +10,7 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.YearMonth;
/**
*
@ -38,11 +39,11 @@ public class TaskListIssueCmd implements Serializable {
@ApiModelProperty(value = "执行周期开始时间", required = true)
@NotNull(message = "执行周期开始时间不能为空")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime periodStartTime;
@JsonFormat(pattern = "yyyy-MM")
private YearMonth periodStartTime;
@ApiModelProperty(value = "执行周期结束时间", required = true)
@NotNull(message = "执行周期结束时间不能为空")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime periodEndTime;
@JsonFormat(pattern = "yyyy-MM")
private YearMonth periodEndTime;
}

View File

@ -22,4 +22,7 @@ public interface TaskListIssueGateway {
List<TaskListIssueE> listExpiredInProgress();
List<TaskListIssueE> listIssuedWithPeriod();
// 清单是否下发
Boolean isIssued(String taskListId);
}

View File

@ -25,6 +25,9 @@ public class TaskListIssueE extends BaseE {
private Long executeUserId;
private Integer issueStatus;
private LocalDateTime issueTime;
private Long issueCorpId;
private Long issueDepartmentId;
private Long issueUserId;
private LocalDateTime periodStartTime;
private LocalDateTime periodEndTime;
private Integer status;

View File

@ -94,4 +94,11 @@ public class TaskListIssueGatewayImpl implements TaskListIssueGateway {
}
return eList;
}
// 清单是否下发
@Override
public Boolean isIssued(String taskListId){
List<TaskListIssueDO> taskListIssueDOList = taskListIssueRepository.listByTaskListId(taskListId);
return taskListIssueDOList != null && taskListIssueDOList.size() > 0;
}
}

View File

@ -33,6 +33,12 @@ public class TaskListIssueDO extends BaseDO {
private Integer issueStatus;
@ApiModelProperty(value = "下发时间")
private LocalDateTime issueTime;
@ApiModelProperty(value = "下发公司")
private Long issueCorpId;
@ApiModelProperty(value = "下发部门")
private Long issueDepartmentId;
@ApiModelProperty(value = "下发人员")
private Long issueUserId;
@ApiModelProperty(value = "执行周期开始时间")
private LocalDateTime periodStartTime;
@ApiModelProperty(value = "执行周期结束时间")