mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	流程详情页 90% - 接入审批通过、审批不通过的功能
This commit is contained in:
		| @ -46,14 +46,14 @@ public class BpmTaskController { | |||||||
|     @PutMapping("/approve") |     @PutMapping("/approve") | ||||||
|     @ApiOperation("通过任务") |     @ApiOperation("通过任务") | ||||||
|     public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) { |     public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) { | ||||||
|         taskService.approveTask(reqVO); |         taskService.approveTask(getLoginUserId(), reqVO); | ||||||
|         return success(true); |         return success(true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PutMapping("/reject") |     @PutMapping("/reject") | ||||||
|     @ApiOperation("不通过任务") |     @ApiOperation("不通过任务") | ||||||
|     public CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) { |     public CommonResult<Boolean> rejectTask(@Valid @RequestBody BpmTaskRejectReqVO reqVO) { | ||||||
|         taskService.rejectTask(reqVO); |         taskService.rejectTask(getLoginUserId(), reqVO); | ||||||
|         return success(true); |         return success(true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -42,6 +42,7 @@ public interface BpmErrorCodeConstants { | |||||||
|  |  | ||||||
|     // ========== 流程任务 1-009-005-000 ========== |     // ========== 流程任务 1-009-005-000 ========== | ||||||
|     ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "审批任务失败,原因:该任务不处于未审批"); |     ErrorCode TASK_COMPLETE_FAIL_NOT_EXISTS = new ErrorCode(1009004000, "审批任务失败,原因:该任务不处于未审批"); | ||||||
|  |     ErrorCode TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1009004001, "审批任务失败,原因:该任务的审批人不是你"); | ||||||
|  |  | ||||||
|     // ========== 流程任务分配规则 1-009-006-000 ========== |     // ========== 流程任务分配规则 1-009-006-000 ========== | ||||||
|     ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则"); |     ErrorCode TASK_ASSIGN_RULE_EXISTS = new ErrorCode(1009006000, "流程({}) 的任务({}) 已经存在分配规则"); | ||||||
|  | |||||||
| @ -21,7 +21,6 @@ public interface BpmTaskService { | |||||||
|      * 获得指定流程实例的 Running 进行中的流程任务列表 |      * 获得指定流程实例的 Running 进行中的流程任务列表 | ||||||
|      * |      * | ||||||
|      * @param processInstanceId 流程实例的编号 |      * @param processInstanceId 流程实例的编号 | ||||||
|      * @return 流程任务列表 |  | ||||||
|      */ |      */ | ||||||
|     List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId); |     List<Task> getRunningTaskListByProcessInstanceId(String processInstanceId); | ||||||
|  |  | ||||||
| @ -81,16 +80,18 @@ public interface BpmTaskService { | |||||||
|     /** |     /** | ||||||
|      * 通过任务 |      * 通过任务 | ||||||
|      * |      * | ||||||
|  |      * @param userId 用户编号 | ||||||
|      * @param reqVO 通过请求 |      * @param reqVO 通过请求 | ||||||
|      */ |      */ | ||||||
|     void approveTask(@Valid BpmTaskApproveReqVO reqVO); |     void approveTask(Long userId, @Valid BpmTaskApproveReqVO reqVO); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 不通过任务 |      * 不通过任务 | ||||||
|      * |      * | ||||||
|  |      * @param userId 用户编号 | ||||||
|      * @param reqVO 不通过请求 |      * @param reqVO 不通过请求 | ||||||
|      */ |      */ | ||||||
|     void rejectTask(@Valid BpmTaskRejectReqVO reqVO); |     void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 返回高亮的流转进程 |      * 返回高亮的流转进程 | ||||||
|  | |||||||
| @ -14,6 +14,7 @@ import cn.iocoder.yudao.adminserver.modules.system.dal.dataobject.dept.SysDeptDO | |||||||
| import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService; | import cn.iocoder.yudao.adminserver.modules.system.service.dept.SysDeptService; | ||||||
| import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; | ||||||
| import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; | ||||||
|  | import cn.iocoder.yudao.framework.activiti.core.util.ActivitiUtils; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||||||
| import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | ||||||
| @ -200,12 +201,15 @@ public class BpmTaskServiceImpl implements BpmTaskService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void approveTask(BpmTaskApproveReqVO reqVO) { |     public void approveTask(Long userId, BpmTaskApproveReqVO reqVO) { | ||||||
|         // 校验任务存在 |         // 校验任务存在 | ||||||
|         Task task = getTask(reqVO.getId()); |         Task task = getTask(reqVO.getId()); | ||||||
|         if (task == null) { |         if (task == null) { | ||||||
|             throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); |             throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); | ||||||
|         } |         } | ||||||
|  |         if (!ActivitiUtils.equals(task.getAssignee(), userId)) { | ||||||
|  |             throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF); | ||||||
|  |         } | ||||||
|         // 校验流程实例存在 |         // 校验流程实例存在 | ||||||
|         ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); |         ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); | ||||||
|         if (instance == null) { |         if (instance == null) { | ||||||
| @ -224,12 +228,15 @@ public class BpmTaskServiceImpl implements BpmTaskService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void rejectTask(@Valid BpmTaskRejectReqVO reqVO) { |     public void rejectTask(Long userId, @Valid BpmTaskRejectReqVO reqVO) { | ||||||
|         // 校验任务存在 |         // 校验任务存在 | ||||||
|         Task task = getTask(reqVO.getId()); |         Task task = getTask(reqVO.getId()); | ||||||
|         if (task == null) { |         if (task == null) { | ||||||
|             throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); |             throw exception(TASK_COMPLETE_FAIL_NOT_EXISTS); | ||||||
|         } |         } | ||||||
|  |         if (!ActivitiUtils.equals(task.getAssignee(), userId)) { | ||||||
|  |             throw exception(TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF); | ||||||
|  |         } | ||||||
|         // 校验流程实例存在 |         // 校验流程实例存在 | ||||||
|         ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); |         ProcessInstance instance = processInstanceService.getProcessInstance(task.getProcessInstanceId()); | ||||||
|         if (instance == null) { |         if (instance == null) { | ||||||
|  | |||||||
| @ -32,6 +32,9 @@ public class SysAuthPermissionInfoRespVO { | |||||||
|     @Builder |     @Builder | ||||||
|     public static class UserVO { |     public static class UserVO { | ||||||
|  |  | ||||||
|  |         @ApiModelProperty(value = "用户编号", required = true, example = "1024") | ||||||
|  |         private Long id; | ||||||
|  |  | ||||||
|         @ApiModelProperty(value = "用户昵称", required = true, example = "芋道源码") |         @ApiModelProperty(value = "用户昵称", required = true, example = "芋道源码") | ||||||
|         private String nickname; |         private String nickname; | ||||||
|  |  | ||||||
|  | |||||||
| @ -31,7 +31,7 @@ public interface SysAuthConvert { | |||||||
|  |  | ||||||
|     default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) { |     default SysAuthPermissionInfoRespVO convert(SysUserDO user, List<SysRoleDO> roleList, List<SysMenuDO> menuList) { | ||||||
|         return SysAuthPermissionInfoRespVO.builder() |         return SysAuthPermissionInfoRespVO.builder() | ||||||
|             .user(SysAuthPermissionInfoRespVO.UserVO.builder().nickname(user.getNickname()).avatar(user.getAvatar()).build()) |             .user(SysAuthPermissionInfoRespVO.UserVO.builder().id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).build()) | ||||||
|             .roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode)) |             .roles(CollectionUtils.convertSet(roleList, SysRoleDO::getCode)) | ||||||
|             .permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission)) |             .permissions(CollectionUtils.convertSet(menuList, SysMenuDO::getPermission)) | ||||||
|             .build(); |             .build(); | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ const getters = { | |||||||
|   device: state => state.app.device, |   device: state => state.app.device, | ||||||
|   visitedViews: state => state.tagsView.visitedViews, |   visitedViews: state => state.tagsView.visitedViews, | ||||||
|   cachedViews: state => state.tagsView.cachedViews, |   cachedViews: state => state.tagsView.cachedViews, | ||||||
|  |   userId: state => state.user.id, | ||||||
|   token: state => state.user.token, |   token: state => state.user.token, | ||||||
|   avatar: state => state.user.avatar, |   avatar: state => state.user.avatar, | ||||||
|   name: state => state.user.name, |   name: state => state.user.name, | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ import { getToken, setToken, removeToken } from '@/utils/auth' | |||||||
| const user = { | const user = { | ||||||
|   state: { |   state: { | ||||||
|     token: getToken(), |     token: getToken(), | ||||||
|  |     id: 0, // 用户编号 | ||||||
|     name: '', |     name: '', | ||||||
|     avatar: '', |     avatar: '', | ||||||
|     roles: [], |     roles: [], | ||||||
| @ -11,6 +12,9 @@ const user = { | |||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   mutations: { |   mutations: { | ||||||
|  |     SET_ID: (state, id) => { | ||||||
|  |       state.id = id | ||||||
|  |     }, | ||||||
|     SET_TOKEN: (state, token) => { |     SET_TOKEN: (state, token) => { | ||||||
|       state.token = token |       state.token = token | ||||||
|     }, |     }, | ||||||
| @ -96,6 +100,7 @@ const user = { | |||||||
|           } else { |           } else { | ||||||
|             commit('SET_ROLES', ['ROLE_DEFAULT']) |             commit('SET_ROLES', ['ROLE_DEFAULT']) | ||||||
|           } |           } | ||||||
|  |           commit('SET_ID', user.id) | ||||||
|           commit('SET_NAME', user.userName) |           commit('SET_NAME', user.userName) | ||||||
|           commit('SET_AVATAR', avatar) |           commit('SET_AVATAR', avatar) | ||||||
|           resolve(res) |           resolve(res) | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ | |||||||
|         <div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px;"> |         <div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px;"> | ||||||
|           <el-button  icon="el-icon-edit-outline" type="success" size="mini" @click="handleAudit(item, true)">通过</el-button> |           <el-button  icon="el-icon-edit-outline" type="success" size="mini" @click="handleAudit(item, true)">通过</el-button> | ||||||
|           <el-button  icon="el-icon-circle-close" type="danger" size="mini" @click="handleAudit(item, false)">不通过</el-button> |           <el-button  icon="el-icon-circle-close" type="danger" size="mini" @click="handleAudit(item, false)">不通过</el-button> | ||||||
| <!--          <el-button  icon="el-icon-edit-outline" type="primary" size="mini" @click="handleAssign">转办</el-button>--> |           <!--          <el-button  icon="el-icon-edit-outline" type="primary" size="mini" @click="handleAssign">转办</el-button>--> | ||||||
|           <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate(item)">委派</el-button> |           <el-button icon="el-icon-edit-outline" type="primary" size="mini" @click="handleDelegate(item)">委派</el-button> | ||||||
|           <el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleBack(item)">退回</el-button> |           <el-button icon="el-icon-refresh-left" type="warning" size="mini" @click="handleBack(item)">退回</el-button> | ||||||
|         </div> |         </div> | ||||||
| @ -81,7 +81,7 @@ | |||||||
| <script> | <script> | ||||||
| import {getProcessDefinitionBpmnXML, getProcessDefinitionList} from "@/api/bpm/definition"; | import {getProcessDefinitionBpmnXML, getProcessDefinitionList} from "@/api/bpm/definition"; | ||||||
| import {DICT_TYPE, getDictDatas} from "@/utils/dict"; | import {DICT_TYPE, getDictDatas} from "@/utils/dict"; | ||||||
| import {getForm} from "@/api/bpm/form"; | import store from "@/store"; | ||||||
| import {decodeFields} from "@/utils/formGenerator"; | import {decodeFields} from "@/utils/formGenerator"; | ||||||
| import Parser from '@/components/parser/Parser' | import Parser from '@/components/parser/Parser' | ||||||
| import {createProcessInstance, getMyProcessInstancePage, getProcessInstance} from "@/api/bpm/processInstance"; | import {createProcessInstance, getMyProcessInstancePage, getProcessInstance} from "@/api/bpm/processInstance"; | ||||||
| @ -196,10 +196,14 @@ export default { | |||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         // 需要审核的记录 |         // 需要审核的记录 | ||||||
|  |         const userId = store.getters.userId; | ||||||
|         this.historicTasks.forEach(task => { |         this.historicTasks.forEach(task => { | ||||||
|           if (task.result !== 1) { // 只有待处理才需要 |           if (task.result !== 1) { // 只有待处理才需要 | ||||||
|             return; |             return; | ||||||
|           } |           } | ||||||
|  |           if (!task.assigneeUser || task.assigneeUser.id !== userId) { // 自己不是处理人 | ||||||
|  |             return; | ||||||
|  |           } | ||||||
|           this.tasks.push({...task}); |           this.tasks.push({...task}); | ||||||
|           this.auditForms.push({ |           this.auditForms.push({ | ||||||
|             comment: '' |             comment: '' | ||||||
|  | |||||||
| @ -106,6 +106,7 @@ | |||||||
|           <!-- TODO 芋艿:权限 --> |           <!-- TODO 芋艿:权限 --> | ||||||
|           <el-button type="text" size="small" icon="el-icon-delete" v-if="scope.row.result === 1" |           <el-button type="text" size="small" icon="el-icon-delete" v-if="scope.row.result === 1" | ||||||
|                      @click="handleCancel(scope.row)">取消</el-button> |                      @click="handleCancel(scope.row)">取消</el-button> | ||||||
|  |           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleDetail(scope.row)">详情</el-button> | ||||||
|         </template> |         </template> | ||||||
|       </el-table-column> |       </el-table-column> | ||||||
|     </el-table> |     </el-table> | ||||||
| @ -204,6 +205,10 @@ export default { | |||||||
|         this.msgSuccess("取消成功"); |         this.msgSuccess("取消成功"); | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|  |     /** 处理详情按钮 */ | ||||||
|  |     handleDetail(row) { | ||||||
|  |       this.$router.push({ path: "/bpm/process-instance/detail", query: { id: row.id}}); | ||||||
|  |     }, | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| </script> | </script> | ||||||
|  | |||||||
| @ -60,7 +60,7 @@ | |||||||
|       <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width"> |       <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width"> | ||||||
|         <template slot-scope="scope"> |         <template slot-scope="scope"> | ||||||
|           <!-- TODO 权限、颜色 --> |           <!-- TODO 权限、颜色 --> | ||||||
|           <el-button size="mini" type="text" icon="el-icon-edit">详情</el-button> |           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleAudit(scope.row)">详情</el-button> | ||||||
|         </template> |         </template> | ||||||
|       </el-table-column> |       </el-table-column> | ||||||
|     </el-table> |     </el-table> | ||||||
| @ -127,7 +127,11 @@ export default { | |||||||
|     }, |     }, | ||||||
|     getDateStar(ms) { |     getDateStar(ms) { | ||||||
|       return getDate(ms); |       return getDate(ms); | ||||||
|     } |     }, | ||||||
|  |     /** 处理审批按钮 */ | ||||||
|  |     handleAudit(row) { | ||||||
|  |       this.$router.push({ path: "/bpm/process-instance/detail", query: { id: row.processInstance.id}}); | ||||||
|  |     }, | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| </script> | </script> | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.activiti.core.util; | |||||||
|  |  | ||||||
| import cn.hutool.core.util.ReflectUtil; | import cn.hutool.core.util.ReflectUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
|  | import cn.iocoder.yudao.framework.common.util.number.NumberUtils; | ||||||
| import com.alibaba.ttl.TransmittableThreadLocal; | import com.alibaba.ttl.TransmittableThreadLocal; | ||||||
| import org.activiti.bpmn.converter.BpmnXMLConverter; | import org.activiti.bpmn.converter.BpmnXMLConverter; | ||||||
| import org.activiti.bpmn.model.BpmnModel; | import org.activiti.bpmn.model.BpmnModel; | ||||||
| @ -13,6 +14,7 @@ import org.activiti.engine.impl.util.io.BytesStreamSource; | |||||||
| import javax.xml.bind.Element; | import javax.xml.bind.Element; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.Objects; | ||||||
| import java.util.function.Consumer; | import java.util.function.Consumer; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -45,6 +47,10 @@ public class ActivitiUtils { | |||||||
|         Authentication.setAuthenticatedUserId(null); |         Authentication.setAuthenticatedUserId(null); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static boolean equals(String userIdStr, Long userId) { | ||||||
|  |         return Objects.equals(userId, NumberUtils.parseLong(userIdStr)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // ========== BPMN XML 相关 ========== |     // ========== BPMN XML 相关 ========== | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV