Files
geg-gas-web/src/views/workflow/task/ProcessMonitor.vue

432 lines
12 KiB
Vue
Raw Normal View History

2024-02-05 09:15:37 +08:00
<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"
2024-02-05 09:15:37 +08:00
>
<template #toolbar>
<!-- <LookProcess ref="lookProcess" :taskId="taskId" :processId="processId" @close="reload"
2024-02-05 09:15:37 +08:00
><a-button v-auth="'monitor:view'">{{ t('查看') }}</a-button></LookProcess
> -->
<!-- <a-button v-auth="'monitor:appointedAuditor'" @click="approveUser" v-if="data.type === 0">{{
2024-02-05 09:15:37 +08:00
t('指派审核人')
}}</a-button> -->
<a-button @click="handleUpdateVersion">{{
t('流程版本变更')
2024-02-05 09:15:37 +08:00
}}</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"/>
2024-02-05 09:15:37 +08:00
<!-- 指派审核人 -->
<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();
}"
/>
2024-02-05 09:15:37 +08:00
</PageWrapper>
</template>
<script lang="ts" setup>
import { createVNode, onMounted, reactive, ref, nextTick } from 'vue';
import { useModal } from '/@/components/Modal';
2024-02-05 09:15:37 +08:00
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';
2024-02-05 09:15:37 +08:00
import { deleteWorkflow, getProcessMonitorPage, postSetSuspended } from '/@/api/workflow/monitor';
import { getDesignList } from '/@/api/workflow/design';
2024-02-05 09:15:37 +08:00
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;
});
2024-02-05 09:15:37 +08:00
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: getDesignList,
showSearch: true,
labelField: 'name',
valueField: 'definitionKey',
getPopupContainer: () => document.body,
},
},
2024-02-05 09:15:37 +08:00
{
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({});
2024-02-05 09:15:37 +08:00
const selectedKeys = ref([0]);
const lookProcess = ref()
2024-02-05 09:15:37 +08:00
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',
2024-02-05 09:15:37 +08:00
},
beforeFetch: (params) => {
//发送请求默认新增 左边树结构所选机构id
queryData.value = {
...params,
definitionKey: params.definitionKey?params.definitionKey:definitionKey.value,
type: data.type
};
return queryData.value
2024-02-05 09:15:37 +08:00
},
useSearchForm: true,
showTableSetting: true,
striped: false,
pagination: {
pageSize: 18,
},
tableSetting: {
size: false,
setting: false,
},
});
let data: {
type: number;
approvedUserVisible: boolean;
visibleVersion: boolean;
2024-02-05 09:15:37 +08:00
} = reactive({
type: 0,
approvedUserVisible: false,
visibleVersion: false,
2024-02-05 09:15:37 +08:00
});
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) {
2024-02-05 09:15:37 +08:00
return selectRows[0];
} else if (selectRows.length > 1) {
notification.open({
type: 'error',
message: t('流程'),
description: t(tip || '请选择单一一个流程进行'),
});
return false;
2024-02-05 09:15:37 +08:00
} 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;
}
2024-02-05 09:15:37 +08:00
</script>