!172 合并 warmflow 功能分支
* update 优化 流程定义页面 点击复制之后跳转到未发布列表
* update 优化 流程定义页面 增加加载loading层
* fix: v-model处理有延迟 需要手动处理
* update 调整流程定义查询
* Merge remote-tracking branch 'origin/dev' into warm-flw-future
* update 调整可驳回的节点
* update: 调整文案
* update: 激活/挂起改为switch操作
* update 优化 代码删除无用输出
* update 统一抄送人使用昵称展示
* update 调整分类接口
* update 统一业务id参数
* update 删除默认顶节点
* !168 优化流程分类
* update 恢复误删除代码
* update 优化流程分类
* update 修复 路由跳转未改全
* [update]
* fix 修复一些问题
* update 重构流程分类表
* update 流程定义增加表单路径与编辑功能 修复一些其他bug
* fix 修复 一些问题
* update 变量统一命名
* add 增加示例
* Merge branch 'warm-flw-future' of https://gitee.com/JavaLionLi/plus-ui…
* update 调整办理人
* Merge remote-tracking branch 'origin/dev' into warm-flw-future
* add 增加示例
* update 调整审批记录 添加流程导出
* remove 删除无用代码
* remove 删除无用代码
* [update]
* [fix]
* 流程干预删除委托
* 增加附件
* 附件修改
* 申请人查询修改
* 1.修改查询条件
* !167 fix 修复 import路径修改不全问题
* fix 修复 import路径修改不全问题
* !166 update 清除 ProcessPreview 引用
* update 清除 ProcessPreview 引用
* remove 删除 bpmn.js 设计器
* remove 删除 bpmn.js 设计器
* remove 删除 bpmn.js 设计器
* remove 删除 bpmn.js 设计器
* fix 修复 前端路径修改不全问题
* update 优化接口请求路径
* add 添加作废
* add 添加流程干预
* update 调整加签,减签
* update 调整加签,减签
* add 增加流程查看
* update 调整委托,转办
* update 调整流程变量显示
* update 调整办理人修改
* update 调整流程实例状态页面
* update 调整已办页面
* add 添加流程撤销
* update 调整任务,流程实例 ,流程定义页面
* Merge branch 'dev' into warm-flw-future
* update 调整流程定义页面
* add 添加流程变量查看
* update 调整设计器路由名称
* update 调整办理人
* update 调整设计器uri
* update 调整设计器请求uri 调整待办状态
* update 调整办理 驳回 终止等状态
* add 添加模型新增
* add 添加warm-ui设计器,删除无用代码
* Merge remote-tracking branch 'origin/dev' into warm-flw-future
* add 添加流程设计
* update 调整驳回
* update 调整视图类型错误
* Merge branch 'warm-flw-future' of https://gitee.com/JavaLionLi/plus-ui…
* 添加已办,未办
* Merge remote-tracking branch 'origin/dev' into warm-flw-future
* update 调整流程实例,待办查询
* add 添加代办人,调整提交按钮校验
* update 调整流程定义查询
* add添加流程定义激活 挂起
* add 添加流程文件部署 调整流程发布
* update 优化 时间搜索组件统一
* Merge remote-tracking branch 'origin/dev' into warm-flw-future
* fix 修复 用户管理编辑安全权限错误问题
* Merge remote-tracking branch 'origin/dev' into warm-flw-future
* update 优化 类型报错问题
* update 优化 切换租户后刷新首页
* update 优化 实现表格行选中切换
* update 优化 使用 vueuse 重构 websocket 实现
* update 优化 使用 vueuse 重构 websocket 实现
* fix 修复 登出后重新登录 sse推送报错问题
* reset 回滚 代码修改 采用其他方案
* fix 修复 登出后重新登录 sse推送报错问题
* update 优化 删除无用代码
* update element-plus 2.7.5 => 2.7.8
* reset 回滚 错误修复
* update 优化 代码生成器编辑页禁用缓存 防止同步后页面不更新问题
* fix 修复 代码生成同步点击取消报错问题
* 初始化添加warm-flow
已添加6个文件
已删除48个文件
已修改24个文件
| | |
| | | "animate.css": "4.1.1", |
| | | "await-to-js": "3.0.0", |
| | | "axios": "1.7.8", |
| | | "bpmn-js": "16.4.0", |
| | | "crypto-js": "4.2.0", |
| | | "diagram-js": "12.3.0", |
| | | "didi": "9.0.2", |
| | |
| | | import request from '@/utils/request'; |
| | | import { AxiosPromise } from 'axios'; |
| | | import { DeptForm, DeptQuery, DeptVO } from './types'; |
| | | import {DeptForm, DeptQuery, DeptTreeVO, DeptVO} from './types'; |
| | | |
| | | // æ¥è¯¢é¨é¨å表 |
| | | export const listDept = (query?: DeptQuery) => { |
| | |
| | | url: '/system/dept/list', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * éè¿deptIdsæ¥è¯¢é¨é¨ |
| | | * @param deptIds |
| | | */ |
| | | export const optionSelect = (deptIds: (number | string)[]): AxiosPromise<DeptVO[]> => { |
| | | return request({ |
| | | url: '/system/dept/optionselect?deptIds=' + deptIds, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | |
| | | }; |
| | | |
| | | // æ¥è¯¢é¨é¨ä¸ææ ç»æ |
| | | export const treeselect = (): AxiosPromise<DeptVO[]> => { |
| | | export const treeselect = (): AxiosPromise<DeptTreeVO[]> => { |
| | | return request({ |
| | | url: '/system/dept/treeselect', |
| | | method: 'get' |
| | |
| | | import request from '@/utils/request'; |
| | | import { AxiosPromise } from 'axios'; |
| | | import { CategoryVO, CategoryForm, CategoryQuery } from '@/api/workflow/category/types'; |
| | | import { CategoryVO, CategoryForm, CategoryQuery, CategoryTreeVO } from '@/api/workflow/category/types'; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±»å表 |
| | |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åç±»è¯¦ç» |
| | | * @param id |
| | | * @param categoryId |
| | | */ |
| | | export const getCategory = (id: string | number): AxiosPromise<CategoryVO> => { |
| | | export const getCategory = (categoryId: string | number): AxiosPromise<CategoryVO> => { |
| | | return request({ |
| | | url: '/workflow/category/' + id, |
| | | url: '/workflow/category/' + categoryId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | |
| | | |
| | | /** |
| | | * å 餿µç¨åç±» |
| | | * @param id |
| | | * @param categoryId |
| | | */ |
| | | export const delCategory = (id: string | number | Array<string | number>) => { |
| | | export const delCategory = (categoryId: string | number | Array<string | number>) => { |
| | | return request({ |
| | | url: '/workflow/category/' + id, |
| | | url: '/workflow/category/' + categoryId, |
| | | method: 'delete' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * è·åæµç¨åç±»æ å表 |
| | | * @param query æµç¨å®ä¾id |
| | | * @returns |
| | | */ |
| | | export const categoryTree = (query?: CategoryForm): AxiosPromise<CategoryTreeVO[]> => { |
| | | return request({ |
| | | url: `/workflow/category/categoryTree`, |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | |
| | | export interface CategoryTreeVO { |
| | | id: number | string; |
| | | label: string; |
| | | parentId: number | string; |
| | | weight: number; |
| | | children: CategoryTreeVO[]; |
| | | } |
| | | export interface CategoryVO { |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | id: string; |
| | | |
| | | /** |
| | | * åç±»åç§° |
| | | * æµç¨åç±»ID |
| | | */ |
| | | categoryName: string; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | categoryCode: string; |
| | | categoryId: string | number; |
| | | |
| | | /** |
| | | * ç¶çº§id |
| | |
| | | parentId: string | number; |
| | | |
| | | /** |
| | | * æåº |
| | | * æµç¨åç±»åç§° |
| | | */ |
| | | sortNum: number; |
| | | categoryName: string; |
| | | |
| | | children?: CategoryVO[]; |
| | | /** |
| | | * æ¾ç¤ºé¡ºåº |
| | | */ |
| | | orderNum: number; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | createTime: string; |
| | | |
| | | /** |
| | | * å对象 |
| | | */ |
| | | children: CategoryVO[]; |
| | | } |
| | | |
| | | export interface CategoryForm extends BaseEntity { |
| | | /** |
| | | * ä¸»é® |
| | | */ |
| | | id?: string | number; |
| | | |
| | | /** |
| | | * åç±»åç§° |
| | | * æµç¨åç±»ID |
| | | */ |
| | | categoryId?: string | number; |
| | | |
| | | /** |
| | | * æµç¨åç±»åç§° |
| | | */ |
| | | categoryName?: string; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | categoryCode?: string; |
| | | |
| | | /** |
| | | * ç¶çº§id |
| | | * ç¶æµç¨åç±»id |
| | | */ |
| | | parentId?: string | number; |
| | | |
| | | /** |
| | | * æåº |
| | | * æ¾ç¤ºé¡ºåº |
| | | */ |
| | | sortNum?: number; |
| | | orderNum?: number; |
| | | |
| | | } |
| | | |
| | | export interface CategoryQuery extends PageQuery { |
| | | export interface CategoryQuery { |
| | | |
| | | /** |
| | | * åç±»åç§° |
| | | * æµç¨åç±»åç§° |
| | | */ |
| | | categoryName?: string; |
| | | |
| | | /** |
| | | * åç±»ç¼ç |
| | | */ |
| | | categoryCode?: string; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request'; |
| | | import { FlowDefinitionQuery, definitionXmlVO, FlowDefinitionForm, FlowDefinitionVo } from '@/api/workflow/definition/types'; |
| | | import { AxiosPromise } from 'axios'; |
| | | |
| | | /** |
| | | * è·åæµç¨å®ä¹å表 |
| | | * @param query æµç¨å®ä¾id |
| | | * @returns |
| | | */ |
| | | export const listDefinition = (query: FlowDefinitionQuery): AxiosPromise<FlowDefinitionVo[]> => { |
| | | return request({ |
| | | url: `/workflow/definition/list`, |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢æªåå¸çæµç¨å®ä¹å表 |
| | | * @param query æµç¨å®ä¾id |
| | | * @returns |
| | | */ |
| | | export const unPublishList = (query: FlowDefinitionQuery): AxiosPromise<FlowDefinitionVo[]> => { |
| | | return request({ |
| | | url: `/workflow/definition/unPublishList`, |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * éè¿æµç¨å®ä¹idè·åxml |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @returns |
| | | */ |
| | | export const definitionXml = (definitionId: string): AxiosPromise<definitionXmlVO> => { |
| | | return request({ |
| | | url: `/workflow/definition/definitionXml/${definitionId}`, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å 餿µç¨å®ä¹ |
| | | * @param id æµç¨å®ä¹id |
| | | * @returns |
| | | */ |
| | | export const deleteDefinition = (id: string | string[]) => { |
| | | return request({ |
| | | url: `/workflow/definition/${id}`, |
| | | method: 'delete' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æèµ·/æ¿æ´» |
| | | * @param definitionId æµç¨å®ä¹id |
| | | * @param activityStatus ç¶æ |
| | | * @returns |
| | | */ |
| | | export const active = (definitionId: string, activityStatus: boolean) => { |
| | | return request({ |
| | | url: `/workflow/definition/active/${definitionId}`, |
| | | method: 'put', |
| | | params: { |
| | | active: activityStatus |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * éè¿zipæxmlé¨ç½²æµç¨å®ä¹ |
| | | * @returns |
| | | */ |
| | | export function importDef(data: any) { |
| | | return request({ |
| | | url: '/workflow/definition/importDef', |
| | | method: 'post', |
| | | data: data, |
| | | headers: { |
| | | repeatSubmit: false |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * å叿µç¨å®ä¹ |
| | | * @param id æµç¨å®ä¹id |
| | | * @returns |
| | | */ |
| | | export const publish = (id: string) => { |
| | | return request({ |
| | | url: `/workflow/definition/publish/${id}`, |
| | | method: 'put' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * åæ¶å叿µç¨å®ä¹ |
| | | * @param id æµç¨å®ä¹id |
| | | * @returns |
| | | */ |
| | | export const unPublish = (id: string) => { |
| | | return request({ |
| | | url: `/workflow/definition/unPublish/${id}`, |
| | | method: 'put' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * è·åæµç¨å®ä¹xmlå符串 |
| | | * @param id æµç¨å®ä¹id |
| | | * @returns |
| | | */ |
| | | export const xmlString = (id: string) => { |
| | | return request({ |
| | | url: `/workflow/definition/xmlString/${id}`, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ°å¢ |
| | | * @param data åæ° |
| | | * @returns |
| | | */ |
| | | export const add = (data: FlowDefinitionForm) => { |
| | | return request({ |
| | | url: `/workflow/definition`, |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * ä¿®æ¹ |
| | | * @param data åæ° |
| | | * @returns |
| | | */ |
| | | export const edit = (data: FlowDefinitionForm) => { |
| | | return request({ |
| | | url: `/workflow/definition`, |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢è¯¦æ
|
| | | * @param id åæ° |
| | | * @returns |
| | | */ |
| | | export const getInfo = (id: number | string) => { |
| | | return request({ |
| | | url: `/workflow/definition/${id}`, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å¤å¶æµç¨å®ä¹ |
| | | * @param id æµç¨å®ä¹id |
| | | * @returns |
| | | */ |
| | | export const copy = (id: string) => { |
| | | return request({ |
| | | url: `/workflow/definition/copy/${id}`, |
| | | method: 'post' |
| | | }); |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | export interface FlowDefinitionQuery extends PageQuery { |
| | | flowCode?: string; |
| | | flowName?: string; |
| | | category: string | number; |
| | | isPublish?: number; |
| | | } |
| | | |
| | | export interface FlowDefinitionVo { |
| | | id: string; |
| | | flowName: string; |
| | | flowCode: string; |
| | | formPath: string; |
| | | version: string; |
| | | isPublish: number; |
| | | activityStatus: number; |
| | | createTime: Date; |
| | | updateTime: Date; |
| | | } |
| | | |
| | | export interface FlowDefinitionForm { |
| | | id: string; |
| | | flowName: string; |
| | | flowCode: string; |
| | | category: string; |
| | | formPath: string; |
| | | } |
| | | |
| | | export interface definitionXmlVO { |
| | | xml: string[]; |
| | | xmlStr: string; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from '@/utils/request'; |
| | | import { FlowInstanceQuery, FlowInstanceVO } from '@/api/workflow/instance/types'; |
| | | import { AxiosPromise } from 'axios'; |
| | | |
| | | /** |
| | | * æ¥è¯¢è¿è¡ä¸å®ä¾å表 |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const pageByRunning = (query: FlowInstanceQuery): AxiosPromise<FlowInstanceVO[]> => { |
| | | return request({ |
| | | url: '/workflow/instance/pageByRunning', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢å·²å®æå®ä¾å表 |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const pageByFinish = (query: FlowInstanceQuery): AxiosPromise<FlowInstanceVO[]> => { |
| | | return request({ |
| | | url: '/workflow/instance/pageByFinish', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * éè¿ä¸å¡idè·åå岿µç¨å¾ |
| | | */ |
| | | export const flowImage = (businessId: string | number) => { |
| | | return request({ |
| | | url: `/workflow/instance/flowImage/${businessId}` + '?t' + Math.random(), |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å页æ¥è¯¢å½åç»å½äººåæ® |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const pageByCurrent = (query: FlowInstanceQuery): AxiosPromise<FlowInstanceVO[]> => { |
| | | return request({ |
| | | url: '/workflow/instance/pageByCurrent', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¤éæµç¨ |
| | | * @param data åæ° |
| | | * @returns |
| | | */ |
| | | export const cancelProcessApply = (data: any) => { |
| | | return request({ |
| | | url: `/workflow/instance/cancelProcessApply`, |
| | | method: 'put', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * è·åæµç¨åé |
| | | * @param instanceId å®ä¾id |
| | | * @returns |
| | | */ |
| | | export const instanceVariable = (instanceId: string | number) => { |
| | | return request({ |
| | | url: `/workflow/instance/instanceVariable/${instanceId}`, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å é¤ |
| | | * @param instanceIds æµç¨å®ä¾id |
| | | * @returns |
| | | */ |
| | | export const deleteByInstanceIds = (instanceIds: Array<string | number> | string | number) => { |
| | | return request({ |
| | | url: `/workflow/instance/deleteByInstanceIds/${instanceIds}`, |
| | | method: 'delete' |
| | | }); |
| | | }; |
| | | /** |
| | | * ä½åºæµç¨ |
| | | * @param data åæ° |
| | | * @returns |
| | | */ |
| | | export const invalid = (data: any) => { |
| | | return request({ |
| | | url: `/workflow/instance/invalid`, |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { FlowTaskVO } from '@/api/workflow/task/types'; |
| | | |
| | | export interface FlowInstanceQuery extends PageQuery { |
| | | category?: string | number; |
| | | nodeName?: string; |
| | | flowCode?: string; |
| | | flowName?: string; |
| | | createByIds?: string[] | number[]; |
| | | businessId?: string; |
| | | } |
| | | |
| | | export interface FlowInstanceVO extends BaseEntity { |
| | | id: string | number; |
| | | definitionId: string; |
| | | flowName: string; |
| | | flowCode: string; |
| | | version: string; |
| | | businessId: string; |
| | | activityStatus: number; |
| | | tenantId: string; |
| | | createTime: string; |
| | | createBy: string; |
| | | flowStatus: string; |
| | | flowStatusName: string; |
| | | flowTaskList: FlowTaskVO[]; |
| | | } |
| | |
| | | import request from '@/utils/request'; |
| | | import { AxiosPromise } from 'axios'; |
| | | import { TaskQuery, TaskVO } from '@/api/workflow/task/types'; |
| | | import { TaskQuery, FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types'; |
| | | |
| | | /** |
| | | * æ¥è¯¢å¾
åå表 |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const getPageByTaskWait = (query: TaskQuery): AxiosPromise<TaskVO[]> => { |
| | | export const pageByTaskWait = (query: TaskQuery): AxiosPromise<FlowTaskVO[]> => { |
| | | return request({ |
| | | url: '/workflow/task/getPageByTaskWait', |
| | | url: '/workflow/task/pageByTaskWait', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const getPageByTaskFinish = (query: TaskQuery): AxiosPromise<TaskVO[]> => { |
| | | export const pageByTaskFinish = (query: TaskQuery): AxiosPromise<FlowTaskVO[]> => { |
| | | return request({ |
| | | url: '/workflow/task/getPageByTaskFinish', |
| | | url: '/workflow/task/pageByTaskFinish', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const getPageByTaskCopy = (query: TaskQuery): AxiosPromise<TaskVO[]> => { |
| | | export const pageByTaskCopy = (query: TaskQuery): AxiosPromise<FlowTaskVO[]> => { |
| | | return request({ |
| | | url: '/workflow/task/getPageByTaskCopy', |
| | | url: '/workflow/task/pageByTaskCopy', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const getPageByAllTaskWait = (query: TaskQuery): AxiosPromise<TaskVO[]> => { |
| | | export const pageByAllTaskWait = (query: TaskQuery): AxiosPromise<FlowTaskVO[]> => { |
| | | return request({ |
| | | url: '/workflow/task/getPageByAllTaskWait', |
| | | url: '/workflow/task/pageByAllTaskWait', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | |
| | | * @param query |
| | | * @returns {*} |
| | | */ |
| | | export const getPageByAllTaskFinish = (query: TaskQuery): AxiosPromise<TaskVO[]> => { |
| | | export const pageByAllTaskFinish = (query: TaskQuery): AxiosPromise<FlowTaskVO[]> => { |
| | | return request({ |
| | | url: '/workflow/task/getPageByAllTaskFinish', |
| | | url: '/workflow/task/pageByAllTaskFinish', |
| | | method: 'get', |
| | | params: query |
| | | }); |
| | |
| | | }; |
| | | |
| | | /** |
| | | * 认é¢ä»»å¡ |
| | | * @param taskId |
| | | * @returns {*} |
| | | */ |
| | | export const claim = (taskId: string): any => { |
| | | return request({ |
| | | url: '/workflow/task/claim/' + taskId, |
| | | method: 'post' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å½è¿ä»»å¡ |
| | | * @param taskId |
| | | * @returns {*} |
| | | */ |
| | | export const returnTask = (taskId: string): any => { |
| | | return request({ |
| | | url: '/workflow/task/returnTask/' + taskId, |
| | | method: 'post' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * ä»»å¡é©³å |
| | | * @param data |
| | | * @returns {*} |
| | |
| | | * @param taskId |
| | | * @returns |
| | | */ |
| | | export const getTaskById = (taskId: string) => { |
| | | export const getTask = (taskId: string) => { |
| | | return request({ |
| | | url: '/workflow/task/getTaskById/' + taskId, |
| | | url: '/workflow/task/getTask/' + taskId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å ç¾ |
| | | * @param data |
| | | * @returns |
| | | */ |
| | | export const addMultiInstanceExecution = (data: any) => { |
| | | return request({ |
| | | url: '/workflow/task/addMultiInstanceExecution', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * åç¾ |
| | | * @param data |
| | | * @returns |
| | | */ |
| | | export const deleteMultiInstanceExecution = (data: any) => { |
| | | return request({ |
| | | url: '/workflow/task/deleteMultiInstanceExecution', |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * ä¿®æ¹ä»»å¡åç人 |
| | | * @param taskIds |
| | | * @param taskIdList |
| | | * @param userId |
| | | * @returns |
| | | */ |
| | | export const updateAssignee = (taskIds: Array<string>, userId: string) => { |
| | | export const updateAssignee = (taskIdList: Array<string>, userId: string) => { |
| | | return request({ |
| | | url: `/workflow/task/updateAssignee/${taskIds}/${userId}`, |
| | | method: 'put' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 转åä»»å¡ |
| | | * @returns |
| | | */ |
| | | export const transferTask = (data: any) => { |
| | | return request({ |
| | | url: `/workflow/task/transferTask`, |
| | | method: 'post', |
| | | data: data |
| | | url: `/workflow/task/updateAssignee/${userId}`, |
| | | method: 'put', |
| | | data: taskIdList |
| | | }); |
| | | }; |
| | | |
| | |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢æµç¨åé |
| | | * @returns |
| | | */ |
| | | export const getInstanceVariable = (taskId: string) => { |
| | | return request({ |
| | | url: `/workflow/task/getInstanceVariable/${taskId}`, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * è·åå¯é©³åå¾ä»»å¡èç¹ |
| | | * @returns |
| | | */ |
| | | export const getTaskNodeList = (processInstanceId: string) => { |
| | | export const getBackTaskNode = (definitionId: string, nodeCode: string) => { |
| | | return request({ |
| | | url: `/workflow/task/getTaskNodeList/${processInstanceId}`, |
| | | url: `/workflow/task/getBackTaskNode/${definitionId}/${nodeCode}`, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * å§æä»»å¡ |
| | | * ä»»å¡æä½ æä½ç±»åï¼å§æ´¾ delegateTaskã转å transferTaskãå ç¾ addSignatureãåç¾ reductionSignature |
| | | * @returns |
| | | */ |
| | | export const delegateTask = (data: any) => { |
| | | export const taskOperation = (data: TaskOperationBo, operation: string) => { |
| | | return request({ |
| | | url: `/workflow/task/delegateTask`, |
| | | url: `/workflow/task/taskOperation/${operation}`, |
| | | method: 'post', |
| | | data: data |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµä»»å¡ç¨æ·éæ©å ç¾äººå |
| | | * @param taskId |
| | | * @returns {*} |
| | | * è·åå½åä»»å¡åç人 |
| | | * @param taskId ä»»å¡id |
| | | * @returns |
| | | */ |
| | | export const getTaskUserIdsByAddMultiInstance = (taskId: string) => { |
| | | export const currentTaskAllUser = (taskId: string | number) => { |
| | | return request({ |
| | | url: '/workflow/task/getTaskUserIdsByAddMultiInstance/' + taskId, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥è¯¢å·¥ä½æµéæ©åç¾äººå |
| | | * @param taskId |
| | | * @returns {*} |
| | | */ |
| | | export const getListByDeleteMultiInstance = (taskId: string) => { |
| | | return request({ |
| | | url: '/workflow/task/getListByDeleteMultiInstance/' + taskId, |
| | | url: `/workflow/task/currentTaskAllUser/${taskId}`, |
| | | method: 'get' |
| | | }); |
| | | }; |
| | |
| | | import { NodeConfigVO } from '@/api/workflow/nodeConfig/types'; |
| | | import { DefinitionConfigVO } from '@/api/workflow/definitionConfig/types'; |
| | | export interface TaskQuery extends PageQuery { |
| | | name?: string; |
| | | processDefinitionKey?: string; |
| | | processDefinitionName?: string; |
| | | nodeName?: string; |
| | | flowCode?: string; |
| | | flowName?: string; |
| | | createByIds?: string[] | number[]; |
| | | } |
| | | |
| | | export interface ParticipantVo { |
| | |
| | | candidateName: string[]; |
| | | claim: boolean; |
| | | } |
| | | |
| | | export interface TaskVO extends BaseEntity { |
| | | id: string; |
| | | name: string; |
| | | description?: string; |
| | | priority: number; |
| | | owner?: string; |
| | | assignee?: string | number; |
| | | assigneeName?: string; |
| | | processInstanceId: string; |
| | | executionId: string; |
| | | taskDefinitionId?: any; |
| | | processDefinitionId: string; |
| | | endTime?: string; |
| | | taskDefinitionKey: string; |
| | | dueDate?: string; |
| | | category?: any; |
| | | parentTaskId?: any; |
| | | tenantId: string; |
| | | claimTime?: string; |
| | | businessStatus?: string; |
| | | businessStatusName?: string; |
| | | processDefinitionName?: string; |
| | | processDefinitionKey?: string; |
| | | participantVo?: ParticipantVo; |
| | | multiInstance?: boolean; |
| | | businessKey?: string; |
| | | wfNodeConfigVo?: NodeConfigVO; |
| | | wfDefinitionConfigVo?: DefinitionConfigVO; |
| | | export interface FlowTaskVO { |
| | | id: string | number; |
| | | createTime?: Date; |
| | | updateTime?: Date; |
| | | tenantId?: string; |
| | | definitionId?: string; |
| | | instanceId: string; |
| | | flowName: string; |
| | | businessId: string; |
| | | nodeCode: string; |
| | | nodeName: string; |
| | | flowCode: string; |
| | | flowStatus: string; |
| | | formCustom: string; |
| | | formPath: string; |
| | | nodeType: number; |
| | | nodeRatio: string | number; |
| | | version?: string; |
| | | } |
| | | |
| | | export interface VariableVo { |
| | | key: string; |
| | | value: string; |
| | | } |
| | | |
| | | export interface TaskOperationBo { |
| | | //å§æ´¾/转å人çç¨æ·IDï¼å¿
å¡«ï¼å坹姿´¾/转å人æä½ï¼ |
| | | userId?: string; |
| | | //å ç¾/åç¾äººçç¨æ·IDå表ï¼å¿
å¡«ï¼é对å ç¾/åç¾æä½ï¼ |
| | | userIds?: string[]; |
| | | //ä»»å¡IDï¼å¿
å¡«ï¼ |
| | | taskId: string | number; |
| | | //æè§æå¤æ³¨ä¿¡æ¯ï¼å¯éï¼ |
| | | message?: string; |
| | | } |
| | |
| | | |
| | | export default { |
| | | routerJump(routerJumpVo: RouterJumpVo, proxy) { |
| | | if (routerJumpVo.wfNodeConfigVo && routerJumpVo.wfNodeConfigVo.formType === 'static' && routerJumpVo.wfNodeConfigVo.wfFormManageVo) { |
| | | proxy.$tab.closePage(proxy.$route); |
| | | proxy.$router.push({ |
| | | path: `${routerJumpVo.wfNodeConfigVo.wfFormManageVo.router}`, |
| | | query: { |
| | | id: routerJumpVo.businessKey, |
| | | type: routerJumpVo.type, |
| | | taskId: routerJumpVo.taskId |
| | | } |
| | | }); |
| | | } else if (routerJumpVo.wfNodeConfigVo && routerJumpVo.wfNodeConfigVo.formType === 'dynamic' && routerJumpVo.wfNodeConfigVo.wfFormManageVo) { |
| | | proxy.$tab.closePage(proxy.$route); |
| | | proxy.$router.push({ |
| | | path: `${routerJumpVo.wfNodeConfigVo.wfFormManageVo.router}`, |
| | | query: { |
| | | id: routerJumpVo.businessKey, |
| | | type: routerJumpVo.type, |
| | | taskId: routerJumpVo.taskId |
| | | } |
| | | }); |
| | | } else { |
| | | proxy?.$modal.msgError('è¯·å°æ¨¡åé
ç½®èåï¼'); |
| | | } |
| | | proxy.$tab.closePage(proxy.$route); |
| | | proxy.$router.push({ |
| | | path: routerJumpVo.formPath, |
| | | query: { |
| | | id: routerJumpVo.businessId, |
| | | type: routerJumpVo.type, |
| | | taskId: routerJumpVo.taskId |
| | | } |
| | | }); |
| | | } |
| | | }; |
| | |
| | | import { NodeConfigVO } from '@/api/workflow/nodeConfig/types'; |
| | | import { DefinitionConfigVO } from '@/api/workflow/definitionConfig/types'; |
| | | |
| | | export interface RouterJumpVo { |
| | | wfNodeConfigVo: NodeConfigVO; |
| | | wfDefinitionConfigVo: DefinitionConfigVO; |
| | | businessKey: string; |
| | | taskId: string; |
| | | businessId: string; |
| | | taskId: string | number; |
| | | type: string; |
| | | formCustom: string; |
| | | formPath: string; |
| | | } |
| | | |
| | | export interface StartProcessBo { |
| | | businessKey: string | number; |
| | | tableName: string; |
| | | businessId: string | number; |
| | | flowCode: string; |
| | | variables: any; |
| | | } |
| | |
| | | --tableHeaderBg: #f8f8f9; |
| | | --tableHeaderTextColor: #515a6e; |
| | | |
| | | // 工使µ |
| | | --bpmn-panel-border: #eeeeee; |
| | | --bpmn-panel-box-shadow: #cccccc; |
| | | --bpmn-panel-bar-background-color: #f5f7fa; |
| | | |
| | | // ele |
| | | --brder-color: #e8e8e8; |
| | | |
| | |
| | | --vxe-table-border-width: 1px; |
| | | --vxe-table-border-color: #37373a; |
| | | --vxe-toolbar-background-color: #37373a; |
| | | |
| | | // 工使µ |
| | | --bpmn-panel-border: #37373a; |
| | | --bpmn-panel-box-shadow: #37373a; |
| | | --bpmn-panel-bar-background-color: #37373a; |
| | | |
| | | // ele |
| | | --brder-color: #37373a; |
| | |
| | | <div class="container"> |
| | | <el-dialog v-model="visible" draggable title="审æ¹è®°å½" :width="props.width" :height="props.height" :close-on-click-modal="false"> |
| | | <el-tabs v-model="tabActiveName" class="demo-tabs"> |
| | | <el-tab-pane label="æµç¨å¾" name="bpmn"> |
| | | <BpmnView ref="bpmnViewRef"></BpmnView> |
| | | <el-tab-pane v-loading="loading" label="æµç¨å¾" name="bpmn"> |
| | | <img :src="imgUrl" width="100%" style="margin: 0 auto" /> |
| | | </el-tab-pane> |
| | | <el-tab-pane v-loading="loading" label="审æ¹ä¿¡æ¯" name="info"> |
| | | <div> |
| | | <el-table :data="historyList" style="width: 100%" border fit> |
| | | <el-table-column type="index" label="åºå·" align="center" width="60"></el-table-column> |
| | | <el-table-column prop="name" label="ä»»å¡åç§°" sortable align="center"></el-table-column> |
| | | <el-table-column prop="nickName" :show-overflow-tooltip="true" label="åç人" sortable align="center"> |
| | | <el-table-column prop="nodeName" label="ä»»å¡åç§°" sortable align="center"></el-table-column> |
| | | <el-table-column prop="approveName" :show-overflow-tooltip="true" label="åç人" sortable align="center"> |
| | | <template #default="scope"> |
| | | <el-tag type="success">{{ scope.row.nickName || 'æ ' }}</el-tag> |
| | | <template v-if="scope.row.approveName"> |
| | | <el-tag v-for="(item, index) in scope.row.approveName.split(',')" :key="index" type="success">{{ item }}</el-tag> |
| | | </template> |
| | | <template v-else> <el-tag type="success">æ </el-tag></template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="ç¶æ" sortable align="center"> |
| | | <el-table-column prop="flowStatus" label="ç¶æ" width="80" sortable align="center"> |
| | | <template #default="scope"> |
| | | <el-tag type="success">{{ scope.row.statusName }}</el-tag> |
| | | <dict-tag :options="wf_task_status" :value="scope.row.flowStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="comment" label="å®¡æ¹æè§" sortable align="center"></el-table-column> |
| | | <el-table-column prop="startTime" label="å¼å§æ¶é´" sortable align="center"></el-table-column> |
| | | <el-table-column prop="endTime" label="ç»ææ¶é´" sortable align="center"></el-table-column> |
| | | <el-table-column prop="runDuration" label="è¿è¡æ¶é¿" sortable align="center"></el-table-column> |
| | | <el-table-column prop="attachmentList" label="éä»¶" sortable align="center"> |
| | | <el-table-column prop="message" label="å®¡æ¹æè§" :show-overflow-tooltip="true" sortable align="center"></el-table-column> |
| | | <el-table-column prop="createTime" label="å¼å§æ¶é´" width="160" :show-overflow-tooltip="true" sortable align="center"></el-table-column> |
| | | <el-table-column prop="updateTime" label="ç»ææ¶é´" width="160" :show-overflow-tooltip="true" sortable align="center"></el-table-column> |
| | | <el-table-column |
| | | prop="runDuration" |
| | | label="è¿è¡æ¶å¸¸" |
| | | width="140" |
| | | :show-overflow-tooltip="true" |
| | | sortable |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column prop="attachmentList" width="120" label="éä»¶" align="center"> |
| | | <template #default="scope"> |
| | | <el-popover v-if="scope.row.attachmentList && scope.row.attachmentList.length > 0" placement="right" :width="310" trigger="click"> |
| | | <template #reference> |
| | | <el-button style="margin-right: 16px">éä»¶</el-button> |
| | | <el-button type="primary" style="margin-right: 16px">éä»¶</el-button> |
| | | </template> |
| | | <el-table border :data="scope.row.attachmentList"> |
| | | <el-table-column prop="name" width="202" :show-overflow-tooltip="true" label="éä»¶åç§°"></el-table-column> |
| | | <el-table-column prop="originalName" width="202" :show-overflow-tooltip="true" label="éä»¶åç§°"></el-table-column> |
| | | <el-table-column prop="name" width="80" align="center" :show-overflow-tooltip="true" label="æä½"> |
| | | <template #default="tool"> |
| | | <el-button type="text" @click="handleDownload(tool.row.contentId)">ä¸è½½</el-button> |
| | | <el-button type="text" @click="handleDownload(tool.row.ossId)">ä¸è½½</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | </div> |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import BpmnView from '@/components/BpmnView/index.vue'; |
| | | import processApi from '@/api/workflow/processInstance'; |
| | | import { flowImage } from '@/api/workflow/instance'; |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | import { listByIds } from '@/api/system/oss'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | const { wf_task_status } = toRefs<any>(proxy?.useDict('wf_task_status')); |
| | | const props = defineProps({ |
| | | width: propTypes.string.def('70%'), |
| | | width: propTypes.string.def('80%'), |
| | | height: propTypes.string.def('100%') |
| | | }); |
| | | const loading = ref(false); |
| | | const visible = ref(false); |
| | | const historyList = ref<Array<any>>([]); |
| | | const tabActiveName = ref('bpmn'); |
| | | |
| | | const bpmnViewRef = ref<BpmnView>(); |
| | | const imgUrl = ref(''); |
| | | |
| | | //åå§åæ¥è¯¢å®¡æ¹è®°å½ |
| | | const init = async (businessKey: string | number) => { |
| | | const init = async (businessId: string | number) => { |
| | | visible.value = true; |
| | | loading.value = true; |
| | | tabActiveName.value = 'bpmn'; |
| | | historyList.value = []; |
| | | processApi.getHistoryRecord(businessKey).then((resp) => { |
| | | historyList.value = resp.data; |
| | | loading.value = false; |
| | | flowImage(businessId).then((resp) => { |
| | | if (resp.data) { |
| | | historyList.value = resp.data.list; |
| | | imgUrl.value = 'data:image/gif;base64,' + resp.data.image; |
| | | if (historyList.value.length > 0) { |
| | | historyList.value.forEach((item) => { |
| | | if (item.ext) { |
| | | getIds(item.ext).then((res) => { |
| | | item.attachmentList = res.data; |
| | | }); |
| | | } else { |
| | | item.attachmentList = []; |
| | | } |
| | | }); |
| | | } |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | await nextTick(() => { |
| | | bpmnViewRef.value.init(businessKey); |
| | | }); |
| | | }; |
| | | const getIds = async (ids: string | number) => { |
| | | const res = await listByIds(ids); |
| | | return res; |
| | | }; |
| | | |
| | | /** ä¸è½½æé®æä½ */ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog v-model="visible" draggable title="æµç¨å¹²é¢" :width="props.width" :height="props.height" :close-on-click-modal="false"> |
| | | <el-descriptions v-loading="loading" class="margin-top" :title="`${task.flowName}(${task.flowCode})`" :column="2" border> |
| | | <el-descriptions-item label="ä»»å¡åç§°">{{ task.nodeName }}</el-descriptions-item> |
| | | <el-descriptions-item label="èç¹ç¼ç ">{{ task.nodeCode }}</el-descriptions-item> |
| | | <el-descriptions-item label="å¼å§æ¶é´">{{ task.createTime }}</el-descriptions-item> |
| | | <el-descriptions-item label="æµç¨å®ä¾ID">{{ task.instanceId }}</el-descriptions-item> |
| | | <el-descriptions-item label="çæ¬å·">{{ task.version }}.0</el-descriptions-item> |
| | | <el-descriptions-item label="ä¸å¡ID">{{ task.businessId }}</el-descriptions-item> |
| | | </el-descriptions> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openTransferTask"> 转å </el-button> |
| | | <el-button |
| | | v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0" |
| | | :disabled="buttonDisabled" |
| | | type="primary" |
| | | @click="openMultiInstanceUser" |
| | | > |
| | | å ç¾ |
| | | </el-button> |
| | | <el-button |
| | | v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0" |
| | | :disabled="buttonDisabled" |
| | | type="primary" |
| | | @click="handleTaskUser" |
| | | > |
| | | åç¾ |
| | | </el-button> |
| | | <el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleTerminationTask"> ç»æ¢ </el-button> |
| | | </span> |
| | | </template> |
| | | <!-- 转å --> |
| | | <UserSelect ref="transferTaskRef" :multiple="false" @confirm-call-back="handleTransferTask"></UserSelect> |
| | | <!-- å ç¾ç»ä»¶ --> |
| | | <UserSelect ref="multiInstanceUserRef" :multiple="true" @confirm-call-back="addMultiInstanceUser"></UserSelect> |
| | | <el-dialog v-model="deleteSignatureVisible" draggable title="åç¾äººå" width="700px" height="400px" append-to-body :close-on-click-modal="false" |
| | | ><div> |
| | | <el-table :data="deleteUserList" border> |
| | | <el-table-column prop="nodeName" label="ä»»å¡åç§°" /> |
| | | <el-table-column prop="nickName" label="åç人" /> |
| | | <el-table-column label="æä½" align="center" width="160"> |
| | | <template #default="scope"> |
| | | <el-button type="danger" size="small" icon="Delete" @click="deleteMultiInstanceUser(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-dialog> |
| | | </el-dialog> |
| | | </template> |
| | | <script lang="ts" setup> |
| | | import { propTypes } from '@/utils/propTypes'; |
| | | import { FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types'; |
| | | import UserSelect from '@/components/UserSelect'; |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | import { getTask, taskOperation, currentTaskAllUser, terminationTask } from '@/api/workflow/task'; |
| | | const props = defineProps({ |
| | | width: propTypes.string.def('50%'), |
| | | height: propTypes.string.def('100%') |
| | | }); |
| | | const emits = defineEmits(['submitCallback']); |
| | | const transferTaskRef = ref<InstanceType<typeof UserSelect>>(); |
| | | const multiInstanceUserRef = ref<InstanceType<typeof UserSelect>>(); |
| | | //é®ç½©å± |
| | | const loading = ref(true); |
| | | //æé® |
| | | const buttonDisabled = ref(true); |
| | | const visible = ref(false); |
| | | //åç¾å¼¹çª |
| | | const deleteSignatureVisible = ref(false); |
| | | //å¯åç¾ç人å |
| | | const deleteUserList = ref<any>([]); |
| | | //ä»»å¡ |
| | | const task = ref<FlowTaskVO>({ |
| | | id: undefined, |
| | | createTime: undefined, |
| | | updateTime: undefined, |
| | | tenantId: undefined, |
| | | definitionId: undefined, |
| | | instanceId: undefined, |
| | | flowName: undefined, |
| | | businessId: undefined, |
| | | nodeCode: undefined, |
| | | nodeName: undefined, |
| | | flowCode: undefined, |
| | | flowStatus: undefined, |
| | | nodeType: undefined, |
| | | nodeRatio: undefined, |
| | | version: undefined |
| | | }); |
| | | |
| | | const open = (taskId: string) => { |
| | | visible.value = true; |
| | | getTask(taskId).then((response) => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | task.value = response.data; |
| | | }); |
| | | }; |
| | | |
| | | //æå¼è½¬å |
| | | const openTransferTask = () => { |
| | | transferTaskRef.value.open(); |
| | | }; |
| | | //转å |
| | | const handleTransferTask = async (data) => { |
| | | if (data && data.length > 0) { |
| | | const taskOperationBo = reactive<TaskOperationBo>({ |
| | | userId: data[0].userId, |
| | | taskId: task.value.id, |
| | | message: '' |
| | | }); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | await taskOperation(taskOperationBo, 'transferTask').finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | visible.value = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | } else { |
| | | proxy?.$modal.msgWarning('è¯·éæ©ç¨æ·ï¼'); |
| | | } |
| | | }; |
| | | //å ç¾ |
| | | const openMultiInstanceUser = async () => { |
| | | multiInstanceUserRef.value.open(); |
| | | }; |
| | | //å ç¾ |
| | | const addMultiInstanceUser = async (data) => { |
| | | if (data && data.length > 0) { |
| | | const taskOperationBo = reactive<TaskOperationBo>({ |
| | | userIds: data.map((e) => e.userId), |
| | | taskId: task.value.id, |
| | | message: '' |
| | | }); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | await taskOperation(taskOperationBo, 'addSignature').finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | visible.value = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | } else { |
| | | proxy?.$modal.msgWarning('è¯·éæ©ç¨æ·ï¼'); |
| | | } |
| | | }; |
| | | //åç¾ |
| | | const deleteMultiInstanceUser = async (row) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | const taskOperationBo = reactive<TaskOperationBo>({ |
| | | userIds: [row.userId], |
| | | taskId: task.value.id, |
| | | message: '' |
| | | }); |
| | | await taskOperation(taskOperationBo, 'reductionSignature').finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | visible.value = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | }; |
| | | //è·ååç人 |
| | | const handleTaskUser = async () => { |
| | | let data = await currentTaskAllUser(task.value.id); |
| | | deleteUserList.value = data.data; |
| | | if (deleteUserList.value && deleteUserList.value.length > 0) { |
| | | deleteUserList.value.forEach((e) => { |
| | | e.nodeName = task.value.nodeName; |
| | | }); |
| | | } |
| | | deleteSignatureVisible.value = true; |
| | | }; |
| | | |
| | | //ç»æ¢ä»»å¡ |
| | | const handleTerminationTask = async () => { |
| | | let params = { |
| | | taskId: task.value.id, |
| | | comment: '' |
| | | }; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤ç»æ¢ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | await terminationTask(params).finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | visible.value = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | }; |
| | | /** |
| | | * 坹夿´é²åç»ä»¶æ¹æ³ |
| | | */ |
| | | defineExpose({ |
| | | open |
| | | }); |
| | | </script> |
| | |
| | | <el-form v-loading="loading" :model="form" label-width="120px"> |
| | | <el-form-item label="æ¶æ¯æé"> |
| | | <el-checkbox-group v-model="form.messageType"> |
| | | <el-checkbox label="1" name="type" disabled>ç«å
ä¿¡</el-checkbox> |
| | | <el-checkbox label="2" name="type">é®ä»¶</el-checkbox> |
| | | <el-checkbox label="3" name="type">çä¿¡</el-checkbox> |
| | | <el-checkbox value="1" name="type" disabled>ç«å
ä¿¡</el-checkbox> |
| | | <el-checkbox value="2" name="type">é®ä»¶</el-checkbox> |
| | | <el-checkbox value="3" name="type">çä¿¡</el-checkbox> |
| | | </el-checkbox-group> |
| | | </el-form-item> |
| | | <el-form-item v-if="task.businessStatus === 'waiting'" label="éä»¶"> |
| | | <fileUpload v-model="form.fileId" :file-type="['doc', 'xls', 'ppt', 'txt', 'pdf', 'xlsx', 'docx', 'zip']" :file-size="'20'" /> |
| | | <el-form-item v-if="task.flowStatus === 'waiting'" label="éä»¶"> |
| | | <fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" /> |
| | | </el-form-item> |
| | | <el-form-item label="æé"> |
| | | <el-button type="primary" icon="Plus" circle @click="openUserSelectCopy" /> |
| | | <el-tag v-for="user in selectCopyUserList" :key="user.userId" closable style="margin: 2px" @close="handleCopyCloseTag(user)"> |
| | | {{ user.userName }} |
| | | {{ user.nickName }} |
| | | </el-tag> |
| | | </el-form-item> |
| | | <el-form-item v-if="task.businessStatus === 'waiting'" label="å®¡æ¹æè§"> |
| | | <el-form-item v-if="task.flowStatus === 'waiting'" label="å®¡æ¹æè§"> |
| | | <el-input v-model="form.message" type="textarea" resize="none" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button :disabled="buttonDisabled" type="primary" @click="handleCompleteTask"> æäº¤ </el-button> |
| | | <el-button v-if="task.businessStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openDelegateTask"> å§æ </el-button> |
| | | <el-button v-if="task.businessStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openTransferTask"> 转å </el-button> |
| | | <el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openDelegateTask"> å§æ </el-button> |
| | | <el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="primary" @click="openTransferTask"> 转å </el-button> |
| | | <el-button |
| | | v-if="task.businessStatus === 'waiting' && task.multiInstance" |
| | | v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0" |
| | | :disabled="buttonDisabled" |
| | | type="primary" |
| | | @click="addMultiInstanceUser" |
| | | @click="openMultiInstanceUser" |
| | | > |
| | | å ç¾ |
| | | </el-button> |
| | | <el-button |
| | | v-if="task.businessStatus === 'waiting' && task.multiInstance" |
| | | v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0" |
| | | :disabled="buttonDisabled" |
| | | type="primary" |
| | | @click="deleteMultiInstanceUser" |
| | | @click="handleTaskUser" |
| | | > |
| | | åç¾ |
| | | </el-button> |
| | | <el-button v-if="task.businessStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleTerminationTask"> ç»æ¢ </el-button> |
| | | <el-button v-if="task.businessStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleBackProcessOpen"> éå </el-button> |
| | | <el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleTerminationTask"> ç»æ¢ </el-button> |
| | | <el-button v-if="task.flowStatus === 'waiting'" :disabled="buttonDisabled" type="danger" @click="handleBackProcessOpen"> éå </el-button> |
| | | <el-button :disabled="buttonDisabled" @click="cancel">åæ¶</el-button> |
| | | </span> |
| | | </template> |
| | |
| | | <!-- å§æ --> |
| | | <UserSelect ref="delegateTaskRef" :multiple="false" @confirm-call-back="handleDelegateTask"></UserSelect> |
| | | <!-- å ç¾ç»ä»¶ --> |
| | | <multiInstanceUser ref="multiInstanceUserRef" :title="title" @submit-callback="closeDialog" /> |
| | | <UserSelect ref="multiInstanceUserRef" :multiple="true" @confirm-call-back="addMultiInstanceUser"></UserSelect> |
| | | |
| | | <!-- 驳åå¼å§ --> |
| | | <el-dialog v-model="backVisible" draggable title="驳å" width="40%" :close-on-click-modal="false"> |
| | | <el-form v-if="task.businessStatus === 'waiting'" v-loading="backLoading" :model="backForm" label-width="120px"> |
| | | <el-form v-if="task.flowStatus === 'waiting'" v-loading="backLoading" :model="backForm" label-width="120px"> |
| | | <el-form-item label="驳åèç¹"> |
| | | <el-select v-model="backForm.targetActivityId" clearable placeholder="è¯·éæ©" style="width: 300px"> |
| | | <el-option v-for="item in taskNodeList" :key="item.nodeId" :label="item.nodeName" :value="item.nodeId" /> |
| | | <el-select v-model="backForm.nodeCode" clearable placeholder="è¯·éæ©" style="width: 300px"> |
| | | <el-option v-for="item in taskNodeList" :key="item.nodeCode" :label="item.nodeName" :value="item.nodeCode" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | <el-form-item label="æ¶æ¯æé"> |
| | |
| | | </template> |
| | | </el-dialog> |
| | | <!-- 驳åç»æ --> |
| | | <el-dialog v-model="deleteSignatureVisible" draggable title="åç¾äººå" width="700px" height="400px" append-to-body :close-on-click-modal="false"> |
| | | <div> |
| | | <el-table :data="deleteUserList" border> |
| | | <el-table-column prop="nodeName" label="ä»»å¡åç§°" /> |
| | | <el-table-column prop="nickName" label="åç人" /> |
| | | <el-table-column label="æä½" align="center" width="160"> |
| | | <template #default="scope"> |
| | | <el-button type="danger" size="small" icon="Delete" @click="deleteMultiInstanceUser(scope.row)">å é¤ </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-dialog> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | |
| | | import { ref } from 'vue'; |
| | | import { ComponentInternalInstance } from 'vue'; |
| | | import { ElForm } from 'element-plus'; |
| | | import { completeTask, backProcess, getTaskById, transferTask, terminationTask, getTaskNodeList, delegateTask } from '@/api/workflow/task'; |
| | | import { completeTask, backProcess, getTask, taskOperation, terminationTask, getBackTaskNode, currentTaskAllUser } from '@/api/workflow/task'; |
| | | import UserSelect from '@/components/UserSelect'; |
| | | import MultiInstanceUser from '@/components/Process/multiInstanceUser.vue'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | import { UserVO } from '@/api/system/user/types'; |
| | | import { TaskVO } from '@/api/workflow/task/types'; |
| | | import { FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types'; |
| | | |
| | | const userSelectCopyRef = ref<InstanceType<typeof UserSelect>>(); |
| | | const transferTaskRef = ref<InstanceType<typeof UserSelect>>(); |
| | | const delegateTaskRef = ref<InstanceType<typeof UserSelect>>(); |
| | | |
| | | //å ç¾ç»ä»¶ |
| | | const multiInstanceUserRef = ref<InstanceType<typeof MultiInstanceUser>>(); |
| | | const multiInstanceUserRef = ref<InstanceType<typeof UserSelect>>(); |
| | | |
| | | const props = defineProps({ |
| | | taskVariables: { |
| | |
| | | const selectCopyUserList = ref<UserVO[]>([]); |
| | | //æé人id |
| | | const selectCopyUserIds = ref<string>(undefined); |
| | | // 驳忝妿¾ç¤º |
| | | //å¯åç¾ç人å |
| | | const deleteUserList = ref<any>([]); |
| | | //驳忝妿¾ç¤º |
| | | const backVisible = ref(false); |
| | | const backLoading = ref(true); |
| | | const backButtonDisabled = ref(true); |
| | | // å¯é©³åå¾ä»»å¡èç¹ |
| | | const taskNodeList = ref([]); |
| | | //ä»»å¡ |
| | | const task = ref<TaskVO>({ |
| | | const task = ref<FlowTaskVO>({ |
| | | id: undefined, |
| | | name: undefined, |
| | | description: undefined, |
| | | priority: undefined, |
| | | owner: undefined, |
| | | assignee: undefined, |
| | | assigneeName: undefined, |
| | | processInstanceId: undefined, |
| | | executionId: undefined, |
| | | taskDefinitionId: undefined, |
| | | processDefinitionId: undefined, |
| | | endTime: undefined, |
| | | taskDefinitionKey: undefined, |
| | | dueDate: undefined, |
| | | category: undefined, |
| | | parentTaskId: undefined, |
| | | createTime: undefined, |
| | | updateTime: undefined, |
| | | tenantId: undefined, |
| | | claimTime: undefined, |
| | | businessStatus: undefined, |
| | | businessStatusName: undefined, |
| | | processDefinitionName: undefined, |
| | | processDefinitionKey: undefined, |
| | | participantVo: undefined, |
| | | multiInstance: undefined, |
| | | businessKey: undefined, |
| | | wfNodeConfigVo: undefined |
| | | definitionId: undefined, |
| | | instanceId: undefined, |
| | | flowName: undefined, |
| | | businessId: undefined, |
| | | nodeCode: undefined, |
| | | nodeName: undefined, |
| | | flowCode: undefined, |
| | | flowStatus: undefined, |
| | | formCustom: undefined, |
| | | formPath: undefined, |
| | | nodeType: undefined, |
| | | nodeRatio: undefined |
| | | }); |
| | | //å ç¾ åç¾æ é¢ |
| | | const title = ref(''); |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: 'æç¤º' |
| | | }); |
| | | |
| | | //åç¾å¼¹çª |
| | | const deleteSignatureVisible = ref(false); |
| | | const form = ref<Record<string, any>>({ |
| | | taskId: undefined, |
| | | message: undefined, |
| | | variables: {}, |
| | | messageType: ['1'], |
| | | wfCopyList: [] |
| | | flowCopyList: [] |
| | | }); |
| | | const backForm = ref<Record<string, any>>({ |
| | | taskId: undefined, |
| | | targetActivityId: undefined, |
| | | nodeCode: undefined, |
| | | message: undefined, |
| | | variables: {}, |
| | | messageType: ['1'] |
| | | }); |
| | | const closeDialog = () => { |
| | | dialog.visible = false; |
| | | }; |
| | | //æå¼å¼¹çª |
| | | const openDialog = (id?: string) => { |
| | | selectCopyUserIds.value = undefined; |
| | |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | nextTick(() => { |
| | | getTaskById(taskId.value).then((response) => { |
| | | getTask(taskId.value).then((response) => { |
| | | task.value = response.data; |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | |
| | | form.value.taskId = taskId.value; |
| | | form.value.taskVariables = props.taskVariables; |
| | | if (selectCopyUserList.value && selectCopyUserList.value.length > 0) { |
| | | let wfCopyList = []; |
| | | let flowCopyList = []; |
| | | selectCopyUserList.value.forEach((e) => { |
| | | let copyUser = { |
| | | userId: e.userId, |
| | | userName: e.nickName |
| | | }; |
| | | wfCopyList.push(copyUser); |
| | | flowCopyList.push(copyUser); |
| | | }); |
| | | form.value.wfCopyList = wfCopyList; |
| | | form.value.flowCopyList = flowCopyList; |
| | | } |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | |
| | | backVisible.value = true; |
| | | backLoading.value = true; |
| | | backButtonDisabled.value = true; |
| | | let data = await getTaskNodeList(task.value.processInstanceId); |
| | | let data = await getBackTaskNode(task.value.definitionId, task.value.nodeCode); |
| | | taskNodeList.value = data.data; |
| | | backLoading.value = false; |
| | | backButtonDisabled.value = false; |
| | | backForm.value.targetActivityId = taskNodeList.value[0].nodeId; |
| | | backForm.value.nodeCode = taskNodeList.value[0].nodeCode; |
| | | }; |
| | | /** é©³åæµç¨ */ |
| | | const handleBackProcess = async () => { |
| | |
| | | loading.value = true; |
| | | backLoading.value = true; |
| | | backButtonDisabled.value = true; |
| | | await backProcess(backForm.value).finally(() => (loading.value = false)); |
| | | await backProcess(backForm.value).finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | dialog.visible = false; |
| | | backLoading.value = false; |
| | | backButtonDisabled.value = false; |
| | |
| | | selectCopyUserIds.value = selectCopyUserList.value.map((item) => item.userId).join(','); |
| | | }; |
| | | //å ç¾ |
| | | const addMultiInstanceUser = () => { |
| | | if (multiInstanceUserRef.value) { |
| | | title.value = 'å ç¾äººå'; |
| | | multiInstanceUserRef.value.getAddMultiInstanceList(taskId.value, []); |
| | | const openMultiInstanceUser = async () => { |
| | | multiInstanceUserRef.value.open(); |
| | | }; |
| | | //å ç¾ |
| | | const addMultiInstanceUser = async (data) => { |
| | | if (data && data.length > 0) { |
| | | const taskOperationBo = reactive<TaskOperationBo>({ |
| | | userIds: data.map((e) => e.userId), |
| | | taskId: taskId.value, |
| | | message: form.value.message |
| | | }); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | await taskOperation(taskOperationBo, 'addSignature').finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | dialog.visible = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | } else { |
| | | proxy?.$modal.msgWarning('è¯·éæ©ç¨æ·ï¼'); |
| | | } |
| | | }; |
| | | //åç¾ |
| | | const deleteMultiInstanceUser = () => { |
| | | if (multiInstanceUserRef.value) { |
| | | title.value = 'åç¾äººå'; |
| | | multiInstanceUserRef.value.getDeleteMultiInstanceList(taskId.value); |
| | | } |
| | | const deleteMultiInstanceUser = async (row) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | const taskOperationBo = reactive<TaskOperationBo>({ |
| | | userIds: [row.userId], |
| | | taskId: taskId.value, |
| | | message: form.value.message |
| | | }); |
| | | await taskOperation(taskOperationBo, 'reductionSignature').finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | dialog.visible = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | }; |
| | | //æå¼è½¬å |
| | | const openTransferTask = () => { |
| | |
| | | //转å |
| | | const handleTransferTask = async (data) => { |
| | | if (data && data.length > 0) { |
| | | let params = { |
| | | taskId: taskId.value, |
| | | const taskOperationBo = reactive<TaskOperationBo>({ |
| | | userId: data[0].userId, |
| | | comment: form.value.message |
| | | }; |
| | | taskId: taskId.value, |
| | | message: form.value.message |
| | | }); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | await transferTask(params).finally(() => (loading.value = false)); |
| | | await taskOperation(taskOperationBo, 'transferTask').finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | dialog.visible = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | |
| | | //å§æ |
| | | const handleDelegateTask = async (data) => { |
| | | if (data && data.length > 0) { |
| | | let params = { |
| | | taskId: taskId.value, |
| | | const taskOperationBo = reactive<TaskOperationBo>({ |
| | | userId: data[0].userId, |
| | | nickName: data[0].nickName |
| | | }; |
| | | taskId: taskId.value, |
| | | message: form.value.message |
| | | }); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æäº¤ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | await delegateTask(params).finally(() => (loading.value = false)); |
| | | await taskOperation(taskOperationBo, 'delegateTask').finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | dialog.visible = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | |
| | | } |
| | | }; |
| | | //ç»æ¢ä»»å¡ |
| | | const handleTerminationTask = async (data) => { |
| | | const handleTerminationTask = async () => { |
| | | let params = { |
| | | taskId: taskId.value, |
| | | comment: form.value.message |
| | |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤ç»æ¢ï¼'); |
| | | loading.value = true; |
| | | buttonDisabled.value = true; |
| | | await terminationTask(params).finally(() => (loading.value = false)); |
| | | await terminationTask(params).finally(() => { |
| | | loading.value = false; |
| | | buttonDisabled.value = false; |
| | | }); |
| | | dialog.visible = false; |
| | | emits('submitCallback'); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | }; |
| | | const handleTaskUser = async () => { |
| | | let data = await currentTaskAllUser(taskId.value); |
| | | deleteUserList.value = data.data; |
| | | if (deleteUserList.value && deleteUserList.value.length > 0) { |
| | | deleteUserList.value.forEach((e) => { |
| | | e.nodeName = task.value.nodeName; |
| | | }); |
| | | } |
| | | deleteSignatureVisible.value = true; |
| | | }; |
| | | |
| | | /** |
| | | * 坹夿´é²åç»ä»¶æ¹æ³ |
| | |
| | | <el-card shadow="hover"> |
| | | <template v-if="prop.multiple" #header> |
| | | <el-tag v-for="user in selectUserList" :key="user.userId" closable style="margin: 2px" @close="handleCloseTag(user)"> |
| | | {{ user.userName }} |
| | | {{ user.nickName }} |
| | | </el-tag> |
| | | </template> |
| | | |
| | |
| | | <script setup lang="ts"> |
| | | import api from '@/api/system/user'; |
| | | import { UserQuery, UserVO } from '@/api/system/user/types'; |
| | | import { DeptVO } from '@/api/system/dept/types'; |
| | | import { DeptTreeVO, DeptVO } from '@/api/system/dept/types'; |
| | | import { VxeTableInstance } from 'vxe-table'; |
| | | import useDialog from '@/hooks/useDialog'; |
| | | |
| | | interface PropType { |
| | | modelValue?: UserVO[] | UserVO | undefined; |
| | | multiple?: boolean; |
| | | data?: string | number | (string | number)[]; |
| | | data?: string | number | (string | number)[] | undefined; |
| | | } |
| | | const prop = withDefaults(defineProps<PropType>(), { |
| | | multiple: true, |
| | |
| | | const total = ref(0); |
| | | const dateRange = ref<[DateModelType, DateModelType]>(['', '']); |
| | | const deptName = ref(''); |
| | | const deptOptions = ref<DeptVO[]>([]); |
| | | const deptOptions = ref<DeptTreeVO[]>([]); |
| | | const selectUserList = ref<UserVO[]>([]); |
| | | |
| | | const deptTreeRef = ref<ElTreeInstance>(); |
| | |
| | | meta: { title: '请åç³è¯·', activeMenu: '/workflow/leave', noCache: true } |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | path: '/workflow/design', |
| | | component: Layout, |
| | | hidden: true, |
| | | permissions: ['workflow:leave:edit'], |
| | | children: [ |
| | | { |
| | | path: 'index', |
| | | component: () => import('@/views/workflow/processDefinition/design.vue'), |
| | | name: 'design', |
| | | meta: { title: 'æµç¨è®¾è®¡', activeMenu: '/workflow/processDefinition', noCache: true } |
| | | } |
| | | ] |
| | | } |
| | | ]; |
| | | |
| | |
| | | <el-form-item label="åç±»åç§°" prop="categoryName"> |
| | | <el-input v-model="queryParams.categoryName" placeholder="请è¾å
¥åç±»åç§°" clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="åç±»ç¼ç " prop="categoryCode"> |
| | | <el-input v-model="queryParams.categoryCode" placeholder="请è¾å
¥åç±»ç¼ç " clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">éç½®</el-button> |
| | |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button v-hasPermi="['workflow:category:add']" type="primary" plain icon="Plus" @click="handleAdd()">æ°å¢</el-button> |
| | | <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['workflow:category:add']">æ°å¢</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">å±å¼/æå </el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar> |
| | | <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | <el-table |
| | | ref="categoryTableRef" |
| | | v-loading="loading" |
| | | :data="categoryList" |
| | | row-key="id" |
| | | row-key="categoryId" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | > |
| | | <el-table-column label="åç±»åç§°" prop="categoryName" /> |
| | | <el-table-column label="åç±»ç¼ç " align="center" prop="categoryCode" /> |
| | | <el-table-column label="æåº" align="center" prop="sortNum" /> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <el-table-column label="åç±»åç§°" prop="categoryName" width="260"/> |
| | | <el-table-column label="æ¾ç¤ºé¡ºåº" align="center" prop="orderNum" width="200" /> |
| | | <el-table-column label="å建æ¶é´" align="center" prop="createTime" width="180" /> |
| | | <el-table-column label="æä½" fixed="right" align="center" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-tooltip content="ä¿®æ¹" placement="top"> |
| | | <el-button v-hasPermi="['workflow:category:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)" /> |
| | | <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['workflow:category:edit']" /> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ°å¢" placement="top"> |
| | | <el-button v-hasPermi="['workflow:category:add']" link type="primary" icon="Plus" @click="handleAdd(scope.row)" /> |
| | | <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['workflow:category:add']" /> |
| | | </el-tooltip> |
| | | <el-tooltip content="å é¤" placement="top"> |
| | | <el-button v-hasPermi="['workflow:category:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)" /> |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['workflow:category:remove']" /> |
| | | </el-tooltip> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-card> |
| | | <!-- æ·»å æä¿®æ¹æµç¨åç±»å¯¹è¯æ¡ --> |
| | | <el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" append-to-body> |
| | | <el-form ref="categoryFormRef" v-loading="loading" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="ç¶çº§åç±»" prop="parentId"> |
| | | <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> |
| | | <el-form ref="categoryFormRef" :model="form" :rules="rules" label-width="80px"> |
| | | <el-form-item label="ä¸çº§åç±»" prop="parentId"> |
| | | <el-tree-select |
| | | v-model="form.parentId" |
| | | :data="categoryOptions" |
| | | :props="{ value: 'id', label: 'categoryName', children: 'children' }" |
| | | value-key="id" |
| | | placeholder="è¯·éæ©ç¶çº§id" |
| | | :props="{ value: 'categoryId', label: 'categoryName', children: 'children' }" |
| | | value-key="categoryId" |
| | | placeholder="è¯·éæ©ä¸çº§åç±»" |
| | | check-strictly |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åç±»åç§°" prop="categoryName"> |
| | | <el-input v-model="form.categoryName" placeholder="请è¾å
¥åç±»åç§°" /> |
| | | </el-form-item> |
| | | <el-form-item label="åç±»ç¼ç " prop="categoryCode"> |
| | | <el-input v-model="form.categoryCode" placeholder="请è¾å
¥åç±»ç¼ç " /> |
| | | </el-form-item> |
| | | <el-form-item label="æåº" prop="sortNum"> |
| | | <el-input-number v-model="form.sortNum" placeholder="请è¾å
¥æåº" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åç±»åç§°" prop="categoryName"> |
| | | <el-input v-model="form.categoryName" placeholder="请è¾å
¥åç±»åç§°" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æåº" prop="orderNum"> |
| | | <el-input-number v-model="form.orderNum" controls-position="right" :min="0" /> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button :loading="buttonLoading" type="primary" @click="submitForm">ç¡® å®</el-button> |
| | | <el-button @click="cancel">å æ¶</el-button> |
| | |
| | | </template> |
| | | |
| | | <script setup name="Category" lang="ts"> |
| | | import { listCategory, getCategory, delCategory, addCategory, updateCategory } from '@/api/workflow/category'; |
| | | import { listCategory, getCategory, delCategory, addCategory, updateCategory } from "@/api/workflow/category"; |
| | | import { CategoryVO, CategoryQuery, CategoryForm } from '@/api/workflow/category/types'; |
| | | |
| | | type CategoryOption = { |
| | | id: number; |
| | | categoryId: number; |
| | | categoryName: string; |
| | | children?: CategoryOption[]; |
| | | }; |
| | | } |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance;; |
| | | |
| | | |
| | | const categoryList = ref<CategoryVO[]>([]); |
| | | const categoryOptions = ref<CategoryOption[]>([]); |
| | |
| | | |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const categoryFormRef = ref<ElFormInstance>(); |
| | | const categoryTableRef = ref<ElTableInstance>(); |
| | | const categoryTableRef = ref<ElTableInstance>() |
| | | |
| | | const dialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: '' |
| | | }); |
| | | |
| | | |
| | | const initFormData: CategoryForm = { |
| | | id: undefined, |
| | | categoryName: undefined, |
| | | categoryCode: undefined, |
| | | categoryId: undefined, |
| | | categoryName: "", |
| | | parentId: undefined, |
| | | sortNum: 0 |
| | | }; |
| | | orderNum: 0, |
| | | } |
| | | |
| | | const data = reactive<PageData<CategoryForm, CategoryQuery>>({ |
| | | form: { ...initFormData }, |
| | | form: {...initFormData}, |
| | | queryParams: { |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | categoryName: undefined, |
| | | categoryCode: undefined |
| | | }, |
| | | rules: { |
| | | id: [{ required: true, message: '主é®ä¸è½ä¸ºç©º', trigger: 'blur' }], |
| | | categoryName: [{ required: true, message: 'åç±»åç§°ä¸è½ä¸ºç©º', trigger: 'blur' }], |
| | | categoryCode: [{ required: true, message: 'åç±»ç¼ç ä¸è½ä¸ºç©º', trigger: 'blur' }], |
| | | parentId: [{ required: true, message: 'ç¶çº§idä¸è½ä¸ºç©º', trigger: 'blur' }] |
| | | categoryId: [ |
| | | { required: true, message: "æµç¨åç±»IDä¸è½ä¸ºç©º", trigger: "blur" } |
| | | ], |
| | | parentId: [{ required: true, message: "è¯·éæ©ä¸çº§åç±»", trigger: "change" }], |
| | | categoryName: [{ required: true, message: "请è¾å
¥åç±»åç§°", trigger: "blur" }] |
| | | } |
| | | }); |
| | | |
| | |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const res = await listCategory(queryParams.value); |
| | | const data = proxy?.handleTree<CategoryVO>(res.data, 'id', 'parentId'); |
| | | const data = proxy?.handleTree<CategoryVO>(res.data, "categoryId", "parentId"); |
| | | if (data) { |
| | | categoryList.value = data; |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | } |
| | | |
| | | /** æ¥è¯¢æµç¨åç±»ä¸ææ ç»æ */ |
| | | const getTreeselect = async () => { |
| | | const res = await listCategory(); |
| | | categoryOptions.value = []; |
| | | const data: CategoryOption = { id: 0, categoryName: '顶级èç¹', children: [] }; |
| | | data.children = proxy?.handleTree<CategoryOption>(res.data, 'id', 'parentId'); |
| | | categoryOptions.value.push(data); |
| | | // å¤çæ å½¢æ°æ® |
| | | const data = proxy?.handleTree<CategoryOption>(res.data, "categoryId", "parentId"); |
| | | if (data) { |
| | | categoryOptions.value = data; // å°å¤çåçæ å½¢æ°æ®èµå¼ |
| | | } |
| | | }; |
| | | |
| | | // åæ¶æé® |
| | | const cancel = () => { |
| | | reset(); |
| | | dialog.visible = false; |
| | | }; |
| | | } |
| | | |
| | | // 表åéç½® |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | form.value = {...initFormData} |
| | | categoryFormRef.value?.resetFields(); |
| | | }; |
| | | } |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | getList(); |
| | | }; |
| | | } |
| | | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value?.resetFields(); |
| | | handleQuery(); |
| | | }; |
| | | } |
| | | |
| | | /** æ°å¢æé®æä½ */ |
| | | const handleAdd = (row?: CategoryVO) => { |
| | | reset(); |
| | | getTreeselect(); |
| | | if (row?.categoryId) { |
| | | form.value.parentId = row.categoryId; |
| | | } else { |
| | | form.value.parentId = undefined; |
| | | } |
| | | dialog.visible = true; |
| | | dialog.title = 'æ·»å æµç¨åç±»'; |
| | | nextTick(() => { |
| | | reset(); |
| | | getTreeselect(); |
| | | if (row != null && row.id) { |
| | | form.value.parentId = row.id; |
| | | } else { |
| | | form.value.parentId = 0; |
| | | } |
| | | }); |
| | | }; |
| | | dialog.title = "æ·»å æµç¨åç±»"; |
| | | } |
| | | |
| | | /** å±å¼/æå æä½ */ |
| | | const handleToggleExpandAll = () => { |
| | | isExpandAll.value = !isExpandAll.value; |
| | | toggleExpandAll(categoryList.value, isExpandAll.value); |
| | | }; |
| | | toggleExpandAll(categoryList.value, isExpandAll.value) |
| | | } |
| | | |
| | | /** å±å¼/æå æä½ */ |
| | | const toggleExpandAll = (data: CategoryVO[], status: boolean) => { |
| | | data.forEach((item) => { |
| | | categoryTableRef.value?.toggleRowExpansion(item, status); |
| | | if (item.children && item.children.length > 0) toggleExpandAll(item.children, status); |
| | | }); |
| | | }; |
| | | categoryTableRef.value?.toggleRowExpansion(item, status) |
| | | if (item.children && item.children.length > 0) toggleExpandAll(item.children, status) |
| | | }) |
| | | } |
| | | |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = (row: CategoryVO) => { |
| | | loading.value = true; |
| | | const handleUpdate = async (row: CategoryVO) => { |
| | | reset(); |
| | | await getTreeselect(); |
| | | if (row != null) { |
| | | form.value.parentId = row.parentId; |
| | | } |
| | | const res = await getCategory(row.categoryId); |
| | | Object.assign(form.value, res.data); |
| | | dialog.visible = true; |
| | | dialog.title = 'ä¿®æ¹æµç¨åç±»'; |
| | | nextTick(async () => { |
| | | reset(); |
| | | await getTreeselect(); |
| | | if (row != null) { |
| | | form.value.parentId = row.id; |
| | | } |
| | | const res = await getCategory(row.id); |
| | | loading.value = false; |
| | | Object.assign(form.value, res.data); |
| | | }); |
| | | }; |
| | | dialog.title = "ä¿®æ¹æµç¨åç±»"; |
| | | } |
| | | |
| | | /** æäº¤æé® */ |
| | | const submitForm = () => { |
| | | categoryFormRef.value.validate(async (valid: boolean) => { |
| | | categoryFormRef.value?.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | buttonLoading.value = true; |
| | | if (form.value.id) { |
| | | await updateCategory(form.value).finally(() => (buttonLoading.value = false)); |
| | | if (form.value.categoryId) { |
| | | await updateCategory(form.value).finally(() => buttonLoading.value = false); |
| | | } else { |
| | | await addCategory(form.value).finally(() => (buttonLoading.value = false)); |
| | | await addCategory(form.value).finally(() => buttonLoading.value = false); |
| | | } |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | proxy?.$modal.msgSuccess("æä½æå"); |
| | | dialog.visible = false; |
| | | await getList(); |
| | | getList(); |
| | | } |
| | | }); |
| | | }; |
| | | } |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row: CategoryVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿µç¨åç±»ç¼å·ä¸º"' + row.id + '"çæ°æ®é¡¹ï¼'); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤"' + row.categoryName + '"çåç±»ï¼'); |
| | | loading.value = true; |
| | | await delCategory(row.id).finally(() => (loading.value = false)); |
| | | await delCategory(row.categoryId).finally(() => loading.value = false); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess('å 餿å'); |
| | | }; |
| | | proxy?.$modal.msgSuccess("å 餿å"); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" :data="leaveList" @selection-change="handleSelectionChange"> |
| | | <el-table v-loading="loading" border :data="leaveList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column v-if="false" label="主é®" align="center" prop="id" /> |
| | | <el-table-column label="请åç±»å" align="center"> |
| | |
| | | <dict-tag :options="wf_business_status" :value="scope.row.status"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <el-table-column label="æä½" align="center" width="162"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | v-if="scope.row.status === 'draft' || scope.row.status === 'cancel' || scope.row.status === 'back'" |
| | | v-hasPermi="['workflow:leave:edit']" |
| | | size="small" |
| | | link |
| | | type="primary" |
| | | icon="Edit" |
| | | @click="handleUpdate(scope.row)" |
| | | >ä¿®æ¹</el-button |
| | | > |
| | | <el-button |
| | | v-if="scope.row.status === 'draft' || scope.row.status === 'cancel' || scope.row.status === 'back'" |
| | | v-hasPermi="['workflow:leave:remove']" |
| | | size="small" |
| | | link |
| | | type="primary" |
| | | icon="Delete" |
| | | @click="handleDelete(scope.row)" |
| | | >å é¤</el-button |
| | | > |
| | | <el-button link type="primary" size="small" icon="View" @click="handleView(scope.row)">æ¥ç</el-button> |
| | | <el-button |
| | | v-if="scope.row.status === 'waiting'" |
| | | link |
| | | size="small" |
| | | type="primary" |
| | | icon="Notification" |
| | | @click="handleCancelProcessApply(scope.row.id)" |
| | | >æ¤é</el-button |
| | | > |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5" v-if="scope.row.status === 'draft' || scope.row.status === 'cancel' || scope.row.status === 'back'"> |
| | | <el-button v-hasPermi="['workflow:leave:edit']" size="small" type="primary" icon="Edit" @click="handleUpdate(scope.row)" |
| | | >ä¿®æ¹</el-button |
| | | > |
| | | </el-col> |
| | | <el-col :span="1.5" v-if="scope.row.status === 'draft' || scope.row.status === 'cancel' || scope.row.status === 'back'"> |
| | | <el-button v-hasPermi="['workflow:leave:remove']" size="small" type="primary" icon="Delete" @click="handleDelete(scope.row)" |
| | | >å é¤</el-button |
| | | > |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" size="small" icon="View" @click="handleView(scope.row)">æ¥ç</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5" v-if="scope.row.status === 'waiting'"> |
| | | <el-button size="small" type="primary" icon="Notification" @click="handleCancelProcessApply(scope.row.id)">æ¤é</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | |
| | | <script setup name="Leave" lang="ts"> |
| | | import { delLeave, listLeave } from '@/api/workflow/leave'; |
| | | import { cancelProcessApply } from '@/api/workflow/processInstance'; |
| | | import { cancelProcessApply } from '@/api/workflow/instance'; |
| | | import { LeaveForm, LeaveQuery, LeaveVO } from '@/api/workflow/leave/types'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | const handleCancelProcessApply = async (id: string) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æ¤éå½ååæ®ï¼'); |
| | | loading.value = true; |
| | | await cancelProcessApply(id).finally(() => (loading.value = false)); |
| | | let data = { |
| | | businessId: id, |
| | | message: 'ç³è¯·äººæ¤éæµç¨ï¼' |
| | | }; |
| | | await cancelProcessApply(data).finally(() => (loading.value = false)); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess('æ¤éæå'); |
| | | }; |
| | |
| | | <submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" /> |
| | | <!-- 审æ¹è®°å½ --> |
| | | <approvalRecord ref="approvalRecordRef" /> |
| | | <el-dialog v-model="dialogVisible.visible" :title="dialogVisible.title" :before-close="handleClose" width="500"> |
| | | <el-select v-model="flowCode" placeholder="Select" style="width: 240px"> |
| | | <el-option v-for="item in flowCodeOptions" :key="item.value" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="handleClose">åæ¶</el-button> |
| | | <el-button type="primary" @click="submitFlow()"> 确认 </el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | label: 'å©å' |
| | | } |
| | | ]; |
| | | const flowCodeOptions = [ |
| | | { |
| | | value: 'leave1', |
| | | label: '请åç³è¯·-æ®é' |
| | | }, |
| | | { |
| | | value: 'leave2', |
| | | label: '请åç³è¯·-æä»ç½å
³' |
| | | }, |
| | | { |
| | | value: 'leave3', |
| | | label: '请åç³è¯·-å¹¶è¡ç½å
³' |
| | | }, |
| | | { |
| | | value: 'leave4', |
| | | label: '请åç³è¯·-ä¼ç¾' |
| | | }, |
| | | { |
| | | value: 'leave5', |
| | | label: '请åç³è¯·-å¹¶è¡ä¼ç¾ç½å
³' |
| | | } |
| | | ]; |
| | | |
| | | const flowCode = ref<string>(''); |
| | | |
| | | const dialogVisible = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: 'æµç¨å®ä¹' |
| | | }); |
| | | //æäº¤ç»ä»¶ |
| | | const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>(); |
| | | //审æ¹è®°å½ç»ä»¶ |
| | |
| | | const leaveFormRef = ref<ElFormInstance>(); |
| | | |
| | | const submitFormData = ref<StartProcessBo>({ |
| | | businessKey: '', |
| | | tableName: '', |
| | | businessId: '', |
| | | flowCode: '', |
| | | variables: {} |
| | | }); |
| | | const taskVariables = ref<Record<string, any>>({}); |
| | |
| | | } |
| | | }); |
| | | |
| | | const handleClose = () => { |
| | | dialogVisible.visible = false; |
| | | flowCode.value = ''; |
| | | buttonLoading.value = false; |
| | | }; |
| | | const { form, rules } = toRefs(data); |
| | | |
| | | /** 表åéç½® */ |
| | |
| | | proxy.$tab.closePage(proxy.$route); |
| | | proxy.$router.go(-1); |
| | | } else { |
| | | if ((form.value.status === 'draft' && (flowCode.value === '' || flowCode.value === null)) || routeParams.value.type === 'add') { |
| | | flowCode.value = flowCodeOptions[0].value; |
| | | dialogVisible.visible = true; |
| | | return; |
| | | } |
| | | //说æå¯å¨è¿å
éæç©¿ä¸ªåæ° |
| | | if (flowCode.value === '' || flowCode.value === null) { |
| | | flowCode.value = 'xx'; |
| | | } |
| | | await handleStartWorkFlow(res.data); |
| | | } |
| | | } |
| | |
| | | } |
| | | }; |
| | | |
| | | const submitFlow = async () => { |
| | | handleStartWorkFlow(form.value); |
| | | dialogVisible.visible = false; |
| | | }; |
| | | //æäº¤ç³è¯· |
| | | const handleStartWorkFlow = async (data: LeaveVO) => { |
| | | try { |
| | | submitFormData.value.tableName = 'test_leave'; |
| | | submitFormData.value.businessKey = data.id; |
| | | submitFormData.value.flowCode = flowCode.value; |
| | | submitFormData.value.businessId = data.id; |
| | | //æµç¨åé |
| | | taskVariables.value = { |
| | | entity: data, |
| | | leaveDays: data.leaveDays, |
| | | userList: ['1', '3'], |
| | | userList2: ['1', '3'] |
| | | userList: ['1', '3', '4'] |
| | | }; |
| | | submitFormData.value.variables = taskVariables.value; |
| | | const resp = await startWorkFlow(submitFormData.value); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div ref="container" class="container"> |
| | | <iframe ref="iframe" :src="iframeUrl" frameborder="0" width="100%" height="100%"></iframe> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="WarmFlow"> |
| | | const { proxy } = getCurrentInstance(); |
| | | import { onMounted } from 'vue'; |
| | | // definitionId为éè¦æ¥è¯¢çæµç¨å®ä¹idï¼ |
| | | // disabled为æ¯å¦å¯ç¼è¾, ä¾å¦ï¼æ¥ççæ¶åä¸å¯ç¼è¾ï¼ä¸å¯ä¿å |
| | | const iframeUrl = ref(''); |
| | | const baseUrl = import.meta.env.VITE_APP_BASE_API; |
| | | import { getToken } from '@/utils/auth'; |
| | | const iframeLoaded = () => { |
| | | // iframeçå¬ç»ä»¶å
设计å¨ä¿åäºä»¶ |
| | | window.onmessage = (event) => { |
| | | switch (event.data.method) { |
| | | case 'close': |
| | | close(); |
| | | break; |
| | | } |
| | | }; |
| | | }; |
| | | const open = async (definitionId, disabled) => { |
| | | let url = baseUrl + `/warm-flow-ui/index.html?id=${definitionId}&disabled=${disabled}`; |
| | | iframeUrl.value = url + '&Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID; |
| | | }; |
| | | /** å
³éæé® */ |
| | | function close() { |
| | | const obj = { path: '/workflow/processDefinition' }; |
| | | proxy.$tab.closeOpenPage(obj); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | iframeLoaded(); |
| | | open(proxy.$route.query.definitionId, proxy.$route.query.disabled); |
| | | }); |
| | | /** |
| | | * 坹夿´é²åç»ä»¶æ¹æ³ |
| | | */ |
| | | defineExpose({ |
| | | open |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .container { |
| | | width: 100%; |
| | | height: calc(100vh - 84px); |
| | | } |
| | | </style> |
| | |
| | | class="mt-2" |
| | | node-key="id" |
| | | :data="categoryOptions" |
| | | :props="{ label: 'categoryName', children: 'children' }" |
| | | :props="{ label: 'label', children: 'children' }" |
| | | :expand-on-click-node="false" |
| | | :filter-node-method="filterNode" |
| | | highlight-current |
| | |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true" label-width="120px"> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" prop="name"> |
| | | <el-input v-model="queryParams.name" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" clearable @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" prop="flowName"> |
| | | <el-input v-model="queryParams.flowName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹KEY" prop="key"> |
| | | <el-input v-model="queryParams.key" placeholder="请è¾å
¥æµç¨å®ä¹KEY" clearable @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹KEY" prop="flowCode"> |
| | | <el-input v-model="queryParams.flowCode" placeholder="请è¾å
¥æµç¨å®ä¹KEY" clearable @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" icon="Plus" @click="handleAdd()">æ·»å </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="success" icon="Edit" :disabled="single" @click="handleUpdate()">ä¿®æ¹</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" icon="Delete" :disabled="multiple" @click="handleDelete()">å é¤</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" icon="UploadFilled" @click="uploadDialog.visible = true">é¨ç½²æµç¨æä»¶</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="warning" icon="Download" :disabled="single" @click="handleExportDef">导åº</el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" border :data="processDefinitionList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column align="center" prop="name" label="æµç¨å®ä¹åç§°" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column align="center" prop="key" label="æ è¯KEY" width="80"></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="80"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="resourceName" label="æµç¨XML" width="100" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <el-link type="primary" @click="clickPreview(scope.row.id, 'xml')">{{ scope.row.resourceName }}</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="diagramResourceName" label="æµç¨å¾ç" width="100" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <el-link type="primary" @click="clickPreview(scope.row.id, 'bpmn')">{{ scope.row.diagramResourceName }}</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="suspensionState" label="ç¶æ" width="80"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.suspensionState == 1" type="success">æ¿æ´»</el-tag> |
| | | <el-tag v-else type="danger">æèµ·</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="deploymentTime" label="é¨ç½²æ¶é´" width="120" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column align="center" label="表å/表åKEY" width="120" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <span v-if="scope.row.wfDefinitionConfigVo"> |
| | | {{ scope.row.wfDefinitionConfigVo.tableName }} |
| | | </span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" label="æä½" align="center" width="220" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | :icon="scope.row.suspensionState === 1 ? 'Lock' : 'Unlock'" |
| | | @click="handleProcessDefState(scope.row)" |
| | | > |
| | | {{ scope.row.suspensionState === 1 ? 'æèµ·æµç¨' : 'æ¿æ´»æµç¨' }} |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Document" @click="getProcessDefinitionHitoryList(scope.row.id, scope.row.key)"> |
| | | åå²çæ¬ |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Delete" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Sort" @click="handleConvertToModel(scope.row)"> è½¬æ¢æ¨¡å </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Tickets" @click="handleDefinitionConfigOpen(scope.row)">ç»å®ä¸å¡</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | :total="total" |
| | | @pagination="getList" |
| | | /> |
| | | <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick"> |
| | | <el-tab-pane label="å·²åå¸" name="0"></el-tab-pane> |
| | | <el-tab-pane label="æªåå¸" name="1"></el-tab-pane> |
| | | <el-table v-loading="loading" border :data="processDefinitionList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" prop="id" label="主é®" v-if="false"></el-table-column> |
| | | <el-table-column align="center" prop="flowName" label="æµç¨å®ä¹åç§°" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column align="center" prop="flowCode" label="æ è¯KEY" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="80"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="activityStatus" label="æ¿æ´»ç¶æ" width="130"> |
| | | <template #default="scope"> |
| | | <el-switch |
| | | v-model="scope.row.activityStatus" |
| | | :active-value="1" |
| | | :inactive-value="0" |
| | | @change="(status) => handleProcessDefState(scope.row, status)" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="isPublish" label="åå¸ç¶æ" width="100"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.isPublish == 0" type="danger">æªåå¸</el-tag> |
| | | <el-tag v-else-if="scope.row.isPublish == 1" type="success">å·²åå¸</el-tag> |
| | | <el-tag v-else type="danger">失æ</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column fixed="right" label="æä½" align="center" width="170" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Delete" @click="handleDelete(scope.row)">å 餿µç¨</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="CopyDocument" @click="handleCopyDef(scope.row)">å¤å¶æµç¨</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" v-if="scope.row.isPublish === 0" icon="Pointer" size="small" @click="design(scope.row)" |
| | | >æµç¨è®¾è®¡</el-button |
| | | > |
| | | <el-button link type="primary" v-else icon="View" size="small" @click="designView(scope.row)">æ¥çæµç¨</el-button> |
| | | </el-col> |
| | | <el-col v-if="scope.row.isPublish !== 1" :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="CircleCheck" @click="handlePublish(scope.row)">å叿µç¨</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | :total="total" |
| | | @pagination="handleQuery" |
| | | /> |
| | | </el-tabs> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- é¢è§å¾çæxml --> |
| | | <process-preview ref="previewRef" /> |
| | | |
| | | <!-- é¨ç½²æä»¶ --> |
| | | <el-dialog v-if="uploadDialog.visible" v-model="uploadDialog.visible" :title="uploadDialog.title" width="30%"> |
| | |
| | | <el-tree-select |
| | | v-model="selectCategory" |
| | | :data="categoryOptions" |
| | | :props="{ value: 'categoryCode', label: 'categoryName', children: 'children' }" |
| | | :props="{ value: 'id', label: 'label', children: 'children' }" |
| | | filterable |
| | | value-key="categoryCode" |
| | | value-key="id" |
| | | :render-after-expand="false" |
| | | check-strictly |
| | | style="width: 240px" |
| | |
| | | multiple |
| | | accept="application/zip,application/xml,.bpmn" |
| | | :before-upload="handlerBeforeUpload" |
| | | :http-request="handerDeployProcessFile" |
| | | :http-request="handlerImportDefinition" |
| | | > |
| | | <el-icon class="UploadFilled"><upload-filled /></el-icon> |
| | | <div class="el-upload__text"><em>ç¹å»ä¸ä¼ ï¼éæ©BPMNæµç¨æä»¶</em></div> |
| | |
| | | </div> |
| | | </el-dialog> |
| | | |
| | | <!-- åå²çæ¬ --> |
| | | <el-dialog v-if="processDefinitionDialog.visible" v-model="processDefinitionDialog.visible" :title="processDefinitionDialog.title" width="70%"> |
| | | <el-table v-loading="loading" :data="processDefinitionHistoryList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column align="center" prop="name" label="æµç¨å®ä¹åç§°" :show-overflow-tooltip="true" min-width="80"></el-table-column> |
| | | <el-table-column align="center" prop="key" label="æ è¯KEY"></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="resourceName" label="æµç¨XML" min-width="80" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <el-link type="primary" @click="clickPreviewXML(scope.row.id)">{{ scope.row.resourceName }}</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="diagramResourceName" label="æµç¨å¾ç" min-width="80" :show-overflow-tooltip="true"> |
| | | <template #default="scope"> |
| | | <el-link type="primary" @click="clickPreviewImg(scope.row.id)">{{ scope.row.diagramResourceName }}</el-link> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="suspensionState" label="ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.suspensionState == 1" type="success">æ¿æ´»</el-tag> |
| | | <el-tag v-else type="danger">æèµ·</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="deploymentTime" label="é¨ç½²æ¶é´" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column fixed="right" label="æä½" align="center" width="200" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button |
| | | link |
| | | type="primary" |
| | | size="small" |
| | | :icon="scope.row.suspensionState === 1 ? 'Lock' : 'Unlock'" |
| | | @click="handleProcessDefState(scope.row)" |
| | | > |
| | | {{ scope.row.suspensionState === 1 ? 'æèµ·æµç¨' : 'æ¿æ´»æµç¨' }} |
| | | </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="text" size="small" icon="Tickets" @click="handleDefinitionConfigOpen(scope.row)">ç»å®ä¸å¡</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" icon="Sort" size="small" @click="handleConvertToModel(scope.row)"> è½¬æ¢æ¨¡å </el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" icon="Delete" size="small" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | |
| | | <!-- 表åé
ç½® --> |
| | | <el-dialog |
| | | v-model="definitionConfigDialog.visible" |
| | | :title="definitionConfigDialog.title" |
| | | width="650px" |
| | | append-to-body |
| | | :close-on-click-modal="false" |
| | | > |
| | | <el-form :model="definitionConfigForm" label-width="auto"> |
| | | <el-form-item label="æµç¨KEY"> |
| | | <el-input v-model="definitionConfigForm.processKey" disabled /> |
| | | </el-form-item> |
| | | <el-form-item label="表å" prop="formId"> |
| | | <el-input v-model="definitionConfigForm.tableName" placeholder="示ä¾:test_leave" /> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨"> |
| | | <el-input v-model="definitionConfigForm.remark" type="textarea" resize="none" /> |
| | | </el-form-item> |
| | | </el-form> |
| | | |
| | | <!-- æ°å¢/ç¼è¾æµç¨å®ä¹ --> |
| | | <el-dialog v-model="modelDialog.visible" :title="modelDialog.title" width="650px" append-to-body :close-on-click-modal="false"> |
| | | <template #footer> |
| | | <el-form ref="defFormRef" :model="form" :rules="rules" label-width="110px"> |
| | | <el-form-item label="æµç¨ç±»å«" prop="category"> |
| | | <el-tree-select |
| | | v-model="form.category" |
| | | :data="categoryOptions" |
| | | :props="{ value: 'id', label: 'label', children: 'children' }" |
| | | filterable |
| | | value-key="id" |
| | | :render-after-expand="false" |
| | | check-strictly |
| | | style="width: 100%" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨ç¼ç " prop="flowCode"> |
| | | <el-input v-model="form.flowCode" placeholder="请è¾å
¥æµç¨ç¼ç " maxlength="40" show-word-limit /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨åç§°" prop="flowName"> |
| | | <el-input v-model="form.flowName" placeholder="请è¾å
¥æµç¨åç§°" maxlength="100" show-word-limit /> |
| | | </el-form-item> |
| | | <el-form-item label="表åè·¯å¾" prop="flowName"> |
| | | <el-input v-model="form.formPath" placeholder="请è¾å
¥è¡¨åè·¯å¾" maxlength="100" show-word-limit /> |
| | | </el-form-item> |
| | | </el-form> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="definitionConfigDialog.visible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="handlerSaveForm">ä¿å</el-button> |
| | | <el-button @click="modelDialog.visible = false">åæ¶</el-button> |
| | | <el-button type="primary" @click="handleSubmit">ä¿å</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup name="processDefinition"> |
| | | import { |
| | | listProcessDefinition, |
| | | definitionImage, |
| | | definitionXml, |
| | | deleteProcessDefinition, |
| | | updateDefinitionState, |
| | | convertToModel, |
| | | deployProcessFile, |
| | | getListByKey |
| | | } from '@/api/workflow/processDefinition'; |
| | | import { getByTableNameNotDefId, getByDefId, saveOrUpdate } from '@/api/workflow/definitionConfig'; |
| | | import ProcessPreview from './components/processPreview.vue'; |
| | | import { listCategory } from '@/api/workflow/category'; |
| | | import { CategoryVO } from '@/api/workflow/category/types'; |
| | | import { ProcessDefinitionQuery, ProcessDefinitionVO } from '@/api/workflow/processDefinition/types'; |
| | | import { DefinitionConfigForm } from '@/api/workflow/definitionConfig/types'; |
| | | import { UploadRequestOptions, ElMessage, ElMessageBox } from 'element-plus'; |
| | | import { listDefinition, deleteDefinition, active, importDef, unPublishList, publish, add, edit, getInfo, copy } from '@/api/workflow/definition'; |
| | | import { categoryTree } from '@/api/workflow/category'; |
| | | import { CategoryTreeVO } from '@/api/workflow/category/types'; |
| | | import { FlowDefinitionQuery, FlowDefinitionVo, FlowDefinitionForm } from '@/api/workflow/definition/types'; |
| | | import { UploadRequestOptions, TabsPaneContext } from 'element-plus'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | |
| | | const previewRef = ref<InstanceType<typeof ProcessPreview>>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const categoryTreeRef = ref<ElTreeInstance>(); |
| | | const definitionConfigForm = ref<DefinitionConfigForm>({}); |
| | | |
| | | type CategoryOption = { |
| | | categoryCode: string; |
| | | categoryName: string; |
| | | children?: CategoryOption[]; |
| | | }; |
| | | |
| | | const loading = ref(true); |
| | | const ids = ref<Array<any>>([]); |
| | | const deploymentIds = ref<Array<any>>([]); |
| | | const keys = ref<Array<any>>([]); |
| | | const flowCodeList = ref<Array<any>>([]); |
| | | const single = ref(true); |
| | | const multiple = ref(true); |
| | | const showSearch = ref(true); |
| | | const total = ref(0); |
| | | const uploadDialogLoading = ref(false); |
| | | const processDefinitionList = ref<ProcessDefinitionVO[]>([]); |
| | | const processDefinitionHistoryList = ref<ProcessDefinitionVO[]>([]); |
| | | const categoryOptions = ref<CategoryOption[]>([]); |
| | | const processDefinitionList = ref<FlowDefinitionVo[]>([]); |
| | | const categoryOptions = ref<CategoryTreeVO[]>([]); |
| | | const categoryName = ref(''); |
| | | /** é¨ç½²æä»¶åç±»éæ© */ |
| | | const selectCategory = ref(); |
| | | |
| | | const defFormRef = ref<ElFormInstance>(); |
| | | const activeName = ref('0'); |
| | | const uploadDialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: 'é¨ç½²æµç¨æä»¶' |
| | |
| | | title: 'åå²çæ¬' |
| | | }); |
| | | |
| | | const definitionConfigDialog = reactive<DialogOption>({ |
| | | const modelDialog = reactive<DialogOption>({ |
| | | visible: false, |
| | | title: 'æµç¨å®ä¹é
ç½®' |
| | | title: '' |
| | | }); |
| | | |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref<ProcessDefinitionQuery>({ |
| | | const queryParams = ref<FlowDefinitionQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | key: undefined, |
| | | categoryCode: undefined |
| | | flowName: undefined, |
| | | flowCode: undefined, |
| | | category: undefined |
| | | }); |
| | | |
| | | const rules = { |
| | | category: [{ required: true, message: 'åç±»åç§°ä¸è½ä¸ºç©º', trigger: 'blur' }], |
| | | flowName: [{ required: true, message: 'æµç¨å®ä¹åç§°ä¸è½ä¸ºç©º', trigger: 'blur' }], |
| | | flowCode: [{ required: true, message: 'æµç¨å®ä¹ç¼ç ä¸è½ä¸ºç©º', trigger: 'blur' }] |
| | | }; |
| | | const initFormData: FlowDefinitionForm = { |
| | | id: '', |
| | | flowName: '', |
| | | flowCode: '', |
| | | category: '', |
| | | formPath: '' |
| | | }; |
| | | //æµç¨å®ä¹åæ° |
| | | const form = ref<FlowDefinitionForm>({ |
| | | id: '', |
| | | flowName: '', |
| | | flowCode: '', |
| | | category: '', |
| | | formPath: '' |
| | | }); |
| | | onMounted(() => { |
| | | getList(); |
| | | handleQuery(); |
| | | getTreeselect(); |
| | | }); |
| | | |
| | | /** èç¹åå»äºä»¶ */ |
| | | const handleNodeClick = (data: CategoryVO) => { |
| | | queryParams.value.categoryCode = data.categoryCode; |
| | | if (data.categoryCode === 'ALL') { |
| | | queryParams.value.categoryCode = ''; |
| | | const handleNodeClick = (data: CategoryTreeVO) => { |
| | | queryParams.value.category = data.id; |
| | | if (data.id === '0') { |
| | | queryParams.value.category = ''; |
| | | } |
| | | handleQuery(); |
| | | }; |
| | |
| | | |
| | | /** æ¥è¯¢æµç¨åç±»ä¸ææ ç»æ */ |
| | | const getTreeselect = async () => { |
| | | const res = await listCategory(); |
| | | categoryOptions.value = []; |
| | | const data: CategoryOption = { categoryCode: 'ALL', categoryName: '顶级èç¹', children: [] }; |
| | | data.children = proxy?.handleTree<CategoryOption>(res.data, 'id', 'parentId'); |
| | | categoryOptions.value.push(data); |
| | | const res = await categoryTree(); |
| | | categoryOptions.value = res.data; |
| | | }; |
| | | |
| | | const handleClick = (tab: TabsPaneContext, event: Event) => { |
| | | // v-modelå¤çæå»¶è¿ éè¦æå¨å¤ç |
| | | activeName.value = tab.index; |
| | | handleQuery(); |
| | | }; |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | queryParams.value.pageNum = 1; |
| | | getList(); |
| | | if (activeName.value === '0') { |
| | | getList(); |
| | | } else { |
| | | getUnPublishList(); |
| | | } |
| | | }; |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.categoryCode = ''; |
| | | queryParams.value.category = ''; |
| | | queryParams.value.pageNum = 1; |
| | | queryParams.value.pageSize = 10; |
| | | handleQuery(); |
| | |
| | | // å¤éæ¡é䏿°æ® |
| | | const handleSelectionChange = (selection: any) => { |
| | | ids.value = selection.map((item: any) => item.id); |
| | | deploymentIds.value = selection.map((item: any) => item.deploymentId); |
| | | keys.value = selection.map((item: any) => item.key); |
| | | flowCodeList.value = selection.map((item: any) => item.flowCode); |
| | | single.value = selection.length !== 1; |
| | | multiple.value = !selection.length; |
| | | }; |
| | | //å页 |
| | | const getList = async () => { |
| | | loading.value = true; |
| | | const resp = await listProcessDefinition(queryParams.value); |
| | | const resp = await listDefinition(queryParams.value); |
| | | processDefinitionList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | | }; |
| | | //è·åå岿µç¨å®ä¹ |
| | | const getProcessDefinitionHitoryList = async (id: string, key: string) => { |
| | | processDefinitionDialog.visible = true; |
| | | //æ¥è¯¢æªåå¸çæµç¨å®ä¹å表 |
| | | const getUnPublishList = async () => { |
| | | loading.value = true; |
| | | const resp = await getListByKey(key); |
| | | if (resp.data && resp.data.length > 0) { |
| | | processDefinitionHistoryList.value = resp.data.filter((item: any) => item.id !== id); |
| | | } |
| | | const resp = await unPublishList(queryParams.value); |
| | | processDefinitionList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | | }; |
| | | |
| | | type PreviewType = 'xml' | 'bpmn'; |
| | | //é¢è§ å
Œ
±æ¹æ³ |
| | | const clickPreview = async (id: string, type: PreviewType) => { |
| | | loading.value = true; |
| | | const resp = await definitionXml(id); |
| | | if (previewRef.value) { |
| | | const xmlStr = resp.data.xmlStr; |
| | | loading.value = false; |
| | | previewRef.value.openDialog(xmlStr, type); |
| | | } |
| | | }; |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row?: ProcessDefinitionVO) => { |
| | | const handleDelete = async (row?: FlowDefinitionVo) => { |
| | | const id = row?.id || ids.value; |
| | | const deployIds = row?.deploymentId || deploymentIds.value; |
| | | const defKeys = row?.key || keys.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿µç¨å®ä¹KEY为ã' + defKeys + 'ãçæ°æ®é¡¹ï¼'); |
| | | const defList = processDefinitionList.value.filter((x) => id.indexOf(x.id) != -1).map((x) => x.flowCode); |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å 餿µç¨å®ä¹KEY为ã' + defList + 'ãçæ°æ®é¡¹ï¼'); |
| | | loading.value = true; |
| | | await deleteProcessDefinition(deployIds, id).finally(() => (loading.value = false)); |
| | | await getList(); |
| | | await deleteDefinition(id).finally(() => (loading.value = false)); |
| | | await handleQuery(); |
| | | proxy?.$modal.msgSuccess('å 餿å'); |
| | | }; |
| | | /** æèµ·/æ¿æ´» */ |
| | | const handleProcessDefState = async (row: ProcessDefinitionVO) => { |
| | | let msg: string; |
| | | if (row.suspensionState === 1) { |
| | | msg = `æååï¼æ¤æµç¨ä¸çææä»»å¡é½ä¸å
许å¾åæµè½¬ï¼æ¨ç¡®å®æèµ·ã${row.name || row.key}ãåï¼`; |
| | | } else { |
| | | msg = `å¯å¨åï¼æ¤æµç¨ä¸çææä»»å¡é½å
许å¾åæµè½¬ï¼æ¨ç¡®å®æ¿æ´»ã${row.name || row.key}ãåï¼`; |
| | | } |
| | | await proxy?.$modal.confirm(msg); |
| | | |
| | | /** å叿µç¨å®ä¹ */ |
| | | const handlePublish = async (row?: FlowDefinitionVo) => { |
| | | await proxy?.$modal.confirm( |
| | | 'æ¯å¦ç¡®è®¤å叿µç¨å®ä¹KEY为ã' + row.flowCode + 'ãçæ¬ä¸ºã' + row.version + 'ãçæ°æ®é¡¹ï¼ï¼åå¸åä¼å°å·²å叿µç¨å®ä¹æ¹ä¸ºå¤±æï¼' |
| | | ); |
| | | loading.value = true; |
| | | await updateDefinitionState(row.id).finally(() => (loading.value = false)); |
| | | await getList(); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | await publish(row.id).finally(() => (loading.value = false)); |
| | | processDefinitionDialog.visible = false; |
| | | await handleQuery(); |
| | | proxy?.$modal.msgSuccess('å叿å'); |
| | | }; |
| | | /** æµç¨å®ä¹è½¬æ¢ä¸ºæ¨¡å */ |
| | | const handleConvertToModel = async (row: ProcessDefinitionVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤è½¬æ¢æµç¨å®ä¹key为ã' + row.key + 'ãçæ°æ®é¡¹ï¼'); |
| | | await convertToModel(row.id).finally(() => (loading.value = false)); |
| | | getList(); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | /** æèµ·/æ¿æ´» */ |
| | | const handleProcessDefState = async (row: FlowDefinitionVo, status: number | string | boolean) => { |
| | | let msg: string; |
| | | if (status === 0) { |
| | | msg = `æååï¼æ¤æµç¨ä¸çææä»»å¡é½ä¸å
许å¾åæµè½¬ï¼æ¨ç¡®å®æèµ·ã${row.flowName || row.flowCode}ãåï¼`; |
| | | } else { |
| | | msg = `å¯å¨åï¼æ¤æµç¨ä¸çææä»»å¡é½å
许å¾åæµè½¬ï¼æ¨ç¡®å®æ¿æ´»ã${row.flowName || row.flowCode}ãåï¼`; |
| | | } |
| | | try { |
| | | loading.value = true; |
| | | await proxy?.$modal.confirm(msg); |
| | | await active(row.id, !!status); |
| | | await handleQuery(); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | } catch (error) { |
| | | row.activityStatus = status === 0 ? 1 : 0; |
| | | console.error(error); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }; |
| | | |
| | | //ä¸ä¼ æä»¶åçé©å |
| | |
| | | } |
| | | }; |
| | | //é¨ç½²æä»¶ |
| | | const handerDeployProcessFile = (data: UploadRequestOptions): XMLHttpRequest => { |
| | | const handlerImportDefinition = (data: UploadRequestOptions): XMLHttpRequest => { |
| | | let formData = new FormData(); |
| | | uploadDialogLoading.value = true; |
| | | formData.append('file', data.file); |
| | | formData.append('categoryCode', selectCategory.value); |
| | | deployProcessFile(formData) |
| | | formData.append('category', selectCategory.value); |
| | | importDef(formData) |
| | | .then(() => { |
| | | uploadDialog.visible = false; |
| | | proxy?.$modal.msgSuccess('é¨ç½²æå'); |
| | |
| | | }); |
| | | return; |
| | | }; |
| | | //æå¼æµç¨å®ä¹é
ç½® |
| | | const handleDefinitionConfigOpen = async (row: ProcessDefinitionVO) => { |
| | | definitionConfigDialog.visible = true; |
| | | definitionConfigForm.value.processKey = row.key; |
| | | definitionConfigForm.value.definitionId = row.id; |
| | | definitionConfigForm.value.version = row.version; |
| | | const resp = await getByDefId(row.id); |
| | | if (resp.data) { |
| | | definitionConfigForm.value = resp.data; |
| | | } else { |
| | | definitionConfigForm.value.tableName = undefined; |
| | | definitionConfigForm.value.remark = undefined; |
| | | } |
| | | }; |
| | | //ä¿å表å |
| | | const handlerSaveForm = async () => { |
| | | getByTableNameNotDefId(definitionConfigForm.value.tableName, definitionConfigForm.value.definitionId).then((res) => { |
| | | if (res.data && res.data.length > 0) { |
| | | ElMessageBox.confirm('表å已被ã' + res.data[0].processKey + 'ãçæ¬v' + res.data[0].version + '.0ç»å®ç¡®è®¤åå°ä¼å é¤ç»å®çæµç¨KEY!', 'æç¤º', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | saveOrUpdate(definitionConfigForm.value).then((resp) => { |
| | | if (resp.code === 200) { |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | definitionConfigDialog.visible = false; |
| | | getList(); |
| | | } |
| | | }); |
| | | }); |
| | | } else { |
| | | saveOrUpdate(definitionConfigForm.value).then((resp) => { |
| | | if (resp.code === 200) { |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | definitionConfigDialog.visible = false; |
| | | getList(); |
| | | } |
| | | }); |
| | | /** |
| | | * 设计æµç¨ |
| | | * @param row |
| | | */ |
| | | const design = async (row: FlowDefinitionVo) => { |
| | | proxy.$router.push({ |
| | | path: `/workflow/design/index`, |
| | | query: { |
| | | definitionId: row.id, |
| | | disabled: false |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * æ¥çæµç¨ |
| | | * @param row |
| | | */ |
| | | const designView = async (row: FlowDefinitionVo) => { |
| | | proxy.$router.push({ |
| | | path: `/workflow/design/index`, |
| | | query: { |
| | | definitionId: row.id, |
| | | disabled: true |
| | | } |
| | | }); |
| | | }; |
| | | /** 表åéç½® */ |
| | | const reset = () => { |
| | | form.value = { ...initFormData }; |
| | | defFormRef.value?.resetFields(); |
| | | }; |
| | | /** |
| | | * æ°å¢ |
| | | */ |
| | | const handleAdd = async () => { |
| | | reset(); |
| | | modelDialog.visible = true; |
| | | modelDialog.title = 'æ°å¢æµç¨'; |
| | | }; |
| | | /** ä¿®æ¹æé®æä½ */ |
| | | const handleUpdate = async (row?: FlowDefinitionVo) => { |
| | | reset(); |
| | | const id = row?.id || ids.value[0]; |
| | | const res = await getInfo(id); |
| | | Object.assign(form.value, res.data); |
| | | modelDialog.visible = true; |
| | | modelDialog.title = 'ä¿®æ¹æµç¨'; |
| | | }; |
| | | |
| | | const handleSubmit = async () => { |
| | | defFormRef.value.validate(async (valid: boolean) => { |
| | | if (valid) { |
| | | loading.value = true; |
| | | if (form.value.id) { |
| | | await edit(form.value).finally(() => loading.value = false); |
| | | } else { |
| | | await add(form.value).finally(() => loading.value = false); |
| | | } |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | modelDialog.visible = false; |
| | | handleQuery(); |
| | | } |
| | | }); |
| | | }; |
| | | //å¤å¶ |
| | | const handleCopyDef = async (row: FlowDefinitionVo) => { |
| | | ElMessageBox.confirm(`æ¯å¦ç¡®è®¤å¤å¶ã${row.flowCode}ãçæ¬ä¸ºã${row.version}ãçæµç¨å®ä¹ï¼`, 'æç¤º', { |
| | | confirmButtonText: '确认', |
| | | cancelButtonText: 'åæ¶', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | loading.value = true; |
| | | copy(row.id).then((resp) => { |
| | | if (resp.code === 200) { |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | activeName.value = "1" |
| | | handleQuery(); |
| | | } |
| | | }).finally(() => loading.value = false); |
| | | }); |
| | | }; |
| | | |
| | | /** å¯¼åºæé®æä½ */ |
| | | const handleExportDef = () => { |
| | | proxy?.download(`/workflow/definition/exportDef/${ids.value[0]}`, {}, `${flowCodeList.value[0]}.xml`); |
| | | }; |
| | | </script> |
| | |
| | | class="mt-2" |
| | | node-key="id" |
| | | :data="categoryOptions" |
| | | :props="{ label: 'categoryName', children: 'children' }" |
| | | :props="{ label: 'label', children: 'children' }" |
| | | :expand-on-click-node="false" |
| | | :filter-node-method="filterNode" |
| | | highlight-current |
| | |
| | | </el-card> |
| | | </el-col> |
| | | <el-col :lg="20" :xs="24"> |
| | | <div class="mb-[10px]"> |
| | | <el-card shadow="hover" class="text-center"> |
| | | <el-radio-group v-model="tab" @change="changeTab(tab)"> |
| | | <el-radio-button value="running">è¿è¡ä¸</el-radio-button> |
| | | <el-radio-button value="finish">已宿</el-radio-button> |
| | | </el-radio-group> |
| | | </el-card> |
| | | </div> |
| | | <!-- <div class="mb-[10px]"> |
| | | <el-card shadow="hover" class="text-center"> |
| | | <el-radio-group v-model="tab" @change="changeTab(tab)"> |
| | | <el-radio-button value="running">è¿è¡ä¸</el-radio-button> |
| | | <el-radio-button value="finish">已宿</el-radio-button> |
| | | </el-radio-group> |
| | | </el-card> |
| | | </div>--> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true" label-width="120px"> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" prop="name"> |
| | | <el-input v-model="queryParams.name" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true"> |
| | | <el-form-item> |
| | | <el-badge :value="userSelectCount" :max="10" class="item"> |
| | | <el-button type="primary" @click="openUserSelect">éæ©ç³è¯·äºº</el-button> |
| | | </el-badge> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹KEY" prop="key"> |
| | | <el-input v-model="queryParams.key" placeholder="请è¾å
¥æµç¨å®ä¹KEY" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="ä»»å¡åç§°" prop="nodeName"> |
| | | <el-input v-model="queryParams.nodeName" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="flowName"> |
| | | <el-input v-model="queryParams.flowName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹ç¼ç " label-width="100" prop="flowCode"> |
| | | <el-input v-model="queryParams.flowCode" placeholder="请è¾å
¥æµç¨å®ä¹ç¼ç " @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | |
| | | <right-toolbar v-model:show-search="showSearch" @query-table="handleQuery"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" border :data="processInstanceList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" align="center" label="æµç¨å®ä¹åç§°"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.processDefinitionName }}v{{ scope.row.processDefinitionVersion }}.0</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionKey" label="æµç¨å®ä¹KEY"></el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionVersion" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.processDefinitionVersion }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column v-if="tab === 'running'" align="center" prop="isSuspended" label="ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="!scope.row.isSuspended" type="success">æ¿æ´»</el-tag> |
| | | <el-tag v-else type="danger">æèµ·</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.businessStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="startTime" label="å¯å¨æ¶é´" width="160"></el-table-column> |
| | | <el-table-column v-if="tab === 'finish'" align="center" prop="endTime" label="ç»ææ¶é´" width="160"></el-table-column> |
| | | <el-table-column label="æä½" align="center" :width="130"> |
| | | <template #default="scope"> |
| | | <el-row v-if="tab === 'running'" :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-popover :ref="`popoverRef${scope.$index}`" trigger="click" placement="left" :width="300"> |
| | | <el-input v-model="deleteReason" resize="none" :rows="3" type="textarea" placeholder="请è¾å
¥ä½åºåå " /> |
| | | <div style="text-align: right; margin: 5px 0px 0px 0px"> |
| | | <el-button size="small" text @click="cancelPopover(scope.$index)">åæ¶</el-button> |
| | | <el-button size="small" type="primary" @click="handleInvalid(scope.row)">确认</el-button> |
| | | </div> |
| | | <template #reference> |
| | | <el-button link type="primary" size="small" icon="CircleClose">ä½åº</el-button> |
| | | </template> |
| | | </el-popover> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Delete" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="View" @click="handleView(scope.row)">æ¥ç</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | :total="total" |
| | | @pagination="handleQuery" |
| | | /> |
| | | <el-tabs v-model="tab" @tab-click="changeTab"> |
| | | <el-tab-pane name="running" label="è¿è¡ä¸"></el-tab-pane> |
| | | <el-tab-pane name="finish" label="已宿"></el-tab-pane> |
| | | <el-table v-loading="loading" border :data="processInstanceList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" align="center" label="æµç¨å®ä¹åç§°"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.flowName }}v{{ scope.row.version }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="nodeName" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="flowCode" label="æµç¨å®ä¹ç¼ç "></el-table-column> |
| | | <el-table-column align="center" prop="createByName" label="ç³è¯·äºº"></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column v-if="tab === 'running'" align="center" prop="isSuspended" label="ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="!scope.row.isSuspended" type="success">æ¿æ´»</el-tag> |
| | | <el-tag v-else type="danger">æèµ·</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.flowStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="createTime" label="å¯å¨æ¶é´" width="160"></el-table-column> |
| | | <el-table-column v-if="tab === 'finish'" align="center" prop="updateTime" label="ç»ææ¶é´" width="160"></el-table-column> |
| | | <el-table-column label="æä½" align="center" :width="162"> |
| | | <template #default="scope"> |
| | | <el-row v-if="tab === 'running'" :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-popover :ref="`popoverRef${scope.$index}`" trigger="click" placement="left" :width="300"> |
| | | <el-input v-model="deleteReason" resize="none" :rows="3" type="textarea" placeholder="请è¾å
¥ä½åºåå " /> |
| | | <div style="text-align: right; margin: 5px 0px 0px 0px"> |
| | | <el-button size="small" text @click="cancelPopover(scope.$index)">åæ¶</el-button> |
| | | <el-button size="small" type="primary" @click="handleInvalid(scope.row)">确认</el-button> |
| | | </div> |
| | | <template #reference> |
| | | <el-button type="danger" size="small" icon="CircleClose">ä½åº</el-button> |
| | | </template> |
| | | </el-popover> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="danger" size="small" icon="Delete" @click="handleDelete(scope.row)">å é¤ </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" size="small" icon="View" @click="handleView(scope.row)">æ¥ç</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" size="small" icon="Document" @click="handleInstanceVariable(scope.row)"> åé </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | :total="total" |
| | | @pagination="handleQuery" |
| | | /> |
| | | </el-tabs> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <el-table v-loading="loading" :data="processDefinitionHistoryList"> |
| | | <el-table-column fixed align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column fixed align="center" prop="name" label="æµç¨å®ä¹åç§°"></el-table-column> |
| | | <el-table-column fixed align="center" prop="nodeName" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="key" label="æ è¯Key"></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="deploymentTime" label="é¨ç½²æ¶é´" :show-overflow-tooltip="true"></el-table-column> |
| | | <el-table-column fixed="right" label="æä½" align="center" width="200" class-name="small-padding fixed-width"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" size="small" icon="Sort" @click="handleChange(scope.row.id)">忢</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-dialog> |
| | | <!-- æµç¨åéå¼å§ --> |
| | | <el-dialog v-model="variableVisible" draggable title="æµç¨åé" width="60%" :close-on-click-modal="false"> |
| | | <el-card v-loading="variableLoading" class="box-card"> |
| | | <template #header> |
| | | <div class="clearfix"> |
| | | <span |
| | | >æµç¨å®ä¹åç§°ï¼<el-tag>{{ processDefinitionName }}</el-tag></span |
| | | > |
| | | </div> |
| | | </template> |
| | | <div class="max-h-500px overflow-y-auto"> |
| | | <VueJsonPretty :data="formatToJsonObject(variables)" /> |
| | | </div> |
| | | </el-card> |
| | | </el-dialog> |
| | | <!-- æµç¨åéç»æ --> |
| | | |
| | | <!-- ç³è¯·äºº --> |
| | | <UserSelect ref="userSelectRef" :multiple="true" :data="selectUserIds" @confirm-call-back="userSelectCallBack"></UserSelect> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { |
| | | getPageByRunning, |
| | | getPageByFinish, |
| | | deleteRunAndHisInstance, |
| | | deleteFinishAndHisInstance, |
| | | deleteRunInstance |
| | | } from '@/api/workflow/processInstance'; |
| | | import { getListByKey, migrationDefinition } from '@/api/workflow/processDefinition'; |
| | | import { listCategory } from '@/api/workflow/category'; |
| | | import { CategoryVO } from '@/api/workflow/category/types'; |
| | | import { ProcessInstanceQuery, ProcessInstanceVO } from '@/api/workflow/processInstance/types'; |
| | | import { pageByRunning, pageByFinish, deleteByInstanceIds, instanceVariable, invalid } from '@/api/workflow/instance'; |
| | | import { categoryTree } from '@/api/workflow/category'; |
| | | import { CategoryTreeVO } from '@/api/workflow/category/types'; |
| | | import { FlowInstanceQuery, FlowInstanceVO } from '@/api/workflow/instance/types'; |
| | | import workflowCommon from '@/api/workflow/workflowCommon'; |
| | | import { RouterJumpVo } from '@/api/workflow/workflowCommon/types'; |
| | | import VueJsonPretty from 'vue-json-pretty'; |
| | | import 'vue-json-pretty/lib/styles.css'; |
| | | import UserSelect from '@/components/UserSelect/index.vue'; |
| | | //审æ¹è®°å½ç»ä»¶ |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status')); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const categoryTreeRef = ref<ElTreeInstance>(); |
| | | import { ref } from 'vue'; |
| | | import { UserVO } from '@/api/system/user/types'; |
| | | |
| | | const userSelectRef = ref<InstanceType<typeof UserSelect>>(); |
| | | // é®ç½©å± |
| | | const loading = ref(true); |
| | | // é䏿°ç» |
| | | const ids = ref<Array<any>>([]); |
| | | // éä¸ä¸å¡idæ°ç» |
| | | const businessKeys = ref<Array<any>>([]); |
| | | // éä¸å®ä¾idæ°ç» |
| | | const instanceIds = ref<Array<number | string>>([]); |
| | | // éå个ç¦ç¨ |
| | | const single = ref(true); |
| | | // éå¤ä¸ªç¦ç¨ |
| | |
| | | const showSearch = ref(true); |
| | | // æ»æ¡æ° |
| | | const total = ref(0); |
| | | // æµç¨å®ä¹id |
| | | const processDefinitionId = ref<string>(''); |
| | | |
| | | // æµç¨å鿝妿¾ç¤º |
| | | const variableVisible = ref(false); |
| | | const variableLoading = ref(true); |
| | | const variables = ref<string>(''); |
| | | //æµç¨å®ä¹åç§° |
| | | const processDefinitionName = ref(); |
| | | // 模åå®ä¹è¡¨æ ¼æ°æ® |
| | | const processInstanceList = ref<ProcessInstanceVO[]>([]); |
| | | const processInstanceList = ref<FlowInstanceVO[]>([]); |
| | | const processDefinitionHistoryList = ref<Array<any>>([]); |
| | | const categoryOptions = ref<CategoryOption[]>([]); |
| | | const categoryName = ref(''); |
| | |
| | | }); |
| | | |
| | | type CategoryOption = { |
| | | categoryCode: string; |
| | | id: string; |
| | | categoryName: string; |
| | | children?: CategoryOption[]; |
| | | }; |
| | |
| | | const tab = ref('running'); |
| | | // ä½åºåå |
| | | const deleteReason = ref(''); |
| | | |
| | | //ç³è¯·äººid |
| | | const selectUserIds = ref<Array<number | string>>([]); |
| | | //ç³è¯·äººéæ©æ°é |
| | | const userSelectCount = ref(0); |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref<ProcessInstanceQuery>({ |
| | | const queryParams = ref<FlowInstanceQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | key: undefined, |
| | | categoryCode: undefined |
| | | nodeName: undefined, |
| | | flowName: undefined, |
| | | flowCode: undefined, |
| | | createByIds: [], |
| | | category: undefined |
| | | }); |
| | | |
| | | /** èç¹åå»äºä»¶ */ |
| | | const handleNodeClick = (data: CategoryVO) => { |
| | | queryParams.value.categoryCode = data.categoryCode; |
| | | if (data.categoryCode === 'ALL') { |
| | | queryParams.value.categoryCode = ''; |
| | | const handleNodeClick = (data: CategoryTreeVO) => { |
| | | queryParams.value.category = data.id; |
| | | if (data.id === '0') { |
| | | queryParams.value.category = ''; |
| | | } |
| | | handleQuery(); |
| | | }; |
| | |
| | | |
| | | /** æ¥è¯¢æµç¨åç±»ä¸ææ ç»æ */ |
| | | const getTreeselect = async () => { |
| | | const res = await listCategory(); |
| | | categoryOptions.value = []; |
| | | const data: CategoryOption = { categoryCode: 'ALL', categoryName: '顶级èç¹', children: [] }; |
| | | data.children = proxy?.handleTree<CategoryOption>(res.data, 'id', 'parentId'); |
| | | categoryOptions.value.push(data); |
| | | const res = await categoryTree(); |
| | | categoryOptions.value = res.data; |
| | | }; |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.categoryCode = ''; |
| | | queryParams.value.category = ''; |
| | | queryParams.value.pageNum = 1; |
| | | queryParams.value.pageSize = 10; |
| | | queryParams.value.createByIds = []; |
| | | userSelectCount.value = 0; |
| | | handleQuery(); |
| | | }; |
| | | // å¤éæ¡é䏿°æ® |
| | | const handleSelectionChange = (selection: ProcessInstanceVO[]) => { |
| | | const handleSelectionChange = (selection: FlowInstanceVO[]) => { |
| | | ids.value = selection.map((item: any) => item.id); |
| | | businessKeys.value = selection.map((item: any) => item.businessKey); |
| | | instanceIds.value = selection.map((item: FlowInstanceVO) => item.id); |
| | | single.value = selection.length !== 1; |
| | | multiple.value = !selection.length; |
| | | }; |
| | | //å页 |
| | | const getProcessInstanceRunningList = () => { |
| | | loading.value = true; |
| | | getPageByRunning(queryParams.value).then((resp) => { |
| | | pageByRunning(queryParams.value).then((resp) => { |
| | | processInstanceList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | |
| | | //å页 |
| | | const getProcessInstanceFinishList = () => { |
| | | loading.value = true; |
| | | getPageByFinish(queryParams.value).then((resp) => { |
| | | pageByFinish(queryParams.value).then((resp) => { |
| | | processInstanceList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | |
| | | }; |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row: any) => { |
| | | const businessKey = row.businessKey || businessKeys.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ä¸å¡id为ã' + businessKey + 'ãçæ°æ®é¡¹ï¼'); |
| | | const handleDelete = async (row: FlowInstanceVO) => { |
| | | const instanceIdList = row.id || instanceIds.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ï¼'); |
| | | loading.value = true; |
| | | if ('running' === tab.value) { |
| | | await deleteRunAndHisInstance(businessKey).finally(() => (loading.value = false)); |
| | | await deleteByInstanceIds(instanceIdList).finally(() => (loading.value = false)); |
| | | getProcessInstanceRunningList(); |
| | | } else { |
| | | await deleteFinishAndHisInstance(businessKey).finally(() => (loading.value = false)); |
| | | await deleteByInstanceIds(instanceIdList).finally(() => (loading.value = false)); |
| | | getProcessInstanceFinishList(); |
| | | } |
| | | proxy?.$modal.msgSuccess('å 餿å'); |
| | |
| | | const changeTab = async (data: string) => { |
| | | processInstanceList.value = []; |
| | | queryParams.value.pageNum = 1; |
| | | if ('running' === data) { |
| | | if ('running' === data.paneName) { |
| | | getProcessInstanceRunningList(); |
| | | } else { |
| | | getProcessInstanceFinishList(); |
| | | } |
| | | }; |
| | | /** ä½åºæé®æä½ */ |
| | | const handleInvalid = async (row: ProcessInstanceVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤ä½åºä¸å¡id为ã' + row.businessKey + 'ãçæ°æ®é¡¹ï¼'); |
| | | const handleInvalid = async (row: FlowInstanceVO) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤ä½åºï¼'); |
| | | loading.value = true; |
| | | if ('running' === tab.value) { |
| | | let param = { |
| | | businessKey: row.businessKey, |
| | | deleteReason: deleteReason.value |
| | | id: row.id, |
| | | comment: deleteReason.value |
| | | }; |
| | | await deleteRunInstance(param).finally(() => (loading.value = false)); |
| | | await invalid(param).finally(() => (loading.value = false)); |
| | | getProcessInstanceRunningList(); |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | } |
| | |
| | | const cancelPopover = async (index: any) => { |
| | | (proxy?.$refs[`popoverRef${index}`] as any).hide(); //å
³éå¼¹çª |
| | | }; |
| | | //è·åæµç¨å®ä¹ |
| | | const getProcessDefinitionHitoryList = (id: string, key: string) => { |
| | | processDefinitionDialog.visible = true; |
| | | processDefinitionId.value = id; |
| | | loading.value = true; |
| | | getListByKey(key).then((resp) => { |
| | | if (resp.data && resp.data.length > 0) { |
| | | processDefinitionHistoryList.value = resp.data.filter((item: any) => item.id !== id); |
| | | } |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | //忢æµç¨çæ¬ |
| | | const handleChange = async (id: string) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤åæ¢ï¼'); |
| | | loading.value = true; |
| | | migrationDefinition(processDefinitionId.value, id).then((resp) => { |
| | | proxy?.$modal.msgSuccess('æä½æå'); |
| | | getProcessInstanceRunningList(); |
| | | processDefinitionDialog.visible = false; |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | /** æ¥çæé®æä½ */ |
| | | const handleView = (row) => { |
| | | const routerJumpVo = reactive<RouterJumpVo>({ |
| | | wfDefinitionConfigVo: row.wfDefinitionConfigVo, |
| | | wfNodeConfigVo: row.wfNodeConfigVo, |
| | | businessKey: row.businessKey, |
| | | businessId: row.businessId, |
| | | taskId: row.id, |
| | | type: 'view' |
| | | type: 'view', |
| | | formCustom: row.formCustom, |
| | | formPath: row.formPath |
| | | }); |
| | | workflowCommon.routerJump(routerJumpVo, proxy); |
| | | }; |
| | | |
| | | //æ¥è¯¢æµç¨åé |
| | | const handleInstanceVariable = async (row: FlowInstanceVO) => { |
| | | variableLoading.value = true; |
| | | variableVisible.value = true; |
| | | processDefinitionName.value = row.flowName; |
| | | let data = await instanceVariable(row.id); |
| | | variables.value = data.data.variable; |
| | | variableLoading.value = false; |
| | | }; |
| | | |
| | | /** |
| | | * json转为对象 |
| | | * @param data åå§æ°æ® |
| | | */ |
| | | function formatToJsonObject(data: string) { |
| | | try { |
| | | return JSON.parse(data); |
| | | } catch (error) { |
| | | return data; |
| | | } |
| | | } |
| | | |
| | | //æå¼ç³è¯·äººéæ© |
| | | const openUserSelect = () => { |
| | | userSelectRef.value.open(); |
| | | }; |
| | | //ç¡®è®¤éæ©ç³è¯·äºº |
| | | const userSelectCallBack = (data: UserVO[]) => { |
| | | userSelectCount.value = 0; |
| | | if (data && data.length > 0) { |
| | | userSelectCount.value = data.length; |
| | | selectUserIds.value = data.map((item) => item.userId); |
| | | queryParams.value.createByIds = selectUserIds.value; |
| | | } |
| | | }; |
| | | onMounted(() => { |
| | | getProcessInstanceRunningList(); |
| | | getTreeselect(); |
| | |
| | | <template> |
| | | <div class="p-2"> |
| | | <div class="mb-[10px]"> |
| | | <el-card shadow="hover" class="text-center"> |
| | | <el-radio-group v-model="tab" @change="changeTab(tab)"> |
| | | <el-radio-button value="waiting">å¾
åä»»å¡</el-radio-button> |
| | | <el-radio-button value="finish">å·²åä»»å¡</el-radio-button> |
| | | </el-radio-group> |
| | | </el-card> |
| | | </div> |
| | | <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true"> |
| | | <el-form-item label="ä»»å¡åç§°" prop="name"> |
| | | <el-input v-model="queryParams.name" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item> |
| | | <el-badge :value="userSelectCount" :max="10" class="item"> |
| | | <el-button type="primary" @click="openUserSelect">éæ©ç³è¯·äºº</el-button> |
| | | </el-badge> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="processDefinitionName"> |
| | | <el-input v-model="queryParams.processDefinitionName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="ä»»å¡åç§°" prop="nodeName"> |
| | | <el-input v-model="queryParams.nodeName" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹KEY" label-width="100" prop="processDefinitionKey"> |
| | | <el-input v-model="queryParams.processDefinitionKey" placeholder="请è¾å
¥æµç¨å®ä¹KEY" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="flowName"> |
| | | <el-input v-model="queryParams.flowName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | |
| | | <el-card shadow="hover"> |
| | | <template #header> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" plain icon="Edit" :disabled="multiple" @click="handleUpdate">ä¿®æ¹åç人</el-button> |
| | | <el-col :span="1.5" v-if="tab === 'waiting'"> |
| | | <el-button type="primary" plain icon="Edit" :disabled="multiple" @click="handleUpdate">ä¿®æ¹åç人 </el-button> |
| | | </el-col> |
| | | <right-toolbar v-model:show-search="showSearch" @query-table="handleQuery"></right-toolbar> |
| | | </el-row> |
| | | </template> |
| | | |
| | | <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" align="center" label="æµç¨å®ä¹åç§°"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.processDefinitionName }}v{{ scope.row.processDefinitionVersion }}.0</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionKey" label="æµç¨å®ä¹KEY"></el-table-column> |
| | | <el-table-column align="center" prop="name" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="assigneeName" label="åç人"> |
| | | <template v-if="tab === 'waiting'" #default="scope"> |
| | | <template v-if="scope.row.participantVo && scope.row.assignee === null"> |
| | | <el-tag v-for="(item, index) in scope.row.participantVo.candidateName" :key="index" type="success"> |
| | | {{ item }} |
| | | </el-tag> |
| | | <el-tabs v-model="tab" @tab-click="changeTab"> |
| | | <el-tab-pane name="waiting" label="å¾
åä»»å¡"> </el-tab-pane> |
| | | <el-tab-pane name="finish" label="å·²åä»»å¡"> </el-tab-pane> |
| | | <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="æµç¨å®ä¹åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="flowCode" label="æµç¨å®ä¹ç¼ç "></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="nodeName" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="createByName" label="ç³è¯·äºº"></el-table-column> |
| | | <el-table-column align="center" label="åç人"> |
| | | <template #default="scope"> |
| | | <template v-if="tab === 'waiting'"> |
| | | <template v-if="scope.row.assigneeNames"> |
| | | <el-tag v-for="(name, index) in scope.row.assigneeNames.split(',')" :key="index" type="success"> |
| | | {{ name }} |
| | | </el-tag> |
| | | </template> |
| | | <template v-else> |
| | | <el-tag type="success"> æ </el-tag> |
| | | </template> |
| | | </template> |
| | | <template v-else> |
| | | <el-tag type="success"> {{ scope.row.approveName }}</el-tag> |
| | | </template> |
| | | </template> |
| | | <template v-else> |
| | | <el-tag type="success"> |
| | | {{ scope.row.assigneeName || 'æ ' }} |
| | | </el-tag> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" prop="flowStatus" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.flowStatus"></dict-tag> |
| | | </template> |
| | | </template> |
| | | <template v-else-if="tab === 'finish'" #default="scope"> |
| | | <el-tag type="success"> |
| | | {{ scope.row.assigneeName || 'æ ' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag v-if="tab === 'waiting'" :options="wf_business_status" :value="scope.row.businessStatus"></dict-tag> |
| | | <el-tag v-else type="success">已宿</el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column v-if="tab === 'waiting'" align="center" prop="createTime" label="å建æ¶é´" width="160"></el-table-column> |
| | | <el-table-column v-if="tab === 'finish'" align="center" prop="startTime" label="å建æ¶é´" width="160"></el-table-column> |
| | | <el-table-column label="æä½" align="center" :width="tab === 'finish' ? '80' : '151'"> |
| | | <template #default="scope"> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="View" @click="handleView(scope.row)">æ¥ç</el-button> |
| | | </el-col> |
| | | <el-col v-if="tab === 'waiting'" :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Document" @click="handleInstanceVariable(scope.row)">æµç¨åé</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row v-if="scope.row.multiInstance" :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="Remove" @click="deleteMultiInstanceUser(scope.row)">åç¾</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5"> |
| | | <el-button link type="primary" size="small" icon="CirclePlus" @click="addMultiInstanceUser(scope.row)">å ç¾</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | :total="total" |
| | | @pagination="handleQuery" |
| | | /> |
| | | </el-table-column> |
| | | <el-table-column v-if="tab === 'finish'" align="center" label="ä»»å¡ç¶æ" prop="flowTaskStatus" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_task_status" :value="scope.row.flowTaskStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="createTime" label="å建æ¶é´" width="160"></el-table-column> |
| | | <el-table-column label="æä½" align="center" :width="tab === 'finish' ? '88' : '188'"> |
| | | <template #default="scope"> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5" v-if="tab === 'waiting' || tab === 'finish'"> |
| | | <el-button type="primary" size="small" icon="View" @click="handleView(scope.row)">æ¥ç</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5" v-if="tab === 'waiting'"> |
| | | <el-button type="primary" size="small" icon="Setting" @click="handleMeddle(scope.row)">æµç¨å¹²é¢ </el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination |
| | | v-show="total > 0" |
| | | v-model:page="queryParams.pageNum" |
| | | v-model:limit="queryParams.pageSize" |
| | | :total="total" |
| | | @pagination="handleQuery" |
| | | /> |
| | | </el-tabs> |
| | | </el-card> |
| | | <!-- å ç¾ç»ä»¶ --> |
| | | <multiInstanceUser ref="multiInstanceUserRef" :title="title" @submit-callback="handleQuery" /> |
| | | <!-- é人ç»ä»¶ --> |
| | | <UserSelect ref="userSelectRef" :multiple="false" @confirm-call-back="submitCallback"></UserSelect> |
| | | <!-- æµç¨åéå¼å§ --> |
| | | <el-dialog v-model="variableVisible" draggable title="æµç¨åé" width="60%" :close-on-click-modal="false"> |
| | | <el-card v-loading="variableLoading" class="box-card"> |
| | | <template #header> |
| | | <div class="clearfix"> |
| | | <span |
| | | >æµç¨å®ä¹åç§°ï¼<el-tag>{{ processDefinitionName }}</el-tag></span |
| | | > |
| | | </div> |
| | | </template> |
| | | <div v-for="(v, index) in variableList" :key="index"> |
| | | <el-form v-if="v.key !== '_FLOWABLE_SKIP_EXPRESSION_ENABLED'" :label-position="'right'" label-width="150px"> |
| | | <el-form-item :label="v.key + 'ï¼'"> |
| | | {{ v.value }} |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-card> |
| | | </el-dialog> |
| | | <!-- æµç¨åéç»æ --> |
| | | <!-- é人ç»ä»¶ --> |
| | | <processMeddle ref="processMeddleRef" @submitCallback="getWaitingList"></processMeddle> |
| | | <!-- ç³è¯·äºº --> |
| | | <UserSelect ref="applyUserSelectRef" :multiple="true" :data="selectUserIds" @confirm-call-back="userSelectCallBack"></UserSelect> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { getPageByAllTaskWait, getPageByAllTaskFinish, updateAssignee, getInstanceVariable } from '@/api/workflow/task'; |
| | | import MultiInstanceUser from '@/components/Process/multiInstanceUser.vue'; |
| | | import { pageByAllTaskWait, pageByAllTaskFinish, updateAssignee } from '@/api/workflow/task'; |
| | | import UserSelect from '@/components/UserSelect'; |
| | | import { TaskQuery, TaskVO, VariableVo } from '@/api/workflow/task/types'; |
| | | import { TaskQuery } from '@/api/workflow/task/types'; |
| | | import workflowCommon from '@/api/workflow/workflowCommon'; |
| | | import { RouterJumpVo } from '@/api/workflow/workflowCommon/types'; |
| | | //审æ¹è®°å½ç»ä»¶ |
| | | //å ç¾ç»ä»¶ |
| | | const multiInstanceUserRef = ref<InstanceType<typeof MultiInstanceUser>>(); |
| | | import processMeddle from '@/components/Process/processMeddle'; |
| | | import { UserVO } from '@/api/system/user/types'; |
| | | import { TabsPaneContext } from 'element-plus'; |
| | | //é人ç»ä»¶ |
| | | const userSelectRef = ref<InstanceType<typeof UserSelect>>(); |
| | | |
| | | //æµç¨å¹²é¢ç»ä»¶ |
| | | const processMeddleRef = ref<InstanceType<typeof processMeddle>>(); |
| | | //é人ç»ä»¶ |
| | | const applyUserSelectRef = ref<InstanceType<typeof UserSelect>>(); |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status')); |
| | | const { wf_task_status } = toRefs<any>(proxy?.useDict('wf_task_status')); |
| | | // é®ç½©å± |
| | | const loading = ref(true); |
| | | // é䏿°ç» |
| | |
| | | // 模åå®ä¹è¡¨æ ¼æ°æ® |
| | | const taskList = ref([]); |
| | | const title = ref(''); |
| | | // æµç¨å鿝妿¾ç¤º |
| | | const variableVisible = ref(false); |
| | | const variableLoading = ref(true); |
| | | // æµç¨åé |
| | | const variableList = ref<VariableVo>({ |
| | | key: '', |
| | | value: '' |
| | | }); |
| | | //æµç¨å®ä¹åç§° |
| | | const processDefinitionName = ref(); |
| | | //ç³è¯·äººid |
| | | const selectUserIds = ref<Array<number | string>>([]); |
| | | //ç³è¯·äººéæ©æ°é |
| | | const userSelectCount = ref(0); |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref<TaskQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | processDefinitionName: undefined, |
| | | processDefinitionKey: undefined |
| | | nodeName: undefined, |
| | | flowName: undefined, |
| | | flowCode: undefined, |
| | | createByIds: [] |
| | | }); |
| | | const tab = ref('waiting'); |
| | | |
| | | //å ç¾ |
| | | const addMultiInstanceUser = (row: TaskVO) => { |
| | | if (multiInstanceUserRef.value) { |
| | | title.value = 'å ç¾äººå'; |
| | | multiInstanceUserRef.value.getAddMultiInstanceList(row.id, []); |
| | | } |
| | | }; |
| | | //åç¾ |
| | | const deleteMultiInstanceUser = (row: TaskVO) => { |
| | | if (multiInstanceUserRef.value) { |
| | | title.value = 'åç¾äººå'; |
| | | multiInstanceUserRef.value.getDeleteMultiInstanceList(row.id); |
| | | } |
| | | }; |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | if ('waiting' === tab.value) { |
| | |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | queryParams.value.pageSize = 10; |
| | | queryParams.value.createByIds = []; |
| | | userSelectCount.value = 0; |
| | | handleQuery(); |
| | | }; |
| | | // å¤éæ¡é䏿°æ® |
| | |
| | | single.value = selection.length !== 1; |
| | | multiple.value = !selection.length; |
| | | }; |
| | | const changeTab = async (data: string) => { |
| | | const changeTab = async (data: TabsPaneContext) => { |
| | | taskList.value = []; |
| | | queryParams.value.pageNum = 1; |
| | | if ('waiting' === data) { |
| | | if ('waiting' === data.paneName) { |
| | | getWaitingList(); |
| | | } else { |
| | | getFinishList(); |
| | |
| | | //å页 |
| | | const getWaitingList = () => { |
| | | loading.value = true; |
| | | getPageByAllTaskWait(queryParams.value).then((resp) => { |
| | | pageByAllTaskWait(queryParams.value).then((resp) => { |
| | | taskList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | |
| | | }; |
| | | const getFinishList = () => { |
| | | loading.value = true; |
| | | getPageByAllTaskFinish(queryParams.value).then((resp) => { |
| | | pageByAllTaskFinish(queryParams.value).then((resp) => { |
| | | taskList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | |
| | | proxy?.$modal.msgWarning('è¯·éæ©ç¨æ·ï¼'); |
| | | } |
| | | }; |
| | | //æ¥è¯¢æµç¨åé |
| | | const handleInstanceVariable = async (row: TaskVO) => { |
| | | variableLoading.value = true; |
| | | variableVisible.value = true; |
| | | processDefinitionName.value = row.processDefinitionName; |
| | | let data = await getInstanceVariable(row.id); |
| | | variableList.value = data.data; |
| | | variableLoading.value = false; |
| | | }; |
| | | /** æ¥çæé®æä½ */ |
| | | const handleView = (row) => { |
| | | const routerJumpVo = reactive<RouterJumpVo>({ |
| | | wfDefinitionConfigVo: row.wfDefinitionConfigVo, |
| | | wfNodeConfigVo: row.wfNodeConfigVo, |
| | | businessKey: row.businessKey, |
| | | businessId: row.businessId, |
| | | taskId: row.id, |
| | | type: 'view' |
| | | type: 'view', |
| | | formCustom: row.formCustom, |
| | | formPath: row.formPath |
| | | }); |
| | | workflowCommon.routerJump(routerJumpVo, proxy); |
| | | }; |
| | | const handleMeddle = (row) => { |
| | | processMeddleRef.value.open(row.id); |
| | | }; |
| | | //æå¼ç³è¯·äººéæ© |
| | | const openUserSelect = () => { |
| | | applyUserSelectRef.value.open(); |
| | | }; |
| | | //ç¡®è®¤éæ©ç³è¯·äºº |
| | | const userSelectCallBack = (data: UserVO[]) => { |
| | | userSelectCount.value = 0; |
| | | if (data && data.length > 0) { |
| | | userSelectCount.value = data.length; |
| | | selectUserIds.value = data.map((item) => item.userId); |
| | | queryParams.value.createByIds = selectUserIds.value; |
| | | } |
| | | }; |
| | | onMounted(() => { |
| | | getWaitingList(); |
| | | }); |
| | |
| | | class="mt-2" |
| | | node-key="id" |
| | | :data="categoryOptions" |
| | | :props="{ label: 'categoryName', children: 'children' }" |
| | | :props="{ label: 'label', children: 'children' }" |
| | | :expand-on-click-node="false" |
| | | :filter-node-method="filterNode" |
| | | highlight-current |
| | |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true" label-width="120px"> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" prop="name"> |
| | | <el-input v-model="queryParams.name" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹ç¼ç " prop="flowCode"> |
| | | <el-input v-model="queryParams.flowCode" placeholder="请è¾å
¥æµç¨å®ä¹ç¼ç " @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column v-if="false" align="center" prop="id" label="id"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" align="center" label="æµç¨å®ä¹åç§°"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.processDefinitionName }}v{{ scope.row.processDefinitionVersion }}.0</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionKey" label="æµç¨å®ä¹KEY"></el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionVersion" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.processDefinitionVersion }}.0</template> |
| | | <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="æµç¨å®ä¹åç§°"> </el-table-column> |
| | | <el-table-column align="center" prop="flowCode" label="æµç¨å®ä¹ç¼ç "></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column v-if="tab === 'running'" align="center" prop="isSuspended" label="ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | |
| | | </el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.businessStatus"></dict-tag> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.flowStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="startTime" label="å¯å¨æ¶é´" width="160"></el-table-column> |
| | | <el-table-column v-if="tab === 'finish'" align="center" prop="endTime" label="ç»ææ¶é´" width="160"></el-table-column> |
| | | <el-table-column label="æä½" align="center" class-name="small-padding fixed-width"> |
| | | <el-table-column align="center" prop="createTime" label="å¯å¨æ¶é´" width="160"></el-table-column> |
| | | <el-table-column label="æä½" align="center" width="162"> |
| | | <template #default="scope"> |
| | | <el-tooltip |
| | | v-if="scope.row.businessStatus === 'draft' || scope.row.businessStatus === 'cancel' || scope.row.businessStatus === 'back'" |
| | | content="ä¿®æ¹" |
| | | placement="top" |
| | | > |
| | | <el-button link type="primary" icon="Edit" @click="handleOpen(scope.row, 'update')"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip |
| | | v-if="scope.row.businessStatus === 'draft' || scope.row.businessStatus === 'cancel' || scope.row.businessStatus === 'back'" |
| | | content="å é¤" |
| | | placement="top" |
| | | > |
| | | <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip placement="top" content="æ¥ç"> |
| | | <el-button link type="primary" icon="View" @click="handleOpen(scope.row, 'view')"></el-button> |
| | | </el-tooltip> |
| | | <el-tooltip v-if="scope.row.businessStatus === 'waiting'" content="æ¤é" placement="top"> |
| | | <el-button link type="primary" icon="Notification" @click="handleCancelProcessApply(scope.row.businessKey)"></el-button> |
| | | </el-tooltip> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5" v-if="scope.row.flowStatus === 'draft' || scope.row.flowStatus === 'cancel' || scope.row.flowStatus === 'back'"> |
| | | <el-button type="primary" size="small" icon="Edit" @click="handleOpen(scope.row, 'update')">ç¼è¾</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5" v-if="scope.row.flowStatus === 'draft' || scope.row.flowStatus === 'cancel' || scope.row.flowStatus === 'back'"> |
| | | <el-button type="primary" size="small" icon="Delete" @click="handleDelete(scope.row)">å é¤</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="10" class="mb8"> |
| | | <el-col :span="1.5"> |
| | | <el-button type="primary" size="small" icon="View" @click="handleOpen(scope.row, 'view')">æ¥ç</el-button> |
| | | </el-col> |
| | | <el-col :span="1.5" v-if="scope.row.flowStatus === 'waiting'"> |
| | | <el-button type="primary" size="small" icon="Notification" @click="handleCancelProcessApply(scope.row.businessId)" |
| | | >æ¤é</el-button |
| | | > |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { getPageByCurrent, deleteRunAndHisInstance, cancelProcessApply } from '@/api/workflow/processInstance'; |
| | | import { listCategory } from '@/api/workflow/category'; |
| | | import { CategoryVO } from '@/api/workflow/category/types'; |
| | | import { ProcessInstanceQuery, ProcessInstanceVO } from '@/api/workflow/processInstance/types'; |
| | | import { pageByCurrent, deleteByInstanceIds, cancelProcessApply } from '@/api/workflow/instance'; |
| | | import { categoryTree } from '@/api/workflow/category'; |
| | | import { CategoryTreeVO } from '@/api/workflow/category/types'; |
| | | import { FlowInstanceQuery, FlowInstanceVO } from '@/api/workflow/instance/types'; |
| | | import workflowCommon from '@/api/workflow/workflowCommon'; |
| | | import { RouterJumpVo } from '@/api/workflow/workflowCommon/types'; |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | |
| | | // é®ç½©å± |
| | | const loading = ref(true); |
| | | // é䏿°ç» |
| | | const businessKeys = ref<Array<any>>([]); |
| | | const businessIds = ref<Array<number | string>>([]); |
| | | const instanceIds = ref<Array<number | string>>([]); |
| | | // éå个ç¦ç¨ |
| | | const single = ref(true); |
| | | // éå¤ä¸ªç¦ç¨ |
| | |
| | | // æ»æ¡æ° |
| | | const total = ref(0); |
| | | // 模åå®ä¹è¡¨æ ¼æ°æ® |
| | | const processInstanceList = ref<ProcessInstanceVO[]>([]); |
| | | const processInstanceList = ref<FlowInstanceVO[]>([]); |
| | | |
| | | const categoryOptions = ref<CategoryOption[]>([]); |
| | | const categoryOptions = ref<CategoryTreeVO[]>([]); |
| | | const categoryName = ref(''); |
| | | |
| | | interface CategoryOption { |
| | | categoryCode: string; |
| | | categoryName: string; |
| | | children?: CategoryOption[]; |
| | | } |
| | | |
| | | const tab = ref('running'); |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref<ProcessInstanceQuery>({ |
| | | const queryParams = ref<FlowInstanceQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | categoryCode: undefined |
| | | flowCode: undefined, |
| | | category: undefined |
| | | }); |
| | | |
| | | onMounted(() => { |
| | |
| | | }); |
| | | |
| | | /** èç¹åå»äºä»¶ */ |
| | | const handleNodeClick = (data: CategoryVO) => { |
| | | queryParams.value.categoryCode = data.categoryCode; |
| | | if (data.categoryCode === 'ALL') { |
| | | queryParams.value.categoryCode = ''; |
| | | const handleNodeClick = (data: CategoryTreeVO) => { |
| | | queryParams.value.category = data.id; |
| | | if (data.id === '0') { |
| | | queryParams.value.category = ''; |
| | | } |
| | | handleQuery(); |
| | | }; |
| | |
| | | |
| | | /** æ¥è¯¢æµç¨åç±»ä¸ææ ç»æ */ |
| | | const getTreeselect = async () => { |
| | | const res = await listCategory(); |
| | | categoryOptions.value = []; |
| | | const data: CategoryOption = { categoryCode: 'ALL', categoryName: '顶级èç¹', children: [] }; |
| | | data.children = proxy?.handleTree<CategoryOption>(res.data, 'id', 'parentId'); |
| | | categoryOptions.value.push(data); |
| | | const res = await categoryTree(); |
| | | categoryOptions.value = res.data; |
| | | }; |
| | | |
| | | /** æç´¢æé®æä½ */ |
| | |
| | | /** éç½®æé®æä½ */ |
| | | const resetQuery = () => { |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.categoryCode = ''; |
| | | queryParams.value.category = ''; |
| | | queryParams.value.pageNum = 1; |
| | | queryParams.value.pageSize = 10; |
| | | handleQuery(); |
| | | }; |
| | | // å¤éæ¡é䏿°æ® |
| | | const handleSelectionChange = (selection: ProcessInstanceVO[]) => { |
| | | businessKeys.value = selection.map((item: any) => item.businessKey); |
| | | const handleSelectionChange = (selection: FlowInstanceVO[]) => { |
| | | businessIds.value = selection.map((item: any) => item.businessId); |
| | | instanceIds.value = selection.map((item: FlowInstanceVO) => item.id); |
| | | single.value = selection.length !== 1; |
| | | multiple.value = !selection.length; |
| | | }; |
| | | //å页 |
| | | const getList = () => { |
| | | loading.value = true; |
| | | getPageByCurrent(queryParams.value).then((resp) => { |
| | | pageByCurrent(queryParams.value).then((resp) => { |
| | | processInstanceList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | |
| | | }; |
| | | |
| | | /** å é¤æé®æä½ */ |
| | | const handleDelete = async (row: ProcessInstanceVO) => { |
| | | const businessKey = row.businessKey || businessKeys.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ä¸å¡id为ã' + businessKey + 'ãçæ°æ®é¡¹ï¼'); |
| | | const handleDelete = async (row: FlowInstanceVO) => { |
| | | const instanceIdList = row.id || instanceIds.value; |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤å é¤ï¼'); |
| | | loading.value = true; |
| | | if ('running' === tab.value) { |
| | | await deleteRunAndHisInstance(businessKey).finally(() => (loading.value = false)); |
| | | await deleteByInstanceIds(instanceIdList).finally(() => (loading.value = false)); |
| | | getList(); |
| | | } |
| | | proxy?.$modal.msgSuccess('å 餿å'); |
| | | }; |
| | | |
| | | /** æ¤éæé®æä½ */ |
| | | const handleCancelProcessApply = async (businessKey: string) => { |
| | | const handleCancelProcessApply = async (businessId: string) => { |
| | | await proxy?.$modal.confirm('æ¯å¦ç¡®è®¤æ¤éå½ååæ®ï¼'); |
| | | loading.value = true; |
| | | if ('running' === tab.value) { |
| | | await cancelProcessApply(businessKey).finally(() => (loading.value = false)); |
| | | let data = { |
| | | businessId: businessId, |
| | | message: 'ç³è¯·äººæ¤éæµç¨ï¼' |
| | | }; |
| | | await cancelProcessApply(data).finally(() => (loading.value = false)); |
| | | getList(); |
| | | } |
| | | proxy?.$modal.msgSuccess('æ¤éæå'); |
| | |
| | | //åç |
| | | const handleOpen = async (row, type) => { |
| | | const routerJumpVo = reactive<RouterJumpVo>({ |
| | | wfDefinitionConfigVo: row.wfDefinitionConfigVo, |
| | | wfNodeConfigVo: row.wfNodeConfigVo, |
| | | businessKey: row.businessKey, |
| | | businessId: row.businessId, |
| | | taskId: row.id, |
| | | type: type |
| | | type: type, |
| | | formCustom: row.formCustom, |
| | | formPath: row.formPath |
| | | }); |
| | | workflowCommon.routerJump(routerJumpVo, proxy); |
| | | }; |
| | |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true"> |
| | | <el-form-item label="ä»»å¡åç§°" prop="name"> |
| | | <el-input v-model="queryParams.name" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="ä»»å¡åç§°" prop="nodeName"> |
| | | <el-input v-model="queryParams.nodeName" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="processDefinitionName"> |
| | | <el-input v-model="queryParams.processDefinitionName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="flowName"> |
| | | <el-input v-model="queryParams.flowName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹KEY" label-width="100" prop="processDefinitionKey"> |
| | | <el-input v-model="queryParams.processDefinitionKey" placeholder="请è¾å
¥æµç¨å®ä¹KEY" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹ç¼ç " label-width="100" prop="flowCode"> |
| | | <el-input v-model="queryParams.flowCode" placeholder="请è¾å
¥æµç¨å®ä¹ç¼ç " @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | |
| | | <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" align="center" label="æµç¨å®ä¹åç§°"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.processDefinitionName }}v{{ scope.row.processDefinitionVersion }}.0</span> |
| | | </template> |
| | | <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="æµç¨å®ä¹åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="flowCode" label="æµç¨å®ä¹KEY"></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionKey" label="æµç¨å®ä¹KEY"></el-table-column> |
| | | <el-table-column align="center" prop="name" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="assigneeName" label="åç人"> |
| | | <template #default="scope"> |
| | | <template v-if="scope.row.participantVo && scope.row.assignee === null"> |
| | | <el-tag v-for="(item, index) in scope.row.participantVo.candidateName" :key="index" type="success"> |
| | | {{ item }} |
| | | </el-tag> |
| | | </template> |
| | | <template v-else> |
| | | <el-tag type="success"> |
| | | {{ scope.row.assigneeName || 'æ ' }} |
| | | </el-tag> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="nodeName" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.businessStatus"></dict-tag> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.flowStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="æä½" align="center" width="200"> |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { getPageByTaskCopy } from '@/api/workflow/task'; |
| | | import { pageByTaskCopy } from '@/api/workflow/task'; |
| | | import { TaskQuery } from '@/api/workflow/task/types'; |
| | | import workflowCommon from '@/api/workflow/workflowCommon'; |
| | | import { RouterJumpVo } from '@/api/workflow/workflowCommon/types'; |
| | |
| | | const queryParams = ref<TaskQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | processDefinitionName: undefined, |
| | | processDefinitionKey: undefined |
| | | nodeName: undefined, |
| | | flowName: undefined, |
| | | flowCode: undefined |
| | | }); |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | |
| | | //å页 |
| | | const getTaskCopyList = () => { |
| | | loading.value = true; |
| | | getPageByTaskCopy(queryParams.value).then((resp) => { |
| | | pageByTaskCopy(queryParams.value).then((resp) => { |
| | | taskList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | |
| | | /** æ¥çæé®æä½ */ |
| | | const handleView = (row) => { |
| | | const routerJumpVo = reactive<RouterJumpVo>({ |
| | | wfDefinitionConfigVo: row.wfDefinitionConfigVo, |
| | | wfNodeConfigVo: row.wfNodeConfigVo, |
| | | businessKey: row.businessKey, |
| | | businessId: row.businessId, |
| | | taskId: row.id, |
| | | type: 'view' |
| | | type: 'view', |
| | | formCustom: row.formCustom, |
| | | formPath: row.formPath |
| | | }); |
| | | workflowCommon.routerJump(routerJumpVo, proxy); |
| | | }; |
| | |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true"> |
| | | <el-form-item label="ä»»å¡åç§°" prop="name"> |
| | | <el-input v-model="queryParams.name" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item> |
| | | <el-badge :value="userSelectCount" :max="10" class="item"> |
| | | <el-button type="primary" @click="openUserSelect">éæ©ç³è¯·äºº</el-button> |
| | | </el-badge> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="processDefinitionName"> |
| | | <el-input v-model="queryParams.processDefinitionName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="ä»»å¡åç§°" prop="nodeName"> |
| | | <el-input v-model="queryParams.nodeName" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹KEY" label-width="100" prop="processDefinitionKey"> |
| | | <el-input v-model="queryParams.processDefinitionKey" placeholder="请è¾å
¥æµç¨å®ä¹KEY" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="flowName"> |
| | | <el-input v-model="queryParams.flowName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹ç¼ç " label-width="100" prop="flowCode"> |
| | | <el-input v-model="queryParams.flowCode" placeholder="请è¾å
¥æµç¨å®ä¹ç¼ç " @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | |
| | | <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" align="center" label="æµç¨å®ä¹åç§°"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.processDefinitionName }}v{{ scope.row.processDefinitionVersion }}.0</span> |
| | | </template> |
| | | <el-table-column align="center" prop="flowName" label="æµç¨å®ä¹åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="flowCode" label="æµç¨å®ä¹ç¼ç "></el-table-column> |
| | | <el-table-column align="center" prop="version" label="çæ¬å·" width="90"> |
| | | <template #default="scope"> v{{ scope.row.version }}.0</template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionKey" label="æµç¨å®ä¹KEY"></el-table-column> |
| | | <el-table-column align="center" prop="name" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="assigneeName" label="åç人"> |
| | | <el-table-column align="center" prop="nodeName" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="createByName" label="ç³è¯·äºº"></el-table-column> |
| | | <el-table-column align="center" prop="approverName" label="åç人"> |
| | | <template #default="scope"> |
| | | <el-tag type="success"> |
| | | {{ scope.row.assigneeName || 'æ ' }} |
| | | {{ scope.row.approveName || 'æ ' }} |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="startTime" label="å建æ¶é´" width="160"></el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" prop="flowStatus" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.flowStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="ä»»å¡ç¶æ" prop="flowTaskStatus" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_task_status" :value="scope.row.flowTaskStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="createTime" label="å建æ¶é´" width="160"></el-table-column> |
| | | <el-table-column label="æä½" align="center" width="200"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" size="small" icon="View" @click="handleView(scope.row)">æ¥ç</el-button> |
| | |
| | | @pagination="handleQuery" |
| | | /> |
| | | </el-card> |
| | | <!-- ç³è¯·äºº --> |
| | | <UserSelect ref="userSelectRef" :multiple="true" :data="selectUserIds" @confirm-call-back="userSelectCallBack"></UserSelect> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { getPageByTaskFinish } from '@/api/workflow/task'; |
| | | import { TaskQuery, TaskVO } from '@/api/workflow/task/types'; |
| | | import { pageByTaskFinish } from '@/api/workflow/task'; |
| | | import { TaskQuery, FlowTaskVO } from '@/api/workflow/task/types'; |
| | | import workflowCommon from '@/api/workflow/workflowCommon'; |
| | | import { RouterJumpVo } from '@/api/workflow/workflowCommon/types'; |
| | | //审æ¹è®°å½ç»ä»¶ |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status')); |
| | | const { wf_task_status } = toRefs<any>(proxy?.useDict('wf_task_status')); |
| | | import UserSelect from '@/components/UserSelect'; |
| | | import { ref } from 'vue'; |
| | | import { UserVO } from '@/api/system/user/types'; |
| | | |
| | | const userSelectRef = ref<InstanceType<typeof UserSelect>>(); |
| | | // é®ç½©å± |
| | | const loading = ref(true); |
| | | // é䏿°ç» |
| | |
| | | const queryParams = ref<TaskQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | processDefinitionName: undefined, |
| | | processDefinitionKey: undefined |
| | | nodeName: undefined, |
| | | flowName: undefined, |
| | | flowCode: undefined, |
| | | createByIds: [] |
| | | }); |
| | | //ç³è¯·äººid |
| | | const selectUserIds = ref<Array<number | string>>([]); |
| | | //ç³è¯·äººéæ©æ°é |
| | | const userSelectCount = ref(0); |
| | | /** æç´¢æé®æä½ */ |
| | | const handleQuery = () => { |
| | | getFinishList(); |
| | |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | queryParams.value.pageSize = 10; |
| | | queryParams.value.createByIds = []; |
| | | userSelectCount.value = 0; |
| | | handleQuery(); |
| | | }; |
| | | // å¤éæ¡é䏿°æ® |
| | |
| | | }; |
| | | const getFinishList = () => { |
| | | loading.value = true; |
| | | getPageByTaskFinish(queryParams.value).then((resp) => { |
| | | pageByTaskFinish(queryParams.value).then((resp) => { |
| | | taskList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | /** æ¥çæé®æä½ */ |
| | | const handleView = (row: TaskVO) => { |
| | | const handleView = (row: FlowTaskVO) => { |
| | | const routerJumpVo = reactive<RouterJumpVo>({ |
| | | wfDefinitionConfigVo: row.wfDefinitionConfigVo, |
| | | wfNodeConfigVo: row.wfNodeConfigVo, |
| | | businessKey: row.businessKey, |
| | | businessId: row.businessId, |
| | | taskId: row.id, |
| | | type: 'view' |
| | | type: 'view', |
| | | formCustom: row.formCustom, |
| | | formPath: row.formPath |
| | | }); |
| | | workflowCommon.routerJump(routerJumpVo, proxy); |
| | | }; |
| | | |
| | | //æå¼ç³è¯·äººéæ© |
| | | const openUserSelect = () => { |
| | | userSelectRef.value.open(); |
| | | }; |
| | | //ç¡®è®¤éæ©ç³è¯·äºº |
| | | const userSelectCallBack = (data: UserVO[]) => { |
| | | userSelectCount.value = 0; |
| | | if (data && data.length > 0) { |
| | | userSelectCount.value = data.length; |
| | | selectUserIds.value = data.map((item) => item.userId); |
| | | queryParams.value.createByIds = selectUserIds.value; |
| | | } |
| | | }; |
| | | onMounted(() => { |
| | | getFinishList(); |
| | | }); |
| | |
| | | <div v-show="showSearch" class="mb-[10px]"> |
| | | <el-card shadow="hover"> |
| | | <el-form v-show="showSearch" ref="queryFormRef" :model="queryParams" :inline="true"> |
| | | <el-form-item label="ä»»å¡åç§°" prop="name"> |
| | | <el-input v-model="queryParams.name" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item> |
| | | <el-badge :value="userSelectCount" :max="10" class="item"> |
| | | <el-button type="primary" @click="openUserSelect">éæ©ç³è¯·äºº</el-button> |
| | | </el-badge> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="processDefinitionName"> |
| | | <el-input v-model="queryParams.processDefinitionName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="ä»»å¡åç§°" prop="nodeName"> |
| | | <el-input v-model="queryParams.nodeName" placeholder="请è¾å
¥ä»»å¡åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹KEY" label-width="100" prop="processDefinitionKey"> |
| | | <el-input v-model="queryParams.processDefinitionKey" placeholder="请è¾å
¥æµç¨å®ä¹KEY" @keyup.enter="handleQuery" /> |
| | | <el-form-item label="æµç¨å®ä¹åç§°" label-width="100" prop="flowName"> |
| | | <el-input v-model="queryParams.flowName" placeholder="请è¾å
¥æµç¨å®ä¹åç§°" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="æµç¨å®ä¹ç¼ç " label-width="100" prop="flowCode"> |
| | | <el-input v-model="queryParams.flowCode" placeholder="请è¾å
¥æµç¨å®ä¹ç¼ç " @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">æç´¢</el-button> |
| | |
| | | <el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange"> |
| | | <el-table-column type="selection" width="55" align="center" /> |
| | | <el-table-column align="center" type="index" label="åºå·" width="60"></el-table-column> |
| | | <el-table-column :show-overflow-tooltip="true" align="center" label="æµç¨å®ä¹åç§°"> |
| | | <el-table-column :show-overflow-tooltip="true" prop="flowName" align="center" label="æµç¨å®ä¹åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="flowCode" label="æµç¨å®ä¹ç¼ç "></el-table-column> |
| | | <el-table-column align="center" prop="nodeName" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="createByName" label="ç³è¯·äºº"></el-table-column> |
| | | <el-table-column align="center" label="åç人"> |
| | | <template #default="scope"> |
| | | <span>{{ scope.row.processDefinitionName }}v{{ scope.row.processDefinitionVersion }}.0</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="processDefinitionKey" label="æµç¨å®ä¹KEY"></el-table-column> |
| | | <el-table-column align="center" prop="name" label="ä»»å¡åç§°"></el-table-column> |
| | | <el-table-column align="center" prop="assigneeName" label="åç人"> |
| | | <template #default="scope"> |
| | | <template v-if="scope.row.participantVo && scope.row.assignee === null"> |
| | | <el-tag v-for="(item, index) in scope.row.participantVo.candidateName" :key="index" type="success"> |
| | | {{ item }} |
| | | <template v-if="scope.row.assigneeNames"> |
| | | <el-tag v-for="(name, index) in scope.row.assigneeNames.split(',')" :key="index" type="success"> |
| | | {{ name }} |
| | | </el-tag> |
| | | </template> |
| | | <template v-else> |
| | | <el-tag type="success"> |
| | | {{ scope.row.assigneeName || 'æ ' }} |
| | | </el-tag> |
| | | <el-tag type="success"> æ </el-tag> |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" min-width="70"> |
| | | <el-table-column align="center" label="æµç¨ç¶æ" prop="flowStatusName" min-width="70"> |
| | | <template #default="scope"> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.businessStatus"></dict-tag> |
| | | <dict-tag :options="wf_business_status" :value="scope.row.flowStatus"></dict-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column align="center" prop="createTime" label="å建æ¶é´" width="160"></el-table-column> |
| | |
| | | @pagination="handleQuery" |
| | | /> |
| | | </el-card> |
| | | <!-- ç³è¯·äºº --> |
| | | <UserSelect ref="userSelectRef" :multiple="true" :data="selectUserIds" @confirm-call-back="userSelectCallBack"></UserSelect> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { getPageByTaskWait } from '@/api/workflow/task'; |
| | | import { TaskQuery, TaskVO } from '@/api/workflow/task/types'; |
| | | import { pageByTaskWait } from '@/api/workflow/task'; |
| | | import { TaskQuery, FlowTaskVO } from '@/api/workflow/task/types'; |
| | | import workflowCommon from '@/api/workflow/workflowCommon'; |
| | | import { RouterJumpVo } from '@/api/workflow/workflowCommon/types'; |
| | | |
| | | const { proxy } = getCurrentInstance() as ComponentInternalInstance; |
| | | const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status')); |
| | | import UserSelect from '@/components/UserSelect'; |
| | | import { ref } from 'vue'; |
| | | import { UserVO } from '@/api/system/user/types'; |
| | | |
| | | const userSelectRef = ref<InstanceType<typeof UserSelect>>(); |
| | | //æäº¤ç»ä»¶ |
| | | const queryFormRef = ref<ElFormInstance>(); |
| | | // é®ç½©å± |
| | |
| | | const total = ref(0); |
| | | // 模åå®ä¹è¡¨æ ¼æ°æ® |
| | | const taskList = ref([]); |
| | | |
| | | //ç³è¯·äººid |
| | | const selectUserIds = ref<Array<number | string>>([]); |
| | | //ç³è¯·äººéæ©æ°é |
| | | const userSelectCount = ref(0); |
| | | // æ¥è¯¢åæ° |
| | | const queryParams = ref<TaskQuery>({ |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | name: undefined, |
| | | processDefinitionName: undefined, |
| | | processDefinitionKey: undefined |
| | | nodeName: undefined, |
| | | flowName: undefined, |
| | | flowCode: undefined, |
| | | createByIds: [] |
| | | }); |
| | | onMounted(() => { |
| | | getWaitingList(); |
| | |
| | | queryFormRef.value?.resetFields(); |
| | | queryParams.value.pageNum = 1; |
| | | queryParams.value.pageSize = 10; |
| | | queryParams.value.createByIds = []; |
| | | userSelectCount.value = 0; |
| | | handleQuery(); |
| | | }; |
| | | // å¤éæ¡é䏿°æ® |
| | |
| | | //å页 |
| | | const getWaitingList = () => { |
| | | loading.value = true; |
| | | getPageByTaskWait(queryParams.value).then((resp) => { |
| | | pageByTaskWait(queryParams.value).then((resp) => { |
| | | taskList.value = resp.rows; |
| | | total.value = resp.total; |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | //åç |
| | | const handleOpen = async (row: TaskVO) => { |
| | | const handleOpen = async (row: FlowTaskVO) => { |
| | | const routerJumpVo = reactive<RouterJumpVo>({ |
| | | wfDefinitionConfigVo: row.wfDefinitionConfigVo, |
| | | wfNodeConfigVo: row.wfNodeConfigVo, |
| | | businessKey: row.businessKey, |
| | | businessId: row.businessId, |
| | | taskId: row.id, |
| | | type: 'approval' |
| | | type: 'approval', |
| | | formCustom: row.formCustom, |
| | | formPath: row.formPath |
| | | }); |
| | | workflowCommon.routerJump(routerJumpVo, proxy); |
| | | }; |
| | | //æå¼ç³è¯·äººéæ© |
| | | const openUserSelect = () => { |
| | | userSelectRef.value.open(); |
| | | }; |
| | | //ç¡®è®¤éæ©ç³è¯·äºº |
| | | const userSelectCallBack = (data: UserVO[]) => { |
| | | userSelectCount.value = 0; |
| | | if (data && data.length > 0) { |
| | | userSelectCount.value = data.length; |
| | | selectUserIds.value = data.map((item) => item.userId); |
| | | queryParams.value.createByIds = selectUserIds.value; |
| | | } |
| | | }; |
| | | </script> |
| | |
| | | 'echarts', |
| | | 'vue-i18n', |
| | | '@vueup/vue-quill', |
| | | 'bpmn-js/lib/Viewer', |
| | | 'bpmn-js/lib/Modeler.js', |
| | | 'bpmn-js-properties-panel', |
| | | 'min-dash', |
| | | 'diagram-js/lib/navigation/movecanvas', |
| | | 'diagram-js/lib/navigation/zoomscroll', |
| | | 'bpmn-js/lib/features/palette/PaletteProvider', |
| | | 'bpmn-js/lib/features/context-pad/ContextPadProvider', |
| | | 'diagram-js/lib/draw/BaseRenderer', |
| | | 'tiny-svg', |
| | | 'image-conversion', |
| | | 'element-plus/es/components/**/css' |
| | | ] |