mirror of
https://gitee.com/hhyykk/ipms-sjy-ui.git
synced 2025-06-19 14:52:00 +08:00
【工作流】- 流程实例新界面修改
This commit is contained in:
parent
4680a7dcfd
commit
27d24cd02d
@ -1,6 +1,6 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
import { ProcessDefinitionVO } from '@/api/bpm/model'
|
import { ProcessDefinitionVO } from '@/api/bpm/model'
|
||||||
|
import { NodeType } from '@/components/SimpleProcessDesignerV2/src/consts'
|
||||||
export type Task = {
|
export type Task = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
@ -22,6 +22,35 @@ export type ProcessInstanceVO = {
|
|||||||
processDefinition?: ProcessDefinitionVO
|
processDefinition?: ProcessDefinitionVO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
export type User = {
|
||||||
|
id: number,
|
||||||
|
nickname: string,
|
||||||
|
avatar: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审批任务信息
|
||||||
|
export type ApprovalTaskInfo = {
|
||||||
|
id: number,
|
||||||
|
ownerUser: User,
|
||||||
|
assigneeUser: User,
|
||||||
|
status: number,
|
||||||
|
reason: string
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审批节点信息
|
||||||
|
export type ApprovalNodeInfo = {
|
||||||
|
id : number
|
||||||
|
name: string
|
||||||
|
nodeType: NodeType
|
||||||
|
status: number
|
||||||
|
startTime?: Date
|
||||||
|
endTime?: Date
|
||||||
|
candidateUserList?: User[]
|
||||||
|
tasks: ApprovalTaskInfo[]
|
||||||
|
}
|
||||||
|
|
||||||
export const getProcessInstanceMyPage = async (params: any) => {
|
export const getProcessInstanceMyPage = async (params: any) => {
|
||||||
return await request.get({ url: '/bpm/process-instance/my-page', params })
|
return await request.get({ url: '/bpm/process-instance/my-page', params })
|
||||||
}
|
}
|
||||||
@ -57,3 +86,8 @@ export const getProcessInstance = async (id: string) => {
|
|||||||
export const getProcessInstanceCopyPage = async (params: any) => {
|
export const getProcessInstanceCopyPage = async (params: any) => {
|
||||||
return await request.get({ url: '/bpm/process-instance/copy/page', params })
|
return await request.get({ url: '/bpm/process-instance/copy/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 })
|
||||||
|
}
|
||||||
|
@ -1,5 +1,51 @@
|
|||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务状态枚举
|
||||||
|
*/
|
||||||
|
export enum TaskStatusEnum {
|
||||||
|
/**
|
||||||
|
* 未开始
|
||||||
|
*/
|
||||||
|
NOT_START = -1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 待审批
|
||||||
|
*/
|
||||||
|
WAIT = 0,
|
||||||
|
/**
|
||||||
|
* 审批中
|
||||||
|
*/
|
||||||
|
RUNNING = 1,
|
||||||
|
/**
|
||||||
|
* 审批通过
|
||||||
|
*/
|
||||||
|
APPROVE = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批不通过
|
||||||
|
*/
|
||||||
|
REJECT = 3,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已取消
|
||||||
|
*/
|
||||||
|
CANCEL = 4,
|
||||||
|
/**
|
||||||
|
* 已退回
|
||||||
|
*/
|
||||||
|
RETURN = 5,
|
||||||
|
/**
|
||||||
|
* 委派中
|
||||||
|
*/
|
||||||
|
DELEGATE = 6,
|
||||||
|
/**
|
||||||
|
* 审批通过中
|
||||||
|
*/
|
||||||
|
APPROVING = 7,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export type TaskVO = {
|
export type TaskVO = {
|
||||||
id: number
|
id: number
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="simple-flow-canvas">
|
<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-area-container">
|
||||||
<div class="top-actions">
|
<div class="top-actions">
|
||||||
@ -15,7 +15,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="scale-container" :style="`transform: scale(${scaleValue / 100});`">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<Dialog v-model="errorDialogVisible" title="保存失败" width="400" :fullscreen="false">
|
<Dialog v-model="errorDialogVisible" title="保存失败" width="400" :fullscreen="false">
|
||||||
@ -46,6 +49,7 @@ import * as DeptApi from '@/api/system/dept'
|
|||||||
import * as PostApi from '@/api/system/post'
|
import * as PostApi from '@/api/system/post'
|
||||||
import * as UserApi from '@/api/system/user'
|
import * as UserApi from '@/api/system/user'
|
||||||
import * as UserGroupApi from '@/api/bpm/userGroup'
|
import * as UserGroupApi from '@/api/bpm/userGroup'
|
||||||
|
import { fa } from 'element-plus/es/locale'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'SimpleProcessDesigner'
|
name: 'SimpleProcessDesigner'
|
||||||
})
|
})
|
||||||
@ -56,7 +60,7 @@ const props = defineProps({
|
|||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const loading = ref(true)
|
||||||
const formFields = ref<string[]>([])
|
const formFields = ref<string[]>([])
|
||||||
const formType = ref(20)
|
const formType = ref(20)
|
||||||
const roleOptions = ref<RoleApi.RoleVO[]>([]) // 角色列表
|
const roleOptions = ref<RoleApi.RoleVO[]>([]) // 角色列表
|
||||||
@ -163,6 +167,8 @@ const zoomIn = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
// 获取表单字段
|
// 获取表单字段
|
||||||
const bpmnModel = await getModel(props.modelId)
|
const bpmnModel = await getModel(props.modelId)
|
||||||
if (bpmnModel) {
|
if (bpmnModel) {
|
||||||
@ -202,5 +208,8 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -292,7 +292,7 @@ const remainingRouter: AppRouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'process-instance/detail',
|
path: 'process-instance/detail',
|
||||||
component: () => import('@/views/bpm/processInstance/detail/index.vue'),
|
component: () => import('@/views/bpm/processInstance/detail/index_new.vue'),
|
||||||
name: 'BpmProcessInstanceDetail',
|
name: 'BpmProcessInstanceDetail',
|
||||||
meta: {
|
meta: {
|
||||||
noCache: true,
|
noCache: true,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="h-50px position-fixed bottom-10 text-14px flex items-center color-#32373c dark:color-#fff font-bold btn-container"
|
class="h-50px bottom-10 text-14px flex items-center color-#32373c dark:color-#fff font-bold btn-container"
|
||||||
>
|
>
|
||||||
<el-popover :visible="passVisible" placement="top-end" :width="500" trigger="click">
|
<el-popover :visible="passVisible" placement="top-end" :width="500" trigger="click">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
@ -120,6 +120,7 @@
|
|||||||
<div @click="handleSign"> <Icon :size="14" icon="ep:plus" /> 加签 </div>
|
<div @click="handleSign"> <Icon :size="14" icon="ep:plus" /> 加签 </div>
|
||||||
<div @click="handleBack"> <Icon :size="14" icon="fa:mail-reply" /> 退回 </div>
|
<div @click="handleBack"> <Icon :size="14" icon="fa:mail-reply" /> 退回 </div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- </div> -->
|
||||||
<!-- 弹窗:转派审批人 -->
|
<!-- 弹窗:转派审批人 -->
|
||||||
<TaskTransferForm ref="taskTransferFormRef" @success="getDetail" />
|
<TaskTransferForm ref="taskTransferFormRef" @success="getDetail" />
|
||||||
<!-- 弹窗:回退节点 -->
|
<!-- 弹窗:回退节点 -->
|
||||||
@ -299,10 +300,11 @@ defineExpose({ loadRunningTask })
|
|||||||
|
|
||||||
.btn-container {
|
.btn-container {
|
||||||
> div {
|
> div {
|
||||||
|
display: flex;
|
||||||
margin: 0 15px;
|
margin: 0 15px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #6db5ff;
|
color: #6db5ff;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,94 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-timeline class="pt-20px">
|
<el-timeline class="pt-20px">
|
||||||
<el-timeline-item v-for="(activity, index) in mockData" :key="index" size="large">
|
<el-timeline-item
|
||||||
|
v-for="(activity, index) in approveNodes"
|
||||||
|
:key="index"
|
||||||
|
size="large"
|
||||||
|
:icon="getApprovalNodeIcon(activity.status, activity.nodeType)"
|
||||||
|
:color="getApprovalNodeColor(activity.status)"
|
||||||
|
>
|
||||||
<div class="flex flex-col items-start">
|
<div class="flex flex-col items-start">
|
||||||
<div class="font-bold"> {{ activity.name }}</div>
|
<div class="font-bold"> {{ activity.name }}</div>
|
||||||
<div class="color-#a1a6ae text-12px mb-10px"> {{ activity.assigneeUser.nickname }}</div>
|
<div class="flex items-center mt-1">
|
||||||
|
<div v-for="(task, idx) in activity.tasks" :key="idx" class="flex items-center">
|
||||||
|
<div class="flex items-center flex-col pr-2">
|
||||||
|
<div class="position-relative" v-if="task.assigneeUser || task.ownerUser">
|
||||||
|
<el-avatar
|
||||||
|
:size="36"
|
||||||
|
v-if="task.assigneeUser && task.assigneeUser.avatar"
|
||||||
|
:src="task.assigneeUser.avatar"
|
||||||
|
/>
|
||||||
|
<el-avatar v-else-if="task.assigneeUser && task.assigneeUser.nickname">
|
||||||
|
{{ task.assigneeUser.nickname.substring(0, 1) }}</el-avatar
|
||||||
|
>
|
||||||
|
<el-avatar
|
||||||
|
v-else-if="task.ownerUser && task.ownerUser.avatar"
|
||||||
|
:src="task.ownerUser.avatar"
|
||||||
|
/>
|
||||||
|
<el-avatar v-else-if="task.ownerUser && task.ownerUser.nickname">
|
||||||
|
{{ task.ownerUser.nickname.substring(0, 1) }}</el-avatar
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="position-absolute top-26px left-26px bg-#fff rounded-full flex items-center p-2px"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
:size="12"
|
||||||
|
:icon="statusIconMap2[task.status]?.icon"
|
||||||
|
:color="statusIconMap2[task.status]?.color"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col mt-1">
|
||||||
|
<div
|
||||||
|
v-if="task.assigneeUser && task.assigneeUser.nickname"
|
||||||
|
class="text-10px text-align-center"
|
||||||
|
>{{ task.assigneeUser.nickname }}</div
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-else-if="task.ownerUser && task.ownerUser.nickname"
|
||||||
|
class="text-10px text-align-center"
|
||||||
|
>
|
||||||
|
{{ task.ownerUser.nickname }}</div
|
||||||
|
>
|
||||||
|
<!-- <div v-if="task.reason" :title="task.reason" class="text-13px text-truncate w-150px mt-1"> 审批意见: {{ task.reason }}</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-for="(user, idx1) in activity.candidateUserList"
|
||||||
|
:key="idx1"
|
||||||
|
class="flex items-center"
|
||||||
|
>
|
||||||
|
<div class="flex items-center flex-col pr-2">
|
||||||
|
<div class="position-relative">
|
||||||
|
<el-avatar :size="36" v-if="user.avatar" :src="user.avatar" />
|
||||||
|
<el-avatar v-else-if="user.nickname && user.nickname">
|
||||||
|
{{ user.nickname.substring(0, 1) }}</el-avatar
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="position-absolute top-26px left-26px bg-#fff rounded-full flex items-center p-2px"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
:size="12"
|
||||||
|
:icon="statusIconMap2['-1']?.icon"
|
||||||
|
:color="statusIconMap2['-1']?.color"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col mt-1">
|
||||||
|
<div v-if="user.nickname" class="text-10px text-align-center">{{
|
||||||
|
user.nickname
|
||||||
|
}}</div>
|
||||||
|
<!-- <div v-if="task.reason" :title="task.reason" class="text-13px text-truncate w-150px mt-1"> 审批意见: {{ task.reason }}</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="activity.status !== TaskStatusEnum.NOT_START" class="text-#a5a5a5 text-13px mt-1">
|
||||||
|
{{ getApprovalNodeTime(activity) }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="color-#a1a6ae text-12px mb-10px"> {{ activity.assigneeUser.nickname }}</div>
|
||||||
<div v-if="activity.opinion" class="text-#a5a5a5 text-12px w-100%">
|
<div v-if="activity.opinion" class="text-#a5a5a5 text-12px w-100%">
|
||||||
<div class="mb-5px">审批意见:</div>
|
<div class="mb-5px">审批意见:</div>
|
||||||
<div
|
<div
|
||||||
@ -14,50 +99,113 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="activity.createTime" class="text-#a5a5a5 text-13px">
|
<div v-if="activity.createTime" class="text-#a5a5a5 text-13px">
|
||||||
{{ formatDate(activity.createTime) }}
|
{{ formatDate(activity.createTime) }}
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<!-- 该节点用户的头像 -->
|
|
||||||
<template #dot>
|
|
||||||
<div class="w-35px h-35px position-relative">
|
|
||||||
<img
|
|
||||||
src="@/assets/imgs/avatar.jpg"
|
|
||||||
class="rounded-full w-full h-full position-absolute bottom-6px right-12px"
|
|
||||||
alt=""
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="position-absolute top-16px left-8px bg-#fff rounded-full flex items-center content-center p-2px"
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
:size="12"
|
|
||||||
:icon="optIconMap[activity.status]?.icon"
|
|
||||||
:color="optIconMap[activity.status]?.color"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-timeline-item>
|
</el-timeline-item>
|
||||||
</el-timeline>
|
</el-timeline>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { formatDate } from '@/utils/formatTime'
|
import { formatDate } from '@/utils/formatTime'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
|
||||||
|
import { TaskStatusEnum } from '@/api/bpm/task'
|
||||||
|
import { NodeType } from '@/components/SimpleProcessDesignerV2/src/consts'
|
||||||
|
import { Check, Close, Loading, Clock, Minus, Delete } from '@element-plus/icons-vue'
|
||||||
defineOptions({ name: 'BpmProcessInstanceTimeline' })
|
defineOptions({ name: 'BpmProcessInstanceTimeline' })
|
||||||
defineProps({
|
const props = defineProps({
|
||||||
tasks: propTypes.array // 流程任务的数组
|
// 流程实例编号
|
||||||
|
processInstanceId: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 流程定义编号
|
||||||
|
processDefinitionId: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const optIconMap = {
|
// 审批节点
|
||||||
|
const approveNodes = ref<ProcessInstanceApi.ApprovalNodeInfo[]>([])
|
||||||
|
|
||||||
|
const statusIconMap2 = {
|
||||||
|
// 未开始
|
||||||
|
'-1': { color: '#e5e7ec', icon: 'ep-clock' },
|
||||||
|
// 待审批
|
||||||
|
'0': { color: '#e5e7ec', icon: 'ep:loading' },
|
||||||
// 审批中
|
// 审批中
|
||||||
'1': {
|
'1': { color: '#448ef7', icon: 'ep:loading'},
|
||||||
color: '#00b32a',
|
|
||||||
icon: 'fa-solid:clock'
|
|
||||||
},
|
|
||||||
// 审批通过
|
// 审批通过
|
||||||
'2': { color: '#00b32a', icon: 'fa-solid:check-circle' },
|
'2': { color: '#00b32a', icon: 'ep:circle-check-filled' },
|
||||||
// 审批不通过
|
// 审批不通过
|
||||||
'3': { color: '#f46b6c', icon: 'fa-solid:times-circle' }
|
'3': { color: '#f46b6c', icon: 'fa-solid:times-circle' },
|
||||||
|
// 取消
|
||||||
|
'4': { color: '#cccccc', icon: 'ep:delete-filled' },
|
||||||
|
// 回退
|
||||||
|
'5': { color: '#f46b6c', icon: 'ep:remove-filled' },
|
||||||
|
// 委派中
|
||||||
|
'6': { color: '#448ef7', icon: 'ep:loading' },
|
||||||
|
// 审批通过中
|
||||||
|
'7': { color: '#00b32a', icon: 'ep:circle-check-filled' },
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusIconMap = {
|
||||||
|
// 审批未开始
|
||||||
|
'-1': { color: '#e5e7ec', icon: Clock },
|
||||||
|
'0': { color: '#e5e7ec', icon: Clock },
|
||||||
|
// 审批中
|
||||||
|
'1': { color: '#448ef7', icon: Loading },
|
||||||
|
// 审批通过
|
||||||
|
'2': { color: '#00b32a', icon: Check },
|
||||||
|
// 审批不通过
|
||||||
|
'3': { color: '#f46b6c', icon: Close },
|
||||||
|
// 已取消
|
||||||
|
'4': { color: '#cccccc', icon: Delete },
|
||||||
|
// 回退
|
||||||
|
'5' : { color: '#f46b6c', icon: Minus },
|
||||||
|
// 委派中
|
||||||
|
'6': { color: '#448ef7', icon: Loading },
|
||||||
|
// 审批通过中
|
||||||
|
'7': { color: '#00b32a', icon: Check },
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获得审批详情 */
|
||||||
|
const getApprovalDetail = async () => {
|
||||||
|
const data = await ProcessInstanceApi.getApprovalDetail(
|
||||||
|
props.processInstanceId,
|
||||||
|
props.processDefinitionId
|
||||||
|
)
|
||||||
|
console.log('approveNodes is []', data)
|
||||||
|
approveNodes.value = data.approveNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
const getApprovalNodeIcon = (taskStatus: number , nodeType: NodeType) => {
|
||||||
|
|
||||||
|
if(taskStatus == TaskStatusEnum.NOT_START) {
|
||||||
|
return statusIconMap[taskStatus]?.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeType === NodeType.START_USER_NODE || nodeType === NodeType.USER_TASK_NODE) {
|
||||||
|
return statusIconMap[taskStatus]?.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const getApprovalNodeColor = (taskStatus: number) => {
|
||||||
|
return statusIconMap[taskStatus]?.color
|
||||||
|
}
|
||||||
|
|
||||||
|
const getApprovalNodeTime = (node: ProcessInstanceApi.ApprovalNodeInfo) => {
|
||||||
|
|
||||||
|
if(node.endTime) {
|
||||||
|
return `结束时间:${formatDate(node.endTime)}`
|
||||||
|
}
|
||||||
|
if(node.startTime) {
|
||||||
|
return `创建时间:${formatDate(node.startTime)}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mockData: any = [
|
const mockData: any = [
|
||||||
@ -125,6 +273,70 @@ const mockData: any = [
|
|||||||
formFields: null,
|
formFields: null,
|
||||||
formVariables: null
|
formVariables: null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'fe1190ee-68c3-11ef-9c7d-00a6181404fd',
|
||||||
|
name: '财务总监审核',
|
||||||
|
createTime: 1725237646192,
|
||||||
|
endTime: null,
|
||||||
|
durationInMillis: null,
|
||||||
|
status: 3,
|
||||||
|
reason: null,
|
||||||
|
ownerUser: null,
|
||||||
|
assigneeUser: {
|
||||||
|
id: 104,
|
||||||
|
nickname: '财务总监',
|
||||||
|
deptId: 107,
|
||||||
|
deptName: '运维部门'
|
||||||
|
},
|
||||||
|
taskDefinitionKey: 'task-01',
|
||||||
|
processInstanceId: 'fe0c60c6-68c3-11ef-9c7d-00a6181404fd',
|
||||||
|
processInstance: {
|
||||||
|
id: 'fe0c60c6-68c3-11ef-9c7d-00a6181404fd',
|
||||||
|
name: 'oa_leave',
|
||||||
|
createTime: null,
|
||||||
|
processDefinitionId: 'oa_leave:1:6e5ac269-5f87-11ef-bdb6-00a6181404fd',
|
||||||
|
startUser: null
|
||||||
|
},
|
||||||
|
parentTaskId: null,
|
||||||
|
children: null,
|
||||||
|
formId: null,
|
||||||
|
formName: null,
|
||||||
|
formConf: null,
|
||||||
|
formFields: null,
|
||||||
|
formVariables: null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'fe1190ee-68c3-11ef-9c7d-00a6181404fd',
|
||||||
|
name: '领导审批',
|
||||||
|
createTime: 1725237646192,
|
||||||
|
endTime: null,
|
||||||
|
durationInMillis: null,
|
||||||
|
status: 2,
|
||||||
|
reason: null,
|
||||||
|
ownerUser: null,
|
||||||
|
assigneeUser: {
|
||||||
|
id: 104,
|
||||||
|
nickname: '领导',
|
||||||
|
deptId: 107,
|
||||||
|
deptName: '运维部门'
|
||||||
|
},
|
||||||
|
taskDefinitionKey: 'task-01',
|
||||||
|
processInstanceId: 'fe0c60c6-68c3-11ef-9c7d-00a6181404fd',
|
||||||
|
processInstance: {
|
||||||
|
id: 'fe0c60c6-68c3-11ef-9c7d-00a6181404fd',
|
||||||
|
name: 'oa_leave',
|
||||||
|
createTime: null,
|
||||||
|
processDefinitionId: 'oa_leave:1:6e5ac269-5f87-11ef-bdb6-00a6181404fd',
|
||||||
|
startUser: null
|
||||||
|
},
|
||||||
|
parentTaskId: null,
|
||||||
|
children: null,
|
||||||
|
formId: null,
|
||||||
|
formName: null,
|
||||||
|
formConf: null,
|
||||||
|
formFields: null,
|
||||||
|
formVariables: null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'fe1190ee-68c3-11ef-9c7d-00a6181404fd',
|
id: 'fe1190ee-68c3-11ef-9c7d-00a6181404fd',
|
||||||
name: '财务总监审核',
|
name: '财务总监审核',
|
||||||
@ -158,4 +370,8 @@ const mockData: any = [
|
|||||||
formVariables: null
|
formVariables: null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
getApprovalDetail()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,33 +1,42 @@
|
|||||||
<template>
|
<template>
|
||||||
<ContentWrap :bodyStyle="{ padding: '10px 20px' }" class="position-relative">
|
<ContentWrap :bodyStyle="{ padding: '10px 20px' }" class="position-relative">
|
||||||
|
<div class="processInstance-wrap-main">
|
||||||
|
<el-scrollbar>
|
||||||
<img
|
<img
|
||||||
class="position-absolute right-20px"
|
class="position-absolute right-20px"
|
||||||
width="150"
|
width="150"
|
||||||
:src="auditIcons[processInstance.status]"
|
:src="auditIcons[processInstance.status]"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
<div class="text-#878c93">编号:{{ id }}</div>
|
<div class="text-#878c93 h-15px">编号:{{ id }}</div>
|
||||||
<el-divider class="!my-8px" />
|
<el-divider class="!my-8px" />
|
||||||
<div class="flex items-center gap-5 mb-10px">
|
<div class="flex items-center gap-5 mb-10px h-40px">
|
||||||
<div class="text-26px font-bold mb-5px">{{ processInstance.name }}</div>
|
<div class="text-26px font-bold mb-5px">{{ processInstance.name }}</div>
|
||||||
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="processInstance.status" />
|
<dict-tag :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS" :value="processInstance.status" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-5 mb-10px text-13px">
|
<div class="flex items-center gap-5 mb-10px text-13px h-35px">
|
||||||
<div class="bg-gray-100 h-35px rounded-3xl flex items-center p-8px gap-2 dark:color-gray-600">
|
<div
|
||||||
|
class="bg-gray-100 h-35px rounded-3xl flex items-center p-8px gap-2 dark:color-gray-600"
|
||||||
|
>
|
||||||
<img class="rounded-full h-28px" src="@/assets/imgs/avatar.jpg" alt="" />
|
<img class="rounded-full h-28px" src="@/assets/imgs/avatar.jpg" alt="" />
|
||||||
{{ processInstance?.startUser?.nickname }}
|
{{ processInstance?.startUser?.nickname }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-#878c93"> {{ formatDate(processInstance.startTime) }} 提交 </div>
|
<div class="text-#878c93"> {{ formatDate(processInstance.startTime) }} 提交 </div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-tabs>
|
<el-tabs v-model="activeTab">
|
||||||
<!-- 表单信息 -->
|
<!-- 表单信息 -->
|
||||||
<el-tab-pane label="表单信息">
|
<el-tab-pane label="表单信息" name="form">
|
||||||
|
<div class="form-scoll-area">
|
||||||
|
<el-scrollbar>
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :span="18" class="!flex !flex-col formCol">
|
<el-col :span="18" class="!flex !flex-col formCol">
|
||||||
<!-- 表单信息 -->
|
<!-- 表单信息 -->
|
||||||
<div v-loading="processInstanceLoading" class="form-box flex flex-col mb-30px flex-1">
|
<div
|
||||||
|
v-loading="processInstanceLoading"
|
||||||
|
class="form-box flex flex-col mb-30px flex-1"
|
||||||
|
>
|
||||||
<!-- 情况一:流程表单 -->
|
<!-- 情况一:流程表单 -->
|
||||||
<el-col
|
<el-col
|
||||||
v-if="processInstance?.processDefinition?.formType === 10"
|
v-if="processInstance?.processDefinition?.formType === 10"
|
||||||
@ -46,23 +55,18 @@
|
|||||||
<BusinessFormComponent :id="processInstance.businessKey" />
|
<BusinessFormComponent :id="processInstance.businessKey" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 操作栏按钮 -->
|
|
||||||
<ProcessInstanceOperationButton
|
|
||||||
ref="operationButtonRef"
|
|
||||||
:processInstance="processInstance"
|
|
||||||
:userOptions="userOptions"
|
|
||||||
@success="getDetail"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<!-- 审批记录时间线 -->
|
<!-- 审批记录时间线 -->
|
||||||
<ProcessInstanceTimeline :process-instance="processInstance" :tasks="tasks" />
|
<ProcessInstanceTimeline :process-instance-id="id" />
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<!-- 流程图 -->
|
<!-- 流程图 -->
|
||||||
<el-tab-pane label="流程图">
|
<el-tab-pane label="流程图" name="diagram">
|
||||||
<ProcessInstanceBpmnViewer
|
<ProcessInstanceBpmnViewer
|
||||||
:id="`${id}`"
|
:id="`${id}`"
|
||||||
:bpmn-xml="bpmnXml"
|
:bpmn-xml="bpmnXml"
|
||||||
@ -72,7 +76,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- 流转记录 -->
|
<!-- 流转记录 -->
|
||||||
<el-tab-pane label="流转记录">
|
<el-tab-pane label="流转记录" name="record">
|
||||||
<ProcessInstanceTaskList
|
<ProcessInstanceTaskList
|
||||||
:loading="tasksLoad"
|
:loading="tasksLoad"
|
||||||
:process-instance="processInstance"
|
:process-instance="processInstance"
|
||||||
@ -81,8 +85,20 @@
|
|||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- 流转评论 -->
|
<!-- 流转评论 -->
|
||||||
<el-tab-pane label="流转评论"> 流转评论 </el-tab-pane>
|
<el-tab-pane label="流转评论" name="comment"> 流转评论 </el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
|
<div class=" b-t-solid border-t-1px border-[var(--el-border-color)]" v-if="activeTab === 'form'">
|
||||||
|
<!-- 操作栏按钮 -->
|
||||||
|
<ProcessInstanceOperationButton
|
||||||
|
ref="operationButtonRef"
|
||||||
|
:processInstance="processInstance"
|
||||||
|
:userOptions="userOptions"
|
||||||
|
@success="getDetail"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@ -209,6 +225,9 @@ const getTaskList = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 当前的Tab */
|
||||||
|
const activeTab = ref('form')
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
|
const userOptions = ref<UserApi.UserVO[]>([]) // 用户列表
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@ -219,9 +238,29 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
$wrap-padding-height: 30px ;
|
||||||
|
$wrap-margin-height: 15px;
|
||||||
|
$button-height: 51px;
|
||||||
|
$process-header-height: 194px;
|
||||||
|
|
||||||
|
.processInstance-wrap-main {
|
||||||
|
height: calc(100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - 45px);
|
||||||
|
max-height: calc(100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - 45px);
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.form-scoll-area {
|
||||||
|
height: calc(100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - 45px - $process-header-height - 40px);
|
||||||
|
max-height: calc(100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - 45px - $process-header-height - 40px);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.form-box {
|
.form-box {
|
||||||
:deep(.el-card) {
|
:deep(.el-card) {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user