Skip to content

Commit c7ecb0a

Browse files
committed
feat: 工作流审批页面-时间线组件样式布局重构与展示逻辑调整
1 parent de073e8 commit c7ecb0a

File tree

4 files changed

+81
-169
lines changed

4 files changed

+81
-169
lines changed

src/assets/svgs/bpm/condition.svg

Lines changed: 1 addition & 1 deletion
Loading

src/assets/svgs/bpm/copy.svg

Lines changed: 1 addition & 1 deletion
Loading

src/assets/svgs/bpm/parallel.svg

Lines changed: 1 addition & 1 deletion
Loading

src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue

Lines changed: 78 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -38,88 +38,80 @@
3838
<div class="flex items-center flex-wrap mt-1">
3939
<!-- 情况一:遍历每个审批节点下的【进行中】task 任务 -->
4040
<div v-for="(task, idx) in activity.tasks" :key="idx" class="flex items-center">
41-
<div class="flex flex-col pr-2">
42-
<div class="position-relative" v-if="task.assigneeUser || task.ownerUser">
43-
<!-- 信息:头像 -->
44-
<el-avatar
45-
v-if="task.assigneeUser && task.assigneeUser.avatar"
46-
:size="36"
47-
:src="task.assigneeUser.avatar"
48-
/>
49-
<el-avatar v-else-if="task.assigneeUser && task.assigneeUser.nickname">
50-
{{ task.assigneeUser.nickname.substring(0, 1) }}
51-
</el-avatar>
52-
<el-avatar
53-
v-else-if="task.ownerUser && task.ownerUser.avatar"
54-
:src="task.ownerUser.avatar"
55-
/>
56-
<el-avatar v-else-if="task.ownerUser && task.ownerUser.nickname">
57-
{{ task.ownerUser.nickname.substring(0, 1) }}
58-
</el-avatar>
59-
<!-- 信息:任务 ICON -->
41+
<div class="flex flex-col pr-2 gap2">
42+
<div
43+
class="position-relative flex flex-wrap gap2"
44+
v-if="task.assigneeUser || task.ownerUser"
45+
>
46+
<!-- 信息:头像昵称 -->
6047
<div
61-
class="position-absolute top-26px left-26px bg-#fff rounded-full flex items-center p-2px"
48+
class="bg-gray-100 h-35px rounded-3xl flex items-center p-8px gap-2 dark:color-gray-600 position-relative"
6249
>
63-
<Icon
64-
:size="12"
65-
:icon="statusIconMap2[task.status]?.icon"
66-
:color="statusIconMap2[task.status]?.color"
67-
/>
68-
</div>
69-
</div>
70-
<div class="flex flex-col mt-1">
71-
<!-- 信息:昵称 -->
72-
<div
73-
v-if="task.assigneeUser && task.assigneeUser.nickname"
74-
class="text-12px text-align-center"
75-
>
76-
{{ task.assigneeUser.nickname }}
50+
<template v-if="task.assigneeUser?.avatar || task.assigneeUser?.nickname">
51+
<el-avatar
52+
:size="28"
53+
v-if="task.assigneeUser?.avatar"
54+
:src="task.assigneeUser?.avatar"
55+
/>
56+
<el-avatar :size="28" v-else>
57+
{{ task.assigneeUser?.nickname.substring(0, 1) }}
58+
</el-avatar>
59+
{{ task.assigneeUser?.nickname }}
60+
</template>
61+
<template v-else-if="task.ownerUser?.avatar || task.ownerUser?.nickname">
62+
<el-avatar
63+
:size="28"
64+
v-if="task.ownerUser?.avatar"
65+
:src="task.ownerUser?.avatar"
66+
/>
67+
<el-avatar :size="28" v-else>
68+
{{ task.ownerUser?.nickname.substring(0, 1) }}
69+
</el-avatar>
70+
{{ task.ownerUser?.nickname }}
71+
</template>
72+
<!-- 信息:任务 ICON -->
73+
<div
74+
v-if="onlyStatusIconShow.includes(task.status)"
75+
class="position-absolute top-22px left-26px bg-#fff rounded-full flex items-center p-2px"
76+
>
77+
<Icon
78+
:size="12"
79+
:icon="statusIconMap2[task.status]?.icon"
80+
:color="statusIconMap2[task.status]?.color"
81+
/>
82+
</div>
7783
</div>
84+
<!-- 情况二:遍历每个审批节点下的【候选的】task 任务。例如说,1)依次审批,2)未来的审批任务等 -->
7885
<div
79-
v-else-if="task.ownerUser && task.ownerUser.nickname"
80-
class="text-10px text-align-center"
86+
v-for="(user, idx1) in activity.candidateUsers"
87+
:key="idx1"
88+
class="bg-gray-100 h-35px rounded-3xl flex items-center p-8px gap-2 dark:color-gray-600 position-relative"
8189
>
82-
{{ task.ownerUser.nickname }}
83-
</div>
84-
<div
85-
v-if="task.reason && activity.nodeType === NodeType.USER_TASK_NODE"
86-
class="text-#a5a5a5 text-13px mt-1"
87-
>
88-
审批意见:{{ task.reason }}
89-
</div>
90-
</div>
91-
</div>
92-
</div>
93-
<!-- 情况二:遍历每个审批节点下的【候选的】task 任务。例如说,1)依次审批,2)未来的审批任务等 -->
94-
<div
95-
v-for="(user, idx1) in activity.candidateUsers"
96-
:key="idx1"
97-
class="flex items-center self-start"
98-
>
99-
<div class="flex items-center flex-col pr-2">
100-
<div class="position-relative">
101-
<!-- 信息:头像 -->
102-
<el-avatar :size="36" v-if="user.avatar" :src="user.avatar" />
103-
<el-avatar v-else-if="user.nickname && user.nickname">
104-
{{ user.nickname.substring(0, 1) }}
105-
</el-avatar>
106-
<!-- 信息:任务 ICON -->
107-
<div
108-
class="position-absolute top-26px left-26px bg-#fff rounded-full flex items-center p-2px"
109-
>
110-
<Icon
111-
:size="12"
112-
:icon="statusIconMap2['-1']?.icon"
113-
:color="statusIconMap2['-1']?.color"
114-
/>
115-
</div>
116-
</div>
117-
<div class="flex flex-col mt-1">
118-
<!-- 信息:昵称 -->
119-
<div v-if="user.nickname" class="text-10px text-align-center">
90+
<el-avatar :size="28" v-if="user.avatar" :src="user.avatar" />
91+
<el-avatar :size="28" v-else>
92+
{{ user.nickname.substring(0, 1) }}
93+
</el-avatar>
12094
{{ user.nickname }}
95+
96+
<!-- 信息:任务 ICON -->
97+
<div
98+
v-if="onlyStatusIconShow.includes(task.status)"
99+
class="position-absolute top-22px left-26px bg-#fff rounded-full flex items-center p-2px"
100+
>
101+
<Icon
102+
:size="12"
103+
:icon="statusIconMap2['-1']?.icon"
104+
:color="statusIconMap2['-1']?.color"
105+
/>
106+
</div>
121107
</div>
122108
</div>
109+
<div
110+
v-if="task.reason && activity.nodeType === NodeType.USER_TASK_NODE"
111+
class="text-#a5a5a5 text-13px mt-1 w-full bg-#f8f8fa p2 rounded-md"
112+
>
113+
审批意见:{{ task.reason }}
114+
</div>
123115
</div>
124116
</div>
125117
</div>
@@ -141,93 +133,9 @@ import conditionSvg from '@/assets/svgs/bpm/condition.svg'
141133
import parallelSvg from '@/assets/svgs/bpm/parallel.svg'
142134
143135
defineOptions({ name: 'BpmProcessInstanceTimeline' })
144-
// defineProps<{
145-
// approveNodes: ProcessInstanceApi.ApprovalNodeInfo[] // 审批节点信息
146-
// }>()
147-
const approveNodes = [
148-
{
149-
id: 1,
150-
name: '发起审批',
151-
nodeType: NodeType.START_USER_NODE,
152-
status: TaskStatusEnum.NOT_START,
153-
startTime: new Date('2024-10-01 10:00:00'),
154-
endTime: null,
155-
candidateUsers: [],
156-
tasks: []
157-
},
158-
{
159-
id: 2,
160-
name: '经理审批',
161-
nodeType: NodeType.USER_TASK_NODE,
162-
status: TaskStatusEnum.RUNNING, // 审批中
163-
startTime: new Date('2024-10-02 11:00:00'),
164-
endTime: null,
165-
candidateUsers: [
166-
{
167-
nickname: '张经理',
168-
avatar: 'https://picsum.photos/200?r=1'
169-
},
170-
{
171-
nickname: '张经理',
172-
avatar: 'https://picsum.photos/200?r=1'
173-
},
174-
{
175-
nickname: '张经理',
176-
avatar: 'https://picsum.photos/200?r=1'
177-
},
178-
{
179-
nickname: '张经理',
180-
avatar: 'https://picsum.photos/200?r=1'
181-
}
182-
],
183-
tasks: [
184-
{
185-
assigneeUser: {
186-
nickname: '李经理',
187-
avatar: 'https://picsum.photos/200?r=1'
188-
},
189-
ownerUser: null,
190-
status: TaskStatusEnum.RUNNING, // 审批中
191-
reason: '同意'
192-
}
193-
]
194-
},
195-
{
196-
id: 3,
197-
name: '财务审批',
198-
nodeType: NodeType.USER_TASK_NODE,
199-
status: TaskStatusEnum.APPROVE, // 审批通过
200-
startTime: new Date('2024-10-03 14:00:00'),
201-
endTime: new Date('2024-10-03 15:00:00'),
202-
candidateUsers: [],
203-
tasks: [
204-
{
205-
assigneeUser: {
206-
nickname: '王财务',
207-
avatar: 'https://picsum.photos/200?r=1'
208-
},
209-
ownerUser: null,
210-
status: TaskStatusEnum.APPROVE, // 审批通过
211-
reason: '审批通过'
212-
}
213-
]
214-
},
215-
{
216-
id: 4,
217-
name: '总经理审批',
218-
nodeType: NodeType.USER_TASK_NODE,
219-
status: TaskStatusEnum.NOT_START, // 未开始
220-
startTime: null,
221-
endTime: null,
222-
candidateUsers: [
223-
{
224-
nickname: '总经理',
225-
avatar: 'https://picsum.photos/200?r=1'
226-
}
227-
],
228-
tasks: []
229-
}
230-
]
136+
defineProps<{
137+
approveNodes: ProcessInstanceApi.ApprovalNodeInfo[] // 审批节点信息
138+
}>()
231139
232140
// 审批节点
233141
const statusIconMap2 = {
@@ -273,17 +181,21 @@ const statusIconMap = {
273181
274182
const nodeTypeSvgMap = {
275183
// 发起人节点
276-
[NodeType.START_USER_NODE]: { color: '', svg: starterSvg },
184+
[NodeType.START_USER_NODE]: { color: '#ffffff', svg: starterSvg },
277185
// 审批人节点
278-
[NodeType.USER_TASK_NODE]: { color: '', svg: auditorSvg },
186+
[NodeType.USER_TASK_NODE]: { color: '#ff943e', svg: auditorSvg },
279187
// 抄送人节点
280-
[NodeType.COPY_TASK_NODE]: { color: '', svg: copySvg },
188+
[NodeType.COPY_TASK_NODE]: { color: '#3296fb', svg: copySvg },
281189
// 条件分支节点
282-
[NodeType.CONDITION_NODE]: { color: '', svg: conditionSvg },
190+
[NodeType.CONDITION_NODE]: { color: '#14bb83', svg: conditionSvg },
283191
// 并行分支节点
284-
[NodeType.PARALLEL_BRANCH_NODE]: { color: '', svg: parallelSvg }
192+
[NodeType.PARALLEL_BRANCH_NODE]: { color: '#14bb83', svg: parallelSvg }
285193
}
286194
195+
// 只有只有状态是 -1、0、1 才展示头像右小角状态小icon
196+
const onlyStatusIconShow = [-1, 0, 1]
197+
198+
// timeline时间线上icon图标
287199
const getApprovalNodeImg = (nodeType: NodeType) => {
288200
return nodeTypeSvgMap[nodeType]?.svg
289201
}

0 commit comments

Comments
 (0)