feat(workflow): 添加作业撤回功能支持
- 新增 EightworkInfoWithdrawCmd 命令类用于撤回请求参数 - 实现 EightworkInfoWithdrawExe 执行器处理撤回业务逻辑 - 在 EightworkInfoDO 和相关模型中添加 lockFlag 字段控制撤回权限 - 添加 withdraw 接口到 EightworkInfoController 和服务层 - 实现物理删除 task_log 记录的批量删除功能 - 添加盲板工作类型筛选查询条件 - 修改菜单枚举配置支持新的作业类型路径 - 实现 CAS 乐观锁机制防止并发冲突master
parent
9fe44ac750
commit
f6e39da335
|
|
@ -5,6 +5,7 @@ import com.zcloud.eightwork.api.EightworkInfoServiceI;
|
||||||
import com.zcloud.eightwork.dto.EightworkInfoAddCmd;
|
import com.zcloud.eightwork.dto.EightworkInfoAddCmd;
|
||||||
import com.zcloud.eightwork.dto.EightworkInfoPageQry;
|
import com.zcloud.eightwork.dto.EightworkInfoPageQry;
|
||||||
import com.zcloud.eightwork.dto.EightworkInfoUpdateCmd;
|
import com.zcloud.eightwork.dto.EightworkInfoUpdateCmd;
|
||||||
|
import com.zcloud.eightwork.dto.EightworkInfoWithdrawCmd;
|
||||||
import com.zcloud.eightwork.dto.ForceTerminateCmd;
|
import com.zcloud.eightwork.dto.ForceTerminateCmd;
|
||||||
import com.zcloud.eightwork.dto.clientobject.StatisticsByWorkTypeCO;
|
import com.zcloud.eightwork.dto.clientobject.StatisticsByWorkTypeCO;
|
||||||
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
||||||
|
|
@ -45,8 +46,8 @@ public class EightworkInfoController {
|
||||||
@ApiOperation("分页")
|
@ApiOperation("分页")
|
||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
public PageResponse<EightworkInfoCO> page(@RequestBody EightworkInfoPageQry qry) {
|
public PageResponse<EightworkInfoCO> page(@RequestBody EightworkInfoPageQry qry) {
|
||||||
qry.setEqDepartmentId(AuthContext.getOrgId());
|
// qry.setEqDepartmentId(AuthContext.getOrgId());
|
||||||
qry.setEqCreateId(AuthContext.getUserId());
|
// qry.setEqCreateId(AuthContext.getUserId());
|
||||||
return eightworkInfoService.listPage(qry);
|
return eightworkInfoService.listPage(qry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,6 +84,13 @@ public class EightworkInfoController {
|
||||||
return SingleResponse.buildSuccess();
|
return SingleResponse.buildSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("撤回作业到暂存")
|
||||||
|
@PostMapping("/withdraw")
|
||||||
|
public Response withdraw(@Validated @RequestBody EightworkInfoWithdrawCmd cmd) {
|
||||||
|
eightworkInfoService.withdraw(cmd.getId(), cmd.getReason());
|
||||||
|
return SingleResponse.buildSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation("强制终止工作流")
|
@ApiOperation("强制终止工作流")
|
||||||
@PostMapping("/forceTerminate")
|
@PostMapping("/forceTerminate")
|
||||||
public Response forceTerminate(@RequestBody ForceTerminateCmd cmd) {
|
public Response forceTerminate(@RequestBody ForceTerminateCmd cmd) {
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ public class EightworkInfoSaveDraftExe {
|
||||||
eightworkInfo.setStatus(DRAFT_STATUS);
|
eightworkInfo.setStatus(DRAFT_STATUS);
|
||||||
eightworkInfo.setInfo(cmd.getInfo().toJSONString());
|
eightworkInfo.setInfo(cmd.getInfo().toJSONString());
|
||||||
eightworkInfo.setDepartmentId(cmd.getDepartmentId());
|
eightworkInfo.setDepartmentId(cmd.getDepartmentId());
|
||||||
|
eightworkInfo.setLockFlag(2); // 设置为未锁定(可撤回)
|
||||||
|
|
||||||
eightworkInfoRepository.save(eightworkInfo);
|
eightworkInfoRepository.save(eightworkInfo);
|
||||||
log.info("主表创建成功: workId={}", eightworkInfo.getWorkId());
|
log.info("主表创建成功: workId={}", eightworkInfo.getWorkId());
|
||||||
|
|
@ -222,6 +223,7 @@ public class EightworkInfoSaveDraftExe {
|
||||||
existingInfo.setGasFlag(cmd.getGasFlag());
|
existingInfo.setGasFlag(cmd.getGasFlag());
|
||||||
existingInfo.setInfo(cmd.getInfo().toJSONString());
|
existingInfo.setInfo(cmd.getInfo().toJSONString());
|
||||||
existingInfo.setDepartmentId(cmd.getDepartmentId());
|
existingInfo.setDepartmentId(cmd.getDepartmentId());
|
||||||
|
existingInfo.setLockFlag(2); // 设置为未锁定(可撤回)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,139 @@
|
||||||
|
package com.zcloud.eightwork.command;
|
||||||
|
|
||||||
|
import com.alibaba.cola.exception.BizException;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
|
||||||
|
import com.zcloud.eightwork.domain.model.TaskLogE;
|
||||||
|
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
|
||||||
|
import com.zcloud.eightwork.dto.EightworkInfoWithdrawCmd;
|
||||||
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
|
import com.zcloud.eightwork.persistence.dataobject.TaskLogDO;
|
||||||
|
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
||||||
|
import com.zcloud.eightwork.persistence.repository.MeasuresLogsRepository;
|
||||||
|
import com.zcloud.eightwork.persistence.repository.TaskLogRepository;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回作业执行器
|
||||||
|
* 将作业撤回到暂存状态
|
||||||
|
*
|
||||||
|
* @Author fangjiakai
|
||||||
|
* @Date 2026-04-07
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EightworkInfoWithdrawExe {
|
||||||
|
|
||||||
|
private static final Integer LOCK_FLAG_LOCKED = 1; // 锁定不可撤回
|
||||||
|
private static final Integer LOCK_FLAG_UNLOCKED = 2; // 未锁定可撤回
|
||||||
|
private static final Integer DRAFT_STATUS = 0; // 暂存状态
|
||||||
|
private static final Long APPLY_STEP_ID = 1L; // 申请步骤ID
|
||||||
|
|
||||||
|
private final EightworkInfoRepository eightworkInfoRepository;
|
||||||
|
private final TaskLogRepository taskLogRepository;
|
||||||
|
private final TaskLogGateway taskLogGateway;
|
||||||
|
private final MeasuresLogsRepository measuresLogsRepository;
|
||||||
|
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void execute(EightworkInfoWithdrawCmd cmd) {
|
||||||
|
log.info("开始撤回作业: id={}, reason={}", cmd.getId(), cmd.getReason());
|
||||||
|
|
||||||
|
// 1. 查询作业记录(加锁,确保并发安全)
|
||||||
|
EightworkInfoDO infoDO = eightworkInfoRepository.getById(cmd.getId());
|
||||||
|
if (infoDO == null) {
|
||||||
|
throw new BizException("作业记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录当前状态,用于并发检测
|
||||||
|
Integer currentStatus = infoDO.getStatus();
|
||||||
|
Integer currentLockFlag = infoDO.getLockFlag();
|
||||||
|
|
||||||
|
// 2. 检查是否可以撤回(未锁定)
|
||||||
|
if (LOCK_FLAG_LOCKED.equals(currentLockFlag)) {
|
||||||
|
throw new BizException("作业已进行审批流程,无法撤回");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查当前状态是否允许撤回
|
||||||
|
if (!TaskLogStatus.APPROVED.equalsCode(currentStatus)) {
|
||||||
|
throw new BizException("只能撤回进行中的作业");
|
||||||
|
}
|
||||||
|
|
||||||
|
String workId = infoDO.getWorkId();
|
||||||
|
|
||||||
|
// 4. 检查是否满足撤回条件:除申请外无完成流程
|
||||||
|
List<TaskLogE> logs = taskLogGateway.listAllByWorkId(workId);
|
||||||
|
boolean canWithdraw = checkCanWithdraw(logs);
|
||||||
|
if (!canWithdraw) {
|
||||||
|
throw new BizException("作业已有审批流程进行,无法撤回");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 再次检查状态(防止在检查期间状态被修改)
|
||||||
|
EightworkInfoDO latestInfo = eightworkInfoRepository.getById(cmd.getId());
|
||||||
|
if (!latestInfo.getStatus().equals(currentStatus) ||
|
||||||
|
!latestInfo.getLockFlag().equals(currentLockFlag)) {
|
||||||
|
log.warn("撤回失败:作业状态已被修改 originalStatus={}, originalLockFlag={}, currentStatus={}, currentLockFlag={}",
|
||||||
|
currentStatus, currentLockFlag, latestInfo.getStatus(), latestInfo.getLockFlag());
|
||||||
|
throw new BizException("操作失败:作业状态已被修改,请刷新后重试");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 撤回操作
|
||||||
|
// 6.1 更新主表状态为暂存
|
||||||
|
latestInfo.setStatus(DRAFT_STATUS);
|
||||||
|
latestInfo.setLockFlag(LOCK_FLAG_UNLOCKED);
|
||||||
|
eightworkInfoRepository.updateById(latestInfo);
|
||||||
|
|
||||||
|
// 6.2 删除除申请外的其他 task_log 记录(物理删除)
|
||||||
|
List<Long> toDeleteIds = logs.stream()
|
||||||
|
.filter(taskLog -> !taskLog.getStepId().equals(APPLY_STEP_ID))
|
||||||
|
.map(TaskLogE::getId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (!toDeleteIds.isEmpty()) {
|
||||||
|
taskLogRepository.physicalDeleteByIds(toDeleteIds);
|
||||||
|
log.info("已物理删除 {} 条非申请步骤记录", toDeleteIds.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6.3 将申请步骤状态改为未开始
|
||||||
|
TaskLogE applyLog = logs.stream()
|
||||||
|
.filter(taskLog -> taskLog.getStepId().equals(APPLY_STEP_ID))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (applyLog != null) {
|
||||||
|
// 无论申请步骤当前是什么状态(进行中或通过),都改为未开始
|
||||||
|
TaskLogDO updateLog = new TaskLogDO();
|
||||||
|
updateLog.setId(applyLog.getId());
|
||||||
|
updateLog.setStatus(TaskLogStatus.IN_PROGRESS.getCode());
|
||||||
|
taskLogRepository.updateById(updateLog);
|
||||||
|
log.info("申请步骤状态已改为未开始");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("作业撤回成功: workId={}, id={}", workId, cmd.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否可以撤回
|
||||||
|
* 条件:除申请外再无完成流程(只有申请步骤在进行中,其他步骤都是未开始状态)
|
||||||
|
*/
|
||||||
|
private boolean checkCanWithdraw(List<TaskLogE> logs) {
|
||||||
|
for (TaskLogE taskLog : logs) {
|
||||||
|
// 跳过申请步骤
|
||||||
|
if (APPLY_STEP_ID.equals(taskLog.getStepId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果其他步骤是完成状态,说明已有审批流程进行
|
||||||
|
if (TaskLogStatus.APPROVED.equalsCode(taskLog.getStatus())) {
|
||||||
|
log.info("不可撤回: stepId={}, stepName={}, status={}",
|
||||||
|
taskLog.getStepId(), taskLog.getStepName(), taskLog.getStatus());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -363,6 +363,9 @@ public class TaskLogAddExe {
|
||||||
);
|
);
|
||||||
handleInfoStep(eightworkInfo,cmd.getSignLogs());
|
handleInfoStep(eightworkInfo,cmd.getSignLogs());
|
||||||
|
|
||||||
|
// 设置初始锁定标识为未锁定(可撤回)
|
||||||
|
eightworkInfo.setLockFlag(2);
|
||||||
|
|
||||||
eightworkInfoRepository.save(eightworkInfo);
|
eightworkInfoRepository.save(eightworkInfo);
|
||||||
return eightworkInfo.getWorkId();
|
return eightworkInfo.getWorkId();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,18 @@ public class TaskLogUpdateExe {
|
||||||
* 强制终止状态码
|
* 强制终止状态码
|
||||||
*/
|
*/
|
||||||
private static final Integer FORCE_TERMINATE_STATUS = 998;
|
private static final Integer FORCE_TERMINATE_STATUS = 998;
|
||||||
|
/**
|
||||||
|
* 锁定标识:锁定不可撤回
|
||||||
|
*/
|
||||||
|
private static final Integer LOCK_FLAG_LOCKED = 1;
|
||||||
|
/**
|
||||||
|
* 锁定标识:未锁定可撤回
|
||||||
|
*/
|
||||||
|
private static final Integer LOCK_FLAG_UNLOCKED = 2;
|
||||||
|
/**
|
||||||
|
* 申请步骤ID
|
||||||
|
*/
|
||||||
|
private static final Long APPLY_STEP_ID = 1L;
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void nextStep(TaskLogNextCmd cmd) {
|
public void nextStep(TaskLogNextCmd cmd) {
|
||||||
|
|
@ -251,6 +263,12 @@ public class TaskLogUpdateExe {
|
||||||
log.info("附件步骤已保存附件: filePath={}", cmd.getFilePath());
|
log.info("附件步骤已保存附件: filePath={}", cmd.getFilePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 非申请步骤完成时,更新主表 lockFlag 为锁定状态(不可撤回)
|
||||||
|
if (!APPLY_STEP_ID.equals(currentLog.getStepId()) &&
|
||||||
|
TaskLogStatus.APPROVED.equalsCode(cmd.getStatus())) {
|
||||||
|
updateLockFlagToLocked(cmd.getWorkId());
|
||||||
|
}
|
||||||
|
|
||||||
// 发送待办完成事件
|
// 发送待办完成事件
|
||||||
sendTodoCompleteEvent(currentLog.getId());
|
sendTodoCompleteEvent(currentLog.getId());
|
||||||
|
|
||||||
|
|
@ -760,6 +778,52 @@ public class TaskLogUpdateExe {
|
||||||
log.info("已保存关闭原因: workId={}, closeReason={}", workId, closeReason);
|
log.info("已保存关闭原因: workId={}, closeReason={}", workId, closeReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新主表 lockFlag 为锁定状态
|
||||||
|
* 当非申请步骤完成时调用,表示作业已进入审批流程,不可撤回
|
||||||
|
* 使用状态检查防止并发问题
|
||||||
|
*/
|
||||||
|
private void updateLockFlagToLocked(String workId) {
|
||||||
|
// 使用查询构建器,确保获取最新状态
|
||||||
|
EightworkInfoDO infoDO = eightworkInfoRepository.getOne(
|
||||||
|
new LambdaQueryWrapper<EightworkInfoDO>()
|
||||||
|
.eq(EightworkInfoDO::getWorkId, workId)
|
||||||
|
.select(EightworkInfoDO::getId, EightworkInfoDO::getLockFlag,
|
||||||
|
EightworkInfoDO::getStatus, EightworkInfoDO::getWorkId));
|
||||||
|
|
||||||
|
if (infoDO == null) {
|
||||||
|
log.warn("未找到作业信息,无法更新锁定标识: workId={}", workId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查当前状态,确保作业未被撤回
|
||||||
|
if (!TaskLogStatus.APPROVED.equalsCode(infoDO.getStatus())) {
|
||||||
|
log.info("作业状态已变更(可能已被撤回),跳过锁定: workId={}, status={}",
|
||||||
|
workId, infoDO.getStatus());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经是锁定状态,跳过
|
||||||
|
if (LOCK_FLAG_LOCKED.equals(infoDO.getLockFlag())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
infoDO.setLockFlag(LOCK_FLAG_LOCKED);
|
||||||
|
|
||||||
|
// 使用 CAS 方式更新(防止并发)
|
||||||
|
boolean updated = eightworkInfoRepository.updateLockFlagToLocked(
|
||||||
|
infoDO.getId(),
|
||||||
|
LOCK_FLAG_UNLOCKED, // 期望的当前值(未锁定)
|
||||||
|
LOCK_FLAG_LOCKED, // 新值(锁定)
|
||||||
|
TaskLogStatus.APPROVED.getCode()); // 期望的当前状态
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
log.info("作业已锁定,不可撤回: workId={}", workId);
|
||||||
|
} else {
|
||||||
|
log.info("锁定失败:作业状态可能已被修改(可能已被撤回): workId={}", workId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理打回工作流
|
* 处理打回工作流
|
||||||
* status为2时打回到申请步骤,删除后续流程,允许修改后重新提交
|
* status为2时打回到申请步骤,删除后续流程,允许修改后重新提交
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import com.zcloud.eightwork.api.TaskLogServiceI;
|
||||||
import com.zcloud.eightwork.command.EightworkInfoAddExe;
|
import com.zcloud.eightwork.command.EightworkInfoAddExe;
|
||||||
import com.zcloud.eightwork.command.EightworkInfoRemoveExe;
|
import com.zcloud.eightwork.command.EightworkInfoRemoveExe;
|
||||||
import com.zcloud.eightwork.command.EightworkInfoUpdateExe;
|
import com.zcloud.eightwork.command.EightworkInfoUpdateExe;
|
||||||
|
import com.zcloud.eightwork.command.EightworkInfoWithdrawExe;
|
||||||
import com.zcloud.eightwork.command.query.EightworkInfoQueryExe;
|
import com.zcloud.eightwork.command.query.EightworkInfoQueryExe;
|
||||||
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
|
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
|
||||||
import com.zcloud.eightwork.domain.model.TaskLogE;
|
import com.zcloud.eightwork.domain.model.TaskLogE;
|
||||||
|
|
@ -44,6 +45,7 @@ public class EightworkInfoServiceImpl implements EightworkInfoServiceI {
|
||||||
private final TaskLogServiceI taskLogService;
|
private final TaskLogServiceI taskLogService;
|
||||||
private final TaskLogGateway taskLogGateway;
|
private final TaskLogGateway taskLogGateway;
|
||||||
private final EightworkInfoRepository eightworkInfoRepository;
|
private final EightworkInfoRepository eightworkInfoRepository;
|
||||||
|
private final EightworkInfoWithdrawExe eightworkInfoWithdrawExe;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EightworkInfoCO queryById(Long id) {
|
public EightworkInfoCO queryById(Long id) {
|
||||||
|
|
@ -135,6 +137,26 @@ public class EightworkInfoServiceImpl implements EightworkInfoServiceI {
|
||||||
log.info("工作流已强制终止: workId={}, stepId={}, closeReason={}", workId, currentLog.getStepId(), closeReason);
|
log.info("工作流已强制终止: workId={}, stepId={}, closeReason={}", workId, currentLog.getStepId(), closeReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回作业到暂存状态
|
||||||
|
*
|
||||||
|
* @param id 主表ID
|
||||||
|
* @param reason 撤回原因
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void withdraw(Long id, String reason) {
|
||||||
|
log.info("撤回作业: id={}, reason={}", id, reason);
|
||||||
|
|
||||||
|
com.zcloud.eightwork.dto.EightworkInfoWithdrawCmd cmd = new com.zcloud.eightwork.dto.EightworkInfoWithdrawCmd();
|
||||||
|
cmd.setId(id);
|
||||||
|
cmd.setReason(reason);
|
||||||
|
|
||||||
|
eightworkInfoWithdrawExe.execute(cmd);
|
||||||
|
|
||||||
|
log.info("作业已撤回: id={}", id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<StatisticsByWorkTypeCO> statisticsByWorkType(EightworkInfoPageQry qry){
|
public List<StatisticsByWorkTypeCO> statisticsByWorkType(EightworkInfoPageQry qry){
|
||||||
return eightworkInfoQueryExe.statisticsByWorkType(qry);
|
return eightworkInfoQueryExe.statisticsByWorkType(qry);
|
||||||
|
|
|
||||||
|
|
@ -38,5 +38,13 @@ public interface EightworkInfoServiceI {
|
||||||
void forceTerminate(Long id, String closeReason);
|
void forceTerminate(Long id, String closeReason);
|
||||||
|
|
||||||
List<StatisticsByWorkTypeCO> statisticsByWorkType(EightworkInfoPageQry qry);
|
List<StatisticsByWorkTypeCO> statisticsByWorkType(EightworkInfoPageQry qry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回作业到暂存状态
|
||||||
|
*
|
||||||
|
* @param id 主表ID
|
||||||
|
* @param reason 撤回原因
|
||||||
|
*/
|
||||||
|
void withdraw(Long id, String reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,9 @@ public class EightworkInfoPageQry extends PageQuery {
|
||||||
private Integer eqIsInnerWork;
|
private Integer eqIsInnerWork;
|
||||||
private String likeLimitedSpaceNameAndCode;
|
private String likeLimitedSpaceNameAndCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 盲板工作类型筛选(精确查询)
|
||||||
|
*/
|
||||||
|
private String eqBlindboardWorkType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.zcloud.eightwork.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 撤回作业命令
|
||||||
|
*
|
||||||
|
* @Author fangjiakai
|
||||||
|
* @Date 2026-04-07
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class EightworkInfoWithdrawCmd {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "主表ID", required = true)
|
||||||
|
@NotNull(message = "主表ID不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "撤回原因")
|
||||||
|
private String reason;
|
||||||
|
}
|
||||||
|
|
@ -53,6 +53,9 @@ public class EightworkInfoCO extends ClientObject {
|
||||||
//状态
|
//状态
|
||||||
@ApiModelProperty(value = "状态")
|
@ApiModelProperty(value = "状态")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
//锁定标识 1锁定不可撤回 2未锁定可撤回
|
||||||
|
@ApiModelProperty(value = "锁定标识 1锁定不可撤回 2未锁定可撤回")
|
||||||
|
private Integer lockFlag;
|
||||||
//详细信息
|
//详细信息
|
||||||
@ApiModelProperty(value = "详细信息")
|
@ApiModelProperty(value = "详细信息")
|
||||||
private JSONObject info;
|
private JSONObject info;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ public class EightworkInfoE extends BaseE {
|
||||||
private String currentStep;
|
private String currentStep;
|
||||||
//状态
|
//状态
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
//锁定标识 1锁定不可撤回 2未锁定可撤回
|
||||||
|
private Integer lockFlag;
|
||||||
//详细信息
|
//详细信息
|
||||||
private String info;
|
private String info;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,15 +14,16 @@ import java.util.stream.Collectors;
|
||||||
@Getter
|
@Getter
|
||||||
public enum MenuEnum {
|
public enum MenuEnum {
|
||||||
|
|
||||||
FIREWORK_LIST("/hidden/container/branchCompany/average/ledger/list", "hidden-tz-fgs"),
|
HOT_WORK("/eightwork/container/enterprise/hotWork/homework/list", "hotwork-list"),
|
||||||
SPACEWORK_LIST("/hidden/container/branchCompany/average/ignore/list", "hidden-hl-fgs"),
|
BLINDBOARD_WORK("/eightwork/container/enterprise/blindBoardWork/homework/list", "blindboardwork-list"),
|
||||||
HIDDEN_QR_FGS("/hidden/container/branchCompany/average/confirm/list", "hidden-qr-fgs"),
|
BREAKGROUND_WORK("/eightwork/container/enterprise/digWork/homework/list", "digwork-list"),
|
||||||
HIDDEN_YS_FGS("/hidden/container/branchCompany/average/acceptance/list", "hidden-ys-fgs"),
|
CONFINEDSPACE("/eightwork/container/enterprise/confinedSpaceWork/ledger/list", "confinedspacework-ledger-list"),
|
||||||
HIDDEN_YQ_FGS("/hidden/container/branchCompany/average/postponement/list", "hidden-yq-fgs"),
|
CONFINEDSPACE_WORK("/eightwork/container/enterprise/confinedSpaceWork/homework/list", "confinedspacework-list"),
|
||||||
HIDDEN_ZG_FGS("/hidden/container/branchCompany/average/rectification/list", "hidden-zg-fgs"),
|
CUTROAD_WORK("/eightwork/container/enterprise/cutWork/homework/list", "cutwork-list"),
|
||||||
HIDDEN_TSCZ_FGS("/hidden/container/branchCompany/average/specialDisposal/list", "hidden-tscz-fgs"),
|
ELECTRICITY_WORK("/eightwork/container/enterprise/electricWork/homework/list", "electricwork-list"),
|
||||||
HIDDEN_YHQRR_FGS("/hidden/container/branchCompany/average/confirmUser", "hidden-yhqrr-fgs")
|
HIGH_WORK("/eightwork/container/enterprise/highPlaceWork/homework/list", "highplacework-list"),
|
||||||
;
|
HOISTING("/eightwork/container/enterprise/liftingWork/homework/list", "liftingwork-list");
|
||||||
|
|
||||||
|
|
||||||
private final String path;
|
private final String path;
|
||||||
private final String menuKey;
|
private final String menuKey;
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,9 @@ public class EightworkInfoDO extends BaseDO {
|
||||||
//状态
|
//状态
|
||||||
@ApiModelProperty(value = "状态")
|
@ApiModelProperty(value = "状态")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
//锁定标识 1锁定不可撤回 2未锁定可撤回
|
||||||
|
@ApiModelProperty(value = "锁定标识 1锁定不可撤回 2未锁定可撤回")
|
||||||
|
private Integer lockFlag;
|
||||||
//详细信息
|
//详细信息
|
||||||
@ApiModelProperty(value = "详细信息")
|
@ApiModelProperty(value = "详细信息")
|
||||||
private String info;
|
private String info;
|
||||||
|
|
|
||||||
|
|
@ -35,5 +35,13 @@ public interface TaskLogMapper extends BaseMapper<TaskLogDO> {
|
||||||
* @return 删除的记录数
|
* @return 删除的记录数
|
||||||
*/
|
*/
|
||||||
int physicalDeleteByWorkId(@Param("workId") String workId);
|
int physicalDeleteByWorkId(@Param("workId") String workId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物理删除指定 ID 列表的记录
|
||||||
|
*
|
||||||
|
* @param ids ID 列表
|
||||||
|
* @return 删除的记录数
|
||||||
|
*/
|
||||||
|
int physicalDeleteByIds(@Param("ids") List<Long> ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,5 +24,17 @@ public interface EightworkInfoRepository extends BaseRepository<EightworkInfoDO>
|
||||||
Long countByWorkType(String workType);
|
Long countByWorkType(String workType);
|
||||||
|
|
||||||
List<StatisticsByWorkTypeDTO> statisticsByWorkType(Map<String, Object> params);
|
List<StatisticsByWorkTypeDTO> statisticsByWorkType(Map<String, Object> params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 CAS 方式更新 lockFlag(乐观锁)
|
||||||
|
* 只有当 lockFlag 和 status 都匹配时才更新
|
||||||
|
*
|
||||||
|
* @param id 主表ID
|
||||||
|
* @param expectedLockFlag 期望的当前 lockFlag 值
|
||||||
|
* @param newLockFlag 新的 lockFlag 值
|
||||||
|
* @param expectedStatus 期望的当前 status 值
|
||||||
|
* @return 是否更新成功(true=成功,false=状态不匹配更新失败)
|
||||||
|
*/
|
||||||
|
boolean updateLockFlagToLocked(Long id, Integer expectedLockFlag, Integer newLockFlag, Integer expectedStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,5 +34,13 @@ public interface TaskLogRepository extends BaseRepository<TaskLogDO> {
|
||||||
* @return 删除的记录数
|
* @return 删除的记录数
|
||||||
*/
|
*/
|
||||||
int physicalDeleteByWorkId(String workId);
|
int physicalDeleteByWorkId(String workId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物理删除指定 ID 列表的记录
|
||||||
|
*
|
||||||
|
* @param ids ID 列表
|
||||||
|
* @return 删除的记录数
|
||||||
|
*/
|
||||||
|
int physicalDeleteByIds(List<Long> ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,4 +72,15 @@ public class EightworkInfoRepositoryImpl extends BaseRepositoryImpl<EightworkInf
|
||||||
public List<StatisticsByWorkTypeDTO> statisticsByWorkType(Map<String, Object> params){
|
public List<StatisticsByWorkTypeDTO> statisticsByWorkType(Map<String, Object> params){
|
||||||
return eightworkInfoMapper.statisticsByWorkType(params);
|
return eightworkInfoMapper.statisticsByWorkType(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateLockFlagToLocked(Long id, Integer expectedLockFlag, Integer newLockFlag, Integer expectedStatus) {
|
||||||
|
LambdaUpdateWrapper<EightworkInfoDO> updateWrapper = new LambdaUpdateWrapper<>();
|
||||||
|
updateWrapper.eq(EightworkInfoDO::getId, id)
|
||||||
|
.eq(EightworkInfoDO::getLockFlag, expectedLockFlag) // CAS:期望的当前值
|
||||||
|
.eq(EightworkInfoDO::getStatus, expectedStatus) // CAS:期望的状态
|
||||||
|
.set(EightworkInfoDO::getLockFlag, newLockFlag); // 新值
|
||||||
|
|
||||||
|
return update(updateWrapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,5 +68,11 @@ public class TaskLogRepositoryImpl extends BaseRepositoryImpl<TaskLogMapper, Tas
|
||||||
// 使用 Mapper 中定义的物理删除 SQL
|
// 使用 Mapper 中定义的物理删除 SQL
|
||||||
return taskLogMapper.physicalDeleteByWorkId(workId);
|
return taskLogMapper.physicalDeleteByWorkId(workId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int physicalDeleteByIds(List<Long> ids) {
|
||||||
|
// 使用 Mapper 中定义的物理删除 SQL
|
||||||
|
return taskLogMapper.physicalDeleteByIds(ids);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,9 @@
|
||||||
<if test="params.likeWorkContent != null and params.likeWorkContent != ''">
|
<if test="params.likeWorkContent != null and params.likeWorkContent != ''">
|
||||||
and t.info->>'$.workContent' like concat('%', #{params.likeCreateName}, '%')
|
and t.info->>'$.workContent' like concat('%', #{params.likeCreateName}, '%')
|
||||||
</if>
|
</if>
|
||||||
|
<if test="params.eqBlindboardWorkType != null and params.eqBlindboardWorkType != ''">
|
||||||
|
and t.info->>'$.blindboardWorkType' = #{params.eqBlindboardWorkType}
|
||||||
|
</if>
|
||||||
<if test="params.geWorkStartTime != null and params.geWorkStartTime != ''">
|
<if test="params.geWorkStartTime != null and params.geWorkStartTime != ''">
|
||||||
and t.info->>'$.workStartTime' >= #{params.geWorkStartTime}
|
and t.info->>'$.workStartTime' >= #{params.geWorkStartTime}
|
||||||
</if>
|
</if>
|
||||||
|
|
|
||||||
|
|
@ -64,5 +64,12 @@
|
||||||
<delete id="physicalDeleteByWorkId">
|
<delete id="physicalDeleteByWorkId">
|
||||||
DELETE FROM task_log WHERE work_id = #{workId}
|
DELETE FROM task_log WHERE work_id = #{workId}
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
|
<delete id="physicalDeleteByIds">
|
||||||
|
DELETE FROM task_log WHERE id IN
|
||||||
|
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue