Merge branch 'dev' of https://gitee.com/yudaocode/yudao-ui-admin-vben into dev
This commit is contained in:
@@ -346,7 +346,12 @@ onMounted(async () => {
|
||||
</Row>
|
||||
</TabPane>
|
||||
|
||||
<TabPane tab="流程图" key="diagram" class="tab-pane-content">
|
||||
<TabPane
|
||||
tab="流程图"
|
||||
key="diagram"
|
||||
class="tab-pane-content"
|
||||
:force-render="true"
|
||||
>
|
||||
<div class="h-full">
|
||||
<ProcessInstanceSimpleViewer
|
||||
v-show="
|
||||
|
||||
@@ -1,9 +1,180 @@
|
||||
<script setup lang="ts">
|
||||
defineOptions({ name: 'ProcessInstanceSimpleViewer' });
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import type { SimpleFlowNode } from '#/components/simple-process-design';
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
import { SimpleProcessViewer } from '#/components/simple-process-design';
|
||||
import { BpmNodeTypeEnum, BpmTaskStatusEnum } from '#/utils';
|
||||
|
||||
defineOptions({ name: 'BpmProcessInstanceSimpleViewer' });
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
loading?: boolean; // 是否加载中
|
||||
modelView?: any;
|
||||
simpleJson?: string; // Simple 模型结构数据 (json 格式)
|
||||
}>(),
|
||||
{
|
||||
loading: false,
|
||||
modelView: () => ({}),
|
||||
simpleJson: '',
|
||||
},
|
||||
);
|
||||
|
||||
const simpleModel = ref<any>({});
|
||||
// 用户任务
|
||||
const tasks = ref([]);
|
||||
// 流程实例
|
||||
const processInstance = ref();
|
||||
|
||||
/** 监控模型视图 包括任务列表、进行中的活动节点编号等 */
|
||||
watch(
|
||||
() => props.modelView,
|
||||
async (newModelView) => {
|
||||
if (newModelView) {
|
||||
tasks.value = newModelView.tasks;
|
||||
processInstance.value = newModelView.processInstance;
|
||||
// 已经拒绝的活动节点编号集合,只包括 UserTask
|
||||
const rejectedTaskActivityIds: string[] =
|
||||
newModelView.rejectedTaskActivityIds;
|
||||
// 进行中的活动节点编号集合, 只包括 UserTask
|
||||
const unfinishedTaskActivityIds: string[] =
|
||||
newModelView.unfinishedTaskActivityIds;
|
||||
// 已经完成的活动节点编号集合, 包括 UserTask、Gateway 等
|
||||
const finishedActivityIds: string[] =
|
||||
newModelView.finishedTaskActivityIds;
|
||||
// 已经完成的连线节点编号集合,只包括 SequenceFlow
|
||||
const finishedSequenceFlowActivityIds: string[] =
|
||||
newModelView.finishedSequenceFlowActivityIds;
|
||||
setSimpleModelNodeTaskStatus(
|
||||
newModelView.simpleModel,
|
||||
newModelView.processInstance?.status,
|
||||
rejectedTaskActivityIds,
|
||||
unfinishedTaskActivityIds,
|
||||
finishedActivityIds,
|
||||
finishedSequenceFlowActivityIds,
|
||||
);
|
||||
simpleModel.value = newModelView.simpleModel || {};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
/** 监控模型结构数据 */
|
||||
watch(
|
||||
() => props.simpleJson,
|
||||
async (value) => {
|
||||
if (value) {
|
||||
simpleModel.value = JSON.parse(value);
|
||||
}
|
||||
},
|
||||
);
|
||||
const setSimpleModelNodeTaskStatus = (
|
||||
simpleModel: SimpleFlowNode | undefined,
|
||||
processStatus: number,
|
||||
rejectedTaskActivityIds: string[],
|
||||
unfinishedTaskActivityIds: string[],
|
||||
finishedActivityIds: string[],
|
||||
finishedSequenceFlowActivityIds: string[],
|
||||
) => {
|
||||
if (!simpleModel) {
|
||||
return;
|
||||
}
|
||||
// 结束节点
|
||||
if (simpleModel.type === BpmNodeTypeEnum.END_EVENT_NODE) {
|
||||
simpleModel.activityStatus = finishedActivityIds.includes(simpleModel.id)
|
||||
? processStatus
|
||||
: BpmTaskStatusEnum.NOT_START;
|
||||
return;
|
||||
}
|
||||
// 审批节点
|
||||
if (
|
||||
simpleModel.type === BpmNodeTypeEnum.START_USER_NODE ||
|
||||
simpleModel.type === BpmNodeTypeEnum.USER_TASK_NODE ||
|
||||
simpleModel.type === BpmNodeTypeEnum.TRANSACTOR_NODE ||
|
||||
simpleModel.type === BpmNodeTypeEnum.CHILD_PROCESS_NODE
|
||||
) {
|
||||
simpleModel.activityStatus = BpmTaskStatusEnum.NOT_START;
|
||||
if (rejectedTaskActivityIds.includes(simpleModel.id)) {
|
||||
simpleModel.activityStatus = BpmTaskStatusEnum.REJECT;
|
||||
} else if (unfinishedTaskActivityIds.includes(simpleModel.id)) {
|
||||
simpleModel.activityStatus = BpmTaskStatusEnum.RUNNING;
|
||||
} else if (finishedActivityIds.includes(simpleModel.id)) {
|
||||
simpleModel.activityStatus = BpmTaskStatusEnum.APPROVE;
|
||||
}
|
||||
// TODO 是不是还缺一个 cancel 的状态
|
||||
}
|
||||
// 抄送节点
|
||||
if (simpleModel.type === BpmNodeTypeEnum.COPY_TASK_NODE) {
|
||||
// 抄送节点,只有通过和未执行状态
|
||||
simpleModel.activityStatus = finishedActivityIds.includes(simpleModel.id)
|
||||
? BpmTaskStatusEnum.APPROVE
|
||||
: BpmTaskStatusEnum.NOT_START;
|
||||
}
|
||||
// 延迟器节点
|
||||
if (simpleModel.type === BpmNodeTypeEnum.DELAY_TIMER_NODE) {
|
||||
// 延迟器节点,只有通过和未执行状态
|
||||
simpleModel.activityStatus = finishedActivityIds.includes(simpleModel.id)
|
||||
? BpmTaskStatusEnum.APPROVE
|
||||
: BpmTaskStatusEnum.NOT_START;
|
||||
}
|
||||
// 触发器节点
|
||||
if (simpleModel.type === BpmNodeTypeEnum.TRIGGER_NODE) {
|
||||
// 触发器节点,只有通过和未执行状态
|
||||
simpleModel.activityStatus = finishedActivityIds.includes(simpleModel.id)
|
||||
? BpmTaskStatusEnum.APPROVE
|
||||
: BpmTaskStatusEnum.NOT_START;
|
||||
}
|
||||
|
||||
// 条件节点对应 SequenceFlow
|
||||
if (simpleModel.type === BpmNodeTypeEnum.CONDITION_NODE) {
|
||||
// 条件节点,只有通过和未执行状态
|
||||
simpleModel.activityStatus = finishedSequenceFlowActivityIds.includes(
|
||||
simpleModel.id,
|
||||
)
|
||||
? BpmTaskStatusEnum.APPROVE
|
||||
: BpmTaskStatusEnum.NOT_START;
|
||||
}
|
||||
// 网关节点
|
||||
if (
|
||||
simpleModel.type === BpmNodeTypeEnum.CONDITION_BRANCH_NODE ||
|
||||
simpleModel.type === BpmNodeTypeEnum.PARALLEL_BRANCH_NODE ||
|
||||
simpleModel.type === BpmNodeTypeEnum.INCLUSIVE_BRANCH_NODE ||
|
||||
simpleModel.type === BpmNodeTypeEnum.ROUTER_BRANCH_NODE
|
||||
) {
|
||||
// 网关节点。只有通过和未执行状态
|
||||
simpleModel.activityStatus = finishedActivityIds.includes(simpleModel.id)
|
||||
? BpmTaskStatusEnum.APPROVE
|
||||
: BpmTaskStatusEnum.NOT_START;
|
||||
simpleModel.conditionNodes?.forEach((node) => {
|
||||
setSimpleModelNodeTaskStatus(
|
||||
node,
|
||||
processStatus,
|
||||
rejectedTaskActivityIds,
|
||||
unfinishedTaskActivityIds,
|
||||
finishedActivityIds,
|
||||
finishedSequenceFlowActivityIds,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
setSimpleModelNodeTaskStatus(
|
||||
simpleModel.childNode,
|
||||
processStatus,
|
||||
rejectedTaskActivityIds,
|
||||
unfinishedTaskActivityIds,
|
||||
finishedActivityIds,
|
||||
finishedSequenceFlowActivityIds,
|
||||
);
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<h1>Simple BPM Viewer</h1>
|
||||
<div v-loading="loading">
|
||||
<SimpleProcessViewer
|
||||
:flow-node="simpleModel"
|
||||
:tasks="tasks"
|
||||
:process-instance="processInstance"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance';
|
||||
|
||||
import { h, nextTick, onMounted, ref } from 'vue';
|
||||
import { nextTick, onMounted, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { confirm, Page } from '@vben/common-ui';
|
||||
import { Page, prompt } from '@vben/common-ui';
|
||||
|
||||
import { Input, message } from 'ant-design-vue';
|
||||
|
||||
@@ -29,7 +29,6 @@ const processDefinitionId = query.processDefinitionId as string;
|
||||
const formFields = ref<any[]>([]);
|
||||
const userList = ref<any[]>([]); // 用户列表
|
||||
const gridReady = ref(false); // 表格是否准备好
|
||||
const cancelReason = ref(''); // 取消原因
|
||||
|
||||
// 表格的列需要解析表单字段,这里定义成变量,解析表单字段后再渲染
|
||||
let Grid: any = null;
|
||||
@@ -81,26 +80,19 @@ const handleDetail = (row: BpmProcessInstanceApi.ProcessInstance) => {
|
||||
|
||||
/** 取消按钮操作 */
|
||||
const handleCancel = async (row: BpmProcessInstanceApi.ProcessInstance) => {
|
||||
cancelReason.value = ''; // 重置取消原因
|
||||
confirm({
|
||||
prompt({
|
||||
content: '请输入取消原因:',
|
||||
title: '取消流程',
|
||||
content: h('div', [
|
||||
h('p', '请输入取消原因:'),
|
||||
h(Input, {
|
||||
value: cancelReason.value,
|
||||
'onUpdate:value': (val: string) => {
|
||||
cancelReason.value = val;
|
||||
},
|
||||
placeholder: '请输入取消原因',
|
||||
}),
|
||||
]),
|
||||
beforeClose: async ({ isConfirm }) => {
|
||||
if (!isConfirm) return;
|
||||
if (!cancelReason.value.trim()) {
|
||||
icon: 'question',
|
||||
component: Input,
|
||||
modelPropName: 'value',
|
||||
async beforeClose(scope) {
|
||||
if (!scope.isConfirm) return;
|
||||
if (!scope.value) {
|
||||
message.warning('请输入取消原因');
|
||||
return false;
|
||||
}
|
||||
await cancelProcessInstanceByAdmin(row.id, cancelReason.value);
|
||||
await cancelProcessInstanceByAdmin(row.id, scope.value);
|
||||
return true;
|
||||
},
|
||||
}).then(() => {
|
||||
|
||||
Reference in New Issue
Block a user