444 lines
12 KiB
Vue
444 lines
12 KiB
Vue
<template>
|
|
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
|
|
<div
|
|
class="w-1/4 xl:w-1/5 overflow-hidden bg-white h-full"
|
|
:style="{ 'border-right': '1px solid #e5e7eb' }"
|
|
>
|
|
<BasicTree
|
|
:title="t('流程监控状态')"
|
|
:clickRowToExpand="true"
|
|
:treeData="treeData"
|
|
:fieldNames="{ key: 'id', title: 'name' }"
|
|
@select="handleSelect"
|
|
:selectedKeys="selectedKeys"
|
|
/>
|
|
</div>
|
|
<BasicTable
|
|
@register="registerTable"
|
|
class="w-3/4 xl:w-4/5"
|
|
@selection-change="selectionChange"
|
|
@row-dbClick="dbClickRow"
|
|
>
|
|
<template #toolbar>
|
|
<!-- <LookProcess ref="lookProcess" :taskId="taskId" :processId="processId" @close="reload"
|
|
><a-button v-auth="'monitor:view'">{{ t('查看') }}</a-button></LookProcess
|
|
> -->
|
|
<!-- <a-button v-auth="'monitor:appointedAuditor'" @click="approveUser" v-if="data.type === 0">{{
|
|
t('指派审核人')
|
|
}}</a-button> -->
|
|
<a-button @click="handleUpdateVersion">{{
|
|
t('流程版本变更')
|
|
}}</a-button>
|
|
<a-button v-auth="'monitor:pending'" @click="setSuspended" v-if="data.type === 0">{{
|
|
suspendedTitle
|
|
}}</a-button>
|
|
|
|
<a-button v-auth="'monitor:delete'" @click="deleteFlow" v-if="data.type === 0">{{
|
|
t('删除流程')
|
|
}}</a-button>
|
|
</template>
|
|
<template #status="{ record }">
|
|
<Tag color="warning" v-if="record.status == ProcessMonitorStatus.SUSPENDED">{{
|
|
t('挂起')
|
|
}}</Tag>
|
|
<Tag color="processing" v-if="record.status == ProcessMonitorStatus.ACTIVE">{{
|
|
t('活动中')
|
|
}}</Tag>
|
|
<Tag color="success" v-if="record.status == ProcessMonitorStatus.COMPLETED">{{
|
|
t('完成')
|
|
}}</Tag>
|
|
<Tag color="error" v-if="record.status == ProcessMonitorStatus.INTERNALLY_TERMINATED">{{
|
|
t('内部终止')
|
|
}}</Tag>
|
|
</template>
|
|
<template #currentProgress="{ record }">
|
|
<a-progress v-if="record.currentProgress" :percent="record.currentProgress" size="small" />
|
|
</template>
|
|
</BasicTable>
|
|
|
|
<!-- 查看 -->
|
|
<LookProcess ref="lookProcess" :taskId="taskId" :processId="processId" @close="reload"/>
|
|
<!-- 指派审核人 -->
|
|
<ApproveProcessMonitorUser
|
|
v-if="data.approvedUserVisible"
|
|
:taskId="taskId"
|
|
:schemaId="schemaId"
|
|
:title="approvedUserTitle"
|
|
@close="
|
|
() => {
|
|
data.approvedUserVisible = false;
|
|
reload();
|
|
}
|
|
"
|
|
/>
|
|
<!-- 流程版本变更 -->
|
|
<UpdateProcessVersionModal
|
|
v-if="data.visibleVersion"
|
|
title="流程版本变更"
|
|
:processDefinitionKey="versionData.definitionKey"
|
|
:schemaId="versionData.schemaId"
|
|
:processIds="versionData.processIds"
|
|
@register="registerUpdateProcessVersionModal"
|
|
@success="() => {
|
|
data.visibleVersion = false;
|
|
reload();
|
|
clearSelectedRowKeys();
|
|
}"
|
|
@cancel="() => {
|
|
data.visibleVersion = false;
|
|
reload();
|
|
clearSelectedRowKeys();
|
|
}"
|
|
/>
|
|
</PageWrapper>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { createVNode, onMounted, reactive, ref, nextTick } from 'vue';
|
|
import { useModal } from '/@/components/Modal';
|
|
import { BasicTree } from '/@/components/Tree';
|
|
import { PageWrapper } from '/@/components/Page';
|
|
import LookProcess from './components/LookProcess.vue';
|
|
import ApproveProcessMonitorUser from './components/flow/ApproveProcessMonitorUser.vue';
|
|
import { UpdateProcessVersionModal } from '/@/components/UpdateProcessVersion';
|
|
import { deleteWorkflow, getProcessMonitorPage, postSetSuspended } from '/@/api/workflow/monitor';
|
|
import { getDesignList, getDesignPage } from '/@/api/workflow/design';
|
|
import { Modal } from 'ant-design-vue';
|
|
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
|
import { notification, Tag } from 'ant-design-vue';
|
|
import { ProcessMonitorStatus } from '/@/enums/workflowEnum';
|
|
import { BasicTable, useTable, FormSchema, BasicColumn } from '/@/components/Table';
|
|
import { useI18n } from '/@/hooks/web/useI18n';
|
|
import { useRouter } from 'vue-router';
|
|
const { currentRoute } = useRouter();
|
|
const router = useRouter();
|
|
|
|
const definitionKey = ref('');
|
|
onMounted(() => {
|
|
definitionKey.value = currentRoute.value.query.definitionKey as string;
|
|
});
|
|
|
|
const { t } = useI18n();
|
|
const configColumns: BasicColumn[] = [
|
|
{
|
|
title: t('流水号'),
|
|
dataIndex: 'serialNumber',
|
|
sorter: {
|
|
multiple: 1,
|
|
},
|
|
align: 'left',
|
|
},
|
|
{
|
|
title: t('任务'),
|
|
dataIndex: 'currentTaskName',
|
|
width: 120,
|
|
sorter: {
|
|
multiple: 2,
|
|
},
|
|
align: 'left',
|
|
},
|
|
{
|
|
title: t('标题'),
|
|
dataIndex: 'schemaName',
|
|
width: 120,
|
|
sorter: {
|
|
multiple: 3,
|
|
},
|
|
align: 'left',
|
|
},
|
|
{
|
|
title: t('状态'),
|
|
dataIndex: 'status',
|
|
sorter: {
|
|
multiple: 4,
|
|
},
|
|
align: 'left',
|
|
slots: { customRender: 'status' },
|
|
},
|
|
// {
|
|
// title: '状态详情',
|
|
// dataIndex: 'statusMessage',
|
|
// },
|
|
{
|
|
title: t('当前进度'),
|
|
dataIndex: 'currentProgress',
|
|
align: 'left',
|
|
slots: { customRender: 'currentProgress' },
|
|
},
|
|
{
|
|
title: t('发起人'),
|
|
dataIndex: 'originator',
|
|
align: 'left',
|
|
},
|
|
{
|
|
title: t('时间'),
|
|
width: 160,
|
|
dataIndex: 'createDate',
|
|
align: 'left',
|
|
},
|
|
];
|
|
const searchFormSchema: FormSchema[] = [
|
|
{
|
|
field: 'definitionKey',
|
|
label: '流程',
|
|
component: 'ApiSelect',
|
|
value: definitionKey,
|
|
componentProps: {
|
|
mode: 'single',
|
|
api: getDesignPageProcessed,
|
|
showSearch: true,
|
|
labelField: 'name',
|
|
valueField: 'definitionKey',
|
|
getPopupContainer: () => document.body,
|
|
},
|
|
},
|
|
{
|
|
field: 'keyword',
|
|
label: t('关键字'),
|
|
component: 'Input',
|
|
colProps: { span: 8 },
|
|
componentProps: {
|
|
placeholder: t('请输入关键字'),
|
|
},
|
|
},
|
|
{
|
|
field: 'searchDate',
|
|
label: t('时间范围'),
|
|
component: 'RangePicker',
|
|
colProps: { span: 8 },
|
|
},
|
|
];
|
|
|
|
const treeData = [
|
|
{
|
|
key: 0,
|
|
id: 0,
|
|
name: t('未完成'),
|
|
icon: 'ant-design:profile-outlined',
|
|
},
|
|
{
|
|
key: 1,
|
|
id: 1,
|
|
name: t('已完成'),
|
|
icon: 'ant-design:profile-outlined',
|
|
},
|
|
];
|
|
const queryData = ref({});
|
|
const selectedKeys = ref([0]);
|
|
const lookProcess = ref()
|
|
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({
|
|
title: t('流程监控列表'),
|
|
api: getProcessMonitorPage,
|
|
rowKey: 'processId',
|
|
columns: configColumns,
|
|
formConfig: {
|
|
rowProps: {
|
|
gutter: 16,
|
|
},
|
|
schemas: searchFormSchema,
|
|
fieldMapToTime: [['searchDate', ['startTime', 'endTime'], 'YYYY-MM-DD', true]],
|
|
showResetButton: false,
|
|
},
|
|
rowSelection: {
|
|
// type: 'radio',
|
|
type: 'group',
|
|
},
|
|
beforeFetch: (params) => {
|
|
//发送请求默认新增 左边树结构所选机构id
|
|
queryData.value = {
|
|
...params,
|
|
definitionKey: params.definitionKey?params.definitionKey:definitionKey.value,
|
|
type: data.type
|
|
};
|
|
return queryData.value
|
|
},
|
|
useSearchForm: true,
|
|
showTableSetting: true,
|
|
striped: false,
|
|
pagination: {
|
|
pageSize: 18,
|
|
},
|
|
tableSetting: {
|
|
size: false,
|
|
setting: false,
|
|
},
|
|
});
|
|
let data: {
|
|
type: number;
|
|
approvedUserVisible: boolean;
|
|
visibleVersion: boolean;
|
|
} = reactive({
|
|
type: 0,
|
|
approvedUserVisible: false,
|
|
visibleVersion: false,
|
|
});
|
|
const processId = ref('');
|
|
const taskId = ref('');
|
|
const schemaId = ref('');
|
|
const approvedUserTitle = ref(t('任务'));
|
|
const suspendedTitle = ref(t('挂起'));
|
|
function selectionChange({ keys, rows }) {
|
|
if (keys?.length > 0) {
|
|
processId.value = rows[0].processId;
|
|
taskId.value = rows[0].taskId;
|
|
schemaId.value = rows[0].schemaId;
|
|
approvedUserTitle.value = t('任务-') + rows[0].schemaName + '-' + rows[0].currentTaskName;
|
|
suspendedTitle.value =
|
|
rows[0].status && rows[0].status === ProcessMonitorStatus.SUSPENDED ? t('恢复') : t('挂起');
|
|
} else {
|
|
processId.value = '';
|
|
taskId.value = '';
|
|
schemaId.value = '';
|
|
approvedUserTitle.value = t('任务');
|
|
suspendedTitle.value = t('挂起');
|
|
}
|
|
}
|
|
|
|
async function setSuspended() {
|
|
let row = checkSelectSingleRow();
|
|
if (row) {
|
|
let res = await postSetSuspended(row.processId);
|
|
if (res) {
|
|
reload();
|
|
notification.open({
|
|
type: 'success',
|
|
message: suspendedTitle.value,
|
|
description: t('成功'),
|
|
});
|
|
}
|
|
}
|
|
clearSelectedRowKeys();
|
|
}
|
|
function deleteFlow() {
|
|
let row = checkSelectSingleRow('请先选择一行后再进行操作。');
|
|
if (row) {
|
|
Modal.confirm({
|
|
title: t('提示'),
|
|
icon: createVNode(ExclamationCircleOutlined),
|
|
content: t('请确认是否删除该流程?删除后无法进行恢复。'),
|
|
okText: t('确定'),
|
|
okType: 'danger',
|
|
cancelText: t('取消'),
|
|
onOk() {
|
|
if (row.processId) {
|
|
deleteWorkflow(row.processId).then((res) => {
|
|
if (res) {
|
|
reload();
|
|
notification.open({
|
|
type: 'success',
|
|
message: t('删除成功'),
|
|
description: t('成功'),
|
|
});
|
|
}
|
|
});
|
|
}
|
|
},
|
|
onCancel() {},
|
|
});
|
|
}
|
|
clearSelectedRowKeys();
|
|
}
|
|
function handleSelect(_, e) {
|
|
clearSelectedRowKeys();
|
|
data.type = e.node.key;
|
|
selectedKeys.value = [e.node.key];
|
|
reload();
|
|
}
|
|
function approveUser() {
|
|
let row = checkSelectSingleRow();
|
|
if (row) {
|
|
if (row.taskId) {
|
|
data.approvedUserVisible = true;
|
|
}
|
|
}
|
|
}
|
|
function checkSelectSingleRow(tip?) {
|
|
const selectRows: any = getSelectRows();
|
|
if (selectRows.length == 1) {
|
|
return selectRows[0];
|
|
} else if (selectRows.length > 1) {
|
|
notification.open({
|
|
type: 'error',
|
|
message: t('流程'),
|
|
description: t(tip || '请选择单一一个流程进行'),
|
|
});
|
|
return false;
|
|
} else {
|
|
notification.open({
|
|
type: 'error',
|
|
message: t('流程'),
|
|
description: t(tip || '请选择一个流程进行'),
|
|
});
|
|
return false;
|
|
}
|
|
}
|
|
function checkSelectGroupRow(tip?) {
|
|
const selectRows: any = getSelectRows();
|
|
if (selectRows.length > 0) {
|
|
let processDefinitionKey = selectRows[0].processDefinitionKey;
|
|
let flagCheck = true;
|
|
selectRows.forEach(element => {
|
|
if(element.processDefinitionKey != processDefinitionKey) flagCheck = false;
|
|
});
|
|
if(!flagCheck) {
|
|
notification.open({
|
|
type: 'error',
|
|
message: t('选择了多个流程'),
|
|
description: t(tip || '请按单一流程选择后重新批量配置'),
|
|
});
|
|
return false;
|
|
}
|
|
return selectRows;
|
|
} else {
|
|
notification.open({
|
|
type: 'error',
|
|
message: t('流程'),
|
|
description: t(tip || '请选择最少一个流程实例进行'),
|
|
});
|
|
return false;
|
|
}
|
|
}
|
|
async function dbClickRow(record) {
|
|
processId.value = record.processId;
|
|
taskId.value = record.taskId;//改版 一个流程中可能有多个taskId 已不返回
|
|
await nextTick()
|
|
await lookProcess.value.look();
|
|
}
|
|
|
|
const [registerUpdateProcessVersionModal, { openModal: openUpdateProcessVersionModal }] = useModal();
|
|
const versionData = {
|
|
definitionKey: '',
|
|
schemaId: '',
|
|
processIds: [],
|
|
}
|
|
/**
|
|
* 更新选中的流程图对应的执行流程的版本
|
|
*/
|
|
async function handleUpdateVersion() {
|
|
let selectRows = checkSelectGroupRow();
|
|
if (selectRows) {
|
|
versionData.definitionKey = selectRows[0].processDefinitionKey;
|
|
versionData.schemaId = selectRows[0].schemaId;
|
|
versionData.processIds = selectRows.map(selectRows => selectRows.processId);
|
|
await getNextTick();
|
|
openUpdateProcessVersionModal();
|
|
}
|
|
}
|
|
|
|
function getNextTick () {
|
|
data.visibleVersion = true;
|
|
}
|
|
|
|
async function getDesignPageProcessed() {
|
|
const searchParams = {
|
|
...{
|
|
limit: 1,
|
|
size: 100
|
|
},
|
|
enabledMark: 1,
|
|
};
|
|
const response = await getDesignPage(searchParams);
|
|
return response.list;
|
|
}
|
|
</script>
|