Commit 33f3bc05 by YunaiV

【功能优化】工作流:BPMN 流程图高亮的计算,切换到后端为主

parent 619491b4
......@@ -95,7 +95,7 @@
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"autoprefixer": "^10.4.17",
"bpmn-js": "8.9.0",
"bpmn-js": "8.10.0",
"bpmn-js-properties-panel": "0.46.0",
"consola": "^3.2.3",
"eslint": "^8.57.0",
......
import request from '@/config/axios'
export const getActivityList = async (params) => {
return await request.get({
url: '/bpm/activity/list',
params
})
}
......@@ -24,24 +24,23 @@ export type ProcessInstanceVO = {
// 用户信息
export type User = {
id: number,
nickname: string,
id: number
nickname: string
avatar: string
}
// 审批任务信息
export type ApprovalTaskInfo = {
id: number,
ownerUser: User,
assigneeUser: User,
status: number,
id: number
ownerUser: User
assigneeUser: User
status: number
reason: string
}
// 审批节点信息
export type ApprovalNodeInfo = {
id : number
id: number
name: string
nodeType: NodeType
status: number
......@@ -88,12 +87,22 @@ export const getProcessInstanceCopyPage = async (params: any) => {
}
// 获取审批详情
export const getApprovalDetail = async (processInstanceId?:string, processDefinitionId?:string) => {
const param = processInstanceId ? '?processInstanceId='+ processInstanceId : '?processDefinitionId='+ processDefinitionId
return await request.get({ url: 'bpm/process-instance/get-approval-detail'+ param })
export const getApprovalDetail = async (
processInstanceId?: string,
processDefinitionId?: string
) => {
const param = processInstanceId
? '?processInstanceId=' + processInstanceId
: '?processDefinitionId=' + processDefinitionId
return await request.get({ url: 'bpm/process-instance/get-approval-detail' + param })
}
// 获取表单字段权限
export const getFormFieldsPermission = async (params: any) => {
return await request.get({ url: '/bpm/process-instance/get-form-fields-permission', params })
}
// 获取流程实例的 BPMN 模型视图
export const getProcessInstanceBpmnModelView = async (id: string) => {
return await request.get({ url: '/bpm/process-instance/get-bpmn-model-view?id=' + id })
}
<template>
<div class="simple-flow-canvas" v-loading="loading">
<div class="simple-flow-container" >
<div class="simple-flow-container">
<div class="top-area-container">
<div class="top-actions">
<div class="canvas-control">
......@@ -15,10 +15,7 @@
</div>
</div>
<div class="scale-container" :style="`transform: scale(${scaleValue / 100});`">
<ProcessNodeTree
v-if="processNodeTree"
v-model:flow-node="processNodeTree"
/>
<ProcessNodeTree v-if="processNodeTree" v-model:flow-node="processNodeTree" />
</div>
</div>
<Dialog v-model="errorDialogVisible" title="保存失败" width="400" :fullscreen="false">
......@@ -49,7 +46,7 @@ import * as DeptApi from '@/api/system/dept'
import * as PostApi from '@/api/system/post'
import * as UserApi from '@/api/system/user'
import * as UserGroupApi from '@/api/bpm/userGroup'
import { fa } from 'element-plus/es/locale'
defineOptions({
name: 'SimpleProcessDesigner'
})
......
@import './process-designer.scss';
@import './process-panel.scss';
$success-color: #4eb819;
$primary-color: #409EFF;
$danger-color: #F56C6C;
$cancel-color: #909399;
.process-viewer {
position: relative;
border: 1px solid #EFEFEF;
background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImEiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZD0iTTAgMTBoNDBNMTAgMHY0ME0wIDIwaDQwTTIwIDB2NDBNMCAzMGg0ME0zMCAwdjQwIiBmaWxsPSJub25lIiBzdHJva2U9IiNlMGUwZTAiIG9wYWNpdHk9Ii4yIi8+PHBhdGggZD0iTTQwIDBIMHY0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZTBlMGUwIi8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+') repeat!important;
.success-arrow {
fill: $success-color;
stroke: $success-color;
}
.success-conditional {
fill: white;
stroke: $success-color;
}
.success.djs-connection {
.djs-visual path {
stroke: $success-color!important;
//marker-end: url(#sequenceflow-end-white-success)!important;
}
}
.success.djs-connection.condition-expression {
.djs-visual path {
//marker-start: url(#conditional-flow-marker-white-success)!important;
}
}
.success.djs-shape {
.djs-visual rect {
stroke: $success-color!important;
fill: $success-color!important;
fill-opacity: 0.15!important;
}
.djs-visual polygon {
stroke: $success-color!important;
}
.djs-visual path:nth-child(2) {
stroke: $success-color!important;
fill: $success-color!important;
}
.djs-visual circle {
stroke: $success-color!important;
fill: $success-color!important;
fill-opacity: 0.15!important;
}
}
.primary.djs-shape {
.djs-visual rect {
stroke: $primary-color!important;
fill: $primary-color!important;
fill-opacity: 0.15!important;
}
.djs-visual polygon {
stroke: $primary-color!important;
}
.djs-visual circle {
stroke: $primary-color!important;
fill: $primary-color!important;
fill-opacity: 0.15!important;
}
}
.danger.djs-shape {
.djs-visual rect {
stroke: $danger-color!important;
fill: $danger-color!important;
fill-opacity: 0.15!important;
}
.djs-visual polygon {
stroke: $danger-color!important;
}
.djs-visual circle {
stroke: $danger-color!important;
fill: $danger-color!important;
fill-opacity: 0.15!important;
}
}
.cancel.djs-shape {
.djs-visual rect {
stroke: $cancel-color!important;
fill: $cancel-color!important;
fill-opacity: 0.15!important;
}
.djs-visual polygon {
stroke: $cancel-color!important;
}
.djs-visual circle {
stroke: $cancel-color!important;
fill: $cancel-color!important;
fill-opacity: 0.15!important;
}
}
}
.process-viewer .djs-tooltip-container, .process-viewer .djs-overlay-container, .process-viewer .djs-palette {
display: none;
}
......@@ -292,7 +292,8 @@ const remainingRouter: AppRouteRecordRaw[] = [
},
{
path: 'process-instance/detail',
component: () => import('@/views/bpm/processInstance/detail/index_new.vue'),
// component: () => import('@/views/bpm/processInstance/detail/index_new.vue'),
component: () => import('@/views/bpm/processInstance/detail/index.vue'),
name: 'BpmProcessInstanceDetail',
meta: {
noCache: true,
......@@ -301,13 +302,11 @@ const remainingRouter: AppRouteRecordRaw[] = [
title: '流程详情',
activeMenu: '/bpm/task/my'
},
props: route => (
{
id: route.query.id,
taskId: route.query.taskId,
activityId: route.query.activityId
}
)
props: (route) => ({
id: route.query.id,
taskId: route.query.taskId,
activityId: route.query.activityId
})
},
{
path: 'oa/leave/create',
......
......@@ -449,3 +449,11 @@ export const BpmModelFormType = {
NORMAL: 10, // 流程表单
CUSTOM: 20 // 业务表单
}
export const BpmProcessInstanceStatus = {
NOT_START: -1, // 未开始
RUNNING: 1, // 审批中
APPROVE: 2, // 审批通过
REJECT: 3, // 审批不通过
CANCEL: 4 // 已取消
}
......@@ -3,48 +3,43 @@
<template #header>
<span class="el-icon-picture-outline">流程图</span>
</template>
<MyProcessViewer
key="designer"
:activityData="activityList"
:prefix="bpmnControlForm.prefix"
:processInstanceData="processInstance"
:taskData="tasks"
:value="bpmnXml"
v-bind="bpmnControlForm"
/>
<MyProcessViewer key="designer" :xml="view.bpmnXml" :view="view" class="h-700px" />
</el-card>
</template>
<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes'
import { MyProcessViewer } from '@/components/bpmnProcessDesigner/package'
import * as ActivityApi from '@/api/bpm/activity'
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
defineOptions({ name: 'BpmProcessInstanceBpmnViewer' })
const props = defineProps({
loading: propTypes.bool, // 是否加载中
loading: propTypes.bool.def(false), // 是否加载中
id: propTypes.string, // 流程实例的编号
processInstance: propTypes.any, // 流程实例的信息
tasks: propTypes.array, // 流程任务的数组
bpmnXml: propTypes.string // BPMN XML
})
const bpmnControlForm = ref({
prefix: 'flowable'
})
const activityList = ref([]) // 任务列表
const view = ref({
bpmnXml: ''
}) // BPMN 流程图数据
/** 只有 loading 完成时,才去加载流程列表 */
watch(
() => props.loading,
async (value) => {
if (value && props.id) {
activityList.value = await ActivityApi.getActivityList({
processInstanceId: props.id
})
view.value = await ProcessInstanceApi.getProcessInstanceBpmnModelView(props.id)
}
}
)
/** 监听 bpmnXml */
watch(
() => props.bpmnXml,
(value) => {
view.value.bpmnXml = value
}
)
</script>
<style>
.box-card {
......
......@@ -157,13 +157,7 @@
/>
<!-- 高亮流程图 -->
<ProcessInstanceBpmnViewer
:id="`${id}`"
:bpmn-xml="bpmnXml"
:loading="processInstanceLoading"
:process-instance="processInstance"
:tasks="tasks"
/>
<ProcessInstanceBpmnViewer :id="`${id}`" :loading="processInstanceLoading" />
<!-- 弹窗:转派审批人 -->
<TaskTransferForm ref="taskTransferFormRef" @success="getDetail" />
......
......@@ -66,13 +66,7 @@
</el-tab-pane>
<!-- 流程图 -->
<el-tab-pane label="流程图" name="diagram">
<ProcessInstanceBpmnViewer
:id="`${id}`"
:bpmn-xml="bpmnXml"
:loading="processInstanceLoading"
:process-instance="processInstance"
:tasks="tasks"
/>
<ProcessInstanceBpmnViewer :id="`${id}`" :loading="processInstanceLoading" />
</el-tab-pane>
<!-- 流转记录 -->
<el-tab-pane label="流转记录" name="record">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment