1
1
<template >
2
- <div class =" flex items-center h-50px" >
2
+ <div class =" flex items-center h-50px" v-memo = " [categoryInfo.name, isCategorySorting] " >
3
3
<!-- 头部:分类名 -->
4
4
<div class =" flex items-center" >
5
5
<el-tooltip content =" 拖动排序" v-if =" isCategorySorting" >
13
13
<div class =" color-gray-600 text-16px" > ({{ categoryInfo.modelList?.length || 0 }}) </div >
14
14
</div >
15
15
<!-- 头部:操作 -->
16
- <div class =" flex-1 flex" v-if =" !isCategorySorting" >
16
+ <div class =" flex-1 flex" v-show =" !isCategorySorting" >
17
17
<div
18
18
v-if =" categoryInfo.modelList.length > 0"
19
19
class =" ml-20px flex items-center"
69
69
<el-collapse-transition >
70
70
<div v-show =" isExpand" >
71
71
<el-table
72
+ v-if =" modelList && modelList.length > 0"
72
73
:class =" categoryInfo.name"
73
74
ref =" tableRef"
74
- :header-cell-style =" { backgroundColor: isDark ? '' : '#edeff0', paddingLeft: '10px' }"
75
- :cell-style =" { paddingLeft: '10px' }"
76
- :row-style =" { height: '68px' }"
77
75
:data =" modelList"
78
76
row-key =" id"
77
+ :header-cell-style =" tableHeaderStyle"
78
+ :cell-style =" tableCellStyle"
79
+ :row-style =" { height: '68px' }"
79
80
>
80
81
<el-table-column label =" 流程名" prop =" name" min-width =" 150" >
81
- <template #default =" scope " >
82
+ <template #default =" { row } " >
82
83
<div class =" flex items-center" >
83
84
<el-tooltip content =" 拖动排序" v-if =" isModelSorting" >
84
85
<Icon
85
86
icon =" ic:round-drag-indicator"
86
87
class =" drag-icon cursor-move text-#8a909c mr-10px"
87
88
/>
88
89
</el-tooltip >
89
- <el-image :src =" scope. row.icon" class =" h-38px w-38px mr-10px rounded" />
90
- {{ scope. row.name }}
90
+ <el-image v-if = " row.icon " :src =" row.icon" class =" h-38px w-38px mr-10px rounded" />
91
+ {{ row.name }}
91
92
</div >
92
93
</template >
93
94
</el-table-column >
94
95
<el-table-column label =" 可见范围" prop =" startUserIds" min-width =" 150" >
95
- <template #default =" scope " >
96
- <el-text v-if =" !scope.row.startUsers || scope.row.startUsers.length === 0" >
97
- 全部可见
98
- </el-text >
99
- <el-text v-else-if =" scope.row.startUsers.length == 1" >
100
- {{ scope.row.startUsers[0].nickname }}
96
+ <template #default =" { row } " >
97
+ <el-text v-if =" !row.startUsers?.length" > 全部可见 </el-text >
98
+ <el-text v-else-if =" row.startUsers.length === 1" >
99
+ {{ row.startUsers[0].nickname }}
101
100
</el-text >
102
101
<el-text v-else >
103
102
<el-tooltip
104
103
class =" box-item"
105
104
effect =" dark"
106
105
placement =" top"
107
- :content =" scope. row.startUsers.map((user: any) => user.nickname).join('、')"
106
+ :content =" row.startUsers.map((user: any) => user.nickname).join('、')"
108
107
>
109
- {{ scope. row.startUsers[0].nickname }}等 {{ scope. row.startUsers.length }} 人可见
108
+ {{ row.startUsers[0].nickname }}等 {{ row.startUsers.length }} 人可见
110
109
</el-tooltip >
111
110
</el-text >
112
111
</template >
245
244
<script lang="ts" setup>
246
245
import { CategoryApi , CategoryVO } from ' @/api/bpm/category'
247
246
import Sortable from ' sortablejs'
248
- import { propTypes } from ' @/utils/propTypes'
249
247
import { formatDate } from ' @/utils/formatTime'
250
248
import * as ModelApi from ' @/api/bpm/model'
251
249
import * as FormApi from ' @/api/bpm/form'
@@ -254,15 +252,49 @@ import { BpmModelFormType } from '@/utils/constants'
254
252
import { checkPermi } from ' @/utils/permission'
255
253
import { useUserStoreWithOut } from ' @/store/modules/user'
256
254
import { useAppStore } from ' @/store/modules/app'
257
- import { cloneDeep } from ' lodash-es'
255
+ import { cloneDeep , isEqual } from ' lodash-es'
258
256
import { useTagsView } from ' @/hooks/web/useTagsView'
257
+ import { useDebounceFn } from ' @vueuse/core'
259
258
260
259
defineOptions ({ name: ' BpmModel' })
261
260
262
- const props = defineProps ({
263
- categoryInfo: propTypes .object .def ([]), // 分类后的数据
264
- isCategorySorting: propTypes .bool .def (false ) // 是否分类在排序
265
- })
261
+ // 优化 Props 类型定义
262
+ interface UserInfo {
263
+ nickname: string
264
+ [key : string ]: any
265
+ }
266
+
267
+ interface ProcessDefinition {
268
+ deploymentTime: string
269
+ version: number
270
+ suspensionState: number
271
+ }
272
+
273
+ interface ModelInfo {
274
+ id: number
275
+ name: string
276
+ icon? : string
277
+ startUsers? : UserInfo []
278
+ processDefinition? : ProcessDefinition
279
+ formType? : number
280
+ formId? : number
281
+ formName? : string
282
+ formCustomCreatePath? : string
283
+ managerUserIds? : number []
284
+ [key : string ]: any
285
+ }
286
+
287
+ interface CategoryInfoProps {
288
+ id: number
289
+ name: string
290
+ modelList: ModelInfo []
291
+ }
292
+
293
+ const props = defineProps <{
294
+ categoryInfo: CategoryInfoProps
295
+ isCategorySorting: boolean
296
+ }>()
297
+
266
298
const emit = defineEmits ([' success' ])
267
299
const message = useMessage () // 消息弹窗
268
300
const { t } = useI18n () // 国际化
@@ -271,10 +303,20 @@ const userStore = useUserStoreWithOut() // 用户信息缓存
271
303
const isDark = computed (() => useAppStore ().getIsDark ) // 是否黑暗模式
272
304
273
305
const isModelSorting = ref (false ) // 是否正处于排序状态
274
- const originalData: any = ref ([]) // 原始数据
275
- const modelList: any = ref ([]) // 模型列表
306
+ const originalData = ref < ModelInfo []> ([]) // 原始数据
307
+ const modelList = ref < ModelInfo []> ([]) // 模型列表
276
308
const isExpand = ref (false ) // 是否处于展开状态
277
309
310
+ // 使用 computed 优化表格样式计算
311
+ const tableHeaderStyle = computed (() => ({
312
+ backgroundColor: isDark .value ? ' ' : ' #edeff0' ,
313
+ paddingLeft: ' 10px'
314
+ }))
315
+
316
+ const tableCellStyle = computed (() => ({
317
+ paddingLeft: ' 10px'
318
+ }))
319
+
278
320
/** 权限校验:通过 computed 解决列表的卡顿问题 */
279
321
const hasPermiUpdate = computed (() => {
280
322
return checkPermi ([' bpm:model:update' ])
@@ -449,14 +491,15 @@ const handleModelSortCancel = () => {
449
491
450
492
/** 创建拖拽实例 */
451
493
const tableRef = ref ()
452
- const initSort = () => {
494
+ const initSort = useDebounceFn ( () => {
453
495
const table = document .querySelector (` .${props .categoryInfo .name } .el-table__body-wrapper tbody ` )
496
+ if (! table ) return
497
+
454
498
Sortable .create (table , {
455
499
group: ' shared' ,
456
500
animation: 150 ,
457
501
draggable: ' .el-table__row' ,
458
502
handle: ' .drag-icon' ,
459
- // 结束拖动事件
460
503
onEnd : ({ newDraggableIndex , oldDraggableIndex }) => {
461
504
if (oldDraggableIndex !== newDraggableIndex ) {
462
505
modelList .value .splice (
@@ -467,15 +510,18 @@ const initSort = () => {
467
510
}
468
511
}
469
512
})
470
- }
513
+ }, 200 )
471
514
472
515
/** 更新 modelList 模型列表 */
473
- const updateModeList = () => {
474
- modelList .value = cloneDeep (props .categoryInfo .modelList )
475
- if (props .categoryInfo .modelList .length > 0 ) {
476
- isExpand .value = true
516
+ const updateModeList = useDebounceFn (() => {
517
+ const newModelList = props .categoryInfo .modelList
518
+ if (! isEqual (modelList .value , newModelList )) {
519
+ modelList .value = cloneDeep (newModelList )
520
+ if (newModelList ?.length > 0 ) {
521
+ isExpand .value = true
522
+ }
477
523
}
478
- }
524
+ }, 100 )
479
525
480
526
/** 重命名弹窗确定 */
481
527
const renameCategoryVisible = ref (false )
@@ -526,14 +572,15 @@ const openModelForm = async (type: string, id?: number) => {
526
572
}
527
573
}
528
574
529
- watch (() => props .categoryInfo .modelList , updateModeList , { immediate: true })
530
- watch (
531
- () => props .isCategorySorting ,
532
- (val ) => {
533
- if (val ) isExpand .value = false
534
- },
535
- { immediate: true }
536
- )
575
+ watchEffect (() => {
576
+ if (props .categoryInfo ?.modelList ) {
577
+ updateModeList ()
578
+ }
579
+
580
+ if (props .isCategorySorting ) {
581
+ isExpand .value = false
582
+ }
583
+ })
537
584
</script >
538
585
539
586
<style lang="scss">
@@ -550,10 +597,16 @@ watch(
550
597
}
551
598
</style >
552
599
<style lang="scss" scoped>
553
- :deep() {
554
- .el-table__cell {
600
+ .category-draggable-model {
601
+ : deep ( .el-table__cell ) {
555
602
overflow : hidden ;
556
603
border-bottom : none !important ;
557
604
}
605
+
606
+ // 优化表格渲染性能
607
+ :deep(.el-table__body ) {
608
+ will-change : transform ;
609
+ transform : translateZ (0 );
610
+ }
558
611
}
559
612
</style >
0 commit comments