Skip to content

Commit 738289b

Browse files
authored
Merge pull request #106 from GoldenZqqq/feature/bpm
工作流模块优化与bug修复
2 parents 12bd71e + 39f183b commit 738289b

File tree

6 files changed

+101
-24
lines changed

6 files changed

+101
-24
lines changed

src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,10 @@ const getApprovalDetail = async (row: any) => {
162162
startUserSelectTasks.value = data.activityNodes?.filter(
163163
(node: ApprovalNodeInfo) => CandidateStrategy.START_USER_SELECT === node.candidateStrategy
164164
)
165-
for (const node of startUserSelectTasks.value) {
166-
startUserSelectAssignees.value[node.id] = []
165+
if (startUserSelectTasks.value?.length > 0) {
166+
for (const node of startUserSelectTasks.value) {
167+
startUserSelectAssignees.value[node.id] = []
168+
}
167169
}
168170
169171
// 获取审批节点,显示 Timeline 的数据

src/views/bpm/processInstance/create/index.vue

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<el-col :span="5">
2323
<div class="flex flex-col">
2424
<div
25-
v-for="category in categoryList"
25+
v-for="category in availableCategories"
2626
:key="category.code"
2727
class="flex items-center p-10px cursor-pointer text-14px rounded-md"
2828
:class="categoryActive.code === category.code ? 'text-#3e7bff bg-#e8eeff' : ''"
@@ -33,7 +33,7 @@
3333
</div>
3434
</el-col>
3535
<el-col :span="19">
36-
<el-scrollbar ref="scrollWrapper" height="700">
36+
<el-scrollbar ref="scrollWrapper" height="700" @scroll="handleScroll">
3737
<div
3838
class="mb-20px pl-10px"
3939
v-for="(definitions, categoryCode) in processDefinitionGroup"
@@ -137,10 +137,6 @@ const getCategoryList = async () => {
137137
try {
138138
// 流程分类
139139
categoryList.value = await CategoryApi.getCategorySimpleList()
140-
// 选中首个分类
141-
if (categoryList.value.length > 0) {
142-
categoryActive.value = categoryList.value[0]
143-
}
144140
} finally {
145141
}
146142
}
@@ -154,6 +150,11 @@ const getProcessDefinitionList = async () => {
154150
})
155151
// 初始化过滤列表为全部流程定义
156152
filteredProcessDefinitionList.value = processDefinitionList.value
153+
154+
// 在获取完所有数据后,设置第一个有效分类为激活状态
155+
if (availableCategories.value.length > 0 && !categoryActive.value?.code) {
156+
categoryActive.value = availableCategories.value[0]
157+
}
157158
} finally {
158159
}
159160
}
@@ -220,10 +221,62 @@ const handleSelect = async (row, formVariables?) => {
220221
processDefinitionDetailRef.value?.initProcessInfo(row, formVariables)
221222
}
222223
224+
/** 处理滚动事件 */
225+
const handleScroll = (e) => {
226+
// 直接使用事件对象获取滚动位置
227+
const scrollTop = e.scrollTop
228+
229+
// 获取所有分类区域的位置信息
230+
const categoryPositions = categoryList.value
231+
.map((category) => {
232+
const categoryRef = proxy.$refs[`category-${category.code}`]
233+
if (categoryRef?.[0]) {
234+
return {
235+
code: category.code,
236+
offsetTop: categoryRef[0].offsetTop,
237+
height: categoryRef[0].offsetHeight
238+
}
239+
}
240+
return null
241+
})
242+
.filter(Boolean)
243+
244+
// 查找当前滚动位置对应的分类
245+
let currentCategory = categoryPositions[0]
246+
for (const position of categoryPositions) {
247+
// 为了更好的用户体验,可以添加一个缓冲区域(比如 50px)
248+
if (scrollTop >= position.offsetTop - 50) {
249+
currentCategory = position
250+
} else {
251+
break
252+
}
253+
}
254+
255+
// 更新当前 active 的分类
256+
if (currentCategory && categoryActive.value.code !== currentCategory.code) {
257+
categoryActive.value = categoryList.value.find((c) => c.code === currentCategory.code)
258+
}
259+
}
260+
223261
/** 初始化 */
224262
onMounted(() => {
225263
getList()
226264
})
265+
266+
/** 过滤出有流程的分类列表 */
267+
const availableCategories = computed(() => {
268+
if (!categoryList.value?.length || !processDefinitionGroup.value) {
269+
return []
270+
}
271+
272+
// 获取所有有流程的分类代码
273+
const availableCategoryCodes = Object.keys(processDefinitionGroup.value)
274+
275+
// 过滤出有流程的分类
276+
return categoryList.value.filter(category =>
277+
availableCategoryCodes.includes(category.code)
278+
)
279+
})
227280
</script>
228281

229282
<style lang="scss" scoped>

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,22 @@ watch(
4040
}
4141
)
4242
</script>
43-
<style>
43+
<style lang="scss" scoped>
4444
.box-card {
45+
height: 100%;
4546
width: 100%;
46-
margin-bottom: 20px;
47-
}
47+
margin-bottom: 0;
48+
49+
:deep(.el-card__body) {
50+
height: 100%;
51+
padding: 0;
52+
}
4853
49-
:deep(.process-viewer) {
50-
height: 100% !important;
51-
min-height: 500px;
54+
:deep(.process-viewer) {
55+
height: 100% !important;
56+
min-height: 100%;
57+
width: 100%;
58+
overflow: auto;
59+
}
5260
}
5361
</style>

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div v-loading="loading" class="mb-20px">
2+
<div v-loading="loading" class="process-viewer-container">
33
<SimpleProcessViewer
44
:flow-node="simpleModel"
55
:tasks="tasks"
@@ -154,8 +154,15 @@ const setSimpleModelNodeTaskStatus = (
154154
</script>
155155

156156
<style lang="scss" scoped>
157-
:deep(.process-viewer) {
158-
height: 100% !important;
159-
min-height: 500px;
157+
.process-viewer-container {
158+
height: 100%;
159+
width: 100%;
160+
161+
:deep(.process-viewer) {
162+
height: 100% !important;
163+
min-height: 100%;
164+
width: 100%;
165+
overflow: auto;
166+
}
160167
}
161168
</style>

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
<img class="w-full h-full" :src="getApprovalNodeImg(activity.nodeType)" alt="" />
1717
<div
1818
v-if="showStatusIcon"
19-
class="position-absolute top-17px left-17px rounded-full flex items-center p-2px"
19+
class="position-absolute top-17px left-17px rounded-full flex items-center p-1px border-2 border-white border-solid"
2020
:style="{ backgroundColor: getApprovalNodeColor(activity.status) }"
2121
>
22-
<el-icon :size="12" color="#fff">
22+
<el-icon :size="11" color="#fff">
2323
<component :is="getApprovalNodeIcon(activity.status, activity.nodeType)" />
2424
</el-icon>
2525
</div>
@@ -106,10 +106,10 @@
106106
<!-- 信息:任务 ICON -->
107107
<div
108108
v-if="showStatusIcon && onlyStatusIconShow.includes(task.status)"
109-
class="position-absolute top-19px left-23px rounded-full flex items-center p-2px"
109+
class="position-absolute top-19px left-23px rounded-full flex items-center p-1px border-2 border-white border-solid"
110110
:style="{ backgroundColor: statusIconMap2[task.status]?.color }"
111111
>
112-
<Icon :size="12" :icon="statusIconMap2[task.status]?.icon" color="#FFFFFF" />
112+
<Icon :size="11" :icon="statusIconMap2[task.status]?.icon" color="#FFFFFF" />
113113
</div>
114114
</div>
115115
</div>
@@ -140,10 +140,10 @@
140140
<!-- 信息:任务 ICON -->
141141
<div
142142
v-if="showStatusIcon"
143-
class="position-absolute top-19px left-23px rounded-full flex items-center p-2px"
143+
class="position-absolute top-20px left-24px rounded-full flex items-center p-1px border-2 border-white border-solid"
144144
:style="{ backgroundColor: statusIconMap2['-1']?.color }"
145145
>
146-
<Icon :size="12" :icon="statusIconMap2['-1']?.icon" color="#FFFFFF" />
146+
<Icon :size="11" :icon="statusIconMap2['-1']?.icon" color="#FFFFFF" />
147147
</div>
148148
</div>
149149
</div>

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ import { formatDate } from '@/utils/formatTime'
128128
import { DICT_TYPE } from '@/utils/dict'
129129
import { BpmModelType } from '@/utils/constants'
130130
import { setConfAndFields2 } from '@/utils/formCreate'
131+
import { registerComponent } from '@/utils/routerHelper'
131132
import type { ApiAttrs } from '@form-create/element-ui/types/config'
132133
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
133134
import * as UserApi from '@/api/system/user'
@@ -228,6 +229,9 @@ const getApprovalDetail = async () => {
228229
})
229230
}
230231
})
232+
} else {
233+
// 注意:data.processDefinition.formCustomViewPath 是组件的全路径,例如说:/crm/contract/detail/index.vue
234+
BusinessFormComponent.value = registerComponent(data.processDefinition.formCustomViewPath)
231235
}
232236
233237
// 获取审批节点,显示 Timeline 的数据
@@ -319,9 +323,12 @@ $process-header-height: 194px;
319323
$process-header-height - 40px
320324
);
321325
overflow: auto;
326+
display: flex;
327+
flex-direction: column;
322328
323329
:deep(.box-card) {
324330
height: 100%;
331+
flex: 1;
325332
326333
.el-card__body {
327334
height: 100%;

0 commit comments

Comments
 (0)