Kaynağa Gözat

Merge branch 'devlop' of https://gitee.com/puhui999/yudao-ui-admin-vue3 into dev

# Conflicts:
#	src/views/system/menu/index.vue
YunaiV 6 ay önce
ebeveyn
işleme
3ae486c39f
1 değiştirilmiş dosya ile 129 ekleme ve 92 silme
  1. 129 92
      src/views/system/menu/index.vue

+ 129 - 92
src/views/system/menu/index.vue

@@ -53,6 +53,10 @@
           <Icon class="mr-5px" icon="ep:plus" />
           新增
         </el-button>
+        <el-button plain type="danger" @click="toggleExpandAll">
+          <Icon class="mr-5px" icon="ep:sort" />
+          展开/折叠
+        </el-button>
         <el-button plain @click="refreshMenu">
           <Icon class="mr-5px" icon="ep:refresh" />
           刷新菜单缓存
@@ -63,148 +67,169 @@
 
   <!-- 列表 -->
   <ContentWrap>
-    <div style="height: 700px">
-      <!-- AutoResizer 自动调节大小 -->
-      <el-auto-resizer>
-        <template #default="{ height, width }">
-          <!-- Virtualized Table 虚拟化表格:高性能,解决表格在大数据量下的卡顿问题 -->
-          <el-table-v2
-            v-loading="loading"
-            :columns="columns"
-            :data="list"
-            :width="width"
-            :height="height"
-            expand-column-key="name"
-          />
-        </template>
-      </el-auto-resizer>
-    </div>
+    <el-auto-resizer>
+      <template #default="{ width }">
+        <el-table-v2
+          v-model:expanded-row-keys="expandedRowKeys"
+          :columns="columns"
+          :data="list"
+          :expand-column-key="columns[0].key"
+          :height="1000"
+          :width="width"
+          fixed
+          row-key="id"
+        />
+      </template>
+    </el-auto-resizer>
   </ContentWrap>
 
   <!-- 表单弹窗:添加/修改 -->
   <MenuForm ref="formRef" @success="getList" />
 </template>
-<script lang="ts" setup>
+<script lang="tsx" setup>
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { handleTree } from '@/utils/tree'
 import * as MenuApi from '@/api/system/menu'
 import { MenuVO } from '@/api/system/menu'
 import MenuForm from './MenuForm.vue'
-import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
-import { h } from 'vue'
-import { Column, ElButton } from 'element-plus'
+import DictTag from '@/components/DictTag/src/DictTag.vue'
 import { Icon } from '@/components/Icon'
-import { hasPermission } from '@/directives/permission/hasPermi'
+import { ElButton, TableV2FixedDir } from 'element-plus'
+import { checkPermi } from '@/utils/permission'
 import { CommonStatusEnum } from '@/utils/constants'
+import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 
 defineOptions({ name: 'SystemMenu' })
 
-const { wsCache } = useCache()
-const { t } = useI18n() // 国际化
-const message = useMessage() // 消息弹窗
-
-// 表格的 column 字段
-const columns: Column[] = [
+// 虚拟列表表格
+const columns = [
   {
-    dataKey: 'name',
+    key: 'name',
     title: '菜单名称',
-    width: 250
+    dataKey: 'name',
+    width: 250,
+    fixed: TableV2FixedDir.LEFT
   },
   {
-    dataKey: 'icon',
+    key: 'icon',
     title: '图标',
-    width: 150,
-    cellRenderer: ({ rowData }) => {
-      return h(Icon, {
-        icon: rowData.icon
-      })
-    }
+    dataKey: 'icon',
+    width: 100,
+    align: 'center',
+    cellRenderer: ({ cellData: icon }) => <Icon icon={icon} />
   },
   {
-    dataKey: 'sort',
+    key: 'sort',
     title: '排序',
-    width: 100
+    dataKey: 'sort',
+    width: 60
   },
   {
-    dataKey: 'permission',
+    key: 'permission',
     title: '权限标识',
-    width: 240
+    dataKey: 'permission',
+    width: 300
   },
   {
-    dataKey: 'component',
+    key: 'component',
     title: '组件路径',
-    width: 240
+    dataKey: 'component',
+    width: 500
   },
   {
-    dataKey: 'componentName',
+    key: 'componentName',
     title: '组件名称',
-    width: 240
+    dataKey: 'componentName',
+    width: 200
   },
   {
-    dataKey: 'status',
+    key: 'status',
     title: '状态',
-    width: 160,
+    dataKey: 'status',
+    width: 60,
+    fixed: TableV2FixedDir.RIGHT,
     cellRenderer: ({ rowData }) => {
-      return h(ElSwitch, {
-        modelValue: rowData.status,
-        activeValue: CommonStatusEnum.ENABLE,
-        inactiveValue: CommonStatusEnum.DISABLE,
-        loading: menuStatusUpdating.value[rowData.id],
-        disabled: !hasPermission(['system:menu:update']),
-        onChange: (val) => handleStatusChanged(rowData, val as number)
-      })
+      // 检查权限
+      if (!checkPermi(['system:menu:update'])) {
+        return <DictTag type={DICT_TYPE.COMMON_STATUS} value={rowData.status} />
+      }
+
+      // 如果有权限,渲染 ElSwitch
+      return (
+        <ElSwitch
+          v-model={rowData.status}
+          active-value={CommonStatusEnum.ENABLE}
+          inactive-value={CommonStatusEnum.DISABLE}
+          loading={menuStatusUpdating[rowData.id]}
+          class="ml-4px"
+          onChange={(val) => handleStatusChanged(rowData, val)}
+        />
+      )
     }
   },
   {
-    dataKey: 'operation',
+    key: 'operations',
     title: '操作',
-    width: 200,
+    align: 'center',
+    width: 160,
+    fixed: TableV2FixedDir.RIGHT,
     cellRenderer: ({ rowData }) => {
-      return h(
-        'div',
-        [
-          hasPermission(['system:menu:update']) &&
-            h(
-              ElButton,
-              {
-                link: true,
-                type: 'primary',
-                onClick: () => openForm('update', rowData.id)
-              },
-              '修改'
-            ),
-          hasPermission(['system:menu:create']) &&
-            h(
-              ElButton,
-              {
-                link: true,
-                type: 'primary',
-                onClick: () => openForm('create', undefined, rowData.id)
-              },
-              '新增'
-            ),
-          hasPermission(['system:menu:delete']) &&
-            h(
-              ElButton,
-              {
-                link: true,
-                type: 'danger',
-                onClick: () => handleDelete(rowData.id)
-              },
-              '删除'
-            )
-        ].filter(Boolean)
-      )
+      // 定义按钮列表
+      const buttons = []
+
+      // 检查权限并添加按钮
+      if (checkPermi(['system:menu:update'])) {
+        buttons.push(
+          <ElButton key="edit" link type="primary" onClick={() => openForm('update', rowData.id)}>
+            修改
+          </ElButton>
+        )
+      }
+      if (checkPermi(['system:menu:create'])) {
+        buttons.push(
+          <ElButton
+            key="create"
+            link
+            type="primary"
+            onClick={() => openForm('create', undefined, rowData.id)}
+          >
+            新增
+          </ElButton>
+        )
+      }
+      if (checkPermi(['system:menu:delete'])) {
+        buttons.push(
+          <ElButton key="delete" link type="danger" onClick={() => handleDelete(rowData.id)}>
+            删除
+          </ElButton>
+        )
+      }
+      // 如果没有权限,返回 null
+      if (buttons.length === 0) {
+        return null
+      }
+      // 渲染按钮列表
+      return <>{buttons}</>
     }
   }
 ]
+
+const { wsCache } = useCache()
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
 const loading = ref(true) // 列表的加载中
-const list = ref<any>([]) // 列表的数据
+const list = ref<any[]>([]) // 列表的数据
 const queryParams = reactive({
   name: undefined,
   status: undefined
 })
 const queryFormRef = ref() // 搜索的表单
+const isExpandAll = ref(false) // 是否展开,默认全部折叠
+const refreshTable = ref(true) // 重新渲染表格状态
+
+// 添加展开行控制
+const expandedRowKeys = ref<number[]>([])
 
 /** 查询列表 */
 const getList = async () => {
@@ -234,6 +259,18 @@ const openForm = (type: string, id?: number, parentId?: number) => {
   formRef.value.open(type, id, parentId)
 }
 
+/** 展开/折叠操作 */
+const toggleExpandAll = () => {
+  if (!isExpandAll.value) {
+    // 展开所有
+    expandedRowKeys.value = list.value.map((item) => item.id)
+  } else {
+    // 折叠所有
+    expandedRowKeys.value = []
+  }
+  isExpandAll.value = !isExpandAll.value
+}
+
 /** 刷新菜单缓存按钮操作 */
 const refreshMenu = async () => {
   try {