Selaa lähdekoodia

Merge branch 'feature/mockApi' of http://face3d.4dage.com:7005/zhangyupeng/zfb_mp into feature/mockApi

tangning 3 vuotta sitten
vanhempi
commit
2447b36fd3

+ 19 - 8
src/api/system/model/systemModel.ts

@@ -18,8 +18,15 @@ export type DeptParams = {
 };
 
 export type MenuParams = {
-  menuName?: string;
-  status?: string;
+  icon: string;
+  name: string;
+  orderNum: number;
+  parentId: number;
+  parentName: string;
+  perms: string;
+  status: number;
+  type: number;
+  url: string;
 };
 
 export interface AccountListItem {
@@ -42,13 +49,17 @@ export interface DeptListItem {
 }
 
 export interface MenuListItem {
-  id: string;
-  orderNo: string;
-  createTime: string;
-  status: number;
+  menuId: string;
+  children?: MenuListItem[];
   icon: string;
-  component: string;
-  permission: string;
+  name: string;
+  orderNum: number;
+  parentId: number;
+  parentName: string;
+  perms: string;
+  status: number;
+  type: number;
+  url: string;
 }
 
 export interface RoleListItem {

+ 11 - 0
src/api/system/system.ts

@@ -24,6 +24,9 @@ enum Api {
   MenuList = '/zfb-api/zfb/shop/sys/menu/queryAll',
   RolePageList = '/zfb-api/zfb/shop/sys/role/list',
   GetAllRoleList = '/basic-api/system/getAllRoleList',
+  saveMenu = '/zfb-api/zfb/shop/sys/menu/save',
+  updateMenu = '/zfb-api/zfb/shop/sys/menu/update',
+  deleteMenu = '/zfb-api/zfb/shop/sys/menu/delete',
 }
 
 export const getAccountList = (params: AccountParams) =>
@@ -37,6 +40,14 @@ export const getMenuList = (params?: MenuParams) =>
     url: Api.MenuList,
     params: params,
   });
+export const saveMenuApi = (params?: MenuParams) =>
+  defHttp.post<MenuListGetResultModel>({ url: Api.saveMenu, params });
+
+export const updateMenuApi = (params?: MenuParams) =>
+  defHttp.post<MenuListGetResultModel>({ url: Api.updateMenu, params });
+
+export const deleteMenuApi = (params?: (string | number)[]) =>
+  defHttp.post<MenuListGetResultModel>({ url: Api.deleteMenu, params });
 
 export const getRoleListByPage = (params?: RolePageParams) =>
   defHttp.post<RolePageListGetResultModel>({ url: Api.RolePageList, params });

+ 39 - 1
src/utils/treeUtils.ts

@@ -1,9 +1,32 @@
-interface TreeNode {
+export interface TreeNode {
   id: number;
   parentId: number;
   name: string;
+  key?: string;
   children?: TreeNode[];
 }
+export interface TreeMenuNode {
+  menuId: number;
+  parentId: number;
+  name: string;
+  key?: (string | number)[];
+  children?: TreeMenuNode[];
+}
+
+// function traverse(tree: TreeMenuNode[], rootId: number) {
+//   tree.forEach((item) => {
+//     if (item.parentId == rootId) {
+//       console.log('name', item.name);
+//       console.log('menuId', item.menuId);
+//       console.log('rootId', rootId);
+//       // temp.push(item.parentId);
+//       // item.key = temp;
+//     }
+//     if (item.children?.length) {
+//       traverse(item.children, item.menuId);
+//     }
+//   });
+// }
 
 export function makeTree(treeNodes: TreeNode[]): TreeNode[] {
   // 提前生成节点查找表。
@@ -16,6 +39,21 @@ export function makeTree(treeNodes: TreeNode[]): TreeNode[] {
     const parent = nodesMap.get(node.parentId) ?? virtualRoot;
     (parent.children ??= []).push(node);
   });
+  // if (virtualRoot.children?.length) {
+  //   traverse(virtualRoot.children, virtualRoot.children[0].id);
+  // }
+
+  return virtualRoot.children ?? [];
+}
 
+export function makeMenuTree(treeNodes: TreeMenuNode[]): TreeMenuNode[] {
+  const nodesMap = new Map<number, TreeMenuNode>(treeNodes.map((node) => [node.menuId, node]));
+
+  // 引入虚拟根节点来统一实现 parent 始终有效,避免空判断
+  const virtualRoot = {} as Partial<TreeMenuNode>;
+  treeNodes.forEach((node) => {
+    const parent = nodesMap.get(node.parentId) ?? virtualRoot;
+    (parent.children ??= []).push(node);
+  });
   return virtualRoot.children ?? [];
 }

+ 6 - 1
src/views/dashboard/scenes/live.vue

@@ -34,7 +34,12 @@ updateUserId: null -->
     <BasicTable @register="registerTable">
       <template #toolbar> </template>
       <template #cover="{ record }">
-        <TableImg :size="150" :simpleShow="true" :imgList="[record.appListPicUrl]" />
+        <TableImg
+          v-if="record.appListPicUrl"
+          :size="150"
+          :simpleShow="true"
+          :imgList="[record.appListPicUrl]"
+        />
       </template>
       <template #houseType="{ record }">
         {{ renderHouseType(record.houseType) }}

+ 16 - 4
src/views/dashboard/system/menu/MenuDrawer.vue

@@ -16,7 +16,8 @@
   import { formSchema } from './menu.data';
   import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
 
-  import { getMenuList } from '/@/api/system/system';
+  import { getMenuList, saveMenuApi, updateMenuApi } from '/@/api/system/system';
+  import { makeMenuTree } from '/@/utils/treeUtils';
 
   export default defineComponent({
     name: 'MenuDrawer',
@@ -42,10 +43,14 @@
             ...data.record,
           });
         }
-        const treeData = await getMenuList();
+        const tData = await getMenuList();
+        console.log('tData', tData);
+        const treeData = makeMenuTree(tData);
         updateSchema({
-          field: 'parentMenu',
-          componentProps: { treeData },
+          field: 'parentId',
+          componentProps: {
+            treeData,
+          },
         });
       });
 
@@ -57,6 +62,13 @@
           setDrawerProps({ confirmLoading: true });
           // TODO custom api
           console.log(values);
+          values.parentId ??= 0;
+          if (!unref(isUpdate)) {
+            await saveMenuApi(values);
+          } else {
+            await updateMenuApi(values);
+          }
+
           closeDrawer();
           emit('success');
         } finally {

+ 14 - 9
src/views/dashboard/system/menu/index.vue

@@ -30,13 +30,13 @@
   import { defineComponent, reactive } from 'vue';
 
   import { BasicTable, useTable, TableAction } from '/@/components/Table';
-  import { getMenuList } from '/@/api/system/system';
+  import { getMenuList, deleteMenuApi } from '/@/api/system/system';
 
   import { useDrawer } from '/@/components/Drawer';
   import MenuDrawer from './MenuDrawer.vue';
 
   import { columns, searchFormSchema } from './menu.data';
-
+  import { makeMenuTree } from '/@/utils/treeUtils';
   export default defineComponent({
     name: 'MenuManagement',
     components: { BasicTable, MenuDrawer, TableAction },
@@ -56,23 +56,23 @@
         isTreeTable: true,
         pagination: false,
         striped: false,
-        useSearchForm: true,
+        useSearchForm: false,
         showTableSetting: true,
         bordered: true,
-        showIndexColumn: false,
-        canResize: false,
+        showIndexColumn: true,
+        canResize: true,
         actionColumn: {
           width: 80,
           title: '操作',
           dataIndex: 'action',
           slots: { customRender: 'action' },
-          fixed: undefined,
+          fixed: 'right',
         },
         afterFetch: handleAfterFetch,
       });
 
       function handleAfterFetch(data) {
-        console.log('data', data);
+        return makeMenuTree(data);
       }
 
       function handleCreate() {
@@ -82,14 +82,19 @@
       }
 
       function handleEdit(record: Recordable) {
+        record.parentId === 0 && Reflect.set(record, 'parentId', null);
+        console.log('record', record.parentId);
         openDrawer(true, {
           record,
           isUpdate: true,
         });
       }
 
-      function handleDelete(record: Recordable) {
-        console.log(record);
+      async function handleDelete(record: Recordable) {
+        console.log(record.en);
+        try {
+          await deleteMenuApi([String(record.menuId)]);
+        } catch (error) {}
       }
 
       function handleSuccess() {

+ 51 - 21
src/views/dashboard/system/menu/menu.data.ts

@@ -8,10 +8,21 @@ import { Icon } from '/@/components/Icon';
 
 export const columns: BasicColumn[] = [
   {
+    title: 'ID',
+    dataIndex: 'menuId',
+    width: 80,
+  },
+  {
+    title: 'parentId(debug)',
+    dataIndex: 'parentId',
+    width: 80,
+  },
+  {
     title: '菜单名称',
     dataIndex: 'name',
     width: 200,
     align: 'left',
+    fixed: 'left',
   },
   {
     title: '上级菜单',
@@ -37,10 +48,29 @@ export const columns: BasicColumn[] = [
     dataIndex: 'type',
     width: 100,
     customRender: ({ record }) => {
-      const color = 'green';
-      const type = record.type;
+      let color: string;
+      let label: string;
+      const type: number = record.type;
+      switch (type) {
+        case 0:
+          color = 'processing';
+          label = '目录';
+          break;
+        case 1:
+          color = 'warning';
+          label = '菜单';
+          break;
+        case 2:
+          color = 'error';
+          label = '按钮';
+          break;
+        default:
+          color = 'green';
+          label = '目录';
+          break;
+      }
 
-      return h(Tag, { color: color }, () => `目录${type}`);
+      return h(Tag, { color: color }, () => label);
     },
   },
   {
@@ -56,7 +86,7 @@ export const columns: BasicColumn[] = [
     customRender: ({ record }) => {
       const status = record.status;
       const enable = ~~status === 0;
-      const color = enable ? 'warning' : 'red';
+      const color = enable ? 'green' : 'red';
       const text = enable ? '启用' : '停用';
       return h(Tag, { color: color }, () => text);
     },
@@ -68,9 +98,9 @@ export const columns: BasicColumn[] = [
   },
 ];
 
-const isDir = (type: string) => type === '0';
-const isMenu = (type: string) => type === '1';
-const isButton = (type: string) => type === '2';
+const isDir = (type: number) => type === 0;
+const isMenu = (type: number) => type === 1;
+const isButton = (type: number) => type === 2;
 
 export const searchFormSchema: FormSchema[] = [
   {
@@ -85,8 +115,8 @@ export const searchFormSchema: FormSchema[] = [
     component: 'Select',
     componentProps: {
       options: [
-        { label: '启用', value: '0' },
-        { label: '停用', value: '1' },
+        { label: '启用', value: 0 },
+        { label: '停用', value: 1 },
       ],
     },
     colProps: { span: 8 },
@@ -98,13 +128,13 @@ export const formSchema: FormSchema[] = [
     field: 'type',
     label: '菜单类型',
     component: 'RadioButtonGroup',
-    defaultValue: '0',
+    defaultValue: 0,
 
     componentProps: {
       options: [
-        { label: '目录', value: '0' },
-        { label: '菜单', value: '1' },
-        { label: '按钮', value: '2' },
+        { label: '目录', value: 0 },
+        { label: '菜单', value: 1 },
+        { label: '按钮', value: 2 },
       ],
     },
     colProps: { lg: 24, md: 24 },
@@ -117,7 +147,7 @@ export const formSchema: FormSchema[] = [
   },
 
   {
-    field: 'parentMenu',
+    field: 'parentId',
     label: '上级菜单',
     component: 'TreeSelect',
     componentProps: {
@@ -158,7 +188,7 @@ export const formSchema: FormSchema[] = [
     ifShow: ({ values }) => isMenu(values.type),
   },
   {
-    field: 'permission',
+    field: 'perms',
     label: '权限标识',
     component: 'Input',
     ifShow: ({ values }) => !isDir(values.type),
@@ -167,11 +197,11 @@ export const formSchema: FormSchema[] = [
     field: 'status',
     label: '状态',
     component: 'RadioButtonGroup',
-    defaultValue: '0',
+    defaultValue: 0,
     componentProps: {
       options: [
-        { label: '启用', value: '0' },
-        { label: '禁用', value: '1' },
+        { label: '启用', value: 0 },
+        { label: '禁用', value: 1 },
       ],
     },
   },
@@ -207,11 +237,11 @@ export const formSchema: FormSchema[] = [
     field: 'show',
     label: '是否显示',
     component: 'RadioButtonGroup',
-    defaultValue: '0',
+    defaultValue: 0,
     componentProps: {
       options: [
-        { label: '是', value: '0' },
-        { label: '否', value: '1' },
+        { label: '是', value: 0 },
+        { label: '否', value: 1 },
       ],
     },
     ifShow: ({ values }) => !isButton(values.type),