Bläddra i källkod

1. 对接新菜单api 2. 删除菜单无用代码 3. 增加菜单类型定义

lfeish 1 år sedan
förälder
incheckning
03905c852a

+ 13 - 26
src/api/system/menu.ts

@@ -1,24 +1,24 @@
 import { http } from '@/utils/http/axios';
+import { MenuDetail } from '@/types/menu/type';
 
 /**
  * @description: 获取动态菜单
  */
-export function adminMenus() {
+export function getRouters() {
   return http.request({
     url: '/login/getRouters',
     method: 'GET',
   });
 }
 
+
 /**
- * 获取tree菜单列表
- * @param params
+ * v4:获取整个菜单树
  */
-export function getMenuList(params?) {
-  return http.request({
-    url: '/menu/menuList',
-    method: 'GET',
-    params,
+export function queryFullMenuTree() {
+  return http.request<MenuDetail[]>({
+    url: '/admin/menu/queryAllMenuTree',
+    method: 'post',
   });
 }
 
@@ -38,23 +38,11 @@ export function addMenu(params?) {
  * 编辑菜单
  * @param params
  */
-export function editMenu(params?) {
+export function editMenu(data: MenuDetail) {
   return http.request({
-    url: '/menu/update',
+    url: '/admin/menu/updateMenu',
     method: 'POST',
-    params,
-  });
-}
-
-/**
- * 菜单信息
- * @param params
- */
-export function menuInfo(params?) {
-  return http.request({
-    url: '/menu/info',
-    method: 'GET',
-    params,
+    data,
   });
 }
 
@@ -62,10 +50,9 @@ export function menuInfo(params?) {
  * 删除菜单
  * @param params
  */
-export function deleteMenu(params) {
+export function deleteMenu(menuId: number) {
   return http.request({
-    url: '/menu/delete',
+    url: `/admin/menu/deleteMenu?menuId=${menuId}`,
     method: 'POST',
-    params,
   });
 }

+ 2 - 2
src/router/generator-routers.ts

@@ -1,4 +1,4 @@
-import { adminMenus } from '@/api/system/menu';
+import { getRouters } from '@/api/system/menu';
 import { constantRouterIcon } from './router-icons';
 import { RouteRecordRaw } from 'vue-router';
 import { Layout, ParentLayout } from '@/router/constant';
@@ -55,7 +55,7 @@ export const routerGenerator = (routerMap, parent?): any[] => {
  */
 export const generatorDynamicRouter = (): Promise<RouteRecordRaw[]> => {
   return new Promise((resolve, reject) => {
-    adminMenus()
+    getRouters()
       .then((result) => {
         const routeList = routerGenerator(result);
         asyncImportRoute(routeList);

+ 69 - 0
src/types/menu/type.ts

@@ -0,0 +1,69 @@
+/**
+ * 后端保存菜单的详细信息
+ * 其中 0 - false,1 - true
+ */
+export interface MenuDetail {
+  // 主键ID
+  id: number | null;
+  // 父级菜单主键ID
+  parentId: number | null;
+  // 菜单编码
+  menuCode: string;
+  // 菜单名
+  menuName: string;
+  // 前端路由 name
+  routeName: string;
+  // 前端路由 path 
+  routeUrl: string;
+  // 路由参数
+  query: string;
+  // 路由对应的组件
+  component: string;
+  // 默认跳转路由
+  redirect: string;
+  // 显示顺序
+  orderNum: number | null;
+  // 菜单icon
+  icon: string;
+  // 菜单是否隐藏
+  isHidden: 0 | 1;
+  // 菜单是否禁用
+  isDisabled: 0 | 1;
+  // 菜单是否缓存
+  isCache: 0 | 1;
+  // 是否固定多标签
+  isAffix: 0 | 1;
+  // 简化路由
+  isAlwaysShow: 0 | 1;
+  // 是否根路由
+  isRoot: 0 | 1;
+  // 是否是外链接
+  isFrame: 0 | 1;
+  // 外连接
+  frameSrc?: string;
+  // 1 - 当前窗口; 2 - 新窗口
+  openType?: 1 | 2;
+  // 选中路由名称
+  activeMenu?: string;
+  // 创建时间
+  createdAt?: string;
+  // 创建人
+  createdBy?: string;
+  // 更新时间
+  updatedAt?: string;
+  // 更新人
+  updatedBy?: string;
+  // 路由是否删除(逻辑删除)
+  isDeleted?: number;
+  // 子菜单
+  children?: MenuDetail[];
+}
+
+/**
+ * 用于 element-plus 树形控件 展示
+ */
+export interface MenuSimple {
+  label: string;
+  key: number | string;
+  children?: MenuSimple[] | null;
+}

+ 62 - 118
src/views/system/menu/MenuForm.vue

@@ -9,15 +9,7 @@
   >
     <el-divider border-style="dashed" class="mt-0 mb-10">基本设置</el-divider>
 
-    <el-form-item label="类型" prop="menuType">
-      <el-radio-group v-model="formParams.menuType" name="menuTypeGroup">
-        <el-radio-button :label="0">目录</el-radio-button>
-        <el-radio-button :label="1">菜单</el-radio-button>
-        <el-radio-button :label="2">按钮</el-radio-button>
-      </el-radio-group>
-    </el-form-item>
-
-    <el-form-item :label="`上级${getTypeLable}`" prop="parentId">
+    <el-form-item label="上级菜单" prop="parentId">
       <el-tree-select
         rowKey="key"
         :data="getPermissionList"
@@ -29,12 +21,12 @@
 
     <el-row :gutter="24">
       <el-col :span="12">
-        <el-form-item :label="`${getTypeLable}名称`" prop="menuName">
-          <el-input :placeholder="`${getTypeLable}名称`" v-model="formParams.menuName" />
+        <el-form-item label="菜单名称" prop="menuName">
+          <el-input placeholder="菜单名称" v-model="formParams.menuName" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item :label="`${getTypeLable}图标`" prop="icon">
+        <el-form-item label="菜单图标" prop="icon">
           <template #label>
             <div class="flex items-center">
               <el-tooltip trigger="hover">
@@ -42,21 +34,20 @@
                   <QuestionCircleOutlined />
                 </el-icon>
                 <template #content>
-                  {{ getTypeLable }}图标,填写图标组件名称,需在 `src\router\router-icons.ts`
-                  中导入并映射
+                  菜单图标,填写图标组件名称,需在 `src\router\router-icons.ts` 中导入并映射
                 </template>
               </el-tooltip>
-              <span>{{ getTypeLable }}图标</span>
+              <span>菜单图标</span>
             </div>
           </template>
-          <el-input :placeholder="`${getTypeLable}图标映射名称`" v-model="formParams.icon" />
+          <el-input placeholder="菜单图标映射名称" v-model="formParams.icon" />
         </el-form-item>
       </el-col>
     </el-row>
 
     <el-row :gutter="24">
       <el-col :span="12">
-        <el-form-item prop="routeUrl" v-if="formParams.menuType != 2">
+        <el-form-item prop="routeUrl">
           <template #label>
             <div class="flex items-center">
               <el-tooltip trigger="hover">
@@ -72,7 +63,7 @@
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item prop="routeName" v-if="formParams.menuType != 2">
+        <el-form-item prop="routeName">
           <template #label>
             <div class="flex items-center">
               <el-tooltip trigger="hover">
@@ -91,43 +82,8 @@
       </el-col>
     </el-row>
 
-    <el-row :gutter="24" v-if="formParams.menuType > 0">
-      <el-col :span="12">
-        <el-form-item prop="permissionCode">
-          <template #label>
-            <div class="flex items-center">
-              <el-tooltip trigger="hover">
-                <el-icon :size="18" class="mr-1 text-gray-400 cursor-pointer">
-                  <QuestionCircleOutlined />
-                </el-icon>
-                <template #content> 权限标识,也是权限字符,比如 `system:menu:list` </template>
-              </el-tooltip>
-              <span>权限标识</span>
-            </div>
-          </template>
-          <el-input placeholder="权限标识 system:user:add" v-model="formParams.permissionCode" />
-        </el-form-item>
-      </el-col>
-      <el-col :span="12">
-        <el-form-item prop="permissionName">
-          <template #label>
-            <div class="flex items-center">
-              <el-tooltip trigger="hover">
-                <el-icon :size="18" class="mr-1 text-gray-400 cursor-pointer">
-                  <QuestionCircleOutlined />
-                </el-icon>
-                <template #content>权限名称 对应 权限标识 `中文名称`</template>
-              </el-tooltip>
-              <span>权限名称</span>
-            </div>
-          </template>
-          <el-input placeholder="权限名称" v-model="formParams.permissionName" />
-        </el-form-item>
-      </el-col>
-    </el-row>
-
     <el-row :gutter="24">
-      <el-col v-if="formParams.menuType != 2" :span="12">
+      <el-col :span="12">
         <el-form-item prop="redirect">
           <template #label>
             <div class="flex items-center">
@@ -135,9 +91,9 @@
                 <el-icon :size="18" class="mr-1 text-gray-400 cursor-pointer">
                   <QuestionCircleOutlined />
                 </el-icon>
-                <template #content
-                  >默认跳转路由地址,如:`/system/menu/menu` 多级路由情况下适用</template
-                >
+                <template #content>
+                  默认跳转路由地址,如:`/system/menu/menu` 多级路由情况下适用
+                </template>
               </el-tooltip>
               <span>默认路由</span>
             </div>
@@ -152,7 +108,7 @@
       </el-col>
     </el-row>
 
-    <el-row :gutter="24" v-if="formParams.menuType != 2">
+    <el-row :gutter="24">
       <el-col>
         <el-form-item prop="component">
           <template #label>
@@ -185,18 +141,18 @@
                 <el-icon :size="18" class="mr-1 text-gray-400 cursor-pointer">
                   <QuestionCircleOutlined />
                 </el-icon>
-                <template #content> 选择停用则路由将不会出现在侧边栏,也不能被访问 </template>
+                <template #content>选择停用则路由将不会出现在侧边栏,也不能被访问</template>
               </el-tooltip>
-              <span>{{ getTypeLable }}状态</span>
+              <span>菜单状态</span>
             </div>
           </template>
-          <el-radio-group v-model="formParams.status" name="statusGroup">
+          <el-radio-group v-model="formParams.isDisabled">
             <el-radio-button :label="0">正常</el-radio-button>
             <el-radio-button :label="1">停用</el-radio-button>
           </el-radio-group>
         </el-form-item>
       </el-col>
-      <el-col :span="12" v-if="formParams.menuType != 2">
+      <el-col :span="12">
         <el-form-item label="根路由" prop="isRoot">
           <template #label>
             <div class="flex items-center">
@@ -204,21 +160,19 @@
                 <el-icon :size="18" class="mr-1 text-gray-400 cursor-pointer">
                   <QuestionCircleOutlined />
                 </el-icon>
-                <template #content
-                  >如果使用 `顶部混合菜单`,必须传 true,否则左侧会显示异常</template
-                >
+                <template #content>如果使用 `顶部混合菜单`,必须传 true,否则左侧会显示异常</template>
               </el-tooltip>
               <span>根路由</span>
             </div>
           </template>
-          <el-switch v-model="formParams.isRoot" />
+          <el-switch v-model="formParams.isRoot" :active-value="1" :inactive-value="0" />
         </el-form-item>
       </el-col>
     </el-row>
 
-    <el-row :gutter="24" v-if="formParams.menuType != 2">
+    <el-row :gutter="24">
       <el-col :span="12">
-        <el-form-item prop="isVisible">
+        <el-form-item>
           <template #label>
             <div class="flex items-center">
               <el-tooltip trigger="hover">
@@ -230,7 +184,7 @@
               <span>显示状态</span>
             </div>
           </template>
-          <el-radio-group v-model="formParams.isVisible" name="isVisibleGroup">
+          <el-radio-group v-model="formParams.isHidden">
             <el-radio-button :label="0">显示</el-radio-button>
             <el-radio-button :label="1">隐藏</el-radio-button>
           </el-radio-group>
@@ -252,14 +206,14 @@
             </div>
           </template>
           <el-radio-group v-model="formParams.isCache" name="isCacheGroup">
-            <el-radio-button :label="0">缓存</el-radio-button>
-            <el-radio-button :label="1">缓存</el-radio-button>
+            <el-radio-button :label="0">缓存</el-radio-button>
+            <el-radio-button :label="1">缓存</el-radio-button>
           </el-radio-group>
         </el-form-item>
       </el-col>
     </el-row>
 
-    <el-row :gutter="24" v-if="formParams.menuType != 2">
+    <el-row :gutter="24">
       <el-col :span="12">
         <el-form-item label="是否外链" prop="isFrame">
           <template #label>
@@ -273,9 +227,9 @@
               <span>是否外链</span>
             </div>
           </template>
-          <el-radio-group v-model="formParams.isFrame" name="isFrameGroup">
-            <el-radio-button :label="0"></el-radio-button>
-            <el-radio-button :label="1"></el-radio-button>
+          <el-radio-group v-model="formParams.isFrame">
+            <el-radio-button :label="0"></el-radio-button>
+            <el-radio-button :label="1"></el-radio-button>
           </el-radio-group>
         </el-form-item>
       </el-col>
@@ -295,17 +249,13 @@
               <span>简化路由</span>
             </div>
           </template>
-          <el-switch v-model="formParams.alwaysShow" />
+          <el-switch v-model="formParams.isAlwaysShow" :active-value="1" :inactive-value="0" />
         </el-form-item>
       </el-col>
     </el-row>
-    <el-row :gutter="24" v-if="formParams.menuType != 2">
+    <el-row :gutter="24">
       <el-col>
-        <el-form-item
-          label="外部地址"
-          prop="frameSrc"
-          v-if="formParams.menuType != 2 && formParams.isFrame === 0"
-        >
+        <el-form-item label="外部地址" prop="frameSrc" v-if="formParams.isFrame === 1">
           <el-input placeholder="内联外部地址" v-model="formParams.frameSrc" />
         </el-form-item>
       </el-col>
@@ -319,11 +269,12 @@
 
 <script lang="ts" setup>
   import { ref, computed } from 'vue';
-  import { ElMessage } from 'element-plus';
+  import { ElMessage, FormInstance } from 'element-plus';
   import { addMenu, editMenu } from '@/api/system/menu';
   import { QuestionCircleOutlined } from '@vicons/antd';
   import { replaceParams } from '@/utils/helper/treeHelper';
   import { cloneDeep } from 'lodash-es';
+  import { MenuDetail } from '@/types/menu/type';
 
   const emit = defineEmits(['change']);
 
@@ -338,36 +289,34 @@
     },
   });
 
-  const message = ElMessage;
-  const formRef: any = ref(null);
+  const formRef = ref<FormInstance>();
   const subLoading = ref(false);
 
-  const defaultValueRef = () => ({
+  const defaultFormParams: MenuDetail = {
     id: null,
     parentId: null,
-    activeMenu: '',
-    affix: false,
-    alwaysShow: false,
-    icon: '',
-    isRoot: 1,
-    isCache: 1,
-    isFrame: 1,
-    isVisible: 0,
     menuName: '',
-    menuType: 0,
-    openType: 1,
-    status: 0,
-    orderNum: null,
-    permissionCode: '',
-    permissionName: '',
-    query: '',
-    routeUrl: '',
+    menuCode: '',
     routeName: '',
+    routeUrl: '',
+    component: '',
     redirect: '',
-    component: '', //目录默认 LAYOUT 多级菜单目录 设置 ParentLayout
-  });
+    orderNum: null,
+    icon: '',
+    isHidden: 0,
+    isDisabled: 0,
+    isAlwaysShow: 0,
+    isRoot: 0,
+    isAffix: 0,
+    isCache: 0,
+    isFrame: 0,
+    frameSrc: '',
+    openType: 1, 
+    query: '',
+    children: []
+  };
 
-  const formParams: any = ref(defaultValueRef());
+  const formParams = ref({ ...defaultFormParams });
 
   const getPermissionList = computed(() => {
     // 可根据需要是否需要嵌套这个 避免出现选择器出现 0 的情况
@@ -380,15 +329,10 @@
     ];
   });
 
-  const getTypeLable = computed(() => {
-    const typsStr = ['目录', '菜单', '按钮'];
-    return typsStr[formParams.value.menuType];
-  });
-
   const rules = {
     menuName: {
       required: true,
-      message: `${getTypeLable.value}名称`,
+      message: '菜单名称',
       trigger: 'blur',
     },
     routeUrl: {
@@ -413,20 +357,20 @@
     },
   };
 
-  function setData(data) {
+  function setData(data: MenuDetail) {
     formParams.value = data;
     formRef.value?.resetFields();
   }
 
   function formSubmit() {
     subLoading.value = true;
-    formRef.value.validate((valid) => {
+    formRef.value?.validate((valid) => {
       if (valid) {
         if (!formParams.value.id) {
           addMenu(formParams.value)
             .then(() => {
               subLoading.value = false;
-              message.success('添加成功');
+              ElMessage.success('添加成功');
               handleReset();
               emit('change');
             })
@@ -437,7 +381,7 @@
           editMenu(formParams.value)
             .then(() => {
               subLoading.value = false;
-              message.success('修改成功');
+              ElMessage.success('修改成功');
               handleReset();
               emit('change');
             })
@@ -447,14 +391,14 @@
         }
       } else {
         subLoading.value = false;
-        message.error('请填写完整信息');
+        ElMessage.error('请填写完整信息');
       }
     });
   }
 
   function handleReset() {
-    formRef.value.resetFields();
-    formParams.value = Object.assign(formParams.value, defaultValueRef());
+    formRef.value?.resetFields();
+    formParams.value = Object.assign(formParams.value, defaultFormParams);
   }
 
   defineExpose({

+ 67 - 93
src/views/system/menu/menu.vue

@@ -34,7 +34,7 @@
                 <el-tree
                   ref="treeRef"
                   :pattern="pattern"
-                  :data="treeData"
+                  :data="menuTree"
                   nodeKey="key"
                   highlight-current
                   check-strictly
@@ -51,28 +51,28 @@
           <template #header>
             <div class="flex justify-between">
               <el-space>
-                <span>编辑{{ getTypeMsg }}{{ treeItemTitle ? `:${treeItemTitle}` : '' }}</span>
+                <span>编辑菜单 {{ treeItemTitle ? `:${treeItemTitle}` : '' }}</span>
                 <el-divider direction="vertical" />
                 <p depth="3" class="text-sm"> 从左侧列表选择一项后,进行编辑 </p>
               </el-space>
               <el-popconfirm
                 @confirm="handleDeleteMenu"
                 v-if="isEditMenu"
-                :title="`确定要删除 ${treeItemTitle} ${getTypeMsg}吗?`"
+                :title="`确定要删除菜单${treeItemTitle}吗?`"
               >
                 <template #reference>
-                  <el-button type="danger" size="small">删除{{ getTypeMsg }}</el-button>
+                  <el-button type="danger" size="small">删除菜单</el-button>
                 </template>
               </el-popconfirm>
             </div>
           </template>
           <!-- 表单 -->
-          <div v-loading="loadingR" class="pt-6">
+          <div class="pt-6">
             <MenuForm
               ref="menuFormRef"
-              :permissionList="treeData"
+              :permissionList="menuTree"
               @change="menuChange"
-              class="w-2/4 ml-10"
+              class="w-2/3 ml-10"
               isShowSubmit
             />
           </div>
@@ -82,71 +82,43 @@
     <CreateDrawer
       ref="createDrawerRef"
       :title="drawerTitle"
-      :permissionList="treeData"
+      :permissionList="menuTree"
       @change="menuChange"
     />
   </PageWrapper>
 </template>
 <script lang="ts" setup>
-  import { ref, unref, onMounted, computed } from 'vue';
+  import { ref, onMounted, shallowRef } from 'vue';
   import { ElMessage } from 'element-plus';
   import { AlignLeftOutlined, FileAddOutlined } from '@vicons/antd';
-  import { menuInfo, deleteMenu } from '@/api/system/menu';
-  import { permissionList } from '@/api/system/role';
+  import { deleteMenu } from '@/api/system/menu';
+  import { queryFullMenuTree } from '@/api/system/menu';
+  import { MenuDetail, MenuSimple } from '@/types/menu/type';
   import { getTreeItem } from '@/utils';
   import CreateDrawer from './CreateDrawer.vue';
   import MenuForm from './MenuForm.vue';
-
-  const createDrawerRef = ref();
-  const treeRef = ref();
-  const message = ElMessage;
-
-  let expandedKeys = ref([]);
-
-  const treeData = ref([]);
-
-  const loading = ref(true);
-  const loadingR = ref(false);
-
-  const isEditMenu = ref(false);
+  import { cloneDeep } from 'lodash-es';
+
+  const menuDetailTree = shallowRef<MenuDetail[]>([]); // 菜单详情树
+  const menuTree = shallowRef<MenuSimple[]>([]); // 菜单树,用于展示
+  const selectedMenuId = ref<MenuDetail['id']>(null); // 选中的菜单
+  const loading = ref(true); // 左侧菜单树加载
+  const expandedKeys = ref([]); 
+ 
+  const isEditMenu = ref(false); 
   const treeItemTitle = ref('');
   const pattern = ref('');
   const drawerTitle = ref('');
-  const menuFormRef = ref();
-
-  const menuTypeMsg = ref(['目录', '菜单', '按钮']);
-
-  const formParams = ref({
-    id: null,
-    parentId: 0,
-    activeMenu: '',
-    affix: false,
-    alwaysShow: true,
-    icon: '',
-    isCache: 1,
-    isFrame: 1,
-    isVisible: 0,
-    menuName: '',
-    menuType: 0,
-    openType: 1,
-    status: 0,
-    orderNum: null,
-    permissionCode: '',
-    permissionName: '',
-    query: '',
-    routeUrl: '',
-    routeName: '',
-    component: '',
-    redirect: '',
-  });
 
-  const getTypeMsg = computed(() => {
-    return menuTypeMsg.value[formParams.value.menuType];
-  });
+  // 组件实例引用
+  const createDrawerRef = ref();
+  const treeRef = ref();
+  const menuFormRef = ref();
 
   function handleDeleteMenu() {
-    deleteMenu({ permissionId: formParams.value.id }).then(() => {
-      message.success('删除成功');
+    deleteMenu(selectedMenuId.value!).then(() => {
+      ElMessage.success('删除成功');
+      selectedMenuId.value = null;
       isEditMenu.value = false;
       treeItemTitle.value = '';
       menuFormRef.value.handleReset();
@@ -160,42 +132,21 @@
     openDrawer();
   }
 
-  async function selectedTree(checkedInfo) {
-    const currentKey = checkedInfo.key;
+  async function selectedTree(checkedInfo: MenuSimple) {
+    const currentKey = checkedInfo.key as number;
+    selectedMenuId.value = currentKey;
+
     if (currentKey) {
-      const treeItem = getTreeItem(unref(treeData), currentKey);
+      const treeItem: MenuSimple = getTreeItem(menuTree.value, currentKey);
       treeItemTitle.value = treeItem.label;
-      loadingR.value = true;
-      const info = await menuInfo({ permissionId: currentKey });
-      const newMenuInfo = {
-        id: info.id,
-        parentId: info.parentId,
-        activeMenu: info.activeMenu,
-        affix: info.affix,
-        alwaysShow: info.alwaysShow,
-        component: info.component,
-        icon: info.icon,
-        isCache: info.isCache,
-        isFrame: info.isFrame,
-        isVisible: parseInt(info.visible),
-        menuName: info.menuName,
-        menuType: info.menuType,
-        openType: info.openType,
-        status: parseInt(info.status),
-        orderNum: info.orderNum,
-        permissionCode: info.permissionCode,
-        permissionName: info.permissionName,
-        query: info.query,
-        routeUrl: info.routeUrl,
-        routeName: info.routeName,
-        redirect: info.redirect,
-        frameSrc: info.frameSrc,
-        isRoot: info.isRoot,
-      };
-      formParams.value = newMenuInfo;
-      menuFormRef.value.setData(newMenuInfo);
+
+      const info: MenuDetail = getTreeItem(menuDetailTree.value, currentKey, 'id');
+      const menuFormData = cloneDeep(info);
+      delete menuFormData.children;
+      // console.log('menu form data', menuFormData)
+      menuFormRef.value.setData(menuFormData);
+
       isEditMenu.value = true;
-      loadingR.value = false;
       treeRef.value.setCheckedKeys([currentKey]);
     }
   }
@@ -209,7 +160,7 @@
   function packHandle() {
     if (!expandedKeys.value.length) {
       treeNodeExpand(true);
-      expandedKeys.value = treeData.value?.map((item: any) => item.key as string) as [];
+      expandedKeys.value = menuTree.value?.map((item: any) => item.key as string) as [];
     } else {
       expandedKeys.value = [];
       treeNodeExpand(false);
@@ -218,11 +169,35 @@
 
   async function getPermissionList() {
     loading.value = true;
-    const list = await permissionList();
-    treeData.value = list;
+    menuDetailTree.value = await queryFullMenuTree();
+    menuTree.value = transformToSimpleMenus(menuDetailTree.value);
     loading.value = false;
   }
 
+  function transformToSimpleMenus(menus: MenuDetail[] | null): MenuSimple[] {
+    if (menus == null) {
+      return [];
+    }
+  
+    let tree: MenuSimple[] = [];
+    for (const item of menus) {
+      const treeItem: MenuSimple = { 
+        key: item.id!, 
+        label: item.menuName, 
+        children: null 
+      };
+
+      if (Array.isArray(item.children) && item.children?.length > 0) {
+        treeItem.children = transformToSimpleMenus(item.children);
+        tree.push(treeItem);
+      } else {
+        tree.push(treeItem);
+      }
+    }
+
+    return tree;
+  }
+
   async function menuChange() {
     getPermissionList();
     treeItemTitle.value = '';
@@ -238,4 +213,3 @@
   }
 </script>
 
-<style lang="scss" sctep></style>