Преглед на файлове

Merge branch 'feature/bpm' of https://github.com/GoldenZqqq/yudao-ui-admin-vue3 into feature/bpm

# Conflicts:
#	src/views/bpm/model/CategoryDraggableModel.vue
YunaiV преди 6 месеца
родител
ревизия
6c504adcbc
променени са 1 файла, в които са добавени 101 реда и са изтрити 40 реда
  1. 101 40
      src/views/bpm/model/CategoryDraggableModel.vue

+ 101 - 40
src/views/bpm/model/CategoryDraggableModel.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="flex items-center h-50px">
+  <div class="flex items-center h-50px" v-memo="[categoryInfo.name, isCategorySorting]">
     <!-- 头部:分类名 -->
     <div class="flex items-center">
       <el-tooltip content="拖动排序" v-if="isCategorySorting">
@@ -13,7 +13,7 @@
       <div class="color-gray-600 text-16px"> ({{ categoryInfo.modelList?.length || 0 }}) </div>
     </div>
     <!-- 头部:操作 -->
-    <div class="flex-1 flex" v-if="!isCategorySorting">
+    <div class="flex-1 flex" v-show="!isCategorySorting">
       <div
         v-if="categoryInfo.modelList.length > 0"
         class="ml-20px flex items-center"
@@ -69,16 +69,17 @@
   <el-collapse-transition>
     <div v-show="isExpand">
       <el-table
+        v-if="modelList && modelList.length > 0"
         :class="categoryInfo.name"
         ref="tableRef"
-        :header-cell-style="{ backgroundColor: isDark ? '' : '#edeff0', paddingLeft: '10px' }"
-        :cell-style="{ paddingLeft: '10px' }"
-        :row-style="{ height: '68px' }"
         :data="modelList"
         row-key="id"
+        :header-cell-style="tableHeaderStyle"
+        :cell-style="tableCellStyle"
+        :row-style="{ height: '68px' }"
       >
         <el-table-column label="流程名" prop="name" min-width="150">
-          <template #default="scope">
+          <template #default="{ row }">
             <div class="flex items-center">
               <el-tooltip content="拖动排序" v-if="isModelSorting">
                 <Icon
@@ -86,27 +87,27 @@
                   class="drag-icon cursor-move text-#8a909c mr-10px"
                 />
               </el-tooltip>
-              <el-image :src="scope.row.icon" class="h-38px w-38px mr-10px rounded" />
-              {{ scope.row.name }}
+              <el-image v-if="row.icon" :src="row.icon" class="h-38px w-38px mr-10px rounded" />
+              {{ row.name }}
             </div>
           </template>
         </el-table-column>
         <el-table-column label="可见范围" prop="startUserIds" min-width="150">
-          <template #default="scope">
-            <el-text v-if="!scope.row.startUsers || scope.row.startUsers.length === 0">
+          <template #default="{ row }">
+            <el-text v-if="!row.startUsers?.length">
               全部可见
             </el-text>
-            <el-text v-else-if="scope.row.startUsers.length == 1">
-              {{ scope.row.startUsers[0].nickname }}
+            <el-text v-else-if="row.startUsers.length === 1">
+              {{ row.startUsers[0].nickname }}
             </el-text>
             <el-text v-else>
               <el-tooltip
                 class="box-item"
                 effect="dark"
                 placement="top"
-                :content="scope.row.startUsers.map((user: any) => user.nickname).join('、')"
+                :content="row.startUsers.map((user: any) => user.nickname).join('、')"
               >
-                {{ scope.row.startUsers[0].nickname }}等 {{ scope.row.startUsers.length }} 人可见
+                {{ row.startUsers[0].nickname }}等 {{ row.startUsers.length }} 人可见
               </el-tooltip>
             </el-text>
           </template>
@@ -245,7 +246,6 @@
 <script lang="ts" setup>
 import { CategoryApi, CategoryVO } from '@/api/bpm/category'
 import Sortable from 'sortablejs'
-import { propTypes } from '@/utils/propTypes'
 import { formatDate } from '@/utils/formatTime'
 import * as ModelApi from '@/api/bpm/model'
 import * as FormApi from '@/api/bpm/form'
@@ -254,15 +254,49 @@ import { BpmModelFormType } from '@/utils/constants'
 import { checkPermi } from '@/utils/permission'
 import { useUserStoreWithOut } from '@/store/modules/user'
 import { useAppStore } from '@/store/modules/app'
-import { cloneDeep } from 'lodash-es'
+import { cloneDeep, isEqual } from 'lodash-es'
 import { useTagsView } from '@/hooks/web/useTagsView'
+import { useDebounceFn } from '@vueuse/core'
 
 defineOptions({ name: 'BpmModel' })
 
-const props = defineProps({
-  categoryInfo: propTypes.object.def([]), // 分类后的数据
-  isCategorySorting: propTypes.bool.def(false) // 是否分类在排序
-})
+// 优化 Props 类型定义
+interface UserInfo {
+  nickname: string
+  [key: string]: any
+}
+
+interface ProcessDefinition {
+  deploymentTime: string
+  version: number
+  suspensionState: number
+}
+
+interface ModelInfo {
+  id: number
+  name: string
+  icon?: string
+  startUsers?: UserInfo[]
+  processDefinition?: ProcessDefinition
+  formType?: number
+  formId?: number
+  formName?: string
+  formCustomCreatePath?: string
+  managerUserIds?: number[]
+  [key: string]: any
+}
+
+interface CategoryInfoProps {
+  id: number
+  name: string
+  modelList: ModelInfo[]
+}
+
+const props = defineProps<{
+  categoryInfo: CategoryInfoProps
+  isCategorySorting: boolean
+}>()
+
 const emit = defineEmits(['success'])
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
@@ -271,10 +305,26 @@ const userStore = useUserStoreWithOut() // 用户信息缓存
 const isDark = computed(() => useAppStore().getIsDark) // 是否黑暗模式
 
 const isModelSorting = ref(false) // 是否正处于排序状态
-const originalData: any = ref([]) // 原始数据
-const modelList: any = ref([]) // 模型列表
+const originalData = ref<ModelInfo[]>([]) // 原始数据
+const modelList = ref<ModelInfo[]>([]) // 模型列表
 const isExpand = ref(false) // 是否处于展开状态
 
+// 使用 computed 优化表格样式计算
+const tableHeaderStyle = computed(() => ({
+  backgroundColor: isDark.value ? '' : '#edeff0',
+  paddingLeft: '10px'
+}))
+
+const tableCellStyle = computed(() => ({
+  paddingLeft: '10px'
+}))
+
+// 使用 computed 优化可见性判断
+const isManagerUser = computed(() => {
+  const userId = userStore.getUser?.id
+  return (row: ModelInfo) => row.managerUserIds?.includes(userId)
+})
+
 /** 权限校验:通过 computed 解决列表的卡顿问题 */
 const hasPermiUpdate = computed(() => {
   return checkPermi(['bpm:model:update'])
@@ -449,14 +499,15 @@ const handleModelSortCancel = () => {
 
 /** 创建拖拽实例 */
 const tableRef = ref()
-const initSort = () => {
+const initSort = useDebounceFn(() => {
   const table = document.querySelector(`.${props.categoryInfo.name} .el-table__body-wrapper tbody`)
+  if (!table) return
+
   Sortable.create(table, {
     group: 'shared',
     animation: 150,
     draggable: '.el-table__row',
     handle: '.drag-icon',
-    // 结束拖动事件
     onEnd: ({ newDraggableIndex, oldDraggableIndex }) => {
       if (oldDraggableIndex !== newDraggableIndex) {
         modelList.value.splice(
@@ -467,15 +518,18 @@ const initSort = () => {
       }
     }
   })
-}
+}, 200)
 
 /** 更新 modelList 模型列表 */
-const updateModeList = () => {
-  modelList.value = cloneDeep(props.categoryInfo.modelList)
-  if (props.categoryInfo.modelList.length > 0) {
-    isExpand.value = true
+const updateModeList = useDebounceFn(() => {
+  const newModelList = props.categoryInfo.modelList
+  if (!isEqual(modelList.value, newModelList)) {
+    modelList.value = cloneDeep(newModelList)
+    if (newModelList?.length > 0) {
+      isExpand.value = true
+    }
   }
-}
+}, 100)
 
 /** 重命名弹窗确定 */
 const renameCategoryVisible = ref(false)
@@ -526,14 +580,15 @@ const openModelForm = async (type: string, id?: number) => {
   }
 }
 
-watch(() => props.categoryInfo.modelList, updateModeList, { immediate: true })
-watch(
-  () => props.isCategorySorting,
-  (val) => {
-    if (val) isExpand.value = false
-  },
-  { immediate: true }
-)
+watchEffect(() => {
+  if (props.categoryInfo?.modelList) {
+    updateModeList()
+  }
+
+  if (props.isCategorySorting) {
+    isExpand.value = false
+  }
+})
 </script>
 
 <style lang="scss">
@@ -550,10 +605,16 @@ watch(
 }
 </style>
 <style lang="scss" scoped>
-:deep() {
-  .el-table__cell {
+.category-draggable-model {
+  :deep(.el-table__cell) {
     overflow: hidden;
     border-bottom: none !important;
   }
+
+  // 优化表格渲染性能
+  :deep(.el-table__body) {
+    will-change: transform;
+    transform: translateZ(0);
+  }
 }
 </style>