审核流程撤回时同步更新oa待办状态,已办--》待办。
This commit is contained in:
@@ -8,17 +8,13 @@ import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.vo.LabelValueVO;
|
||||
import com.budwk.app.flow.constant.FlowConst;
|
||||
import com.budwk.app.flow.engine.FlowEngine;
|
||||
import com.budwk.app.flow.engine.event.ProcessEvent;
|
||||
import com.budwk.app.flow.engine.event.ProcessPublisher;
|
||||
import com.budwk.app.flow.engine.model.ProcessModel;
|
||||
import com.budwk.app.flow.engine.model.TaskModel;
|
||||
import com.budwk.app.flow.entity.Candidate;
|
||||
import com.budwk.app.flow.entity.ProcessDefine;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessEventTypeEnum;
|
||||
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskPerformTypeEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.flow.service.FlowCommonService;
|
||||
import com.budwk.app.flow.vo.HighLightVO;
|
||||
@@ -248,37 +244,11 @@ public class FlowCommonController {
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@ApiOperation("撤销任务")
|
||||
public Result revokeTask(@Param("taskId") Long taskId) {
|
||||
// 自己任务
|
||||
ProcessTask selfTask = dao.fetch(ProcessTask.class, taskId);
|
||||
selfTask.setTaskState(ProcessTaskStateEnum.DOING.getCode());
|
||||
|
||||
// 撤销任务
|
||||
List<ProcessTask> taskList = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskParentId, "=", taskId));
|
||||
for (ProcessTask task : taskList) {
|
||||
task.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
|
||||
dao.update(task);
|
||||
if (taskId == null) {
|
||||
return Result.error("任务ID不能为空");
|
||||
}
|
||||
// 会签并行任务 撤销后续任务
|
||||
if (selfTask.getPerformType().equals(ProcessTaskPerformTypeEnum.COUNTERSIGN.getCode())) {
|
||||
List<ProcessTask> doingTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.DOING.getCode())
|
||||
.and(ProcessTask::getProcessInstanceId, "=", selfTask.getProcessInstanceId()));
|
||||
for (ProcessTask doingTask : doingTasks) {
|
||||
doingTask.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
|
||||
dao.update(doingTask);
|
||||
}
|
||||
}
|
||||
|
||||
// 激活
|
||||
dao.update(selfTask);
|
||||
|
||||
// 流程激活
|
||||
dao.update(ProcessInstance.class, Chain.make("state", ProcessInstanceStateEnum.DOING.getCode()),Cnd.where(ProcessInstance::getId, "=", selfTask.getProcessInstanceId()));
|
||||
|
||||
// 发送任务撤回事件 确保上面执行成功
|
||||
for (ProcessTask task : taskList) {
|
||||
ProcessPublisher.notify(ProcessEvent.builder().eventType(ProcessEventTypeEnum.PROCESS_TASK_REVOKE).sourceId(task.getId()).build());
|
||||
}
|
||||
|
||||
// taskId 为原已完成任务 ID;服务同步 OA 后返回 Result 成功结果。
|
||||
flowCommonService.revokeTask(taskId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
package com.budwk.app.flow.service;
|
||||
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.flow.engine.event.ProcessEvent;
|
||||
import com.budwk.app.flow.engine.event.ProcessPublisher;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessEventTypeEnum;
|
||||
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskPerformTypeEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Chain;
|
||||
import java.util.List;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.budwk.app.base.event.flow.jumptofirsttask.FlowJumpToFirstTaskNodePublisher;
|
||||
@@ -17,6 +30,10 @@ public class FlowCommonService {
|
||||
|
||||
@Inject
|
||||
private FlowEngine flowEngine;
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private SchoolOaTodoService schoolOaTodoService;
|
||||
|
||||
/**
|
||||
* 执行 WF 任务,任务状态、业务监听器和后续任务写入共用本地事务;OA 异常向外抛出触发回滚。
|
||||
@@ -75,4 +92,55 @@ public class FlowCommonService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤回已完成的 WF 任务,恢复原 OA 待办并清理被撤销的后续待办。
|
||||
* @param taskId 原已完成任务 ID;沿用原任务及参与人,保持 OA uniqueId 不变
|
||||
* 返回 void;失败抛出异常回滚本地事务,外部 OA 请求不参与数据库事务。
|
||||
*/
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void revokeTask(Long taskId) {
|
||||
// 自己任务
|
||||
ProcessTask selfTask = dao.fetch(ProcessTask.class, taskId);
|
||||
if (selfTask == null) {
|
||||
throw new BaseException("撤回失败:任务不存在");
|
||||
}
|
||||
// 防止重复撤回再次删除后续 OA 待办;原任务必须是已完成状态。
|
||||
if (!ProcessTaskStateEnum.FINISHED.getCode().equals(selfTask.getTaskState())) {
|
||||
throw new BaseException("撤回失败:任务不是已完成状态,请刷新后重试");
|
||||
}
|
||||
schoolOaTodoService.restoreTodo(selfTask);
|
||||
|
||||
// 撤销任务
|
||||
List<ProcessTask> taskList = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskParentId, "=", taskId));
|
||||
for (ProcessTask task : taskList) {
|
||||
// 在本地状态改变前删除 OA 待办,保留 deleteTodo 对历史任务的保护。
|
||||
schoolOaTodoService.deleteTodo(task);
|
||||
task.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
|
||||
dao.update(task);
|
||||
}
|
||||
// 会签并行任务 撤销后续任务
|
||||
if (selfTask.getPerformType().equals(ProcessTaskPerformTypeEnum.COUNTERSIGN.getCode())) {
|
||||
List<ProcessTask> doingTasks = dao.query(ProcessTask.class, Cnd.where(ProcessTask::getTaskState, "=", ProcessTaskStateEnum.DOING.getCode())
|
||||
.and(ProcessTask::getProcessInstanceId, "=", selfTask.getProcessInstanceId()));
|
||||
for (ProcessTask doingTask : doingTasks) {
|
||||
schoolOaTodoService.deleteTodo(doingTask);
|
||||
doingTask.setTaskState(ProcessTaskStateEnum.WITHDRAW.getCode());
|
||||
dao.update(doingTask);
|
||||
}
|
||||
}
|
||||
|
||||
// 激活
|
||||
selfTask.setTaskState(ProcessTaskStateEnum.DOING.getCode());
|
||||
dao.update(selfTask);
|
||||
|
||||
// 流程激活
|
||||
dao.update(ProcessInstance.class, Chain.make("state", ProcessInstanceStateEnum.DOING.getCode()),Cnd.where(ProcessInstance::getId, "=", selfTask.getProcessInstanceId()));
|
||||
|
||||
// 发送任务撤回事件 确保上面执行成功
|
||||
for (ProcessTask task : taskList) {
|
||||
ProcessPublisher.notify(ProcessEvent.builder().eventType(ProcessEventTypeEnum.PROCESS_TASK_REVOKE).sourceId(task.getId()).build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,13 @@ public interface SchoolOaTodoService {
|
||||
*/
|
||||
void completeTodo(ProcessTask processTask);
|
||||
|
||||
/**
|
||||
* 审核撤回时恢复原任务的 OA 待办,保留原任务和参与人组成的 uniqueId。
|
||||
* @param processTask 需要重新办理的原审核任务,包含任务及实例 ID、节点和表单地址
|
||||
* 返回 void;OA 返回非成功状态时抛出异常。
|
||||
*/
|
||||
void restoreTodo(ProcessTask processTask);
|
||||
|
||||
/**
|
||||
* 根据本系统流程任务删除学校 OA 单条待办。
|
||||
*
|
||||
|
||||
@@ -158,6 +158,71 @@ public class SchoolOaTodoServiceImpl implements SchoolOaTodoService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用修改信息接口把原已办恢复为待办;不能重复创建同一个 uniqueId。
|
||||
* @param processTask 被撤回的原审核任务,按实例读取发起人、按任务读取全部接收人
|
||||
* 返回 void;state=200 表示恢复成功,其他状态保持失败并向外抛出。
|
||||
*/
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void restoreTodo(ProcessTask processTask) {
|
||||
if (processTask == null || processTask.getId() == null) {
|
||||
throw new BaseException("学校OA待办恢复失败:流程任务为空");
|
||||
}
|
||||
if (!isSchoolOaEnabled("恢复待办", processTask.getId(), processTask.getProcessInstanceId())) {
|
||||
return;
|
||||
}
|
||||
// 发起节点原本不推送 OA,因此撤回申请时也不恢复该节点的 OA 记录。
|
||||
if (Long.valueOf(0L).equals(processTask.getTaskParentId()) && "startTask".equals(processTask.getTaskName())) {
|
||||
return;
|
||||
}
|
||||
ProcessInstance instance = dao.fetch(ProcessInstance.class, processTask.getProcessInstanceId());
|
||||
if (instance == null) {
|
||||
throw new BaseException("学校OA待办恢复失败:流程实例不存在");
|
||||
}
|
||||
ProcessDefine define = dao.fetch(ProcessDefine.class, instance.getProcessDefineId());
|
||||
Sys_user creator = dao.fetch(Sys_user.class, instance.getOperator());
|
||||
if (define == null || creator == null || StrUtil.hasBlank(creator.getLoginname(), creator.getUsername())) {
|
||||
throw new BaseException("学校OA待办恢复失败:流程定义或发起人信息不完整");
|
||||
}
|
||||
List<ProcessTaskActor> actors = dao.query(ProcessTaskActor.class,
|
||||
Cnd.where(ProcessTaskActor::getProcessTaskId, "=", processTask.getId()));
|
||||
if (actors.isEmpty()) {
|
||||
throw new BaseException("学校OA待办恢复失败:流程任务接收人为空,taskId={}", processTask.getId());
|
||||
}
|
||||
for (ProcessTaskActor actor : actors) {
|
||||
if (skipSuperAdmin(actor, "恢复待办", processTask.getId())) {
|
||||
continue;
|
||||
}
|
||||
if (StrUtil.hasBlank(actor.getActorId(), actor.getActorAccount(), actor.getActorName())) {
|
||||
throw new BaseException("学校OA待办恢复失败:接收人信息不完整,taskId={}", processTask.getId());
|
||||
}
|
||||
String uniqueId = processTask.getId() + "_" + actor.getActorId();
|
||||
JSONObject body = new JSONObject();
|
||||
body.set("flowTypeName", getFlowTypeName(define));
|
||||
body.set("flowId", String.valueOf(instance.getId()));
|
||||
body.set("title", getInstanceTitle(instance, define));
|
||||
body.set("stepName", processTask.getDisplayName());
|
||||
body.set("creatorCode", creator.getLoginname());
|
||||
body.set("creatorName", creator.getUsername());
|
||||
body.set("creatorTime", formatTime(instance.getCreatedAt()));
|
||||
String pcUrl = buildTaskUrl(processTask.getFormKey(), processTask);
|
||||
String appUrl = buildAppTaskUrl(processTask.getH5FormKey(), processTask);
|
||||
body.set("pcUrl", pcUrl);
|
||||
body.set("appUrl", appUrl);
|
||||
body.set("pcPreviewUrl", pcUrl);
|
||||
body.set("appPreviewUrl", appUrl);
|
||||
body.set("uniqueId", uniqueId);
|
||||
body.set("receiveCode", actor.getActorAccount());
|
||||
body.set("receiveName", actor.getActorName());
|
||||
body.set("receiveTime", formatTime(processTask.getCreatedAt()));
|
||||
body.set("isRemark", "0");
|
||||
String url = requireConfig("school-oa.todo.update-handle-url").replace("{uniqueId}", uniqueId);
|
||||
String response = sendTodoRequest(url, body, "学校OA待办恢复失败", "学校OA待办恢复异常");
|
||||
log.info("学校OA待办恢复成功,taskId={},uniqueId={},response={}", processTask.getId(), uniqueId, response);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void deleteFlow(Long flowId) {
|
||||
|
||||
Reference in New Issue
Block a user