提交代码
parent
3f0d87a28d
commit
8045c5535b
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "ruoyi",
|
||||
"name": "yanzhu",
|
||||
"version": "3.6.2",
|
||||
"description": "若依管理系统",
|
||||
"author": "若依",
|
||||
"description": "总包单位管理系统",
|
||||
"author": "研筑",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
@ -19,6 +19,9 @@
|
|||
"@vueup/vue-quill": "1.1.0",
|
||||
"@vueuse/core": "9.5.0",
|
||||
"axios": "0.27.2",
|
||||
"bpmn-js": "^8.10.0",
|
||||
"bpmn-js-task-resize": "^1.2.0",
|
||||
"bpmn-js-token-simulation": "^0.10.0",
|
||||
"echarts": "5.4.0",
|
||||
"element-plus": "2.2.27",
|
||||
"file-saver": "2.0.5",
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { CategoryForm, CategoryQuery, CategoryVO } from '@/api/workflow/category/types';
|
||||
|
||||
// 查询流程分类列表
|
||||
export function listCategory(query: CategoryQuery): AxiosPromise<CategoryVO[]> {
|
||||
return request({
|
||||
url: '/workflow/category/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 查询流程分类列表
|
||||
export function listAllCategory(query?: CategoryQuery): AxiosPromise<CategoryVO[]> {
|
||||
return request({
|
||||
url: '/workflow/category/listAll',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 查询流程分类详细
|
||||
export function getCategory(categoryId?: string | number): AxiosPromise<CategoryVO> {
|
||||
return request({
|
||||
url: '/workflow/category/' + categoryId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 新增流程分类
|
||||
export function addCategory(data: CategoryForm) {
|
||||
return request({
|
||||
url: '/workflow/category',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 修改流程分类
|
||||
export function updateCategory(data: CategoryForm) {
|
||||
return request({
|
||||
url: '/workflow/category',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 删除流程分类
|
||||
export function delCategory(categoryIds?: string | number | Array<string | number>) {
|
||||
return request({
|
||||
url: '/workflow/category/' + categoryIds,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* 流程分类查询对象类型
|
||||
*/
|
||||
export interface CategoryQuery extends PageQuery {
|
||||
categoryName?: string;
|
||||
code?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程分类返回对象
|
||||
*/
|
||||
export interface CategoryVO extends BaseEntity {
|
||||
categoryId: string | number;
|
||||
categoryName: string;
|
||||
code: string;
|
||||
remark: string;
|
||||
}
|
||||
|
||||
export interface CategoryForm {
|
||||
categoryId?: string | number;
|
||||
categoryName?: string;
|
||||
code?: string;
|
||||
remark?: string;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { DeployVO, ProcessQuery } from '@/api/workflow/deploy/types';
|
||||
|
||||
// 查询流程部署列表
|
||||
export function listDeploy(query: ProcessQuery): AxiosPromise<DeployVO[]> {
|
||||
return request({
|
||||
url: '/workflow/deploy/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
export function listPublish(query: ProcessQuery): AxiosPromise<DeployVO[]> {
|
||||
return request({
|
||||
url: '/workflow/deploy/publishList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 获取流程模型流程图
|
||||
export function getBpmnXml(definitionId?: string) {
|
||||
return request({
|
||||
url: '/workflow/deploy/bpmnXml/' + definitionId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 修改流程状态
|
||||
export function changeState(params?: any) {
|
||||
return request({
|
||||
url: '/workflow/deploy/changeState',
|
||||
method: 'put',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
// 删除流程部署
|
||||
export function delDeploy(deployIds?: string | string[]) {
|
||||
return request({
|
||||
url: '/workflow/deploy/' + deployIds,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
export interface DeployVO {
|
||||
definitionId: string;
|
||||
processName: string;
|
||||
processKey: string;
|
||||
category: string;
|
||||
version: number;
|
||||
formId: string | number;
|
||||
formName: string;
|
||||
deploymentId: string;
|
||||
suspended: boolean;
|
||||
deploymentTime: string;
|
||||
}
|
||||
|
||||
export interface ProcessQuery extends PageQuery {
|
||||
processKey?: string;
|
||||
processName?: string;
|
||||
category?: string;
|
||||
state?: string;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
import request from '@/utils/request';
|
||||
import { FormForm, FormQuery, FormVO } from './types';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
// 查询流程表单列表
|
||||
export function listForm(query?: FormQuery): AxiosPromise<FormVO[]> {
|
||||
return request({
|
||||
url: '/workflow/form/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 查询流程表单详细
|
||||
export function getForm(formId: string | number): AxiosPromise<FormVO> {
|
||||
return request({
|
||||
url: '/workflow/form/' + formId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 新增流程表单
|
||||
export function addForm(data: FormForm) {
|
||||
return request({
|
||||
url: '/workflow/form',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 修改流程表单
|
||||
export function updateForm(data: FormForm) {
|
||||
return request({
|
||||
url: '/workflow/form',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 删除流程表单
|
||||
export function delForm(formId?: string | number | (string | number)[]) {
|
||||
return request({
|
||||
url: '/workflow/form/' + formId,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
export interface FormVO extends BaseEntity {
|
||||
formId: number | string;
|
||||
formName: string;
|
||||
content: string;
|
||||
remark: string;
|
||||
}
|
||||
|
||||
export interface FormForm {
|
||||
formId: number | string | undefined;
|
||||
formName: string;
|
||||
content?: string;
|
||||
remark: string;
|
||||
}
|
||||
|
||||
export interface FormQuery extends PageQuery {
|
||||
formName?: string;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { UserVO, DeptVO } from '@/api/workflow/identity/types';
|
||||
|
||||
// 查询流程模型信息
|
||||
export function selectUser(query?: any): AxiosPromise<UserVO[]> {
|
||||
return request({
|
||||
url: '/workflow/identity/selectUser',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
export function deptTreeSelect(): AxiosPromise<DeptVO[]> {
|
||||
return request({
|
||||
url: '/workflow/identity/deptTree',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
export interface UserVO {
|
||||
userId: string | number;
|
||||
username: string;
|
||||
nickname: string;
|
||||
deptId: number;
|
||||
}
|
||||
|
||||
export interface DeptVO {
|
||||
deptId: string | number;
|
||||
deptName: string;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
import request from '@/utils/request';
|
||||
import {ListenerFieldForm, ListenerForm, ListenerQuery, ListenerVO} from './types';
|
||||
import {AxiosPromise} from 'axios';
|
||||
|
||||
// 分页查询流程监听器
|
||||
export function queryListenerPage(query?: ListenerQuery): AxiosPromise<ListenerVO[]> {
|
||||
return request({
|
||||
url: '/workflow/listener/queryPage',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 列表查询流程监听器
|
||||
export function queryListenerList(query?: ListenerQuery): AxiosPromise<ListenerVO[]> {
|
||||
return request({
|
||||
url: '/workflow/listener/queryList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 详细查询流程监听器
|
||||
export function getListener(formId: string | number): AxiosPromise<ListenerVO> {
|
||||
return request({
|
||||
url: '/workflow/listener/query/' + formId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 新增流程监听器
|
||||
export function addListener(data: ListenerForm) {
|
||||
return request({
|
||||
url: '/workflow/listener/insert',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 修改流程监听器
|
||||
export function updateListener(data: ListenerForm) {
|
||||
return request({
|
||||
url: '/workflow/listener/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 删除流程监听器
|
||||
export function delListener(listenerId?: string | number | (string | number)[]) {
|
||||
return request({
|
||||
url: '/workflow/listener/delete/' + listenerId,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
||||
|
||||
// 新增流程监听器字段
|
||||
export function insertListenerFieldAPI(data: ListenerFieldForm) {
|
||||
return request({
|
||||
url: '/workflow/listener/insertField',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 修改流程监听器字段
|
||||
export function updateListenerFieldAPI(data: ListenerFieldForm) {
|
||||
return request({
|
||||
url: '/workflow/listener/updateField',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 删除流程监听器字段
|
||||
export function deleteListenerFieldAPI(fieldIds?: string | number | (string | number)[]) {
|
||||
return request({
|
||||
url: '/workflow/listener/deleteField/' + fieldIds,
|
||||
method: 'post'
|
||||
});
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
export interface ListenerVO {
|
||||
id: number | string;
|
||||
listenerType: string;
|
||||
name: string;
|
||||
eventType: string;
|
||||
valueType: string;
|
||||
value: string;
|
||||
fields: ListenerFieldVO[];
|
||||
}
|
||||
|
||||
export interface ListenerForm {
|
||||
id: number | string | undefined;
|
||||
listenerType: string;
|
||||
name: string;
|
||||
eventType: string;
|
||||
valueType: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface ListenerQuery extends PageQuery {
|
||||
listenerType?: string;
|
||||
eventType?: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export interface ListenerFieldVO {
|
||||
id: number | string;
|
||||
listenerId: number | string;
|
||||
fieldName: string;
|
||||
fieldType: string;
|
||||
fieldValue: string;
|
||||
}
|
||||
|
||||
export interface ListenerFieldForm {
|
||||
id: number | string | undefined;
|
||||
listenerId: number | string | undefined;
|
||||
fieldName: string | undefined;
|
||||
fieldType: string | undefined;
|
||||
fieldValue: string | undefined;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ModelQuery, ModelVO } from './types';
|
||||
|
||||
// 查询流程模型信息
|
||||
export function listModel(query?: ModelQuery): AxiosPromise<ModelVO[]> {
|
||||
return request({
|
||||
url: '/workflow/model/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 查询流程模型信息
|
||||
export function historyModel(query?: ModelQuery): AxiosPromise<ModelVO[]> {
|
||||
return request({
|
||||
url: '/workflow/model/historyList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
export function getModel(modelId?: string) {
|
||||
return request({
|
||||
url: '/workflow/model/' + modelId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 新增模型信息
|
||||
export function addModel(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/model',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 修改模型信息
|
||||
export function updateModel(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/model',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 保存流程模型
|
||||
export function saveModel(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/model/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
export function latestModel(params?: any) {
|
||||
return request({
|
||||
url: '/workflow/model/latest',
|
||||
method: 'post',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
export function delModel(modelIds?: string | string[]) {
|
||||
return request({
|
||||
url: '/workflow/model/' + modelIds,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
export function deployModel(params?: any) {
|
||||
return request({
|
||||
url: '/workflow/model/deploy',
|
||||
method: 'post',
|
||||
params: params
|
||||
});
|
||||
}
|
||||
|
||||
// 获取流程模型流程图
|
||||
export function getBpmnXml(modelId?: string) {
|
||||
return request({
|
||||
url: '/workflow/model/bpmnXml/' + modelId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
export interface ModelVO extends BaseEntity {
|
||||
modelId: string;
|
||||
modelKey: string;
|
||||
modelName: string;
|
||||
category: string;
|
||||
version: number;
|
||||
formType: number;
|
||||
formId: number | string;
|
||||
description: string;
|
||||
createTime: string;
|
||||
bpmnXml: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface ModelForm {
|
||||
modelId: string | undefined;
|
||||
modelKey: string;
|
||||
modelName: string;
|
||||
category: string;
|
||||
description: string;
|
||||
formType: number | undefined;
|
||||
formId: number | string | undefined;
|
||||
bpmnXml: string;
|
||||
newVersion: boolean;
|
||||
}
|
||||
|
||||
export interface ModelQuery extends PageQuery {
|
||||
modelKey?: string;
|
||||
modelName?: string;
|
||||
}
|
||||
|
||||
export interface DesignerForm {
|
||||
modelId: string;
|
||||
form: {
|
||||
processName: string;
|
||||
processKey: string;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ProcessQuery, ProcessVO } from '@/api/workflow/work/types';
|
||||
|
||||
// 查询流程列表
|
||||
export function listProcess(query?: ProcessQuery): AxiosPromise<ProcessVO[]> {
|
||||
return request({
|
||||
url: '/workflow/process/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 查询流程列表
|
||||
export function getProcessForm(query?: any) {
|
||||
return request({
|
||||
url: '/workflow/process/getProcessForm',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 部署流程实例
|
||||
export function startProcess(processDefId?: string, data?: string) {
|
||||
return request({
|
||||
url: '/workflow/process/start/' + processDefId,
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 删除流程实例
|
||||
export function delProcess(ids?: string) {
|
||||
return request({
|
||||
url: '/workflow/process/instance/' + ids,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取流程图
|
||||
export function getBpmnXml(processDefId?: string) {
|
||||
return request({
|
||||
url: '/workflow/process/bpmnXml/' + processDefId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
export function detailProcess(query?: any) {
|
||||
return request({
|
||||
url: '/workflow/process/detail',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 我的发起的流程
|
||||
export function listOwnProcess(query?: any) {
|
||||
return request({
|
||||
url: '/workflow/process/ownList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 我待办的流程
|
||||
export function listTodoProcess(query?: any) {
|
||||
return request({
|
||||
url: '/workflow/process/todoList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 我待签的流程
|
||||
export function listClaimProcess(query?: any) {
|
||||
return request({
|
||||
url: '/workflow/process/claimList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 我已办的流程
|
||||
export function listFinishedProcess(query?: any) {
|
||||
return request({
|
||||
url: '/workflow/process/finishedList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 查询流程抄送列表
|
||||
export function listCopyProcess(query?: any) {
|
||||
return request({
|
||||
url: '/workflow/process/copyList',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
}
|
||||
|
||||
// 取消申请
|
||||
export function stopProcess(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/stopProcess',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import request from '@/utils/request';
|
||||
|
||||
// 完成任务
|
||||
export function complete(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/complete',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 委派任务
|
||||
export function delegate(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/delegate',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 转办任务
|
||||
export function transfer(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/transfer',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 退回任务
|
||||
export function returnTask(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/return',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 拒绝任务
|
||||
export function rejectTask(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/reject',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 签收任务
|
||||
export function claimTask(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/claim',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 可退回任务列表
|
||||
export function returnList(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/returnList',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
// 撤回任务
|
||||
export function revokeProcess(data?: any) {
|
||||
return request({
|
||||
url: '/workflow/task/revokeProcess',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
export interface ProcessVO extends BaseEntity {
|
||||
category: string;
|
||||
definitionId: string;
|
||||
deploymentId: string;
|
||||
deploymentTime: string;
|
||||
formId: string | number;
|
||||
formName: string;
|
||||
processKey: string;
|
||||
processName: string;
|
||||
taskId: string;
|
||||
suspended: boolean;
|
||||
version: number;
|
||||
procInsId?: string;
|
||||
}
|
||||
|
||||
export interface ProcessQuery extends PageQuery {
|
||||
processKey?: string;
|
||||
processName?: string;
|
||||
category?: string;
|
||||
state?: string;
|
||||
}
|
||||
|
||||
export interface TaskForm {
|
||||
comment: string;
|
||||
procInsId: string;
|
||||
taskId: string;
|
||||
userId: string;
|
||||
copyUserIds: string;
|
||||
nextUserIds: string;
|
||||
vars: string;
|
||||
targetKey: string;
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
|
||||
<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="code">
|
||||
<el-input v-model="queryParams.code" 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>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<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="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['workflow:category:edit']">
|
||||
修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['workflow:category:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport()" v-hasPermi="['workflow:category:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="categoryList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="分类编号" align="center" prop="categoryId" v-if="true" />
|
||||
<el-table-column label="分类名称" align="center" prop="categoryName" />
|
||||
<el-table-column label="分类编码" align="center" prop="code" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" width="150" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['workflow:category:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['workflow:category:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<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="categoryName">
|
||||
<el-input v-model="form.categoryName" placeholder="请输入分类名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类编码" prop="code">
|
||||
<el-input v-model="form.code" placeholder="请输入分类编码" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Category" lang="ts">
|
||||
import { listCategory, getCategory, delCategory, addCategory, updateCategory } from "@/api/workflow/category";
|
||||
import { CategoryForm, CategoryQuery, CategoryVO } from "@/api/workflow/category/types";
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const categoryList = ref<CategoryVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref(ElForm);
|
||||
const categoryFormRef = ref(ElForm);
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
const initFormData: CategoryForm = {
|
||||
categoryId: undefined,
|
||||
categoryName: '',
|
||||
code: '',
|
||||
remark: ''
|
||||
}
|
||||
const data = reactive<PageData<CategoryForm, CategoryQuery>>({
|
||||
form: {...initFormData},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
categoryName: '',
|
||||
code: ''
|
||||
},
|
||||
rules: {
|
||||
categoryName: [{ required: true, message: "分类名称不能为空", trigger: "blur" }],
|
||||
code: [{ required: true, message: "分类编码不能为空", trigger: "blur" }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询参数列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listCategory(queryParams.value);
|
||||
categoryList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
categoryFormRef.value.resetFields();
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: CategoryVO[]) => {
|
||||
ids.value = selection.map(item => item.categoryId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
dialog.visible = true;
|
||||
dialog.title = "添加参数";
|
||||
nextTick(() => {
|
||||
reset();
|
||||
})
|
||||
}
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = (row?: CategoryVO) => {
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改参数";
|
||||
const categoryId = row?.categoryId || ids.value[0];
|
||||
nextTick(async () => {
|
||||
reset();
|
||||
const res = await getCategory(categoryId);
|
||||
form.value = res.data;
|
||||
})
|
||||
}
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
categoryFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
form.value.categoryId ? await updateCategory(form.value) : await addCategory(form.value);
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
dialog.visible = false;
|
||||
getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: CategoryVO) => {
|
||||
const categoryIds = row?.categoryId || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除参数编号为"' + categoryIds + '"的数据项?');
|
||||
await delCategory(categoryIds);
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/category/export", {
|
||||
...queryParams.value
|
||||
}, `category_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
})
|
||||
</script>
|
|
@ -0,0 +1,235 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
|
||||
<el-form-item label="流程标识" prop="processKey">
|
||||
<el-input v-model="queryParams.processKey" placeholder="请输入流程标识" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input v-model="queryParams.processName" placeholder="请输入流程名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="流程分类">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="state">
|
||||
<el-select v-model="queryParams.state" clearable placeholder="请选择状态">
|
||||
<el-option :key="1" label="激活" value="active" />
|
||||
<el-option :key="2" label="挂起" value="suspended" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['workflow:deploy:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" fit :data="deployList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="流程标识" align="center" prop="processKey" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" prop="processName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程分类" align="center" prop="categoryName" :formatter="categoryFormat" />
|
||||
<el-table-column label="流程版本" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag size="small">v{{ scope.row.version }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="!scope.row.suspended">激活</el-tag>
|
||||
<el-tag type="warning" v-if="scope.row.suspended">挂起</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="部署时间" align="center" prop="deploymentTime" width="180" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="版本管理" placement="top">
|
||||
<el-button link type="primary" icon="PriceTag" @click="handlePublish(scope.row)" v-hasPermi="['workflow:deploy:list']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['workflow:deploy:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- <!– 流程图对话框 –>-->
|
||||
<!-- <el-dialog :title="processDialog.title" v-model="processDialog.visible" width="500px" append-to-body>-->
|
||||
<!-- <process-viewer :key="`designer-${processView.index}`" :xml="processView.xmlData" :style="{height: '400px'}" />-->
|
||||
<!-- </el-dialog>-->
|
||||
|
||||
<!-- 版本管理 -->
|
||||
<el-dialog title="版本管理" v-model="publishDialog.visible" width="700px" append-to-body>
|
||||
<el-table v-loading="publishLoading" :data="publishList">
|
||||
<el-table-column label="流程标识" align="center" prop="processKey" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" :show-overflow-tooltip="true">
|
||||
<template #default="scope">
|
||||
<el-button type="text" @click="handleProcessView(scope.row)">
|
||||
<span>{{ scope.row.processName }}</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="流程版本" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag size="small">v{{ scope.row.version }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="!scope.row.suspended">激活</el-tag>
|
||||
<el-tag type="warning" v-if="scope.row.suspended">挂起</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="挂起" placement="top">
|
||||
<el-button link type="primary" icon="VideoPause" @click="handleChangeState(scope.row, 'suspended')" v-hasPermi="['workflow:deploy:status']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="激活" placement="top">
|
||||
<el-button link type="primary" icon="VideoPlay" @click="handleChangeState(scope.row, 'active')" v-hasPermi="['workflow:deploy:status']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['workflow:deploy:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="publishTotal > 0" :total="publishTotal" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getPublishList" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Deploy" lang="ts">
|
||||
import { listAllCategory } from '@/api/workflow/category'
|
||||
import { listDeploy, listPublish, getBpmnXml, changeState, delDeploy } from '@/api/workflow/deploy'
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
import {DeployVO, ProcessQuery} from "@/api/workflow/deploy/types";
|
||||
import { ElForm } from 'element-plus';
|
||||
import {ModelVO} from "@/api/workflow/model/types";
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
|
||||
const deployList = ref<DeployVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true)
|
||||
const ids = ref<Array<string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const publishList = ref<DeployVO[]>([]);
|
||||
const publishLoading = ref(true);
|
||||
const publishTotal = ref(0);
|
||||
|
||||
const queryFormRef = ref(ElForm);
|
||||
const processDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
const publishDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
const data = reactive<PageData<{}, ProcessQuery>>({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processKey: '',
|
||||
processName: '',
|
||||
category: ''
|
||||
},
|
||||
rules: {}
|
||||
});
|
||||
const { queryParams } = toRefs(data);
|
||||
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
};
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listDeploy(queryParams.value);
|
||||
deployList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: DeployVO[]) => {
|
||||
ids.value = selection.map(item => item.deploymentId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: DeployVO) => {
|
||||
const deploymentIds = row?.deploymentId || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除参数编号为"' + deploymentIds + '"的数据项?');
|
||||
await delDeploy(deploymentIds);
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
const getPublishList = async () => {
|
||||
publishLoading.value = true;
|
||||
const res = await listPublish(queryParams.value);
|
||||
publishList.value = res.rows;
|
||||
publishTotal.value = res.total;
|
||||
publishLoading.value = false;
|
||||
}
|
||||
const handlePublish = (row: DeployVO) => {
|
||||
queryParams.value.processKey = row.processKey;
|
||||
publishDialog.visible = true;
|
||||
getPublishList();
|
||||
}
|
||||
const handleProcessView = (row: DeployVO) => {
|
||||
|
||||
}
|
||||
const handleChangeState = async (row: DeployVO, state: string) => {
|
||||
const params = {
|
||||
definitionId: row.definitionId,
|
||||
state: state
|
||||
}
|
||||
await changeState(params);
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
getPublishList();
|
||||
}
|
||||
|
||||
const categoryFormat = (row: ModelVO) => {
|
||||
return categoryOptions.value.find(k => k.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
getList();
|
||||
})
|
||||
</script>
|
|
@ -0,0 +1,260 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="表单名称" prop="formName">
|
||||
<el-input v-model="queryParams.formName" 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>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['workflow:form:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['workflow:form:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['workflow:form:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:form:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="formList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="表单主键" align="center" prop="formId" v-if="false" />
|
||||
<el-table-column label="表单名称" align="center" prop="formName" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['workflow:form:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['workflow:form:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['workflow:form:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 流程表单设计器对话框 -->
|
||||
<el-dialog :title="designer.title" v-model="designer.visible" fullscreen>
|
||||
<div id="form-designer">
|
||||
<v-form-designer ref="vfDesignerRef" :resetFormJson="true" :designer-config="designerConfig">
|
||||
<!-- 自定义按钮插槽 -->
|
||||
<template #customToolButtons>
|
||||
<el-button link type="primary" icon="Finished" @click="dialog.visible = true">保存</el-button>
|
||||
</template>
|
||||
</v-form-designer>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 预览表单对话框 -->
|
||||
<el-dialog :title="render.title" v-model="render.visible" width="60%" append-to-body>
|
||||
<v-form-render :form-json="{}" :form-data="{}" ref="vfRenderRef" />
|
||||
</el-dialog>
|
||||
|
||||
<!-- 添加或修改流程表单对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body>
|
||||
<el-form ref="formFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="表单名称" prop="formName">
|
||||
<el-input v-model="form.formName" placeholder="请输入表单名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Form" lang="ts">
|
||||
import { listForm, addForm, updateForm, getForm, delForm } from "@/api/workflow/form";
|
||||
import { FormForm, FormQuery, FormVO } from "@/api/workflow/form/types";
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const formList = ref<FormVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const vfDesignerRef = ref(null);
|
||||
const vfRenderRef = ref(null);
|
||||
const formFormRef = ref(ElForm);
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const designerConfig = reactive({
|
||||
externalLink: true,
|
||||
toolbarMaxWidth: 510,
|
||||
// languageMenu: true,
|
||||
//externalLink: false,
|
||||
//formTemplates: false,
|
||||
//eventCollapse: false,
|
||||
//clearDesignerButton: false,
|
||||
//previewFormButton: false,
|
||||
})
|
||||
const designer = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
})
|
||||
const render = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
})
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
const initFormData: FormForm = {
|
||||
formId: undefined,
|
||||
formName: '',
|
||||
content: '',
|
||||
remark: ''
|
||||
}
|
||||
const data = reactive<PageData<FormForm, FormQuery>>({
|
||||
form: {...initFormData},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
formName: ''
|
||||
},
|
||||
rules: {
|
||||
formName: [{ required: true, message: "表单名称不能为空", trigger: "blur" }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs<PageData<FormForm, FormQuery>>(data);
|
||||
|
||||
/** 查询岗位列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listForm(queryParams.value);
|
||||
formList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: FormVO[]) => {
|
||||
ids.value = selection.map(item => item.formId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 新增表单操作 */
|
||||
const handleAdd = () => {
|
||||
designer.visible = true;
|
||||
nextTick(() => {
|
||||
reset();
|
||||
vfDesignerRef.value.clearDesigner();
|
||||
})
|
||||
}
|
||||
/** 修改表单操作 */
|
||||
const handleUpdate = (row?: FormVO) => {
|
||||
designer.visible = true;
|
||||
nextTick(async () => {
|
||||
const formId = row?.formId || ids.value[0];
|
||||
const res = await getForm(formId);
|
||||
form.value = res.data;
|
||||
vfDesignerRef.value.setFormJson(form.value.content);
|
||||
})
|
||||
}
|
||||
/** 查看表单操作 */
|
||||
const handleDetail = (row: FormVO) => {
|
||||
render.visible = true;
|
||||
render.title = '查看表单详情';
|
||||
nextTick(async () => {
|
||||
vfRenderRef.value.setFormJson(row.content || {formConfig: {}, widgetList: []});
|
||||
});
|
||||
}
|
||||
/** 提交表单操作 */
|
||||
const submitForm = () => {
|
||||
const formJson = vfDesignerRef.value.getFormJson();
|
||||
form.value.content = JSON.stringify(formJson);
|
||||
nextTick(async () => {
|
||||
form.value.formId ? await updateForm(form.value) : await addForm(form.value);
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
dialog.visible = false;
|
||||
designer.visible = false;
|
||||
getList();
|
||||
})
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: FormVO) => {
|
||||
const formIds = row?.formId || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除表单编号为"' + formIds + '"的数据项?');
|
||||
await delForm(formIds);
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/form/export", {
|
||||
...queryParams.value
|
||||
}, `form_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#form-designer {
|
||||
.main-container {
|
||||
margin: 0;
|
||||
}
|
||||
label {
|
||||
font-weight: normal;
|
||||
}
|
||||
:deep(.external-link) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,479 @@
|
|||
<template>
|
||||
<div class="p-2 app-container">
|
||||
<!-- 查询条件 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="search">
|
||||
<el-form ref="queryFormRef" :inline="true" :model="queryParams" label-width="120">
|
||||
<el-form-item label="监听类型" prop="listenerType">
|
||||
<el-select v-model="queryParams.listenerType" clearable placeholder="请选择监听类型" @change="handleQuery">
|
||||
<el-option v-for="dict in sys_listener_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="queryParams.name" clearable placeholder="请输入名称" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="事件类型" prop="eventType">
|
||||
<el-select v-model="queryParams.eventType" clearable placeholder="请选择事件类型" @change="handleQuery">
|
||||
<el-option
|
||||
v-for="dict in sys_task_listener_event_type"
|
||||
v-if="queryParams.listenerType === 'task'"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
<el-option
|
||||
v-for="dict in sys_execution_listener_event_type"
|
||||
v-if="queryParams.listenerType === 'execution'"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
<el-option
|
||||
v-for="dict in sys_task_listener_event_type"
|
||||
v-if="!queryParams.listenerType"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
<el-option
|
||||
v-for="dict in sys_execution_listener_event_type"
|
||||
v-if="!queryParams.listenerType"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="Search" type="primary" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<!-- 操作按钮 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['workflow:listener:add']" icon="Plus" plain type="primary" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['workflow:listener:edit']" :disabled="single" icon="Edit" plain type="success" @click="handleUpdate()"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['workflow:listener:remove']" :disabled="multiple" icon="Delete" plain type="danger" @click="handleDelete()"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button v-hasPermi="['workflow:listener:export']" icon="Download" plain type="warning" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 分页列表 -->
|
||||
<el-table
|
||||
v-loading="tableLoading"
|
||||
:data="listenerList"
|
||||
@selection-change="handleSelectionChange"
|
||||
v-fixTableHeight
|
||||
highlight-current-row
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column type="expand" width="50px">
|
||||
<template #default="props">
|
||||
<el-table :data="props.row.fields" width="60%">
|
||||
<el-table-column v-if="false" label="主键" prop="id" />
|
||||
<el-table-column label="字段名称" prop="fieldName" />
|
||||
<el-table-column label="字段类型" prop="fieldType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_listener_field_type" :value="scope.row.fieldType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="字段值" prop="fieldValue" />
|
||||
<el-table-column align="center" class-name="small-padding fixed-width" label="操作">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
v-hasPermi="['workflow:listener:edit']"
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleFieldUpdate(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
v-hasPermi="['workflow:listener:remove']"
|
||||
icon="Delete"
|
||||
link
|
||||
type="danger"
|
||||
@click="handleFieldDelete(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="false" align="center" label="主键" prop="id" />
|
||||
<el-table-column align="center" label="监听类型" prop="listenerType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_listener_type" :value="scope.row.listenerType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="名称" prop="name" />
|
||||
<el-table-column align="center" label="值类型" prop="valueType">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_listener_value_type" :value="scope.row.valueType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="值" prop="value" />
|
||||
<el-table-column align="center" label="事件类型" prop="eventType">
|
||||
<template #default="scope">
|
||||
<dict-tag v-if="scope.row.listenerType === 'task'" :options="sys_task_listener_event_type" :value="scope.row.eventType" />
|
||||
<dict-tag v-if="scope.row.listenerType === 'execution'" :options="sys_execution_listener_event_type" :value="scope.row.eventType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" class-name="small-padding fixed-width" label="操作">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="添加字段" placement="top">
|
||||
<el-button v-hasPermi="['workflow:listener:edit']" icon="Plus" link type="primary" @click="addField(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['workflow:listener:edit']" icon="Edit" link type="primary" @click="handleUpdate(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['workflow:listener:remove']" icon="Delete" link type="danger" @click="handleDelete(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination v-show="total > 0" v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageNum" :total="total" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改流程表单对话框 -->
|
||||
<el-dialog v-model="dialog.visible" :close-on-click-modal="false" :title="dialog.title" append-to-body width="600px">
|
||||
<el-form ref="listenerFormRef" v-loading="formLoading" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="监听类型" prop="listenerType">
|
||||
<el-radio-group v-model="form.listenerType">
|
||||
<el-radio v-for="dict in sys_listener_type" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="值类型" prop="valueType">
|
||||
<el-radio-group v-model="form.valueType">
|
||||
<el-radio v-for="dict in sys_listener_value_type" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="值" prop="value">
|
||||
<el-input v-model="form.value" placeholder="请输入值" />
|
||||
</el-form-item>
|
||||
<el-form-item label="事件类型" prop="eventType">
|
||||
<el-select v-model="form.eventType" clearable placeholder="请选择事件类型" style="width: 100%">
|
||||
<el-option
|
||||
v-for="dict in sys_task_listener_event_type"
|
||||
v-if="form.listenerType === 'task'"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
<el-option
|
||||
v-for="dict in sys_execution_listener_event_type"
|
||||
v-if="form.listenerType === 'execution'"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 监听器字段对话框 -->
|
||||
<el-dialog v-model="fieldDialog.visible" :close-on-click-modal="false" :title="fieldDialog.title" append-to-body width="600px">
|
||||
<el-form ref="listenerFieldFormRef" v-loading="fieldFormLoading" :model="initFieldFormData" :rules="filedRules" label-width="120px">
|
||||
<el-form-item label="名称" prop="fieldName">
|
||||
<el-input v-model="filedForm.fieldName" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字段类型" prop="fieldType">
|
||||
<el-radio-group v-model="filedForm.fieldType">
|
||||
<el-radio v-for="dict in sys_listener_field_type" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="值" prop="fieldValue">
|
||||
<el-input v-model="filedForm.fieldValue" placeholder="请输入值" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitFieldForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" name="Form" setup>
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
import {
|
||||
addListener,
|
||||
deleteListenerFieldAPI,
|
||||
delListener,
|
||||
getListener,
|
||||
insertListenerFieldAPI,
|
||||
queryListenerPage,
|
||||
updateListener,
|
||||
updateListenerFieldAPI
|
||||
} from "@/api/workflow/listener";
|
||||
import {
|
||||
ListenerFieldForm,
|
||||
ListenerFieldVO,
|
||||
ListenerForm,
|
||||
ListenerQuery,
|
||||
ListenerVO
|
||||
} from "@/api/workflow/listener/types";
|
||||
import {ComponentInternalInstance} from "vue";
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const {
|
||||
sys_listener_type,
|
||||
sys_listener_value_type,
|
||||
sys_task_listener_event_type,
|
||||
sys_execution_listener_event_type,
|
||||
sys_listener_field_type
|
||||
} = toRefs<any>(proxy?.useDict("sys_listener_type", "sys_listener_value_type", "sys_task_listener_event_type", "sys_execution_listener_event_type", "sys_listener_field_type"));
|
||||
|
||||
const listenerList = ref<ListenerVO[]>([]);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const names = ref<Array<string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const tableLoading = ref(false);
|
||||
const formLoading = ref(false);
|
||||
const fieldFormLoading = ref(false);
|
||||
const listenerFormRef = ref(ElForm);
|
||||
const listenerFieldFormRef = ref(ElForm);
|
||||
const queryFormRef = ref(ElForm);
|
||||
const listenerId = ref<number | string>('');
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const fieldDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
const initFormData: ListenerForm = {
|
||||
id: undefined,
|
||||
valueType: '',
|
||||
eventType: '',
|
||||
listenerType: '',
|
||||
name: '',
|
||||
value: ''
|
||||
}
|
||||
|
||||
const data = reactive<PageData<ListenerForm, ListenerQuery>>({
|
||||
form: {...initFormData},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: '',
|
||||
listenerType: '',
|
||||
eventType: ''
|
||||
},
|
||||
rules: {
|
||||
listenerType: [{ required: true, message: "监听类型不能为空", trigger: "blur" }],
|
||||
name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
|
||||
valueType: [{ required: true, message: "值类型不能为空", trigger: "blur" }],
|
||||
value: [{ required: true, message: "值不能为空", trigger: "blur" }]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs<PageData<ListenerForm, ListenerQuery>>(data);
|
||||
|
||||
const initFieldFormData: ListenerFieldForm = {
|
||||
id: undefined,
|
||||
listenerId: undefined,
|
||||
fieldName: undefined,
|
||||
fieldType: undefined,
|
||||
fieldValue: undefined
|
||||
}
|
||||
|
||||
const filedData = reactive({
|
||||
filedForm: {...initFieldFormData},
|
||||
filedRules: {
|
||||
fieldName: [{ required: true, message: "请输入字段名称", trigger: "blur" }],
|
||||
fieldType: [{ required: true, message: "请选择字段类型", trigger: "blur" }]
|
||||
}
|
||||
})
|
||||
|
||||
const { filedForm, filedRules } = toRefs(filedData);
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
tableLoading.value = true;
|
||||
const res = await queryListenerPage(queryParams.value);
|
||||
listenerList.value = res.rows;
|
||||
total.value = res.total;
|
||||
tableLoading.value = false;
|
||||
}
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
fieldDialog.visible = false;
|
||||
}
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
filedForm.value = {...initFieldFormData};
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ListenerVO[]) => {
|
||||
ids.value = selection.map(item => item.id);
|
||||
names.value = selection.map(item => item.name);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 新增表单操作 */
|
||||
const handleAdd = () => {
|
||||
dialog.visible = true;
|
||||
nextTick(() => {
|
||||
reset();
|
||||
})
|
||||
}
|
||||
/** 修改表单操作 */
|
||||
const handleUpdate = (row?: ListenerVO) => {
|
||||
dialog.visible = true;
|
||||
const id = row?.id || ids.value[0];
|
||||
nextTick(async () => {
|
||||
formLoading.value = true;
|
||||
reset();
|
||||
const res = await getListener(id);
|
||||
formLoading.value = false;
|
||||
form.value = res.data;
|
||||
})
|
||||
}
|
||||
/** 提交表单操作 */
|
||||
const submitForm = () => {
|
||||
listenerFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
dialog.visible = true;
|
||||
formLoading.value = true;
|
||||
try {
|
||||
form.value.id ? await updateListener(form.value) : await addListener(form.value);
|
||||
} finally {
|
||||
formLoading.value = false;
|
||||
}
|
||||
dialog.visible = false;
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ListenerVO) => {
|
||||
const listenerIds = row?.id || ids.value;
|
||||
const listenerNames = row?.name || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除【' + listenerNames + '】的数据项?');
|
||||
tableLoading.value = true;
|
||||
try {
|
||||
await delListener(listenerIds);
|
||||
} finally {
|
||||
tableLoading.value = false;
|
||||
}
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
/** 添加字段操作 */
|
||||
const addField = (row: ListenerVO) => {
|
||||
fieldDialog.visible = true;
|
||||
// listenerField.value = row.fields;
|
||||
listenerId.value = row.id;
|
||||
nextTick(() => {
|
||||
reset();
|
||||
filedForm.value.listenerId = row.id;
|
||||
})
|
||||
}
|
||||
/** 修改字段操作 */
|
||||
const handleFieldUpdate = (row: ListenerFieldVO) => {
|
||||
fieldDialog.visible = true;
|
||||
filedForm.value.id = row.id;
|
||||
filedForm.value.listenerId = row.listenerId;
|
||||
filedForm.value.fieldName = row.fieldName;
|
||||
filedForm.value.fieldType = row.fieldType;
|
||||
filedForm.value.fieldValue = row.fieldValue;
|
||||
}
|
||||
/** 提交字段表单操作 */
|
||||
const submitFieldForm = () => {
|
||||
listenerFieldFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
fieldDialog.visible = true;
|
||||
fieldFormLoading.value = true;
|
||||
try {
|
||||
filedForm.value.id ? await updateListenerFieldAPI(filedForm.value) : await insertListenerFieldAPI(filedForm.value);
|
||||
} finally {
|
||||
fieldFormLoading.value = false;
|
||||
}
|
||||
listenerId.value = '';
|
||||
fieldDialog.visible = false;
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 删除字段按钮操作 */
|
||||
const handleFieldDelete = async (row?: ListenerFieldVO) => {
|
||||
const fieldIds = row?.id || ids.value;
|
||||
const fieldNames = row?.fieldName || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除【' + fieldNames + '】的数据项?');
|
||||
tableLoading.value = true;
|
||||
try {
|
||||
await deleteListenerFieldAPI(fieldIds);
|
||||
} finally {
|
||||
tableLoading.value = false;
|
||||
}
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/form/export", {
|
||||
...queryParams.value
|
||||
}, `form_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
</script>
|
|
@ -0,0 +1,436 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="模型标识" prop="modelKey">
|
||||
<el-input v-model="queryParams.modelKey" placeholder="请输入模型标识" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="模型名称" prop="modelName">
|
||||
<el-input v-model="queryParams.modelName" placeholder="请输入模型名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="请选择" @change="handleQuery">
|
||||
<el-option
|
||||
v-for="item in categoryOptions"
|
||||
:key="item.categoryId"
|
||||
:label="item.categoryName"
|
||||
:value="item.code">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="请选择" @change="handleQuery">
|
||||
<el-option
|
||||
v-for="item in categoryOptions"
|
||||
:key="item.categoryId"
|
||||
:label="item.categoryName"
|
||||
:value="item.code">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['workflow:model:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['workflow:model:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:model:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="modelList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="模型标识" align="center" prop="modelKey" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="模型名称" align="center" :show-overflow-tooltip="true">
|
||||
<template #default="scope">
|
||||
<el-button type="text" @click="handleProcessView(scope.row)">
|
||||
<span>{{ scope.row.modelName }}</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="模型名称" align="center" prop="modelName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程分类" align="center" prop="categoryName" :formatter="categoryFormat" />
|
||||
<el-table-column label="模型版本" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag size="small">v{{ scope.row.version }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述" align="center" prop="description" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['workflow:model:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['workflow:model:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="设计" placement="top">
|
||||
<el-button link type="primary" icon="Brush" @click="handleDesigner(scope.row)" v-hasPermi="['workflow:model:designer']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="部署" placement="top">
|
||||
<el-button link type="primary" icon="Promotion" @click="handleDeploy(scope.row)" v-hasPermi="['workflow:model:deploy']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="历史" placement="top">
|
||||
<el-button link type="primary" icon="Discount" @click="handleHistory(scope.row)" v-hasPermi="['workflow:model:list']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改模型信息对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="modelFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="模型标识" prop="modelKey">
|
||||
<el-input v-model="form.modelKey" clearable disabled placeholder="请输入模型标识" />
|
||||
</el-form-item>
|
||||
<el-form-item label="模型名称" prop="modelName">
|
||||
<el-input v-model="form.modelName" clearable :disabled="form.modelId !== undefined" placeholder="请输入模型名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="form.category" placeholder="请选择" clearable style="width:100%">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" type="textarea" placeholder="请输入内容" maxlength="200" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="designer.title" v-model="designer.visible" append-to-body fullscreen>
|
||||
<ProcessDesigner
|
||||
:key="`designer-${reloadIndex}`"
|
||||
ref="modelDesignerRef"
|
||||
v-loading="designerLoading"
|
||||
:designer-form="designerForm"
|
||||
:bpmn-xml="bpmnXml"
|
||||
@save="onSaveDesigner"
|
||||
/>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="history.title" v-model="history.visible" append-to-body>
|
||||
<el-table v-loading="historyLoading" :data="historyList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="模型标识" align="center" prop="modelKey" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="模型名称" align="center" prop="modelName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程分类" align="center" prop="categoryName" :formatter="categoryFormat" />
|
||||
<el-table-column label="模型版本" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag>v{{ scope.row.version }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述" align="center" prop="description" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="部署" placement="top">
|
||||
<el-button link type="primary" icon="Promotion" @click="handleDeploy(scope.row)" v-hasPermi="['workflow:model:deploy']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="设为最新" placement="top">
|
||||
<el-button link type="primary" icon="Star" @click="handleLatest(scope.row)" v-hasPermi="['workflow:model:save']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-dialog>
|
||||
|
||||
<!-- 流程图 -->
|
||||
<el-dialog :title="processDialog.title" v-model="processDialog.visible" width="70%">
|
||||
<process-viewer :key="`designer-${reloadIndex}`" :xml="processXml" :style="{height: '650px'}" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Model" lang="ts">
|
||||
import { getBpmnXml, listModel, historyModel, latestModel, addModel, updateModel, saveModel, delModel, deployModel, getModel } from "@/api/workflow/model";
|
||||
import { listAllCategory } from "@/api/workflow/category";
|
||||
import { ModelForm, ModelQuery, ModelVO, DesignerForm } from "@/api/workflow/model/types";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
import ProcessDesigner from "@/components/ProcessDesigner";
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const modelList = ref<ModelVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
const designerLoading = ref(true);
|
||||
const bpmnXml = ref<string>('');
|
||||
const reloadIndex = ref(0);
|
||||
const processXml = ref<string>("");
|
||||
|
||||
const historyList = ref<ModelVO[]>([]);
|
||||
const historyLoading = ref(true);
|
||||
const historyTotal = ref(0);
|
||||
|
||||
const modelFormRef = ref(ElForm);
|
||||
const queryFormRef = ref(ElForm);
|
||||
const modelDesignerRef = ref(null)
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const processDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: '流程图'
|
||||
});
|
||||
|
||||
const designer = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const history = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ModelForm = {
|
||||
modelId: undefined,
|
||||
modelKey: `Process_${new Date().getTime()}`,
|
||||
modelName: `业务流程_${new Date().getTime()}`,
|
||||
category: '',
|
||||
description: '',
|
||||
formType: undefined,
|
||||
formId: undefined,
|
||||
bpmnXml: '',
|
||||
newVersion: false
|
||||
}
|
||||
|
||||
const data = reactive<PageData<ModelForm, ModelQuery>>({
|
||||
form: {...initFormData},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
modelKey: '',
|
||||
modelName: '',
|
||||
category: ''
|
||||
},
|
||||
rules: {
|
||||
modelKey: [{ required: true, message: "岗位名称不能为空", trigger: "blur" }],
|
||||
modelName: [{ required: true, message: "岗位编码不能为空", trigger: "blur" }],
|
||||
}
|
||||
});
|
||||
|
||||
const designerForm = reactive<DesignerForm>({
|
||||
modelId: '',
|
||||
form: {
|
||||
processName: '',
|
||||
processKey: ''
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs<PageData<ModelForm, ModelQuery>>(data);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
/** 查询模型列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listModel(queryParams.value);
|
||||
modelList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
modelFormRef.value.resetFields();
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ModelVO[]) => {
|
||||
ids.value = selection.map(item => item.modelId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
dialog.visible = true;
|
||||
dialog.title = "添加模型";
|
||||
nextTick(() => {
|
||||
reset();
|
||||
})
|
||||
}
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = (row?: ModelVO) => {
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改模型";
|
||||
nextTick(async () => {
|
||||
reset();
|
||||
const modelId = row?.modelId || ids.value[0];
|
||||
const res = await getModel(modelId);
|
||||
form.value = res.data;
|
||||
});
|
||||
};
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ModelVO) => {
|
||||
const modelIds = row?.modelId || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除参数编号为"' + modelIds + '"的数据项?');
|
||||
await delModel(modelIds);
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/model/export", {
|
||||
...queryParams.value
|
||||
}, `model_${new Date().getTime()}.xlsx`);
|
||||
};
|
||||
/** 查看流程图 */
|
||||
const handleProcessView = async (row: ModelVO) => {
|
||||
reloadIndex.value++;
|
||||
// 发送请求,获取xml
|
||||
const res = await getBpmnXml(row.modelId);
|
||||
processXml.value = res.data;
|
||||
processDialog.visible = true;
|
||||
}
|
||||
/** 设计按钮操作 */
|
||||
const handleDesigner = async (row: ModelVO) => {
|
||||
reloadIndex.value++;
|
||||
designerForm.modelId = row.modelId;
|
||||
const res = await getBpmnXml(row.modelId);
|
||||
bpmnXml.value = res.data || '';
|
||||
designerLoading.value = false;
|
||||
designer.title = "流程设计 - " + row.modelName;
|
||||
designer.visible = true;
|
||||
}
|
||||
const handleDeploy = (row?: ModelVO) => {
|
||||
loading.value = true;
|
||||
nextTick(async () => {
|
||||
await deployModel({ modelId: row?.modelId });
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
router.push({
|
||||
name: 'Deploy',
|
||||
path: '/workflow/deploy'
|
||||
});
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
const handleLatest = async (row: ModelVO) => {
|
||||
await proxy?.$modal.confirm('是否将此模型保存为新版本?');
|
||||
historyLoading.value = true;
|
||||
await latestModel({modelId: row.modelId});
|
||||
history.visible = false;
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
historyLoading.value = false;
|
||||
}
|
||||
/** 查询历史列表 */
|
||||
const getHistoryList = async () => {
|
||||
historyLoading.value = true;
|
||||
const res = await historyModel(queryParams.value);
|
||||
historyList.value = res.rows;
|
||||
historyTotal.value = res.total;
|
||||
historyLoading.value = false;
|
||||
}
|
||||
const handleHistory = (row?: ModelVO) => {
|
||||
history.visible = true;
|
||||
history.title = "模型历史";
|
||||
queryParams.value.modelKey = row?.modelKey;
|
||||
getHistoryList();
|
||||
}
|
||||
/** 提交表单操作 */
|
||||
const submitForm = () => {
|
||||
modelFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
form.value.modelId ? await updateModel(form.value) : await addModel(form.value);
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
dialog.visible = false;
|
||||
getList();
|
||||
}
|
||||
})
|
||||
}
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
}
|
||||
|
||||
const onSaveDesigner = async (str: string) => {
|
||||
bpmnXml.value = str;
|
||||
let dataBody = {
|
||||
modelId: designerForm.modelId,
|
||||
bpmnXml: str
|
||||
}
|
||||
proxy?.$modal.confirm('是否将此模型保存为新版本?').then(() => {
|
||||
confirmSave(dataBody, true)
|
||||
}).catch(action => {
|
||||
if (action === 'cancel') {
|
||||
confirmSave(dataBody, false)
|
||||
}
|
||||
})
|
||||
}
|
||||
const confirmSave = async (body: any, newVersion: boolean) => {
|
||||
designerLoading.value = true;
|
||||
await saveModel(Object.assign(body, { newVersion: newVersion }));
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("保存成功");
|
||||
designerLoading.value = false;
|
||||
designer.visible = false;
|
||||
}
|
||||
|
||||
const categoryFormat = (row: ModelVO) => {
|
||||
return categoryOptions.value.find(k => k.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCategoryList()
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-dialog__body {
|
||||
max-height: calc(100vh) !important;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,142 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input v-model="queryParams.processName" placeholder="请输入流程名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="请选择">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="接收时间" style="width: 308px;">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:process:claimExport']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
|
||||
<el-table v-loading="loading" :data="claimList">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="任务编号" align="center" prop="taskId" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" prop="procDefName" />
|
||||
<el-table-column label="任务节点" align="center" prop="taskName" />
|
||||
<el-table-column label="流程版本" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag>v{{scope.row.procDefVersion}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="流程发起人" align="center" prop="startUserName" />
|
||||
<el-table-column label="接收时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="签收" placement="top">
|
||||
<el-button link type="primary" icon="EditPen" @click="handleClaim(scope.row)" v-hasPermi="['workflow:process:claim']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Claim" lang="ts">
|
||||
import { listClaimProcess } from "@/api/workflow/work/process";
|
||||
import { claimTask } from "@/api/workflow/work/task";
|
||||
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
import { ProcessQuery, ProcessVO } from "@/api/workflow/work/types";
|
||||
import { DateModelType } from "element-plus";
|
||||
import { listAllCategory } from "@/api/workflow/category";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
import { ModelVO } from "@/api/workflow/model/types";
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const claimList = ref<ProcessVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const dateRange = ref<[DateModelType, DateModelType]>(['','']);
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const queryParams = ref<ProcessQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processName: ''
|
||||
});
|
||||
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
}
|
||||
/** 查询待办列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listClaimProcess(proxy?.addDateRange(queryParams.value, dateRange.value));
|
||||
claimList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 签收按钮操作 */
|
||||
const handleClaim = async (row: ProcessVO) => {
|
||||
const res = await claimTask({ taskId: row.taskId })
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
router.push({ path: '/work/todo' })
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/process/claimExport", {
|
||||
...queryParams.value
|
||||
}, `claim_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
const categoryFormat = (row: ModelVO) => {
|
||||
return categoryOptions.value.find(k => k.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
getList();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,133 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input v-model="queryParams.processName" placeholder="请输入流程名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="请选择">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="发起人" prop="originatorName">
|
||||
<el-input v-model="queryParams.originatorName" placeholder="请输入发起人" clearable style="width: 200px" @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>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:process:copyExport']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="copyList">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="抄送编号" align="center" prop="copyId" />
|
||||
<el-table-column label="标题" align="center" prop="title" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" prop="processName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程分类" align="center" prop="category" :formatter="categoryFormat" />
|
||||
<el-table-column label="发起人" align="center" prop="originatorName" />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleDetails(scope.row)" v-hasPermi="['workflow:process:query']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Copy" lang="ts">
|
||||
import { listCopyProcess } from "@/api/workflow/work/process"
|
||||
import {ProcessQuery, ProcessVO} from "@/api/workflow/work/types";
|
||||
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
import { listAllCategory } from "@/api/workflow/category";
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const copyList = ref<ProcessVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const queryParams = ref<ProcessQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processName: "",
|
||||
originatorName: "",
|
||||
category: ''
|
||||
});
|
||||
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
}
|
||||
/** 查询待办列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listCopyProcess(queryParams.value);
|
||||
copyList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 流程详情 */
|
||||
const handleDetails = (row: ProcessVO) => {
|
||||
// router.push({
|
||||
// path: '/workflow/process/detail/' + row.procInsId,
|
||||
// query: {
|
||||
// processed: false
|
||||
// }
|
||||
// })
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/process/copyExport", {
|
||||
...queryParams.value
|
||||
}, `copy_process_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
const categoryFormat = (row: ProcessVO) => {
|
||||
return categoryOptions.value.find(find => find.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
getList();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,544 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-tabs tab-position="top" :model-value="processed === true ? 'approval' : 'form'">
|
||||
<el-tab-pane label="任务办理" name="approval" v-if="processed === true">
|
||||
<el-card class="box-card" shadow="hover" v-if="taskFormOpen">
|
||||
<template #header>
|
||||
<span>填写表单</span>
|
||||
</template>
|
||||
<div class="cu-content">
|
||||
<v-form-render :form-json="{}" :form-data="{}" ref="vfRenderRef" />
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<template #header>
|
||||
<span>审批流程</span>
|
||||
</template>
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="2">
|
||||
<el-form ref="taskFormRef" :model="taskForm" :rules="rules" label-width="120px">
|
||||
<el-form-item label="审批意见" prop="comment">
|
||||
<el-input type="textarea" :rows="5" v-model="taskForm.comment" placeholder="请输入 审批意见" />
|
||||
</el-form-item>
|
||||
<el-form-item label="抄送人" prop="copyUserIds">
|
||||
<el-tag :key="index" v-for="(item, index) in copyUser" closable :disable-transitions="false" @close="handleClose('copy', item)">
|
||||
{{ item.nickName }}
|
||||
</el-tag>
|
||||
<el-button class="button-new-tag" type="primary" icon="el-icon-plus" circle @click="onSelectCopyUsers" />
|
||||
</el-form-item>
|
||||
<el-form-item label="指定审批人" prop="copyUserIds">
|
||||
<el-tag :key="index" v-for="(item, index) in nextUser" closable :disable-transitions="false" @close="handleClose('next', item)">
|
||||
{{ item.nickName }}
|
||||
</el-tag>
|
||||
<el-button class="button-new-tag" type="primary" icon="el-icon-plus" circle @click="onSelectNextUsers" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" type="flex" justify="center">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="CircleCheck" type="success" @click="handleComplete">通过</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="ChatLineSquare" type="primary" @click="handleDelegate">委派</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Switch" type="success" @click="handleTransfer">转办</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="RefreshLeft" type="warning" @click="handleReturn">退回</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="CircleClose" type="danger" @click="handleReject">拒绝</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="表单信息" name="form">
|
||||
<div v-if="formVisible">
|
||||
<el-card class="box-card" shadow="never" v-for="(item, index) in processFormList" :key="index">
|
||||
<template #header>
|
||||
<span>{{ item.title }}</span>
|
||||
</template>
|
||||
<!--流程处理表单模块-->
|
||||
<div class="cu-content">
|
||||
<v-form-render :form-json="item.formModel" :form-data="item.formData" ref="vFormRenderRef" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="流转记录" name="record">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<el-col :span="20" :offset="2">
|
||||
<div class="block">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="(item, index) in historyProcNodeList" :key="index" :type="tagType(item.endTime)">
|
||||
<p style="font-weight: 700">{{ item.activityName }}</p>
|
||||
<el-card v-if="item.activityType === 'startEvent'" class="box-card" shadow="hover">
|
||||
{{ item.assigneeName }} 在 {{ item.createTime }} 发起流程
|
||||
</el-card>
|
||||
<el-card v-if="item.activityType === 'userTask'" class="box-card" shadow="hover">
|
||||
<el-descriptions :column="5" :labelStyle="{'font-weight': 'bold'}">
|
||||
<el-descriptions-item label="实际办理">{{ item.assigneeName || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="候选办理">{{ item.candidate || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="接收时间">{{ item.createTime || '-'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="办结时间">{{ item.endTime || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="耗时">{{ item.duration || '-'}}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div v-if="item.commentList && item.commentList.length > 0">
|
||||
<div v-for="(comment, index) in item.commentList" :key="index">
|
||||
<el-divider content-position="left">
|
||||
<el-tag :type="approveTypeTag(comment.type)">{{ commentType(comment.type) }}</el-tag>
|
||||
<el-tag type="info" effect="plain">{{ comment.time }}</el-tag>
|
||||
</el-divider>
|
||||
<span>{{ comment.fullMessage }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card v-if="item.activityType === 'endEvent'" class="box-card" shadow="hover">
|
||||
{{ item.createTime }} 结束流程
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="流程跟踪" name="track">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<process-viewer
|
||||
:key="`designer-${loadIndex}`"
|
||||
:style="'height:' + height"
|
||||
:xml="processXml"
|
||||
:finishedInfo="finishedInfo"
|
||||
:allCommentList="historyProcNodeList"
|
||||
/>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!--退回流程-->
|
||||
<el-dialog :title="returnDialog.title" v-model="returnDialog.visible" width="40%" append-to-body>
|
||||
<el-radio-group v-model="returnTaskKey">
|
||||
<el-radio-button v-for="item in returnTaskList" :key="item.id" :label="item.id">
|
||||
{{ item.name }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
<template #footer>
|
||||
<el-button @click="returnDialog.visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitReturn">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="userSelectDialog.title" v-model="userSelectDialog.visible" width="60%" append-to-body>
|
||||
<el-row type="flex" :gutter="20">
|
||||
<!--部门数据-->
|
||||
<el-col :span="5">
|
||||
<el-card shadow="never" style="height: 100%">
|
||||
<template #header>
|
||||
<span>部门列表</span>
|
||||
</template>
|
||||
<div class="head-container">
|
||||
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
|
||||
<el-tree
|
||||
:data="deptOptions"
|
||||
:props="{ label: 'label', children: 'children' }"
|
||||
:expand-on-click-node="false"
|
||||
:filter-node-method="filterNode"
|
||||
ref="deptTreeRef"
|
||||
default-expand-all
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-table
|
||||
ref="userTable"
|
||||
:key="userSelectType"
|
||||
height="500"
|
||||
v-loading="userLoading"
|
||||
:data="userList"
|
||||
highlight-current-row
|
||||
@current-change="changeCurrentUser"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column v-if="userSelectType === 'copy' || userSelectType === 'next'" width="55" type="selection" />
|
||||
<el-table-column v-else width="30">
|
||||
<template #default="scope">
|
||||
<el-radio :label="scope.row.userId" v-model="currentUserId">{{''}}</el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="用户名称" align="center" prop="userName" />
|
||||
<el-table-column label="用户昵称" align="center" prop="nickName" />
|
||||
<el-table-column label="手机" align="center" prop="phonenumber" />
|
||||
</el-table>
|
||||
<pagination :total="userTotal" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<el-button @click="userSelectDialog.visible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitUserData">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Detail" lang="ts">
|
||||
import { detailProcess } from "@/api/workflow/work/process";
|
||||
import { complete, delegate, transfer, rejectTask, returnList, returnTask } from "@/api/workflow/work/task";
|
||||
import { deptTreeSelect, selectUser } from "@/api/workflow/identity";
|
||||
import { TaskForm } from "@/api/workflow/work/types";
|
||||
import { UserVO, DeptVO } from "@/api/workflow/identity/types";
|
||||
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const userList = ref<UserVO[]>([]);
|
||||
const processed = ref(false);
|
||||
const taskFormOpen = ref(false)
|
||||
const userMultipleSelection = ref([]);
|
||||
const userSelectType = ref();
|
||||
const currentUserId = ref();
|
||||
const userLoading = ref(false);
|
||||
const userTotal = ref(0);
|
||||
const loadIndex = ref(0);
|
||||
const height = ref(document.documentElement.clientHeight - 205 + 'px;');
|
||||
const processXml = ref('');
|
||||
const taskFormVisible = ref(false);
|
||||
const processFormList = ref([]);
|
||||
const taskFormData = ref([]);
|
||||
const historyProcNodeList = ref<any>();
|
||||
const formVisible = ref(false);
|
||||
const finishedInfo = ref({});
|
||||
|
||||
const deptName = ref('');
|
||||
const deptOptions = ref<DeptVO[]>([]);
|
||||
|
||||
const returnTaskList = ref();
|
||||
const returnTaskKey = ref();
|
||||
|
||||
const copyUser = ref([]);
|
||||
const nextUser = ref([]);
|
||||
|
||||
const taskFormRef = ref(ElForm);
|
||||
const vFormRenderRef = ref(null);
|
||||
const deptTreeRef = ref(null);
|
||||
|
||||
const returnDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: '退回流程'
|
||||
});
|
||||
|
||||
const userSelectDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const taskForm = reactive<TaskForm>({
|
||||
comment: '',
|
||||
procInsId: '',
|
||||
taskId: '',
|
||||
userId: '',
|
||||
copyUserIds: '',
|
||||
nextUserIds: '',
|
||||
vars: '',
|
||||
targetKey: ''
|
||||
});
|
||||
|
||||
const rules = ref({
|
||||
comment: [{ required: true, message: '请输入审批意见', trigger: 'blur' }]
|
||||
});
|
||||
|
||||
const queryParams = ref({
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
});
|
||||
const tagType = (val: any) => {
|
||||
if (val) {
|
||||
return "success";
|
||||
} else {
|
||||
return "info";
|
||||
}
|
||||
}
|
||||
const commentType = (val: string) => {
|
||||
switch (val) {
|
||||
case '1': return '通过'
|
||||
case '2': return '退回'
|
||||
case '3': return '驳回'
|
||||
case '4': return '委派'
|
||||
case '5': return '转办'
|
||||
case '6': return '终止'
|
||||
case '7': return '撤回'
|
||||
}
|
||||
}
|
||||
const approveTypeTag = (val: string) => {
|
||||
switch (val) {
|
||||
case '1': return 'success'
|
||||
case '2': return 'warning'
|
||||
case '3': return 'danger'
|
||||
case '4': return 'primary'
|
||||
case '5': return 'success'
|
||||
case '6': return 'danger'
|
||||
case '7': return 'info'
|
||||
}
|
||||
}
|
||||
|
||||
const initData = () => {
|
||||
taskForm.procInsId = route.params && route.params.procInsId as string;
|
||||
taskForm.taskId = route.query && route.query.taskId as string;
|
||||
processed.value = route.query && (route.query.processed || false) === "true";
|
||||
|
||||
// 流程任务重获取变量表单
|
||||
getProcessDetails(taskForm.procInsId, taskForm.taskId);
|
||||
loadIndex.value++;
|
||||
};
|
||||
/** 通过条件过滤节点 */
|
||||
const filterNode = (value: string, data: any) => {
|
||||
if (!value) return true
|
||||
return data.label.indexOf(value) !== -1
|
||||
}
|
||||
// /** 根据名称筛选部门树 */
|
||||
// watchEffect(
|
||||
// () => {deptTreeRef.value.filter(deptName.value);},
|
||||
// {
|
||||
// flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
|
||||
// }
|
||||
// );
|
||||
// 节点单击事件
|
||||
const handleNodeClick = (data: any) => {
|
||||
getList(data.id);
|
||||
}
|
||||
/** 查询部门下拉树结构 */
|
||||
const getTreeSelect = async () => {
|
||||
const res = await deptTreeSelect();
|
||||
deptOptions.value = res.data;
|
||||
};
|
||||
/** 查询用户列表 */
|
||||
const getList = async (deptId?: number) => {
|
||||
userLoading.value = true;
|
||||
const res = await selectUser({deptId: deptId});
|
||||
userLoading.value = false;
|
||||
userList.value = res.rows;
|
||||
userTotal.value = res.total;
|
||||
}
|
||||
|
||||
const getProcessDetails = async (procInsId: string, taskId: string) => {
|
||||
const params = {procInsId: procInsId, taskId: taskId}
|
||||
const res = await detailProcess(params);
|
||||
const data = res.data;
|
||||
processXml.value = data.bpmnXml;
|
||||
processFormList.value = data.processFormList;
|
||||
taskFormVisible.value = data.existTaskForm;
|
||||
if (taskFormVisible.value) {
|
||||
taskFormData.value = data.taskFormData;
|
||||
}
|
||||
historyProcNodeList.value = data.historyProcNodeList;
|
||||
finishedInfo.value = data.flowViewer;
|
||||
formVisible.value = true;
|
||||
nextTick(() => {
|
||||
processFormList.value.forEach((item: any, index: any) => {
|
||||
if (item.disabled) {
|
||||
vFormRenderRef.value[index].disableForm();
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
const onSelectCopyUsers = () => {
|
||||
userMultipleSelection.value = copyUser;
|
||||
onSelectUsers('添加抄送人', 'copy')
|
||||
}
|
||||
const onSelectNextUsers = () => {
|
||||
userMultipleSelection.value = nextUser;
|
||||
onSelectUsers('指定审批人', 'next')
|
||||
}
|
||||
const onSelectUsers = (title: string, type: string) => {
|
||||
userSelectType.value = type;
|
||||
userSelectDialog.title = title;
|
||||
userSelectDialog.visible = true;
|
||||
getTreeSelect();
|
||||
getList()
|
||||
}
|
||||
/** 通过任务 */
|
||||
const handleComplete = () => {
|
||||
// 校验表单
|
||||
taskFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
const res = await complete(taskForm)
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
goBack();
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 委派任务 */
|
||||
const handleDelegate = () => {
|
||||
userSelectType.value = 'delegate';
|
||||
userSelectDialog.title = '委派任务'
|
||||
userSelectDialog.visible = true;
|
||||
getTreeSelect();
|
||||
}
|
||||
/** 转办任务 */
|
||||
const handleTransfer = () => {
|
||||
userSelectType.value = 'transfer';
|
||||
userSelectDialog.title = '转办任务';
|
||||
userSelectDialog.visible = true;
|
||||
getTreeSelect();
|
||||
}
|
||||
/** 退回任务 */
|
||||
const handleReturn = async () => {
|
||||
// 校验表单
|
||||
taskFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
const res = await returnList(taskForm);
|
||||
returnTaskList.value = res.data;
|
||||
returnDialog.visible = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
/** 拒绝任务 */
|
||||
const handleReject = async () => {
|
||||
await proxy?.$modal.confirm('拒绝审批单流程会终止,是否继续?');
|
||||
await rejectTask(taskForm);
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
goBack();
|
||||
}
|
||||
|
||||
/** 返回页面 */
|
||||
const goBack = () => {
|
||||
// 关闭当前标签页并返回上个页面
|
||||
proxy?.$tab.closePage(route);
|
||||
router.back()
|
||||
}
|
||||
// 关闭标签
|
||||
const handleClose = (type: any, tag: any) => {
|
||||
let userObj = userMultipleSelection.value.find(item => item.userId === tag.id);
|
||||
userMultipleSelection.value.splice(userMultipleSelection.value.indexOf(userObj), 1);
|
||||
if (type === 'copy') {
|
||||
copyUser.value = userMultipleSelection.value;
|
||||
// 设置抄送人ID
|
||||
if (copyUser.value && copyUser.value.length > 0) {
|
||||
const val = copyUser.value.map(item => item.id);
|
||||
taskForm.copyUserIds = val instanceof Array ? val.join(',') : val;
|
||||
} else {
|
||||
taskForm.copyUserIds = '';
|
||||
}
|
||||
} else if (type === 'next') {
|
||||
nextUser.value = userMultipleSelection.value;
|
||||
// 设置抄送人ID
|
||||
if (nextUser.value && nextUser.value.length > 0) {
|
||||
const val = nextUser.value.map(item => item.id);
|
||||
taskForm.nextUserIds = val instanceof Array ? val.join(',') : val;
|
||||
} else {
|
||||
taskForm.nextUserIds = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
const changeCurrentUser = (val: any) => {
|
||||
// currentUserId = val.userId
|
||||
}
|
||||
const handleSelectionChange = () => {
|
||||
|
||||
}
|
||||
const submitReturn = () => {
|
||||
// 校验表单
|
||||
taskFormRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
if (!returnTaskKey) {
|
||||
proxy?.$modal.msgError("请选择退回节点!");
|
||||
}
|
||||
taskForm.targetKey = returnTaskKey.value;
|
||||
const res = await returnTask(taskForm);
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
goBack()
|
||||
}
|
||||
});
|
||||
console.log("taskForm => ", taskForm.targetKey);
|
||||
}
|
||||
const submitUserData = () => {
|
||||
let type = userSelectType.value;
|
||||
if (type === 'copy' || type === 'next') {
|
||||
if (!userMultipleSelection || userMultipleSelection.value.length <= 0) {
|
||||
proxy?.$modal.msgError("请选择用户");
|
||||
return false;
|
||||
}
|
||||
let userIds = userMultipleSelection.value.map(k => k.userId);
|
||||
if (type === 'copy') {
|
||||
// 设置抄送人ID信息
|
||||
copyUser.value = userMultipleSelection.value;
|
||||
taskForm.copyUserIds = userIds instanceof Array ? userIds.join(',') : userIds;
|
||||
} else if (type === 'next') {
|
||||
// 设置下一级审批人ID信息
|
||||
nextUser.value = userMultipleSelection.value;
|
||||
taskForm.nextUserIds = userIds instanceof Array ? userIds.join(',') : userIds;
|
||||
}
|
||||
userSelectDialog.visible = false;
|
||||
} else {
|
||||
if (!taskForm.comment) {
|
||||
proxy?.$modal.msgError("请输入审批意见");
|
||||
return false;
|
||||
}
|
||||
if (!currentUserId.value) {
|
||||
proxy?.$modal.msgError("请选择用户");
|
||||
return false;
|
||||
}
|
||||
taskForm.userId = currentUserId.value;
|
||||
if (type === 'delegate') {
|
||||
delegate(taskForm).then(res => {
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
goBack();
|
||||
});
|
||||
}
|
||||
if (type === 'transfer') {
|
||||
transfer(taskForm).then(res => {
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
goBack();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
.clearfix:after {
|
||||
clear: both
|
||||
}
|
||||
|
||||
.box-card {
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-tag + .el-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-row {
|
||||
margin-bottom: 20px;
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.el-col {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.button-new-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input v-model="queryParams.processName" placeholder="请输入流程名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="请选择">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="审批时间" style="width: 308px;">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:process:finishedExport']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="finishedList">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="任务编号" align="center" prop="taskId" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" prop="procDefName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程分类" align="center" prop="category" :formatter="categoryFormat" />
|
||||
<el-table-column label="任务节点" align="center" prop="taskName" />
|
||||
<el-table-column label="流程发起人" align="center" prop="startUserName" />
|
||||
<el-table-column label="接收时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="审批时间" align="center" prop="finishTime" width="180" />
|
||||
<el-table-column label="耗时" align="center" prop="duration" width="180" />
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleDetails(scope.row)" v-hasPermi="['workflow:process:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="撤回" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleRevoke(scope.row)" v-hasPermi="['workflow:process:revoke']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Finished" lang="ts">
|
||||
import { listFinishedProcess } from "@/api/workflow/work/process";
|
||||
import { revokeProcess } from "@/api/workflow/work/task";
|
||||
import {ProcessQuery, ProcessVO} from "@/api/workflow/work/types";
|
||||
import {DateModelType} from "element-plus";
|
||||
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
import { listAllCategory } from "@/api/workflow/category";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const finishedList = ref<ProcessVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const dateRange = ref<[DateModelType, DateModelType]>(['','']);
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const queryParams = ref<ProcessQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processName: '',
|
||||
category: ''
|
||||
});
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
}
|
||||
/** 查询待办列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listFinishedProcess(proxy?.addDateRange(queryParams.value, dateRange.value));
|
||||
finishedList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 流程流转记录 */
|
||||
const handleDetails = (row: any) => {
|
||||
router.push({
|
||||
path: '/workflow/process/detail/' + row.procInsId,
|
||||
query: {
|
||||
processed: false
|
||||
}
|
||||
})
|
||||
}
|
||||
/** 撤回任务 */
|
||||
const handleRevoke = async (row: any) => {
|
||||
const params = {
|
||||
procInsId: row.procInsId,
|
||||
taskId: row.taskId
|
||||
};
|
||||
const res = await revokeProcess(params);
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
getList();
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/process/finishedExport", {
|
||||
...queryParams.value
|
||||
}, `finished_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
const categoryFormat = (row: ProcessVO) => {
|
||||
return categoryOptions.value.find(find => find.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
getList();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="流程标识" prop="processKey">
|
||||
<el-input v-model="queryParams.processKey" placeholder="请输入流程标识" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input v-model="queryParams.processName" placeholder="请输入流程名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="请选择">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:process:startExport']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="processList">
|
||||
<el-table-column label="流程标识" align="center" prop="processKey" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" :show-overflow-tooltip="true">
|
||||
<template #default="scope">
|
||||
<el-button type="text" @click="handleProcessView(scope.row)">
|
||||
<span>{{ scope.row.processName }}</span>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="流程分类" align="center" prop="categoryName" :formatter="categoryFormat" />
|
||||
<el-table-column label="流程版本" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag>v{{ scope.row.version }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" v-if="!scope.row.suspended">激活</el-tag>
|
||||
<el-tag type="warning" v-if="scope.row.suspended">挂起</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="部署时间" align="center" prop="deploymentTime" width="180" />
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="发起" placement="top">
|
||||
<el-button link type="primary" icon="VideoPlay" @click="handleStart(scope.row)" v-hasPermi="['workflow:process:start']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 流程图 -->
|
||||
<el-dialog :title="processDialog.title" v-model="processDialog.visible" width="70%">
|
||||
<process-viewer :key="`designer-${reloadIndex}`" :xml="processXml" :style="{height: '650px'}" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="WorkProcess" lang="ts">
|
||||
import { listProcess, getBpmnXml } from "@/api/workflow/work/process";
|
||||
import { listAllCategory } from "@/api/workflow/category";
|
||||
import { ProcessQuery, ProcessVO } from "@/api/workflow/work/types";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const processList = ref<ProcessVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const total = ref(0);
|
||||
const reloadIndex = ref(0);
|
||||
const processXml = ref("");
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const processDialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: '流程图'
|
||||
});
|
||||
|
||||
const queryParams = ref<ProcessQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processKey: '',
|
||||
processName: '',
|
||||
category: ''
|
||||
});
|
||||
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
}
|
||||
/** 查询流程列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listProcess(queryParams.value);
|
||||
processList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 查看流程图 */
|
||||
const handleProcessView = async (row: any) => {
|
||||
reloadIndex.value++;
|
||||
// 发送请求,获取xml
|
||||
const res = await getBpmnXml(row.definitionId);
|
||||
processXml.value = res.data;
|
||||
processDialog.visible = true;
|
||||
}
|
||||
/** 发起流程 */
|
||||
const handleStart = (row: ProcessVO) => {
|
||||
router.push({
|
||||
path: '/workflow/process/start/' + row.deploymentId,
|
||||
query: {
|
||||
definitionId: row.definitionId,
|
||||
}
|
||||
})
|
||||
};
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/process/startExport", {
|
||||
...queryParams.value
|
||||
}, `start_process_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
const categoryFormat = (row: ProcessVO) => {
|
||||
return categoryOptions.value.find(k => k.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
getList();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,202 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="流程标识" prop="processKey">
|
||||
<el-input v-model="queryParams.processKey" placeholder="请输入流程标识" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input v-model="queryParams.processName" placeholder="请输入流程名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="流程分类">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="提交时间" style="width: 308px;">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['workflow:process:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:process:ownExport']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="ownProcessList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="流程编号" align="center" prop="procInsId" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" prop="procDefName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程类别" align="center" prop="category" :formatter="categoryFormat" />
|
||||
<el-table-column label="流程版本" align="center" width="80px">
|
||||
<template #default="scope">
|
||||
<el-tag>v{{ scope.row.procDefVersion }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="当前节点" align="center" prop="taskName" />
|
||||
<el-table-column label="提交时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="流程状态" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="wf_process_status" :value="scope.row.processStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="耗时" align="center" prop="duration" width="180" />
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleDetails(scope.row)" v-hasPermi="['workflow:process:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="取消" placement="top">
|
||||
<el-button link type="primary" icon="CircleClose" @click="handleStop(scope.row)" v-hasPermi="['workflow:process:cancel']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="再次发起" placement="top">
|
||||
<el-button link type="primary" icon="RefreshRight" @click="handleAgain(scope.row)" v-hasPermi="['workflow:process:start']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['workflow:process:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Own" lang="ts">
|
||||
import { listOwnProcess, stopProcess, delProcess } from "@/api/workflow/work/process";
|
||||
import { listAllCategory } from "@/api/workflow/category";
|
||||
import { ProcessQuery, ProcessVO } from "@/api/workflow/work/types";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
import { DateModelType } from "element-plus";
|
||||
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { wf_process_status } = toRefs<any>(proxy?.useDict("wf_process_status"));
|
||||
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
|
||||
const ownProcessList = ref<ProcessVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const dateRange = ref<[DateModelType, DateModelType]>(['','']);
|
||||
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const queryParams = ref<ProcessQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processKey: '',
|
||||
processName: '',
|
||||
category: ''
|
||||
});
|
||||
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
};
|
||||
/** 查询我的流程列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listOwnProcess(proxy?.addDateRange(queryParams.value, dateRange.value));
|
||||
ownProcessList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ProcessVO[]) => {
|
||||
ids.value = selection.map(item => item.procInsId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
/** 流程详情 */
|
||||
const handleDetails = (row: ProcessVO) => {
|
||||
router.push({
|
||||
path: '/workflow/process/detail/' + row.procInsId,
|
||||
query: {
|
||||
processed: false
|
||||
}
|
||||
})
|
||||
}
|
||||
/** 取消流程申请 */
|
||||
const handleStop = async (row: ProcessVO) => {
|
||||
await stopProcess( { procInsId: row.procInsId });
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
getList();
|
||||
}
|
||||
/** 再次发起流程 */
|
||||
const handleAgain = (row: ProcessVO) => {
|
||||
// router.push({
|
||||
// path: '/workflow/process/start/' + row.deployId,
|
||||
// query: {
|
||||
// definitionId: row.procDefId,
|
||||
// procInsId: row.procInsId
|
||||
// }
|
||||
// })
|
||||
}
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ProcessVO) => {
|
||||
const procInsIds = row?.procInsId || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除流程定义编号为"' + procInsIds + '"的数据项?');
|
||||
await delProcess(procInsIds);
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/process/ownExport", {
|
||||
...queryParams.value
|
||||
}, `own_process_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
const categoryFormat = (row: ProcessVO) => {
|
||||
return categoryOptions.value.find(k => k.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
getList();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<span>发起流程</span>
|
||||
</template>
|
||||
<div class="form-conf" v-if="dialog.visible">
|
||||
<v-form-render :form-json="formModel" :form-data="formData" ref="vfRenderRef"></v-form-render>
|
||||
<div class="cu-submit">
|
||||
<el-button type="primary" @click="submit">提交</el-button>
|
||||
<el-button @click="reset">重置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="WorkStart" lang="ts">
|
||||
import { getProcessForm, startProcess } from '@/api/workflow/work/process';
|
||||
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
|
||||
const route = useRoute();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const vfRenderRef = ref(null);
|
||||
|
||||
const deployId = ref();
|
||||
const definitionId = ref();
|
||||
const formModel = ref({});
|
||||
const formData = ref({});
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initData = async () => {
|
||||
deployId.value = route.params && route.params.deployId;
|
||||
definitionId.value = route.query && route.query.definitionId;
|
||||
const res = await getProcessForm({ definitionId: definitionId.value, deployId: deployId.value });
|
||||
formModel.value = res.data.formModel;
|
||||
dialog.visible = true;
|
||||
nextTick(async () => {
|
||||
vfRenderRef.value.setFormJson(formModel.value || {formConfig: {}, widgetList: []});
|
||||
});
|
||||
}
|
||||
|
||||
const submit = async () => {
|
||||
const data = await vfRenderRef.value.getFormData();
|
||||
if (definitionId.value) {
|
||||
const res = await startProcess(definitionId.value, JSON.stringify(data));
|
||||
proxy?.$modal.msgSuccess(res.msg);
|
||||
// const obj = { path: "/work/own" };
|
||||
// proxy?.$tab.closeOpenPage(obj);
|
||||
proxy?.$tab.closePage();
|
||||
proxy?.$router.back();
|
||||
}
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
vfRenderRef.value.resetForm();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-conf {
|
||||
margin: 15px auto;
|
||||
width: 80%;
|
||||
padding: 15px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div class="search" v-show="showSearch">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="70">
|
||||
<el-form-item label="流程名称" prop="processName">
|
||||
<el-input v-model="queryParams.processName" placeholder="请输入流程名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="流程分类" prop="category">
|
||||
<el-select v-model="queryParams.category" clearable placeholder="请选择">
|
||||
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.categoryName" :value="item.code" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="接收时间" style="width: 308px;">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</transition>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['workflow:process:todoExport']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="todoList">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="任务编号" align="center" prop="taskId" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="流程名称" align="center" prop="procDefName" />
|
||||
<el-table-column label="任务节点" align="center" prop="taskName" />
|
||||
<el-table-column label="流程分类" align="center" prop="category" :formatter="categoryFormat" />
|
||||
<el-table-column label="流程版本" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag>v{{scope.row.procDefVersion}}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="流程发起人" align="center" prop="startUserName" />
|
||||
<el-table-column label="接收时间" align="center" prop="createTime" width="180" />
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="办理" placement="top">
|
||||
<el-button link type="primary" icon="EditPen" @click="handleProcess(scope.row)" v-hasPermi="['workflow:process:approval']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Todo" lang="ts">
|
||||
import { listTodoProcess } from '@/api/workflow/work/process';
|
||||
import { ProcessVO, ProcessQuery } from "@/api/workflow/work/types";
|
||||
import {DateModelType} from "element-plus";
|
||||
|
||||
import { ComponentInternalInstance } from "vue";
|
||||
import { listAllCategory } from "@/api/workflow/category";
|
||||
import { CategoryVO } from "@/api/workflow/category/types";
|
||||
import { ModelVO } from "@/api/workflow/model/types";
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const todoList = ref<ProcessVO[]>([]);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<number | string>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const dateRange = ref<[DateModelType, DateModelType]>(['','']);
|
||||
const categoryOptions = ref<CategoryVO[]>([]);
|
||||
const queryFormRef = ref(ElForm);
|
||||
|
||||
const queryParams = ref<ProcessQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
processName: '',
|
||||
category: ''
|
||||
});
|
||||
/** 查询流程分类列表 */
|
||||
const getCategoryList = async () => {
|
||||
const res = await listAllCategory();
|
||||
categoryOptions.value = res.data;
|
||||
}
|
||||
/** 查询待办列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listTodoProcess(proxy?.addDateRange(queryParams.value, dateRange.value));
|
||||
todoList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
/** 跳转到处理页面 */
|
||||
const handleProcess = (row: ProcessVO) => {
|
||||
router.push({
|
||||
path: '/workflow/process/detail/' + row.procInsId,
|
||||
query: {
|
||||
taskId: row.taskId,
|
||||
processed: true
|
||||
}
|
||||
})
|
||||
}
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download("workflow/process/todoExport", {
|
||||
...queryParams.value
|
||||
}, `todo_${new Date().getTime()}.xlsx`);
|
||||
}
|
||||
|
||||
const categoryFormat = (row: ModelVO) => {
|
||||
return categoryOptions.value.find(k => k.code === row.category)?.categoryName ?? '';
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCategoryList();
|
||||
getList();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,28 @@
|
|||
import compression from 'vite-plugin-compression';
|
||||
|
||||
export default function createCompression(env: any) {
|
||||
const { VITE_BUILD_COMPRESS } = env;
|
||||
const plugin: any[] = [];
|
||||
if (VITE_BUILD_COMPRESS) {
|
||||
const compressList = VITE_BUILD_COMPRESS.split(',');
|
||||
if (compressList.includes('gzip')) {
|
||||
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
|
||||
plugin.push(
|
||||
compression({
|
||||
ext: '.gz',
|
||||
deleteOriginFile: false
|
||||
})
|
||||
);
|
||||
}
|
||||
if (compressList.includes('brotli')) {
|
||||
plugin.push(
|
||||
compression({
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
deleteOriginFile: false
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
return plugin;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import Icons from 'unplugin-icons/vite';
|
||||
|
||||
export default () => {
|
||||
return Icons({
|
||||
// 自动安装图标库
|
||||
autoInstall: true
|
||||
});
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
import UnoCss from 'unocss/vite';
|
||||
import { presetUno, presetAttributify, presetIcons } from 'unocss';
|
||||
|
||||
export default () => {
|
||||
return UnoCss({
|
||||
presets: [presetUno(), presetAttributify(), presetIcons()],
|
||||
// rules: [['search', {}]],
|
||||
shortcuts: {
|
||||
'panel-title':
|
||||
'pb-[5px] font-sans leading-[1.1] font-medium text-base text-[#6379bb] border-b border-b-solid border-[var(--el-border-color-light)] mb-5 mt-0'
|
||||
}
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue