Merge branch 'dev' of https://gitee.com/yudaocode/yudao-ui-admin-vben into dev
						commit
						e8046f3a48
					
				|  | @ -0,0 +1,163 @@ | |||
| import type { PageParam, PageResult } from '@vben/request'; | ||||
| 
 | ||||
| import type { BpmModelApi } from '#/api/bpm/model'; | ||||
| import type { CandidateStrategy, NodeType } from '#/utils'; | ||||
| 
 | ||||
| import { requestClient } from '#/api/request'; | ||||
| 
 | ||||
| export namespace BpmProcessInstanceApi { | ||||
|   export type Task = { | ||||
|     id: number; | ||||
|     name: string; | ||||
|   }; | ||||
| 
 | ||||
|   export type User = { | ||||
|     avatar: string; | ||||
|     id: number; | ||||
|     nickname: string; | ||||
|   }; | ||||
| 
 | ||||
|   // 审批任务信息
 | ||||
|   export type ApprovalTaskInfo = { | ||||
|     assigneeUser: User; | ||||
|     id: number; | ||||
|     ownerUser: User; | ||||
|     reason: string; | ||||
|     signPicUrl: string; | ||||
|     status: number; | ||||
|   }; | ||||
| 
 | ||||
|   // 审批节点信息
 | ||||
|   export type ApprovalNodeInfo = { | ||||
|     candidateStrategy?: CandidateStrategy; | ||||
|     candidateUsers?: User[]; | ||||
|     endTime?: Date; | ||||
|     id: number; | ||||
|     name: string; | ||||
|     nodeType: NodeType; | ||||
|     startTime?: Date; | ||||
|     status: number; | ||||
|     tasks: ApprovalTaskInfo[]; | ||||
|   }; | ||||
| 
 | ||||
|   export type ProcessInstanceVO = { | ||||
|     businessKey: string; | ||||
|     category: string; | ||||
|     createTime: string; | ||||
|     endTime: string; | ||||
|     fields: string[]; | ||||
|     id: number; | ||||
|     name: string; | ||||
|     processDefinition?: BpmModelApi.ProcessDefinitionVO; | ||||
|     processDefinitionId: string; | ||||
|     remark: string; | ||||
|     result: number; | ||||
|     status: number; | ||||
|     tasks: BpmProcessInstanceApi.Task[]; | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| /** 查询我的流程实例分页 */ | ||||
| export async function getProcessInstanceMyPage(params: PageParam) { | ||||
|   return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstanceVO>>( | ||||
|     '/bpm/process-instance/my-page', | ||||
|     { params }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 查询管理员流程实例分页 */ | ||||
| export async function getProcessInstanceManagerPage(params: PageParam) { | ||||
|   return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstanceVO>>( | ||||
|     '/bpm/process-instance/manager-page', | ||||
|     { params }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 新增流程实例 */ | ||||
| export async function createProcessInstance( | ||||
|   data: BpmProcessInstanceApi.ProcessInstanceVO, | ||||
| ) { | ||||
|   return requestClient.post<BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|     '/bpm/process-instance/create', | ||||
|     data, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 申请人主动取消流程实例 */ | ||||
| export async function cancelProcessInstanceByStartUser( | ||||
|   id: number, | ||||
|   reason: string, | ||||
| ) { | ||||
|   return requestClient.delete<boolean>( | ||||
|     '/bpm/process-instance/cancel-by-start-user', | ||||
|     { | ||||
|       data: { id, reason }, | ||||
|     }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 管理员取消流程实例 */ | ||||
| export async function cancelProcessInstanceByAdmin(id: number, reason: string) { | ||||
|   return requestClient.delete<boolean>( | ||||
|     '/bpm/process-instance/cancel-by-admin', | ||||
|     { | ||||
|       data: { id, reason }, | ||||
|     }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 查询流程实例详情 */ | ||||
| export async function getProcessInstance(id: number) { | ||||
|   return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|     `/bpm/process-instance/get?id=${id}`, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 查询复制流程实例分页 */ | ||||
| export async function getProcessInstanceCopyPage(params: PageParam) { | ||||
|   return requestClient.get<PageResult<BpmProcessInstanceApi.ProcessInstanceVO>>( | ||||
|     '/bpm/process-instance/copy/page', | ||||
|     { params }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 更新流程实例 */ | ||||
| export async function updateProcessInstance( | ||||
|   data: BpmProcessInstanceApi.ProcessInstanceVO, | ||||
| ) { | ||||
|   return requestClient.put<BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|     '/bpm/process-instance/update', | ||||
|     data, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 获取审批详情 */ | ||||
| export async function getApprovalDetail(params: any) { | ||||
|   return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|     `/bpm/process-instance/get-approval-detail`, | ||||
|     { params }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 获取下一个执行的流程节点 */ | ||||
| export async function getNextApprovalNodes(params: any) { | ||||
|   return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|     `/bpm/process-instance/get-next-approval-nodes`, | ||||
|     { params }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 获取表单字段权限 */ | ||||
| export async function getFormFieldsPermission(params: any) { | ||||
|   return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|     `/bpm/process-instance/get-form-fields-permission`, | ||||
|     { params }, | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| /** 获取流程实例 BPMN 模型视图 */ | ||||
| export async function getProcessInstanceBpmnModelView(id: number) { | ||||
|   return requestClient.get<BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|     `/bpm/process-instance/get-bpmn-model-view?id=${id}`, | ||||
|   ); | ||||
| } | ||||
|  | @ -464,3 +464,132 @@ export const BpmAutoApproveType = { | |||
|   APPROVE_ALL: 1, // 仅审批一次,后续重复的审批节点均自动通过
 | ||||
|   APPROVE_SEQUENT: 2, // 仅针对连续审批的节点自动通过
 | ||||
| }; | ||||
| 
 | ||||
| // 候选人策略枚举 ( 用于审批节点。抄送节点 )
 | ||||
| export enum CandidateStrategy { | ||||
|   /** | ||||
|    * 审批人自选 | ||||
|    */ | ||||
|   APPROVE_USER_SELECT = 34, | ||||
|   /** | ||||
|    * 部门的负责人 | ||||
|    */ | ||||
|   DEPT_LEADER = 21, | ||||
|   /** | ||||
|    * 部门成员 | ||||
|    */ | ||||
|   DEPT_MEMBER = 20, | ||||
|   /** | ||||
|    * 流程表达式 | ||||
|    */ | ||||
|   EXPRESSION = 60, | ||||
|   /** | ||||
|    * 表单内部门负责人 | ||||
|    */ | ||||
|   FORM_DEPT_LEADER = 51, | ||||
|   /** | ||||
|    * 表单内用户字段 | ||||
|    */ | ||||
|   FORM_USER = 50, | ||||
|   /** | ||||
|    * 连续多级部门的负责人 | ||||
|    */ | ||||
|   MULTI_LEVEL_DEPT_LEADER = 23, | ||||
|   /** | ||||
|    * 指定岗位 | ||||
|    */ | ||||
|   POST = 22, | ||||
|   /** | ||||
|    * 指定角色 | ||||
|    */ | ||||
|   ROLE = 10, | ||||
|   /** | ||||
|    * 发起人自己 | ||||
|    */ | ||||
|   START_USER = 36, | ||||
|   /** | ||||
|    * 发起人部门负责人 | ||||
|    */ | ||||
|   START_USER_DEPT_LEADER = 37, | ||||
|   /** | ||||
|    * 发起人连续多级部门的负责人 | ||||
|    */ | ||||
|   START_USER_MULTI_LEVEL_DEPT_LEADER = 38, | ||||
|   /** | ||||
|    * 发起人自选 | ||||
|    */ | ||||
|   START_USER_SELECT = 35, | ||||
|   /** | ||||
|    * 指定用户 | ||||
|    */ | ||||
|   USER = 30, | ||||
|   /** | ||||
|    * 指定用户组 | ||||
|    */ | ||||
|   USER_GROUP = 40, | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * 节点类型 | ||||
|  */ | ||||
| export enum NodeType { | ||||
|   /** | ||||
|    * 子流程节点 | ||||
|    */ | ||||
|   CHILD_PROCESS_NODE = 20, | ||||
|   /** | ||||
|    * 条件分支节点 (对应排他网关) | ||||
|    */ | ||||
|   CONDITION_BRANCH_NODE = 51, | ||||
|   /** | ||||
|    * 条件节点 | ||||
|    */ | ||||
|   CONDITION_NODE = 50, | ||||
| 
 | ||||
|   /** | ||||
|    * 抄送人节点 | ||||
|    */ | ||||
|   COPY_TASK_NODE = 12, | ||||
| 
 | ||||
|   /** | ||||
|    * 延迟器节点 | ||||
|    */ | ||||
|   DELAY_TIMER_NODE = 14, | ||||
| 
 | ||||
|   /** | ||||
|    * 结束节点 | ||||
|    */ | ||||
|   END_EVENT_NODE = 1, | ||||
| 
 | ||||
|   /** | ||||
|    * 包容分支节点 (对应包容网关) | ||||
|    */ | ||||
|   INCLUSIVE_BRANCH_NODE = 53, | ||||
| 
 | ||||
|   /** | ||||
|    * 并行分支节点 (对应并行网关) | ||||
|    */ | ||||
|   PARALLEL_BRANCH_NODE = 52, | ||||
| 
 | ||||
|   /** | ||||
|    * 路由分支节点 | ||||
|    */ | ||||
|   ROUTER_BRANCH_NODE = 54, | ||||
|   /** | ||||
|    * 发起人节点 | ||||
|    */ | ||||
|   START_USER_NODE = 10, | ||||
|   /** | ||||
|    * 办理人节点 | ||||
|    */ | ||||
|   TRANSACTOR_NODE = 13, | ||||
| 
 | ||||
|   /** | ||||
|    * 触发器节点 | ||||
|    */ | ||||
|   TRIGGER_NODE = 15, | ||||
|   /** | ||||
|    * 审批人节点 | ||||
|    */ | ||||
|   USER_TASK_NODE = 11, | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,31 @@ | |||
| /** | ||||
|  * 将毫秒,转换成时间字符串。例如说,xx 分钟 | ||||
|  * | ||||
|  * @param ms 毫秒 | ||||
|  * @returns {string} 字符串 | ||||
|  */ | ||||
| export function formatPast2(ms: number): string { | ||||
|   // 定义时间单位常量,便于维护
 | ||||
|   const SECOND = 1000; | ||||
|   const MINUTE = 60 * SECOND; | ||||
|   const HOUR = 60 * MINUTE; | ||||
|   const DAY = 24 * HOUR; | ||||
| 
 | ||||
|   // 计算各时间单位
 | ||||
|   const day = Math.floor(ms / DAY); | ||||
|   const hour = Math.floor((ms % DAY) / HOUR); | ||||
|   const minute = Math.floor((ms % HOUR) / MINUTE); | ||||
|   const second = Math.floor((ms % MINUTE) / SECOND); | ||||
| 
 | ||||
|   // 根据时间长短返回不同格式
 | ||||
|   if (day > 0) { | ||||
|     return `${day} 天${hour} 小时 ${minute} 分钟`; | ||||
|   } | ||||
|   if (hour > 0) { | ||||
|     return `${hour} 小时 ${minute} 分钟`; | ||||
|   } | ||||
|   if (minute > 0) { | ||||
|     return `${minute} 分钟`; | ||||
|   } | ||||
|   return second > 0 ? `${second} 秒` : `${0} 秒`; | ||||
| } | ||||
|  | @ -1,4 +1,5 @@ | |||
| export * from './constants'; | ||||
| export * from './dict'; | ||||
| export * from './formatTime'; | ||||
| export * from './rangePickerProps'; | ||||
| export * from './validator'; | ||||
|  |  | |||
|  | @ -0,0 +1,227 @@ | |||
| import type { VbenFormSchema } from '#/adapter/form'; | ||||
| import type { OnActionClickFn, VxeTableGridOptions } from '#/adapter/vxe-table'; | ||||
| import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance'; | ||||
| 
 | ||||
| import { h } from 'vue'; | ||||
| 
 | ||||
| import { useAccess } from '@vben/access'; | ||||
| 
 | ||||
| import { Button } from 'ant-design-vue'; | ||||
| 
 | ||||
| import { getCategorySimpleList } from '#/api/bpm/category'; | ||||
| import { getSimpleUserList } from '#/api/system/user'; | ||||
| import { $t } from '#/locales'; | ||||
| import { | ||||
|   DICT_TYPE, | ||||
|   formatPast2, | ||||
|   getDictOptions, | ||||
|   getRangePickerDefaultProps, | ||||
| } from '#/utils'; | ||||
| 
 | ||||
| import { BpmProcessInstanceStatus } from '../../../../utils/constants'; | ||||
| 
 | ||||
| const { hasAccessByCodes } = useAccess(); | ||||
| 
 | ||||
| /** 列表的搜索表单 */ | ||||
| export function useGridFormSchema(): VbenFormSchema[] { | ||||
|   return [ | ||||
|     { | ||||
|       fieldName: 'startUserId', | ||||
|       label: '发起人', | ||||
|       component: 'ApiSelect', | ||||
|       componentProps: { | ||||
|         placeholder: '请选择发起人', | ||||
|         allowClear: true, | ||||
|         api: getSimpleUserList, | ||||
|         labelField: 'nickname', | ||||
|         valueField: 'id', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       fieldName: 'name', | ||||
|       label: '流程名称', | ||||
|       component: 'Input', | ||||
|       componentProps: { | ||||
|         placeholder: '请输入流程名称', | ||||
|         allowClear: true, | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       fieldName: 'processDefinitionId', | ||||
|       label: '所属流程', | ||||
|       component: 'Input', | ||||
|       componentProps: { | ||||
|         placeholder: '请输入流程定义的编号', | ||||
|         allowClear: true, | ||||
|       }, | ||||
|     }, | ||||
|     // 流程分类
 | ||||
|     { | ||||
|       fieldName: 'category', | ||||
|       label: '流程分类', | ||||
|       component: 'ApiSelect', | ||||
|       componentProps: { | ||||
|         placeholder: '请输入流程分类', | ||||
|         allowClear: true, | ||||
|         api: getCategorySimpleList, | ||||
|         labelField: 'name', | ||||
|         valueField: 'code', | ||||
|       }, | ||||
|     }, | ||||
|     // 流程状态
 | ||||
|     { | ||||
|       fieldName: 'status', | ||||
|       label: '流程状态', | ||||
|       component: 'Select', | ||||
|       componentProps: { | ||||
|         options: getDictOptions( | ||||
|           DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS, | ||||
|           'number', | ||||
|         ), | ||||
|         placeholder: '请选择流程状态', | ||||
|         allowClear: true, | ||||
|       }, | ||||
|     }, | ||||
|     // 发起时间
 | ||||
|     { | ||||
|       fieldName: 'createTime', | ||||
|       label: '发起时间', | ||||
|       component: 'RangePicker', | ||||
|       componentProps: { | ||||
|         ...getRangePickerDefaultProps(), | ||||
|       }, | ||||
|     }, | ||||
|   ]; | ||||
| } | ||||
| 
 | ||||
| /** 列表的字段 */ | ||||
| export function useGridColumns<T = BpmProcessInstanceApi.ProcessInstanceVO>( | ||||
|   onActionClick: OnActionClickFn<T>, | ||||
|   onTaskClick: (task: BpmProcessInstanceApi.Task) => void, | ||||
| ): VxeTableGridOptions['columns'] { | ||||
|   return [ | ||||
|     { | ||||
|       field: 'name', | ||||
|       title: '流程名称', | ||||
|       minWidth: 200, | ||||
|       fixed: 'left', | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|       field: 'categoryName', | ||||
|       title: '流程分类', | ||||
|       minWidth: 120, | ||||
|       fixed: 'left', | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|       field: 'startUser.nickname', | ||||
|       title: '流程发起人', | ||||
|       minWidth: 120, | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|       field: 'startUser.deptName', | ||||
|       title: '发起部门', | ||||
|       minWidth: 120, | ||||
|     }, | ||||
| 
 | ||||
|     // 流程状态
 | ||||
|     { | ||||
|       field: 'status', | ||||
|       title: '流程状态', | ||||
|       minWidth: 120, | ||||
|       cellRender: { | ||||
|         name: 'CellDict', | ||||
|         props: { type: DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|       field: 'startTime', | ||||
|       title: '发起时间', | ||||
|       minWidth: 180, | ||||
|       formatter: 'formatDateTime', | ||||
|     }, | ||||
|     { | ||||
|       field: 'endTime', | ||||
|       title: '结束时间', | ||||
|       minWidth: 180, | ||||
|       formatter: 'formatDateTime', | ||||
|     }, | ||||
|     { | ||||
|       field: 'durationInMillis', | ||||
|       title: '流程耗时', | ||||
|       minWidth: 180, | ||||
|       slots: { | ||||
|         default: ({ row }) => { | ||||
|           return row.durationInMillis > 0 | ||||
|             ? formatPast2(row.durationInMillis) | ||||
|             : '-'; | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     // 当前审批任务 tasks
 | ||||
|     { | ||||
|       field: 'tasks', | ||||
|       title: '当前审批任务', | ||||
|       minWidth: 320, | ||||
|       slots: { | ||||
|         default: ({ row }) => { | ||||
|           if (!row?.tasks?.length) return '-'; | ||||
| 
 | ||||
|           return row.tasks.map((task: BpmProcessInstanceApi.Task) => | ||||
|             h( | ||||
|               Button, | ||||
|               { | ||||
|                 type: 'link', | ||||
|                 size: 'small', | ||||
|                 onClick: () => onTaskClick(task), | ||||
|               }, | ||||
|               { default: () => task.name }, | ||||
|             ), | ||||
|           ); | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|       field: 'id', | ||||
|       title: '流程编号', | ||||
|       minWidth: 320, | ||||
|     }, | ||||
|     { | ||||
|       field: 'operation', | ||||
|       title: '操作', | ||||
|       minWidth: 180, | ||||
|       align: 'center', | ||||
|       fixed: 'right', | ||||
|       cellRender: { | ||||
|         attrs: { | ||||
|           nameField: 'name', | ||||
|           nameTitle: '流程分类', | ||||
|           onClick: onActionClick, | ||||
|         }, | ||||
|         name: 'CellOperation', | ||||
|         options: [ | ||||
|           { | ||||
|             code: 'detail', | ||||
|             text: $t('ui.actionTitle.detail'), | ||||
|             show: hasAccessByCodes(['bpm:process-instance:query']), | ||||
|           }, | ||||
|           { | ||||
|             code: 'cancel', | ||||
|             text: $t('ui.actionTitle.cancel'), | ||||
|             show: (row: BpmProcessInstanceApi.ProcessInstanceVO) => { | ||||
|               return ( | ||||
|                 row.status === BpmProcessInstanceStatus.RUNNING && | ||||
|                 hasAccessByCodes(['bpm:process-instance:cancel']) | ||||
|               ); | ||||
|             }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     }, | ||||
|   ]; | ||||
| } | ||||
|  | @ -1,31 +1,128 @@ | |||
| <script lang="ts" setup> | ||||
| import { Page } from '@vben/common-ui'; | ||||
| import type { | ||||
|   OnActionClickParams, | ||||
|   VxeTableGridOptions, | ||||
| } from '#/adapter/vxe-table'; | ||||
| import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance'; | ||||
| 
 | ||||
| import { Button } from 'ant-design-vue'; | ||||
| import { h } from 'vue'; | ||||
| 
 | ||||
| import { Page, prompt } from '@vben/common-ui'; | ||||
| 
 | ||||
| import { message, Textarea } from 'ant-design-vue'; | ||||
| 
 | ||||
| import { useVbenVxeGrid } from '#/adapter/vxe-table'; | ||||
| import { | ||||
|   cancelProcessInstanceByAdmin, | ||||
|   getProcessInstanceManagerPage, | ||||
| } from '#/api/bpm/processInstance'; | ||||
| import { DocAlert } from '#/components/doc-alert'; | ||||
| 
 | ||||
| import { useGridColumns, useGridFormSchema } from './data'; | ||||
| 
 | ||||
| defineOptions({ name: 'BpmProcessInstanceManager' }); | ||||
| 
 | ||||
| const [Grid, gridApi] = useVbenVxeGrid({ | ||||
|   formOptions: { | ||||
|     schema: useGridFormSchema(), | ||||
|   }, | ||||
|   gridOptions: { | ||||
|     columns: useGridColumns(onActionClick, onTaskClick), | ||||
|     height: 'auto', | ||||
|     keepSource: true, | ||||
|     proxyConfig: { | ||||
|       ajax: { | ||||
|         query: async ({ page }, formValues) => { | ||||
|           return await getProcessInstanceManagerPage({ | ||||
|             pageNo: page.currentPage, | ||||
|             pageSize: page.pageSize, | ||||
|             ...formValues, | ||||
|           }); | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     rowConfig: { | ||||
|       keyField: 'id', | ||||
|     }, | ||||
|     toolbarConfig: { | ||||
|       refresh: { code: 'query' }, | ||||
|       search: true, | ||||
|     }, | ||||
|   } as VxeTableGridOptions<BpmProcessInstanceApi.ProcessInstanceVO>, | ||||
| }); | ||||
| 
 | ||||
| /** 表格操作按钮的回调函数 */ | ||||
| function onActionClick({ | ||||
|   code, | ||||
|   row, | ||||
| }: OnActionClickParams<BpmProcessInstanceApi.ProcessInstanceVO>) { | ||||
|   switch (code) { | ||||
|     case 'cancel': { | ||||
|       onCancel(row); | ||||
|       break; | ||||
|     } | ||||
|     case 'detail': { | ||||
|       onDetail(row); | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| /** 点击任务 */ | ||||
| function onTaskClick(task: BpmProcessInstanceApi.Task) { | ||||
|   // TODO 待实现 | ||||
|   console.warn(task); | ||||
| } | ||||
| 
 | ||||
| /** 取消流程实例 */ | ||||
| function onCancel(row: BpmProcessInstanceApi.ProcessInstanceVO) { | ||||
|   prompt({ | ||||
|     async beforeClose(scope) { | ||||
|       if (scope.isConfirm) { | ||||
|         if (scope.value) { | ||||
|           try { | ||||
|             await cancelProcessInstanceByAdmin(row.id, scope.value); | ||||
|             message.success('取消成功'); | ||||
|             onRefresh(); | ||||
|           } catch { | ||||
|             return false; | ||||
|           } | ||||
|         } else { | ||||
|           message.error('请输入取消原因'); | ||||
|           return false; | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     component: () => { | ||||
|       return h(Textarea, { | ||||
|         placeholder: '请输入取消原因', | ||||
|         allowClear: true, | ||||
|         rows: 2, | ||||
|         rules: [{ required: true, message: '请输入取消原因' }], | ||||
|       }); | ||||
|     }, | ||||
|     content: '请输入取消原因', | ||||
|     title: '取消流程', | ||||
|     modelPropName: 'value', | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| /** 查看流程实例 */ | ||||
| function onDetail(row: BpmProcessInstanceApi.ProcessInstanceVO) { | ||||
|   console.warn(row); | ||||
| } | ||||
| 
 | ||||
| /** 刷新表格 */ | ||||
| function onRefresh() { | ||||
|   gridApi.query(); | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|   <Page> | ||||
|     <DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm/" /> | ||||
|     <Button | ||||
|       danger | ||||
|       type="link" | ||||
|       target="_blank" | ||||
|       href="https://github.com/yudaocode/yudao-ui-admin-vue3" | ||||
|     > | ||||
|       该功能支持 Vue3 + element-plus 版本! | ||||
|     </Button> | ||||
|     <br /> | ||||
|     <Button | ||||
|       type="link" | ||||
|       target="_blank" | ||||
|       href="https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/bpm/processInstance/manager/index" | ||||
|     > | ||||
|       可参考 | ||||
|       https://github.com/yudaocode/yudao-ui-admin-vue3/blob/master/src/views/bpm/processInstance/manager/index | ||||
|       代码,pull request 贡献给我们! | ||||
|     </Button> | ||||
|   <Page auto-content-height> | ||||
|     <DocAlert title="工作流手册" url="https://doc.iocoder.cn/bpm" /> | ||||
| 
 | ||||
|     <FormModal @success="onRefresh" /> | ||||
|     <Grid table-title="流程实例" /> | ||||
|   </Page> | ||||
| </template> | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
|     "mobile": "Please input a valid {0}" | ||||
|   }, | ||||
|   "actionTitle": { | ||||
|     "cancel": "Cancel {0}", | ||||
|     "edit": "Modify {0}", | ||||
|     "create": "Create {0}", | ||||
|     "delete": "Delete {0}", | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
|     "mobile": "请输入正确的{0}" | ||||
|   }, | ||||
|   "actionTitle": { | ||||
|     "cancel": "取消{0}", | ||||
|     "edit": "修改{0}", | ||||
|     "create": "新增{0}", | ||||
|     "delete": "删除{0}", | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 xingyu4j
						xingyu4j