feat(web): 添加强制终止工作流功能并实现按作业类型统计
- 在EightworkInfoController中新增forceTerminate接口,支持强制终止工作流并传入关闭原因 - 添加StatisticsByWorkTypeCO数据传输对象用于统计结果返回 - 实现statisticsByWorkType接口,提供按作业类型的统计数据查询功能 - 修改forceTerminate方法参数,支持传递关闭原因到工作流终止处理 - 添加安全措施处理逻辑,在暂存和提交时同步处理安全措施确认步骤 - 新增强制终止命令ForceTerminateCmd和统计相关DTO类 - 在数据库映射文件中添加按作业类型统计数据查询的SQL语句 - 修复任务日志状态检查逻辑,确保正确的流转状态验证master
parent
9bd9b69e4c
commit
f50527a3c1
|
|
@ -5,6 +5,8 @@ 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.ForceTerminateCmd;
|
||||||
|
import com.zcloud.eightwork.dto.clientobject.StatisticsByWorkTypeCO;
|
||||||
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
||||||
import com.alibaba.cola.dto.MultiResponse;
|
import com.alibaba.cola.dto.MultiResponse;
|
||||||
import com.alibaba.cola.dto.PageResponse;
|
import com.alibaba.cola.dto.PageResponse;
|
||||||
|
|
@ -82,10 +84,17 @@ public class EightworkInfoController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("强制终止工作流")
|
@ApiOperation("强制终止工作流")
|
||||||
@PostMapping("/forceTerminate/{id}")
|
@PostMapping("/forceTerminate")
|
||||||
public Response forceTerminate(@PathVariable("id") Long id) {
|
public Response forceTerminate(@RequestBody ForceTerminateCmd cmd) {
|
||||||
eightworkInfoService.forceTerminate(id);
|
eightworkInfoService.forceTerminate(cmd.getId(), cmd.getCloseReason());
|
||||||
return SingleResponse.buildSuccess();
|
return SingleResponse.buildSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("按作业类型统计")
|
||||||
|
@PostMapping("/statisticsByWorkType")
|
||||||
|
public MultiResponse<StatisticsByWorkTypeCO> statisticsByWorkType(@RequestBody EightworkInfoPageQry qry) {
|
||||||
|
return MultiResponse.of(eightworkInfoService.statisticsByWorkType(qry));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
package com.zcloud.eightwork.command;
|
package com.zcloud.eightwork.command;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.alibaba.cola.exception.BizException;
|
import com.alibaba.cola.exception.BizException;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.jjb.saas.framework.auth.utils.AuthContext;
|
import com.jjb.saas.framework.auth.utils.AuthContext;
|
||||||
import com.zcloud.eightwork.domain.gateway.TaskFlowGateway;
|
import com.zcloud.eightwork.domain.gateway.TaskFlowGateway;
|
||||||
|
import com.zcloud.eightwork.domain.model.MeasuresLogsE;
|
||||||
import com.zcloud.eightwork.domain.model.TaskFlowE;
|
import com.zcloud.eightwork.domain.model.TaskFlowE;
|
||||||
|
import com.zcloud.eightwork.domain.model.TaskLogE;
|
||||||
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
|
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
|
||||||
import com.zcloud.eightwork.dto.EightworkInfoSaveDraftCmd;
|
import com.zcloud.eightwork.dto.EightworkInfoSaveDraftCmd;
|
||||||
|
import com.zcloud.eightwork.dto.TaskLogNextCmd;
|
||||||
import com.zcloud.eightwork.dto.TaskSignStepInfoCmd;
|
import com.zcloud.eightwork.dto.TaskSignStepInfoCmd;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.MeasuresLogsDO;
|
import com.zcloud.eightwork.persistence.dataobject.MeasuresLogsDO;
|
||||||
|
|
@ -23,7 +29,9 @@ import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 八险作业暂存执行器
|
* 八险作业暂存执行器
|
||||||
|
|
@ -114,6 +122,12 @@ public class EightworkInfoSaveDraftExe {
|
||||||
// 7. 处理其他安全措施
|
// 7. 处理其他安全措施
|
||||||
handleOtherMeasures(existingInfo.getWorkId(), cmd.getWorkType(), cmd.getOthers());
|
handleOtherMeasures(existingInfo.getWorkId(), cmd.getWorkType(), cmd.getOthers());
|
||||||
|
|
||||||
|
// 8. 处理安全措施
|
||||||
|
deleteTaskLogsExceptFirst(existingInfo.getWorkId());
|
||||||
|
if(ObjectUtil.isNotEmpty(cmd.getOthers()) && cmd.getOthers().containsKey("measures")) {
|
||||||
|
handleMeasuresStep(cmd,existingInfo.getWorkId());
|
||||||
|
}
|
||||||
|
|
||||||
log.info("暂存更新成功: workId={}", existingInfo.getWorkId());
|
log.info("暂存更新成功: workId={}", existingInfo.getWorkId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,6 +166,11 @@ public class EightworkInfoSaveDraftExe {
|
||||||
// 4. 处理其他安全措施
|
// 4. 处理其他安全措施
|
||||||
handleOtherMeasures(eightworkInfo.getWorkId(), cmd.getWorkType(), cmd.getOthers());
|
handleOtherMeasures(eightworkInfo.getWorkId(), cmd.getWorkType(), cmd.getOthers());
|
||||||
|
|
||||||
|
// 5. 处理安全措施
|
||||||
|
if(ObjectUtil.isNotEmpty(cmd.getOthers()) && cmd.getOthers().containsKey("measures")) {
|
||||||
|
handleMeasuresStep(cmd,eightworkInfo.getWorkId());
|
||||||
|
}
|
||||||
|
|
||||||
log.info("暂存创建成功: workId={}", eightworkInfo.getWorkId());
|
log.info("暂存创建成功: workId={}", eightworkInfo.getWorkId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,4 +311,46 @@ public class EightworkInfoSaveDraftExe {
|
||||||
|
|
||||||
log.info("暂存时已保存其他安全措施: workId={}, content={}", workId, otherMeasures);
|
log.info("暂存时已保存其他安全措施: workId={}, content={}", workId, otherMeasures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除除申请步骤外的所有 task_log
|
||||||
|
*/
|
||||||
|
private void deleteTaskLogsExceptFirst(String workId) {
|
||||||
|
taskLogRepository.physicalDeleteByWorkId(workId);
|
||||||
|
log.info("已删除除申请步骤外的 task_log: workId={}", workId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理安全措施确认步骤
|
||||||
|
* 保存安全措施记录
|
||||||
|
*/
|
||||||
|
private void handleMeasuresStep(EightworkInfoSaveDraftCmd cmd,String workId) {
|
||||||
|
log.info("暂存 处理安全措施确认");
|
||||||
|
|
||||||
|
List<MeasuresLogsE> measuresList = new ArrayList<>();
|
||||||
|
JSONArray array = cmd.getOthers().getJSONArray("measures");
|
||||||
|
if (array != null) {
|
||||||
|
for (int i = 0; i < array.size(); i++) {
|
||||||
|
MeasuresLogsE item = JSONUtil.toBean(array.getJSONObject(i).toJSONString(), MeasuresLogsE.class);
|
||||||
|
item.setWorkId(workId);
|
||||||
|
measuresList.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtil.isNotEmpty(cmd.getOthers().get("measuresType")) && cmd.getOthers().get("measuresType").equals("2")) {
|
||||||
|
measuresLogsRepository.updateBatchById(measuresList.stream().map(item -> {
|
||||||
|
MeasuresLogsDO d = new MeasuresLogsDO();
|
||||||
|
BeanUtils.copyProperties(item, d);
|
||||||
|
return d;
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
} else {
|
||||||
|
measuresLogsRepository.saveBatch(measuresList.stream().map(item -> {
|
||||||
|
MeasuresLogsDO d = new MeasuresLogsDO();
|
||||||
|
BeanUtils.copyProperties(item, d, "id");
|
||||||
|
d.setType(1);
|
||||||
|
return d;
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,27 @@
|
||||||
package com.zcloud.eightwork.command;
|
package com.zcloud.eightwork.command;
|
||||||
|
|
||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.alibaba.cola.exception.BizException;
|
import com.alibaba.cola.exception.BizException;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.jjb.saas.framework.auth.utils.AuthContext;
|
import com.jjb.saas.framework.auth.utils.AuthContext;
|
||||||
import com.zcloud.eightwork.domain.gateway.TaskFlowGateway;
|
import com.zcloud.eightwork.domain.gateway.TaskFlowGateway;
|
||||||
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
|
import com.zcloud.eightwork.domain.gateway.TaskLogGateway;
|
||||||
|
import com.zcloud.eightwork.domain.model.MeasuresLogsE;
|
||||||
import com.zcloud.eightwork.domain.model.TaskFlowE;
|
import com.zcloud.eightwork.domain.model.TaskFlowE;
|
||||||
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
|
import com.zcloud.eightwork.domain.model.enums.TaskLogStatus;
|
||||||
import com.zcloud.eightwork.domain.model.enums.WorkCodeEnum;
|
import com.zcloud.eightwork.domain.model.enums.WorkCodeEnum;
|
||||||
|
import com.zcloud.eightwork.dto.EightworkInfoSaveDraftCmd;
|
||||||
import com.zcloud.eightwork.dto.TaskLogAddCmd;
|
import com.zcloud.eightwork.dto.TaskLogAddCmd;
|
||||||
import com.zcloud.eightwork.dto.TaskSignStepInfoCmd;
|
import com.zcloud.eightwork.dto.TaskSignStepInfoCmd;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
|
import com.zcloud.eightwork.persistence.dataobject.MeasuresLogsDO;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.TaskLogDO;
|
import com.zcloud.eightwork.persistence.dataobject.TaskLogDO;
|
||||||
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
||||||
|
import com.zcloud.eightwork.persistence.repository.MeasuresLogsRepository;
|
||||||
import com.zcloud.eightwork.persistence.repository.TaskLogRepository;
|
import com.zcloud.eightwork.persistence.repository.TaskLogRepository;
|
||||||
import com.zcloud.gbscommon.utils.DateUtil;
|
import com.zcloud.gbscommon.utils.DateUtil;
|
||||||
import com.zcloud.gbscommon.utils.Tools;
|
import com.zcloud.gbscommon.utils.Tools;
|
||||||
|
|
@ -59,6 +66,7 @@ public class TaskLogAddExe {
|
||||||
private final TaskFlowGateway taskFlowGateway;
|
private final TaskFlowGateway taskFlowGateway;
|
||||||
private final EightworkInfoRepository eightworkInfoRepository;
|
private final EightworkInfoRepository eightworkInfoRepository;
|
||||||
private final StringRedisTemplate stringRedisTemplate;
|
private final StringRedisTemplate stringRedisTemplate;
|
||||||
|
private final MeasuresLogsRepository measuresLogsRepository;
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public List<TaskLogDO> execute(TaskLogAddCmd cmd) {
|
public List<TaskLogDO> execute(TaskLogAddCmd cmd) {
|
||||||
|
|
@ -92,7 +100,7 @@ public class TaskLogAddExe {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查状态,暂存(0)或打回(2)都可以转正式提交
|
// 2. 检查状态,暂存(0)或打回(2)都可以转正式提交
|
||||||
if (!TaskLogStatus.NOT_STARTED.getCode().equals(existingInfo.getStatus()) &&
|
if (!TaskLogStatus.IN_PROGRESS.getCode().equals(existingInfo.getStatus()) &&
|
||||||
!TaskLogStatus.REJECTED.equalsCode(existingInfo.getStatus())) {
|
!TaskLogStatus.REJECTED.equalsCode(existingInfo.getStatus())) {
|
||||||
throw new BizException("只能从暂存状态或打回状态转为正式提交");
|
throw new BizException("只能从暂存状态或打回状态转为正式提交");
|
||||||
}
|
}
|
||||||
|
|
@ -139,6 +147,12 @@ public class TaskLogAddExe {
|
||||||
// 9. 批量保存
|
// 9. 批量保存
|
||||||
taskLogRepository.saveBatch(taskLogs);
|
taskLogRepository.saveBatch(taskLogs);
|
||||||
|
|
||||||
|
// 10. 处理安全措施
|
||||||
|
deleteTaskLogsExceptFirst(existingInfo.getWorkId());
|
||||||
|
if(ObjectUtil.isNotEmpty(cmd.getOthers()) && cmd.getOthers().containsKey("measures")) {
|
||||||
|
handleMeasuresStep(cmd,existingInfo.getWorkId());
|
||||||
|
}
|
||||||
|
|
||||||
log.info("作业流程创建成功(从暂存): workId={}, stepCount={}", existingInfo.getWorkId(), taskLogs.size());
|
log.info("作业流程创建成功(从暂存): workId={}, stepCount={}", existingInfo.getWorkId(), taskLogs.size());
|
||||||
return taskLogs;
|
return taskLogs;
|
||||||
}
|
}
|
||||||
|
|
@ -176,6 +190,11 @@ public class TaskLogAddExe {
|
||||||
// 5. 批量保存
|
// 5. 批量保存
|
||||||
taskLogRepository.saveBatch(taskLogs);
|
taskLogRepository.saveBatch(taskLogs);
|
||||||
|
|
||||||
|
// 6. 处理安全措施
|
||||||
|
if(ObjectUtil.isNotEmpty(cmd.getOthers()) && cmd.getOthers().containsKey("measures")) {
|
||||||
|
handleMeasuresStep(cmd,workId);
|
||||||
|
}
|
||||||
|
|
||||||
log.info("作业流程创建成功: workId={}, stepCount={}", workId, taskLogs.size());
|
log.info("作业流程创建成功: workId={}, stepCount={}", workId, taskLogs.size());
|
||||||
return taskLogs;
|
return taskLogs;
|
||||||
}
|
}
|
||||||
|
|
@ -426,6 +445,46 @@ public class TaskLogAddExe {
|
||||||
|
|
||||||
return mergedJson.toJSONString();
|
return mergedJson.toJSONString();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 删除除申请步骤外的所有 task_log
|
||||||
|
*/
|
||||||
|
private void deleteTaskLogsExceptFirst(String workId) {
|
||||||
|
taskLogRepository.physicalDeleteByWorkId(workId);
|
||||||
|
log.info("已删除除申请步骤外的 task_log: workId={}", workId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理安全措施确认步骤
|
||||||
|
* 保存安全措施记录
|
||||||
|
*/
|
||||||
|
private void handleMeasuresStep(TaskLogAddCmd cmd, String workId) {
|
||||||
|
log.info("暂存 处理安全措施确认");
|
||||||
|
|
||||||
|
List<MeasuresLogsE> measuresList = new ArrayList<>();
|
||||||
|
JSONArray array = cmd.getOthers().getJSONArray("measures");
|
||||||
|
if (array != null) {
|
||||||
|
for (int i = 0; i < array.size(); i++) {
|
||||||
|
MeasuresLogsE item = JSONUtil.toBean(array.getJSONObject(i).toJSONString(), MeasuresLogsE.class);
|
||||||
|
item.setWorkId(workId);
|
||||||
|
measuresList.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ObjectUtil.isNotEmpty(cmd.getOthers().get("measuresType")) && cmd.getOthers().get("measuresType").equals("2")) {
|
||||||
|
measuresLogsRepository.updateBatchById(measuresList.stream().map(item -> {
|
||||||
|
MeasuresLogsDO d = new MeasuresLogsDO();
|
||||||
|
BeanUtils.copyProperties(item, d);
|
||||||
|
return d;
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
} else {
|
||||||
|
measuresLogsRepository.saveBatch(measuresList.stream().map(item -> {
|
||||||
|
MeasuresLogsDO d = new MeasuresLogsDO();
|
||||||
|
BeanUtils.copyProperties(item, d, "id");
|
||||||
|
d.setType(1);
|
||||||
|
return d;
|
||||||
|
}).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建票号 Redis Key
|
* 构建票号 Redis Key
|
||||||
|
|
|
||||||
|
|
@ -699,6 +699,9 @@ public class TaskLogUpdateExe {
|
||||||
// 更新 eightworkInfo.info(只更新本次变化的步骤)
|
// 更新 eightworkInfo.info(只更新本次变化的步骤)
|
||||||
updateEightworkInfo(cmd.getWorkId(), actionLogs);
|
updateEightworkInfo(cmd.getWorkId(), actionLogs);
|
||||||
|
|
||||||
|
// 保存关闭原因到主表 info
|
||||||
|
saveCloseReason(cmd.getWorkId(), cmd.getOthers());
|
||||||
|
|
||||||
// 更新主表状态为998
|
// 更新主表状态为998
|
||||||
eightworkInfoRepository.updateWorkStatus(
|
eightworkInfoRepository.updateWorkStatus(
|
||||||
cmd.getWorkId(),
|
cmd.getWorkId(),
|
||||||
|
|
@ -709,6 +712,53 @@ public class TaskLogUpdateExe {
|
||||||
log.info("工作流已强制终止: workId={}, skippedSteps={}", cmd.getWorkId(), actionLogs.size() - 1);
|
log.info("工作流已强制终止: workId={}, skippedSteps={}", cmd.getWorkId(), actionLogs.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存强制终止关闭原因到主表 info
|
||||||
|
*/
|
||||||
|
private void saveCloseReason(String workId, JSONObject others) {
|
||||||
|
if (others == null || !others.containsKey("closeReason")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String closeReason = others.getString("closeReason");
|
||||||
|
if (StringUtils.isBlank(closeReason)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EightworkInfoDO infoDO = eightworkInfoRepository.getOne(
|
||||||
|
new LambdaQueryWrapper<EightworkInfoDO>()
|
||||||
|
.eq(EightworkInfoDO::getWorkId, workId)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (infoDO == null) {
|
||||||
|
log.warn("未找到作业信息: workId={}", workId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析现有的 info
|
||||||
|
JSONObject infoJson;
|
||||||
|
if (StringUtils.isNotBlank(infoDO.getInfo())) {
|
||||||
|
try {
|
||||||
|
infoJson = JSONObject.parseObject(infoDO.getInfo());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("解析 info 失败,使用空对象: workId={}", workId, e);
|
||||||
|
infoJson = new JSONObject();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
infoJson = new JSONObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加关闭原因
|
||||||
|
infoJson.put("closeReason", closeReason);
|
||||||
|
infoJson.put("closeTime", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN));
|
||||||
|
|
||||||
|
// 更新到数据库
|
||||||
|
infoDO.setInfo(infoJson.toJSONString());
|
||||||
|
eightworkInfoRepository.updateById(infoDO);
|
||||||
|
|
||||||
|
log.info("已保存关闭原因: workId={}, closeReason={}", workId, closeReason);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理打回工作流
|
* 处理打回工作流
|
||||||
* status为2时打回到申请步骤,删除后续流程,允许修改后重新提交
|
* status为2时打回到申请步骤,删除后续流程,允许修改后重新提交
|
||||||
|
|
@ -1035,8 +1085,8 @@ public class TaskLogUpdateExe {
|
||||||
* 如果现有记录数少于签字人数,自动创建新记录
|
* 如果现有记录数少于签字人数,自动创建新记录
|
||||||
*/
|
*/
|
||||||
private void handleMultipleSignStep(TaskLogE firstLog, List<TaskLogE> existingLogs,
|
private void handleMultipleSignStep(TaskLogE firstLog, List<TaskLogE> existingLogs,
|
||||||
List<TaskSignStepInfoCmd> signInfos,
|
List<TaskSignStepInfoCmd> signInfos,
|
||||||
List<TaskLogDO> actionLogs, List<TaskLogE> allLogs) {
|
List<TaskLogDO> actionLogs, List<TaskLogE> allLogs) {
|
||||||
int existingCount = existingLogs.size();
|
int existingCount = existingLogs.size();
|
||||||
int requiredCount = signInfos.size();
|
int requiredCount = signInfos.size();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,18 @@ import com.alibaba.cola.dto.PageResponse;
|
||||||
import com.zcloud.eightwork.command.convertor.EightworkInfoCoConvertor;
|
import com.zcloud.eightwork.command.convertor.EightworkInfoCoConvertor;
|
||||||
import com.zcloud.eightwork.dto.EightworkInfoPageQry;
|
import com.zcloud.eightwork.dto.EightworkInfoPageQry;
|
||||||
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
||||||
|
import com.zcloud.eightwork.dto.clientobject.StatisticsByWorkTypeCO;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
|
import com.zcloud.eightwork.persistence.dataobject.dto.StatisticsByWorkTypeDTO;
|
||||||
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
||||||
import com.zcloud.gbscommon.utils.PageQueryHelper;
|
import com.zcloud.gbscommon.utils.PageQueryHelper;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,5 +52,15 @@ public class EightworkInfoQueryExe {
|
||||||
List<EightworkInfoCO> examCenterCOS = eightworkInfoCoConvertor.converDOsToCOs(pageResponse.getData());
|
List<EightworkInfoCO> examCenterCOS = eightworkInfoCoConvertor.converDOsToCOs(pageResponse.getData());
|
||||||
return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
|
return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<StatisticsByWorkTypeCO> statisticsByWorkType(EightworkInfoPageQry qry) {
|
||||||
|
Map<String, Object> params = PageQueryHelper.toHashMap(qry);
|
||||||
|
List<StatisticsByWorkTypeDTO> statisticsByWorkTypeDTOS = eightworkInfoRepository.statisticsByWorkType(params);
|
||||||
|
return statisticsByWorkTypeDTOS.stream().map(statisticsByWorkTypeDTO -> {
|
||||||
|
StatisticsByWorkTypeCO statisticsByWorkTypeCO = new StatisticsByWorkTypeCO();
|
||||||
|
BeanUtils.copyProperties(statisticsByWorkTypeDTO, statisticsByWorkTypeCO);
|
||||||
|
return statisticsByWorkTypeCO;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import com.zcloud.eightwork.dto.EightworkInfoPageQry;
|
||||||
import com.zcloud.eightwork.dto.EightworkInfoUpdateCmd;
|
import com.zcloud.eightwork.dto.EightworkInfoUpdateCmd;
|
||||||
import com.zcloud.eightwork.dto.TaskLogNextCmd;
|
import com.zcloud.eightwork.dto.TaskLogNextCmd;
|
||||||
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
||||||
|
import com.zcloud.eightwork.dto.clientobject.StatisticsByWorkTypeCO;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
@ -24,6 +25,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* web-app
|
* web-app
|
||||||
*
|
*
|
||||||
|
|
@ -80,15 +83,16 @@ public class EightworkInfoServiceImpl implements EightworkInfoServiceI {
|
||||||
* 业务逻辑参考 TaskLogUpdateExe.handleForceTerminate 方法
|
* 业务逻辑参考 TaskLogUpdateExe.handleForceTerminate 方法
|
||||||
* 1. 根据主表 ID 查询 workId
|
* 1. 根据主表 ID 查询 workId
|
||||||
* 2. 查找当前正在进行的步骤(status=0)
|
* 2. 查找当前正在进行的步骤(status=0)
|
||||||
* 3. 构建 TaskLogNextCmd 并设置 status=998
|
* 3. 构建 TaskLogNextCmd 并设置 status=998 和关闭原因
|
||||||
* 4. 调用 TaskLogService.nextStep 处理强制终止
|
* 4. 调用 TaskLogService.nextStep 处理强制终止
|
||||||
*
|
*
|
||||||
* @param id 主表 ID
|
* @param id 主表 ID
|
||||||
|
* @param closeReason 关闭原因
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void forceTerminate(Long id) {
|
public void forceTerminate(Long id, String closeReason) {
|
||||||
log.info("强制终止工作流: id={}", id);
|
log.info("强制终止工作流: id={}, closeReason={}", id, closeReason);
|
||||||
|
|
||||||
// 1. 根据主表 ID 查询 EightworkInfoDO 获取 workId
|
// 1. 根据主表 ID 查询 EightworkInfoDO 获取 workId
|
||||||
EightworkInfoDO infoDO = eightworkInfoRepository.getById(id);
|
EightworkInfoDO infoDO = eightworkInfoRepository.getById(id);
|
||||||
|
|
@ -118,10 +122,22 @@ public class EightworkInfoServiceImpl implements EightworkInfoServiceI {
|
||||||
cmd.setStepId(currentLog.getStepId());
|
cmd.setStepId(currentLog.getStepId());
|
||||||
cmd.setStatus(998); // 强制终止状态码
|
cmd.setStatus(998); // 强制终止状态码
|
||||||
|
|
||||||
|
// 设置关闭原因到 others
|
||||||
|
if (org.apache.commons.lang.StringUtils.isNotBlank(closeReason)) {
|
||||||
|
com.alibaba.fastjson.JSONObject others = new com.alibaba.fastjson.JSONObject();
|
||||||
|
others.put("closeReason", closeReason);
|
||||||
|
cmd.setOthers(others);
|
||||||
|
}
|
||||||
|
|
||||||
// 4. 调用 TaskLogService.nextStep 处理强制终止
|
// 4. 调用 TaskLogService.nextStep 处理强制终止
|
||||||
taskLogService.nextStep(cmd);
|
taskLogService.nextStep(cmd);
|
||||||
|
|
||||||
log.info("工作流已强制终止: workId={}, stepId={}", workId, currentLog.getStepId());
|
log.info("工作流已强制终止: workId={}, stepId={}, closeReason={}", workId, currentLog.getStepId(), closeReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<StatisticsByWorkTypeCO> statisticsByWorkType(EightworkInfoPageQry qry){
|
||||||
|
return eightworkInfoQueryExe.statisticsByWorkType(qry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ 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.clientobject.EightworkInfoCO;
|
import com.zcloud.eightwork.dto.clientobject.EightworkInfoCO;
|
||||||
|
import com.zcloud.eightwork.dto.clientobject.StatisticsByWorkTypeCO;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* web-client
|
* web-client
|
||||||
|
|
@ -30,7 +33,10 @@ public interface EightworkInfoServiceI {
|
||||||
* 强制终止工作流
|
* 强制终止工作流
|
||||||
*
|
*
|
||||||
* @param id 主表 ID
|
* @param id 主表 ID
|
||||||
|
* @param closeReason 关闭原因
|
||||||
*/
|
*/
|
||||||
void forceTerminate(Long id);
|
void forceTerminate(Long id, String closeReason);
|
||||||
|
|
||||||
|
List<StatisticsByWorkTypeCO> statisticsByWorkType(EightworkInfoPageQry qry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ public class EightworkInfoPageQry extends PageQuery {
|
||||||
* - `ne`: 不等比较查询,对应SQL的!=操作符
|
* - `ne`: 不等比较查询,对应SQL的!=操作符
|
||||||
*/
|
*/
|
||||||
private String eqWorkType;
|
private String eqWorkType;
|
||||||
|
private List<Long> inCorpInfoId;
|
||||||
private String eqCheckNo;
|
private String eqCheckNo;
|
||||||
private Integer eqStatus;
|
private Integer eqStatus;
|
||||||
private String eqWorkLevel;
|
private String eqWorkLevel;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.zcloud.eightwork.dto;
|
||||||
|
|
||||||
|
import com.alibaba.cola.dto.Command;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author fangjiakai
|
||||||
|
* @date 2026/03/31 13:30
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ForceTerminateCmd extends Command {
|
||||||
|
@ApiModelProperty(value = "主键", name = "id", required = true)
|
||||||
|
@NotNull(message = "主键不能为空")
|
||||||
|
private Long id;
|
||||||
|
@ApiModelProperty(value = "关闭原因", name = "closeReason")
|
||||||
|
private String closeReason;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.zcloud.eightwork.dto.clientobject;
|
||||||
|
|
||||||
|
import com.alibaba.cola.dto.ClientObject;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author fangjiakai
|
||||||
|
* @date 2026/03/31 13:42
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class StatisticsByWorkTypeCO extends ClientObject {
|
||||||
|
@ApiModelProperty(value = "企业ID")
|
||||||
|
private Long corpinfoId;
|
||||||
|
@ApiModelProperty(value = "暂存数")
|
||||||
|
private Integer draftCount;
|
||||||
|
@ApiModelProperty(value = "进行中数")
|
||||||
|
private Integer doingCount;
|
||||||
|
@ApiModelProperty(value = "打回数")
|
||||||
|
private Integer rejectedCount;
|
||||||
|
@ApiModelProperty(value = "强制终止数")
|
||||||
|
private Integer forceTerminateCount;
|
||||||
|
@ApiModelProperty(value = "完成数")
|
||||||
|
private Integer doneCount;
|
||||||
|
}
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
|
|
||||||
<mapper namespace="com.zcloud.eightwork.persistence.mapper.ConfinedSpaceMapper">
|
|
||||||
|
|
||||||
</mapper>
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.zcloud.eightwork.persistence.dataobject.dto;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.jjb.saas.framework.repository.basedo.BaseDO;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author fangjiakai
|
||||||
|
* @date 2026/03/31 13:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class StatisticsByWorkTypeDTO extends BaseDO {
|
||||||
|
@ApiModelProperty(value = "企业ID")
|
||||||
|
private Long corpinfoId;
|
||||||
|
@ApiModelProperty(value = "暂存数")
|
||||||
|
private Integer draftCount;
|
||||||
|
@ApiModelProperty(value = "进行中数")
|
||||||
|
private Integer doingCount;
|
||||||
|
@ApiModelProperty(value = "打回数")
|
||||||
|
private Integer rejectedCount;
|
||||||
|
@ApiModelProperty(value = "强制终止数")
|
||||||
|
private Integer forceTerminateCount;
|
||||||
|
@ApiModelProperty(value = "完成数")
|
||||||
|
private Integer doneCount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.jjb.saas.framework.datascope.annotation.DataScope;
|
import com.jjb.saas.framework.datascope.annotation.DataScope;
|
||||||
import com.jjb.saas.framework.datascope.annotation.DataScopes;
|
import com.jjb.saas.framework.datascope.annotation.DataScopes;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
|
import com.zcloud.eightwork.persistence.dataobject.dto.StatisticsByWorkTypeDTO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -24,5 +26,7 @@ import java.util.Map;
|
||||||
public interface EightworkInfoMapper extends BaseMapper<EightworkInfoDO> {
|
public interface EightworkInfoMapper extends BaseMapper<EightworkInfoDO> {
|
||||||
|
|
||||||
IPage<EightworkInfoDO> listPage(Page<Map<String, Object>> page, @Param("params") Map<String, Object> parmas, String menuPerms);
|
IPage<EightworkInfoDO> listPage(Page<Map<String, Object>> page, @Param("params") Map<String, Object> parmas, String menuPerms);
|
||||||
|
|
||||||
|
List<StatisticsByWorkTypeDTO> statisticsByWorkType(@Param("params") Map<String, Object> params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.zcloud.eightwork.persistence.repository;
|
||||||
import com.alibaba.cola.dto.PageResponse;
|
import com.alibaba.cola.dto.PageResponse;
|
||||||
import com.jjb.saas.framework.repository.repo.BaseRepository;
|
import com.jjb.saas.framework.repository.repo.BaseRepository;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
|
import com.zcloud.eightwork.persistence.dataobject.dto.StatisticsByWorkTypeDTO;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -21,5 +22,7 @@ public interface EightworkInfoRepository extends BaseRepository<EightworkInfoDO>
|
||||||
List<EightworkInfoDO> listAllByWorkIds(List<String> workIds);
|
List<EightworkInfoDO> listAllByWorkIds(List<String> workIds);
|
||||||
|
|
||||||
Long countByWorkType(String workType);
|
Long countByWorkType(String workType);
|
||||||
|
|
||||||
|
List<StatisticsByWorkTypeDTO> statisticsByWorkType(Map<String, Object> params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import com.jjb.saas.framework.repository.common.PageHelper;
|
||||||
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
|
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
|
||||||
import com.zcloud.eightwork.domain.model.enums.MenuEnum;
|
import com.zcloud.eightwork.domain.model.enums.MenuEnum;
|
||||||
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
import com.zcloud.eightwork.persistence.dataobject.EightworkInfoDO;
|
||||||
|
import com.zcloud.eightwork.persistence.dataobject.dto.StatisticsByWorkTypeDTO;
|
||||||
import com.zcloud.eightwork.persistence.mapper.EightworkInfoMapper;
|
import com.zcloud.eightwork.persistence.mapper.EightworkInfoMapper;
|
||||||
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
import com.zcloud.eightwork.persistence.repository.EightworkInfoRepository;
|
||||||
import com.zcloud.gbscommon.utils.PageQueryHelper;
|
import com.zcloud.gbscommon.utils.PageQueryHelper;
|
||||||
|
|
@ -66,4 +67,9 @@ public class EightworkInfoRepositoryImpl extends BaseRepositoryImpl<EightworkInf
|
||||||
queryWrapper.eq(EightworkInfoDO::getWorkType, workType);
|
queryWrapper.eq(EightworkInfoDO::getWorkType, workType);
|
||||||
return count(queryWrapper);
|
return count(queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<StatisticsByWorkTypeDTO> statisticsByWorkType(Map<String, Object> params){
|
||||||
|
return eightworkInfoMapper.statisticsByWorkType(params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,5 +88,27 @@
|
||||||
order by t.create_time desc
|
order by t.create_time desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="statisticsByWorkType" resultType="com.zcloud.eightwork.persistence.dataobject.dto.StatisticsByWorkTypeDTO">
|
||||||
|
select t.corpinfo_id,
|
||||||
|
sum(case t.status when 0 then 1 else 0 end) as draftCount,
|
||||||
|
sum(case t.status when 1 then 1 else 0 end) as doingCount,
|
||||||
|
sum(case t.status when 2 then 1 else 0 end) as rejectedCount,
|
||||||
|
sum(case t.status when 998 then 1 else 0 end) as forceTerminateCount,
|
||||||
|
sum(case t.status when 999 then 1 else 0 end) as doneCount
|
||||||
|
|
||||||
|
from eightwork_info t
|
||||||
|
where t.delete_enum = 'FALSE'
|
||||||
|
<if test="params.eqWorkType != null and params.eqWorkType != ''">
|
||||||
|
and t.work_type = #{params.eqWorkType}
|
||||||
|
</if>
|
||||||
|
<if test="params.inCorpInfoId != null and params.inCorpInfoId.size() > 0">
|
||||||
|
and t.corpinfo_id in
|
||||||
|
<foreach collection="params.inCorpInfoId" item="item" open="(" separator="," close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
group by t.corpinfo_id
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue