完成流程实例的取消

This commit is contained in:
YunaiV 2022-01-08 22:11:39 +08:00
parent 2017b03169
commit 2630ad8eaa
12 changed files with 115 additions and 18 deletions

View File

@ -12,6 +12,17 @@ Authorization: Bearer {{token}}
} }
} }
### 请求 /bpm/process-instance/cancel 接口 => 成功
DELETE {{baseUrl}}/bpm/process-instance/cancel
Content-Type: application/json
tenant-id: 1
Authorization: Bearer {{token}}
{
"id": "b9220387-7088-11ec-bcae-a2380e71991a",
"reason": "我就取消"
}
### 请求 /bpm/process-instance/my-page 接口 => 成功 ### 请求 /bpm/process-instance/my-page 接口 => 成功
GET {{baseUrl}}/bpm/process-instance/my-page GET {{baseUrl}}/bpm/process-instance/my-page
tenant-id: 1 tenant-id: 1

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task; package cn.iocoder.yudao.adminserver.modules.bpm.controller.task;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@ -34,6 +35,13 @@ public class BpmProcessInstanceController {
return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO)); return success(processInstanceService.createProcessInstance(getLoginUserId(), createReqVO));
} }
@DeleteMapping("/cancel")
@ApiOperation(value = "取消流程实例", notes = "撤回发起的流程")
public CommonResult<Boolean> cancelProcessInstance(@Valid @RequestBody BpmProcessInstanceCancelReqVO cancelReqVO) {
processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO);
return success(true);
}
@GetMapping("/my-page") @GetMapping("/my-page")
@ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用") @ApiOperation(value = "获得我的实例分页列表", notes = "在【我的流程】菜单中,进行调用")
public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage( public CommonResult<PageResult<BpmProcessInstancePageItemRespVO>> getMyProcessInstancePage(

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;
@ApiModel("流程实例的取消 Request VO")
@Data
public class BpmProcessInstanceCancelReqVO {
@ApiModelProperty(value = "流程实例的编号", required = true, example = "1024")
@NotEmpty(message = "流程实例的编号不能为空")
private String id;
@ApiModelProperty(value = "取消原因", required = true, example = "不请假了!")
@NotEmpty(message = "取消原因不能为空")
private String reason;
}

View File

@ -5,6 +5,7 @@ import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.task.BpmProcessIn
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
@ -22,4 +23,8 @@ public interface BpmProcessInstanceExtMapper extends BaseMapperX<BpmProcessInsta
.orderByDesc("id")); .orderByDesc("id"));
} }
default void updateByProcessInstanceId(String processInstanceId, BpmProcessInstanceExtDO updateObj) {
update(updateObj, new QueryWrapper<BpmProcessInstanceExtDO>().eq("process_instance_id", processInstanceId));
}
} }

View File

@ -10,7 +10,6 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
public interface BpmErrorCodeConstants { public interface BpmErrorCodeConstants {
// ========== 通用流程处理 模块 1-009-000-000 ========== // ========== 通用流程处理 模块 1-009-000-000 ==========
ErrorCode PROCESS_INSTANCE_NOT_EXISTS = new ErrorCode(1009000001, "流程实例不存在");
ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常"); ErrorCode HIGHLIGHT_IMG_ERROR = new ErrorCode(1009000002, "获取高亮流程图异常");
// ========== OA 流程模块 1-009-001-000 ========== // ========== OA 流程模块 1-009-001-000 ==========
@ -34,7 +33,7 @@ public interface BpmErrorCodeConstants {
ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态"); ErrorCode PROCESS_DEFINITION_IS_SUSPENDED = new ErrorCode(1009003002, "流程定义处于挂起状态");
// ========== 流程实例 1-009-004-000 ========== // ========== 流程实例 1-009-004-000 ==========
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "流程取消失败,流程不处于运行中");
// ========== 动态表单模块 1-009-010-000 ========== // ========== 动态表单模块 1-009-010-000 ==========
ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在"); ErrorCode FORM_NOT_EXISTS = new ErrorCode(1009010000, "动态表单不存在");

View File

@ -15,7 +15,7 @@ public enum BpmProcessInstanceResultEnum {
PROCESS(1, "处理中"), PROCESS(1, "处理中"),
PASS(2, "通过"), PASS(2, "通过"),
REJECT(3, "不通过"), REJECT(3, "不通过"),
CANCEL(4, "撤销"); CANCEL(4, "已取消");
/** /**
* 结果 * 结果

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.adminserver.modules.bpm.service.task; package cn.iocoder.yudao.adminserver.modules.bpm.service.task;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@ -28,6 +29,14 @@ public interface BpmProcessInstanceService {
*/ */
String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO); String createProcessInstance(Long userId, @Valid BpmProcessInstanceCreateReqVO createReqVO);
/**
* 取消流程实例
*
* @param userId 用户编号
* @param cancelReqVO 取消信息
*/
void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
/** /**
* 获得流程实例的分页 * 获得流程实例的分页
* *

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.service.task.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCancelReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceCreateReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstanceMyPageReqVO;
import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO; import cn.iocoder.yudao.adminserver.modules.bpm.controller.task.vo.instance.BpmProcessInstancePageItemRespVO;
@ -37,8 +38,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_IS_SUSPENDED; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.*;
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_DEFINITION_NOT_EXISTS;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@ -127,6 +127,23 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
processInstanceExtMapper.insert(instanceExt); processInstanceExtMapper.insert(instanceExt);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void cancelProcessInstance(Long userId, BpmProcessInstanceCancelReqVO cancelReqVO) {
// 校验流程实例存在
ProcessInstance instance = getProcessInstance(cancelReqVO.getId());
if (instance == null) {
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_EXISTS);
}
// 通过删除流程实例实现流程实例的取消
runtimeService.deleteProcessInstance(cancelReqVO.getId(), cancelReqVO.getReason());
// 更新流程实例的拓展表为取消状态
processInstanceExtMapper.updateByProcessInstanceId(cancelReqVO.getId(),
new BpmProcessInstanceExtDO().setStatus(BpmProcessInstanceStatusEnum.FINISH.getStatus())
.setResult(BpmProcessInstanceResultEnum.CANCEL.getResult()));
}
@Override @Override
public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId, public PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
BpmProcessInstanceMyPageReqVO pageReqVO) { BpmProcessInstanceMyPageReqVO pageReqVO) {

View File

@ -42,7 +42,6 @@ import java.io.InputStream;
import java.util.*; import java.util.*;
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.HIGHLIGHT_IMG_ERROR; import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.HIGHLIGHT_IMG_ERROR;
import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@ -228,7 +227,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
// 如果不存在实例 说明数据异常 // 如果不存在实例 说明数据异常
if (hpi == null) { if (hpi == null) {
throw exception(PROCESS_INSTANCE_NOT_EXISTS); // throw exception(PROCESS_INSTANCE_NOT_EXISTS);
throw new RuntimeException("不存在");
} }
// 如果有结束时间 返回model的流程图 // 如果有结束时间 返回model的流程图
if (!ObjectUtils.isEmpty(hpi.getEndTime())) { if (!ObjectUtils.isEmpty(hpi.getEndTime())) {

View File

@ -26,16 +26,12 @@ public class BpmProcessInstanceEventListener implements ActivitiEventListener {
@Override @Override
public void onEvent(ActivitiEvent event) { public void onEvent(ActivitiEvent event) {
// 不处理 ActivitiEventType.PROCESS_STARTED 事件原因事件发布时流程实例还没进行入库就已经发布了 ActivitiEvent 事件 // 不处理 ActivitiEventType.PROCESS_STARTED 事件原因事件发布时流程实例还没进行入库就已经发布了 ActivitiEvent 事件
// 不处理 ActivitiEventType.PROCESS_CANCELLED 事件原因直接在 BpmTaskService#cancelProcessInstance 更新记录
// 正常完成 // 正常完成
if (event.getType() == ActivitiEventType.PROCESS_COMPLETED if (event.getType() == ActivitiEventType.PROCESS_COMPLETED
|| event.getType() == ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT) { || event.getType() == ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT) {
return; // TODO 芋艿更新
}
// 取消
if (event.getType() == ActivitiEventType.PROCESS_CANCELLED) {
// TODO
System.out.println();
} }
} }

View File

@ -7,3 +7,14 @@ export function getMyProcessInstancePage(query) {
params: query params: query
}) })
} }
export function cancelProcessInstance(id, reason) {
return request({
url: '/bpm/process-instance/cancel',
method: 'DELETE',
data: {
id,
reason
}
})
}

View File

@ -103,8 +103,9 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"--> <!-- TODO 芋艿权限 -->
<!-- v-hasPermi="['bpm:process-instance-ext:update']">修改</el-button>--> <el-button type="text" size="small" icon="el-icon-delete" v-if="scope.row.result === 1"
@click="handleCancel(scope.row)">取消</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -162,8 +163,9 @@ import {
deleteProcessInstanceExt, deleteProcessInstanceExt,
getProcessInstanceExt, getProcessInstanceExt,
getProcessInstanceExtPage, getProcessInstanceExtPage,
exportProcessInstanceExtExcel exportProcessInstanceExtExcel, cancelProcessInstance
} from "@/api/bpm/processInstance"; } from "@/api/bpm/processInstance";
import {deleteErrorCode} from "@/api/system/errorCode";
export default { export default {
name: "ProcessInstanceExt", name: "ProcessInstanceExt",
@ -283,7 +285,23 @@ export default {
this.getList(); this.getList();
}); });
}); });
} },
/** 取消按钮操作 */
handleCancel(row) {
const id = row.id;
this.$prompt('请输出取消原因?', "取消流程", {
type: 'warning',
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/, //
inputErrorMessage: "取消原因不能为空",
}).then(({ value }) => {
return cancelProcessInstance(id, value);
}).then(() => {
this.getList();
this.msgSuccess("取消成功");
})
},
} }
}; };
</script> </script>