소스 검색

清理信息 打包

wuheng 2 년 전
부모
커밋
a2844f4e7a
82개의 변경된 파일36개의 추가작업 그리고 6261개의 파일을 삭제
  1. 1 1
      .env
  2. 0 132
      mock/api/auth.ts
  3. 0 295
      mock/api/crud/base.ts
  4. 0 5
      mock/api/crud/index.ts
  5. 0 56
      mock/api/crud/modules/demo.ts
  6. 0 46
      mock/api/crud/modules/header-group.ts
  7. 1 6
      mock/api/index.ts
  8. 0 33
      mock/api/management.ts
  9. 0 29
      mock/api/route.ts
  10. 0 56
      mock/model/auth.ts
  11. 0 2
      mock/model/index.ts
  12. 0 1126
      mock/model/route.ts
  13. 4 4
      src/composables/system.ts
  14. 1 64
      src/locales/lang/en.ts
  15. 1 64
      src/locales/lang/zh-cn.ts
  16. 1 1
      src/router/guard/permission.ts
  17. 1 1
      src/router/modules/about.ts
  18. 1 34
      src/router/modules/archives.ts
  19. 0 38
      src/router/modules/auth-demo.ts
  20. 0 48
      src/router/modules/component.ts
  21. 0 45
      src/router/modules/crud.ts
  22. 0 11
      src/router/modules/dashboard.ts
  23. 0 70
      src/router/modules/document.ts
  24. 0 48
      src/router/modules/exception.ts
  25. 0 51
      src/router/modules/function.ts
  26. 0 61
      src/router/modules/multi-menu.ts
  27. 0 149
      src/router/modules/plugin.ts
  28. 2 21
      src/service/api/auth.ts
  29. 0 1
      src/service/api/index.ts
  30. 0 9
      src/service/api/management.ts
  31. 1 1
      src/store/modules/auth/helpers.ts
  32. 0 1
      src/store/modules/auth/index.ts
  33. 15 15
      src/store/modules/route/index.ts
  34. 2 2
      src/typings/business.d.ts
  35. 1 73
      src/typings/page-route.d.ts
  36. 0 63
      src/typings/system.d.ts
  37. 0 49
      src/views/auth-demo/permission/index.vue
  38. 0 9
      src/views/auth-demo/super/index.vue
  39. 0 575
      src/views/component/button/index.vue
  40. 0 42
      src/views/component/card/index.vue
  41. 0 107
      src/views/component/table/index.vue
  42. 0 43
      src/views/crud/demo/api.ts
  43. 0 113
      src/views/crud/demo/crud.tsx
  44. 0 28
      src/views/crud/demo/index.vue
  45. 0 13
      src/views/crud/doc/index.vue
  46. 0 43
      src/views/crud/header_group/api.ts
  47. 0 96
      src/views/crud/header_group/crud.tsx
  48. 0 32
      src/views/crud/header_group/index.vue
  49. 0 13
      src/views/crud/source/index.vue
  50. 0 136
      src/views/dashboard/analysis/components/bottom-part/index.vue
  51. 0 25
      src/views/dashboard/analysis/components/data-card/components/gradient-bg.vue
  52. 0 3
      src/views/dashboard/analysis/components/data-card/components/index.ts
  53. 0 70
      src/views/dashboard/analysis/components/data-card/index.vue
  54. 0 5
      src/views/dashboard/analysis/components/index.ts
  55. 0 184
      src/views/dashboard/analysis/components/top-chart/index.vue
  56. 0 14
      src/views/dashboard/analysis/index.vue
  57. 0 13
      src/views/document/naive/index.vue
  58. 0 7
      src/views/document/project-link/index.vue
  59. 0 13
      src/views/document/project/index.vue
  60. 0 13
      src/views/document/vite/index.vue
  61. 0 13
      src/views/document/vue/index.vue
  62. 0 27
      src/views/function/tab-detail/index.vue
  63. 0 28
      src/views/function/tab-multi-detail/index.vue
  64. 0 44
      src/views/function/tab/index.vue
  65. 4 31
      src/views/index.ts
  66. 0 9
      src/views/multi-menu/first/second-new/third/index.vue
  67. 0 9
      src/views/multi-menu/first/second/index.vue
  68. 0 482
      src/views/plugin/charts/antv/index.vue
  69. 0 783
      src/views/plugin/charts/echarts/index.vue
  70. 0 33
      src/views/plugin/copy/index.vue
  71. 0 50
      src/views/plugin/editor/markdown/index.vue
  72. 0 45
      src/views/plugin/editor/quill/index.vue
  73. 0 32
      src/views/plugin/icon/icons.ts
  74. 0 51
      src/views/plugin/icon/index.vue
  75. 0 30
      src/views/plugin/map/components/baidu-map.vue
  76. 0 32
      src/views/plugin/map/components/gaode-map.vue
  77. 0 5
      src/views/plugin/map/components/index.ts
  78. 0 32
      src/views/plugin/map/components/tencent-map.vue
  79. 0 30
      src/views/plugin/map/index.vue
  80. 0 39
      src/views/plugin/print/index.vue
  81. 0 109
      src/views/plugin/swiper/index.vue
  82. 0 39
      src/views/plugin/video/index.vue

+ 1 - 1
.env

@@ -10,7 +10,7 @@ VITE_APP_DESC=四福科技-爱扣钉-教务
 VITE_AUTH_ROUTE_MODE = static
 
 # 路由首页(根路由重定向), 用于static模式的权限路由,dynamic模式取决于后端返回的路由首页
-VITE_ROUTE_HOME_PATH=/dashboard/analysis
+VITE_ROUTE_HOME_PATH=/dashboard/workbench
 
 # iconify图标作为组件的前缀
 VITE_ICON_PREFFIX=icon

+ 0 - 132
mock/api/auth.ts

@@ -1,132 +0,0 @@
-import type { MockMethod } from 'vite-plugin-mock';
-import { userModel } from '../model';
-
-/** 参数错误的状态码 */
-const ERROR_PARAM_CODE = 10000;
-
-const ERROR_PARAM_MSG = '参数校验失败!';
-
-const apis: MockMethod[] = [
-  // 获取验证码
-  {
-    url: '/mock/getSmsCode',
-    method: 'post',
-    response: (): Service.MockServiceResult<boolean> => {
-      return {
-        code: 200,
-        message: 'ok',
-        data: true
-      };
-    }
-  },
-  // 用户+密码 登录
-  {
-    url: '/mock/login',
-    method: 'post',
-    response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.Token | null> => {
-      const { userName = undefined, password = undefined } = options.body;
-
-      if (!userName || !password) {
-        return {
-          code: ERROR_PARAM_CODE,
-          message: ERROR_PARAM_MSG,
-          data: null
-        };
-      }
-
-      const findItem = userModel.find(item => item.username === userName && item.password === password);
-
-      if (findItem) {
-        return {
-          code: 200,
-          message: 'ok',
-          data: {
-            token: findItem.token,
-            refreshToken: findItem.refreshToken
-          }
-        };
-      }
-      return {
-        code: 1000,
-        message: '用户名或密码错误!',
-        data: null
-      };
-    }
-  },
-  // 获取用户信息(请求头携带token, 根据token获取用户信息)
-  {
-    url: '/mock/getUserInfo',
-    method: 'get',
-    response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.UserInfo | null> => {
-      // 这里的mock插件得到的字段是authorization, 前端传递的是Authorization字段
-      const { authorization = '' } = options.headers;
-      const REFRESH_TOKEN_CODE = 66666;
-
-      if (!authorization) {
-        return {
-          code: REFRESH_TOKEN_CODE,
-          message: '用户已失效或不存在!',
-          data: null
-        };
-      }
-      const userInfo: Auth.UserInfo = {
-        id: 0,
-        username: '',
-        userRole: 'user',
-        phone: '',
-        email: '',
-        permissions: [],
-        departments: []
-      };
-      const isInUser = userModel.some(item => {
-        const flag = item.token === authorization;
-        if (flag) {
-          const { id: itemUserId, username, userRole } = item;
-          Object.assign(userInfo, { userId: itemUserId, username, userRole });
-        }
-        return flag;
-      });
-
-      if (isInUser) {
-        return {
-          code: 200,
-          message: 'ok',
-          data: userInfo
-        };
-      }
-
-      return {
-        code: REFRESH_TOKEN_CODE,
-        message: '用户信息异常!',
-        data: null
-      };
-    }
-  },
-  {
-    url: '/mock/updateToken',
-    method: 'post',
-    response: (options: Service.MockOption): Service.MockServiceResult<ApiAuth.Token | null> => {
-      const { refreshToken = '' } = options.body;
-
-      const findItem = userModel.find(item => item.refreshToken === refreshToken);
-
-      if (findItem) {
-        return {
-          code: 200,
-          message: 'ok',
-          data: {
-            token: findItem.token,
-            refreshToken: findItem.refreshToken
-          }
-        };
-      }
-      return {
-        code: 3000,
-        message: '用户已失效或不存在!',
-        data: null
-      };
-    }
-  }
-];
-
-export default apis;

+ 0 - 295
mock/api/crud/base.ts

@@ -1,295 +0,0 @@
-export type ListItem = {
-  id?: number;
-  children?: ListItem[];
-  [key: string]: any;
-};
-export type BaseMockOptions = { name: string; copyTimes?: number; list: ListItem[]; idGenerator: number };
-type CopyListParams = { originList: ListItem[]; newList: ListItem[]; options: BaseMockOptions; parentId?: number };
-
-function copyList(props: CopyListParams) {
-  const { originList, newList, options, parentId } = props;
-  for (const item of originList) {
-    const newItem: ListItem = { ...item, parentId };
-    newItem.id = options.idGenerator;
-    options.idGenerator += 1;
-    newList.push(newItem);
-    if (item.children) {
-      newItem.children = [];
-      copyList({
-        originList: item.children,
-        newList: newItem.children,
-        options,
-        parentId: newItem.id
-      });
-    }
-  }
-}
-
-function delById(req: Service.MockOption, list: any[]) {
-  for (let i = 0; i < list.length; i += 1) {
-    const item = list[i];
-    if (item.id === parseInt(req.query.id, 10)) {
-      list.splice(i, 1);
-      break;
-    }
-    if (item.children && item.children.length > 0) {
-      delById(req, item.children);
-    }
-  }
-}
-
-function findById(id: number, list: ListItem[]): any {
-  for (const item of list) {
-    if (item.id === id) {
-      return item;
-    }
-    if (item.children && item.children.length > 0) {
-      const sub = findById(id, item.children);
-      if (sub !== null && sub !== undefined) {
-        return sub;
-      }
-    }
-  }
-  return null;
-}
-
-function matchWithArrayCondition(value: any[], item: ListItem, key: string) {
-  if (value.length === 0) {
-    return true;
-  }
-  let matched = false;
-  for (const i of value) {
-    if (item[key] instanceof Array) {
-      for (const j of item[key]) {
-        if (i === j) {
-          matched = true;
-          break;
-        }
-      }
-      if (matched) {
-        break;
-      }
-    } else if (item[key] === i || (typeof item[key] === 'string' && item[key].indexOf(`${i}`) >= 0)) {
-      matched = true;
-      break;
-    }
-    if (matched) {
-      break;
-    }
-  }
-  return matched;
-}
-
-function matchWithObjectCondition(value: any, item: ListItem, key: string) {
-  let matched = true;
-  for (const key2 of Object.keys(value)) {
-    const v = value[key2];
-    if (v && item[key] && v !== item[key][key2]) {
-      matched = false;
-      break;
-    }
-  }
-  return matched;
-}
-
-function searchFromList(list: ListItem[], query: any) {
-  const filter = (item: ListItem) => {
-    let allFound = true; // 是否所有条件都符合
-    for (const key of Object.keys(query)) {
-      const value = query[key];
-      if (value === undefined || value === null || value === '') {
-        // no nothing
-      } else if (value instanceof Array) {
-        // 如果条件中的value是数组的话,只要查到一个就行
-        const matched = matchWithArrayCondition(value, item, key);
-        if (!matched) {
-          allFound = false;
-        }
-      } else if (value instanceof Object) {
-        // 如果条件中的value是对象的话,需要每个key都匹配
-        const matched = matchWithObjectCondition(value, item, key);
-        if (!matched) {
-          allFound = false;
-        }
-      } else if (item[key] !== value) {
-        allFound = false;
-      }
-    }
-    return allFound;
-  };
-  return list.filter(filter);
-}
-
-export default {
-  buildMock(options: BaseMockOptions) {
-    const name = options.name;
-    if (!options.copyTimes) {
-      options.copyTimes = 29;
-    }
-    const list: any[] = [];
-    for (let i = 0; i < options.copyTimes; i += 1) {
-      copyList({
-        originList: options.list,
-        newList: list,
-        options
-      });
-    }
-    options.list = list;
-    return [
-      {
-        path: `/mock/${name}/page`,
-        method: 'post',
-        handle(req: Service.MockOption) {
-          let data = [...list];
-          let limit = 20;
-          let offset = 0;
-          for (const item of list) {
-            if (item.children && item.children.length === 0) {
-              item.hasChildren = false;
-              item.lazy = false;
-            }
-          }
-          let orderAsc: any;
-          let orderProp: any;
-          if (req && req.body) {
-            const { page, query } = req.body;
-            if (page.limit) {
-              limit = parseInt(page.limit, 10);
-            }
-            if (page.offset) {
-              offset = parseInt(page.offset, 10);
-            }
-            if (Object.keys(query).length > 0) {
-              data = searchFromList(list, query);
-            }
-          }
-
-          const start = offset;
-          let end = offset + limit;
-          if (data.length < end) {
-            end = data.length;
-          }
-
-          if (orderProp) {
-            // 排序
-            data.sort((a, b) => {
-              let ret = 0;
-              if (a[orderProp] > b[orderProp]) {
-                ret = 1;
-              } else if (a[orderProp] < b[orderProp]) {
-                ret = -1;
-              }
-              return orderAsc ? ret : -ret;
-            });
-          }
-
-          const records = data.slice(start, end);
-          const lastOffset = data.length - (data.length % limit);
-          if (offset > lastOffset) {
-            offset = lastOffset;
-          }
-          return {
-            code: 200,
-            message: 'success',
-            data: {
-              records,
-              total: data.length,
-              limit,
-              offset
-            }
-          };
-        }
-      },
-      {
-        path: `/mock/${name}/get`,
-        method: 'get',
-        handle(req: Service.MockOption) {
-          let id = req.query.id;
-          id = parseInt(id, 10);
-          let current = null;
-          for (const item of list) {
-            if (item.id === id) {
-              current = item;
-              break;
-            }
-          }
-          return {
-            code: 200,
-            message: 'success',
-            data: current
-          };
-        }
-      },
-      {
-        path: `/mock/${name}/add`,
-        method: 'post',
-        handle(req: Service.MockOption) {
-          req.body.id = options.idGenerator;
-          options.idGenerator += 1;
-          list.unshift(req.body);
-          return {
-            code: 200,
-            message: 'success',
-            data: req.body.id
-          };
-        }
-      },
-      {
-        path: `/mock/${name}/update`,
-        method: 'post',
-        handle(req: Service.MockOption) {
-          const item = findById(req.body.id, list);
-          if (item) {
-            Object.assign(item, req.body);
-          }
-          return {
-            code: 200,
-            message: 'success',
-            data: null
-          };
-        }
-      },
-      {
-        path: `/mock/${name}/delete`,
-        method: 'post',
-        handle(req: Service.MockOption) {
-          delById(req, list);
-          return {
-            code: 200,
-            message: 'success',
-            data: null
-          };
-        }
-      },
-      {
-        path: `/mock/${name}/batchDelete`,
-        method: 'post',
-        handle(req: Service.MockOption) {
-          const ids = req.body.ids;
-          for (let i = list.length - 1; i >= 0; i -= 1) {
-            const item = list[i];
-            if (ids.indexOf(item.id) >= 0) {
-              list.splice(i, 1);
-            }
-          }
-          return {
-            code: 200,
-            message: 'success',
-            data: null
-          };
-        }
-      },
-      {
-        path: `/mock/${name}/all`,
-        method: 'post',
-        handle() {
-          return {
-            code: 200,
-            message: 'success',
-            data: list
-          };
-        }
-      }
-    ];
-  }
-};

+ 0 - 5
mock/api/crud/index.ts

@@ -1,5 +0,0 @@
-import demo from './modules/demo';
-import headerGroup from './modules/header-group';
-
-const crudApis = [...demo, ...headerGroup];
-export default crudApis;

+ 0 - 56
mock/api/crud/modules/demo.ts

@@ -1,56 +0,0 @@
-import type { MethodType, MockMethod } from 'vite-plugin-mock';
-import type { BaseMockOptions } from '../base';
-import mockBase from '../base';
-import MockOption = Service.MockOption;
-
-const options: BaseMockOptions = {
-  name: 'crud/demo',
-  idGenerator: 0,
-  list: [
-    {
-      select: '1',
-      text: '文本测试',
-      copyable: '文本可复制',
-      avatar: 'http://greper.handsfree.work/extends/avatar.jpg',
-      richtext: '富文本',
-      datetime: '2023-01-30 11:11:11'
-    },
-    {
-      select: '2'
-    },
-    {
-      select: '0'
-    }
-  ]
-};
-const mockedApis = mockBase.buildMock(options);
-
-const apis: MockMethod[] = [
-  {
-    url: `/mock/${options.name}/dict`,
-    method: 'get',
-    response: () => {
-      return {
-        code: 200,
-        message: '',
-        data: [
-          { value: '0', label: '关', color: 'warning' },
-          { value: '1', label: '开', color: 'success' },
-          { value: '2', label: '停' }
-        ]
-      };
-    }
-  }
-];
-
-for (const mockedApi of mockedApis) {
-  apis.push({
-    url: mockedApi.path,
-    method: mockedApi.method as MethodType,
-    response: (request: MockOption) => {
-      return mockedApi.handle(request);
-    }
-  });
-}
-
-export default apis;

+ 0 - 46
mock/api/crud/modules/header-group.ts

@@ -1,46 +0,0 @@
-import type { MethodType, MockMethod } from 'vite-plugin-mock';
-import type { BaseMockOptions } from '../base';
-import mockBase from '../base';
-import MockOption = Service.MockOption;
-
-const options: BaseMockOptions = {
-  name: 'crud/header-group',
-  idGenerator: 0,
-  list: [
-    {
-      name: '张三',
-      age: 18,
-      province: '广东省',
-      city: '深圳市',
-      county: '南山区',
-      street: '粤海街道'
-    },
-    {
-      name: '李四',
-      age: 26,
-      province: '浙江省',
-      city: '杭州市',
-      county: '西湖区',
-      street: '西湖街道'
-    },
-    {
-      name: '王五',
-      age: 24
-    }
-  ]
-};
-const mockedApis = mockBase.buildMock(options);
-
-const apis: MockMethod[] = [];
-
-for (const mockedApi of mockedApis) {
-  apis.push({
-    url: mockedApi.path,
-    method: mockedApi.method as MethodType,
-    response: (request: MockOption) => {
-      return mockedApi.handle(request);
-    }
-  });
-}
-
-export default apis;

+ 1 - 6
mock/api/index.ts

@@ -1,6 +1 @@
-import auth from './auth';
-import route from './route';
-import management from './management';
-import crud from './crud';
-
-export default [...auth, ...route, ...management, ...crud];
+export default [];

+ 0 - 33
mock/api/management.ts

@@ -1,33 +0,0 @@
-import { mock } from 'mockjs';
-import type { MockMethod } from 'vite-plugin-mock';
-
-const apis: MockMethod[] = [
-  {
-    url: '/mock/getAllUserList',
-    method: 'post',
-    response: (): Service.MockServiceResult<ApiUserManagement.User[]> => {
-      const data = mock({
-        'list|1000': [
-          {
-            id: '@id',
-            userName: '@cname',
-            'age|18-56': 56,
-            'gender|1': ['0', '1', null],
-            phone:
-              /^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/,
-            'email|1': ['@email("qq.com")', null],
-            'userStatus|1': ['1', '2', '3', '4', null]
-          }
-        ]
-      });
-
-      return {
-        code: 200,
-        message: 'ok',
-        data: data.list
-      };
-    }
-  }
-];
-
-export default apis;

+ 0 - 29
mock/api/route.ts

@@ -1,29 +0,0 @@
-import type { MockMethod } from 'vite-plugin-mock';
-import { routeModel, userModel } from '../model';
-
-const apis: MockMethod[] = [
-  {
-    url: '/mock/getUserRoutes',
-    method: 'post',
-    response: (options: Service.MockOption): Service.MockServiceResult => {
-      const { userId = undefined } = options.body;
-
-      const routeHomeName: AuthRoute.LastDegreeRouteKey = 'dashboard_analysis';
-
-      const role = userModel.find(item => item.id === userId)?.userRole || 'user';
-
-      const filterRoutes = routeModel[role];
-
-      return {
-        code: 200,
-        message: 'ok',
-        data: {
-          routes: filterRoutes,
-          home: routeHomeName
-        }
-      };
-    }
-  }
-];
-
-export default apis;

+ 0 - 56
mock/model/auth.ts

@@ -1,56 +0,0 @@
-interface UserModel extends Auth.UserInfo {
-  token: string;
-  refreshToken: string;
-  password: string;
-}
-
-export const userModel: UserModel[] = [
-  {
-    token: '__TOKEN_SOYBEAN__',
-    refreshToken: '__REFRESH_TOKEN_SOYBEAN__',
-    id: 0,
-    username: 'Soybean',
-    userRole: 'admin',
-    password: 'soybean123',
-    phone: '',
-    email: '',
-    permissions: [],
-    departments: []
-  },
-  {
-    token: '__TOKEN_SUPER__',
-    refreshToken: '__REFRESH_TOKEN_SUPER__',
-    id: 1,
-    username: 'Super',
-    userRole: 'admin',
-    password: 'super123',
-    phone: '',
-    email: '',
-    permissions: [],
-    departments: []
-  },
-  {
-    token: '__TOKEN_ADMIN__',
-    refreshToken: '__REFRESH_TOKEN_ADMIN__',
-    id: 2,
-    username: 'Admin',
-    userRole: 'admin',
-    password: 'admin123',
-    phone: '',
-    email: '',
-    permissions: [],
-    departments: []
-  },
-  {
-    token: '__TOKEN_USER01__',
-    refreshToken: '__REFRESH_TOKEN_USER01__',
-    id: 3,
-    username: 'User01',
-    userRole: 'user',
-    password: 'user01123',
-    phone: '',
-    email: '',
-    permissions: [],
-    departments: []
-  }
-];

+ 0 - 2
mock/model/index.ts

@@ -1,2 +0,0 @@
-export * from './auth';
-export * from './route';

+ 0 - 1126
mock/model/route.ts

@@ -1,1126 +0,0 @@
-export const routeModel: Record<Auth.RoleType, AuthRoute.Route[]> = {
-  admin: [
-    {
-      name: 'dashboard',
-      path: '/dashboard',
-      component: 'basic',
-      children: [
-        {
-          name: 'dashboard_analysis',
-          path: '/dashboard/analysis',
-          component: 'self',
-          meta: {
-            title: '分析页',
-            requiresAuth: true,
-            icon: 'icon-park-outline:analysis'
-          }
-        },
-        {
-          name: 'dashboard_workbench',
-          path: '/dashboard/workbench',
-          component: 'self',
-          meta: {
-            title: '工作台',
-            requiresAuth: true,
-            icon: 'icon-park-outline:workbench'
-          }
-        }
-      ],
-      meta: {
-        title: '仪表盘',
-        icon: 'mdi:monitor-dashboard',
-        order: 1
-      }
-    },
-    {
-      name: 'document',
-      path: '/document',
-      component: 'basic',
-      children: [
-        {
-          name: 'document_vue',
-          path: '/document/vue',
-          component: 'self',
-          meta: {
-            title: 'vue文档',
-            requiresAuth: true,
-            icon: 'logos:vue'
-          }
-        },
-        {
-          name: 'document_vite',
-          path: '/document/vite',
-          component: 'self',
-          meta: {
-            title: 'vite文档',
-            requiresAuth: true,
-            icon: 'logos:vitejs'
-          }
-        },
-        {
-          name: 'document_naive',
-          path: '/document/naive',
-          component: 'self',
-          meta: {
-            title: 'naive文档',
-            requiresAuth: true,
-            icon: 'logos:naiveui'
-          }
-        },
-        {
-          name: 'document_project',
-          path: '/document/project',
-          component: 'self',
-          meta: {
-            title: '项目文档',
-            requiresAuth: true,
-            localIcon: 'logo'
-          }
-        },
-        {
-          name: 'document_project-link',
-          path: '/document/project-link',
-          meta: {
-            title: '项目文档(外链)',
-            requiresAuth: true,
-            localIcon: 'logo',
-            href: 'https://docs.soybean.pro/'
-          }
-        }
-      ],
-      meta: {
-        title: '文档',
-        icon: 'mdi:file-document-multiple-outline',
-        order: 2
-      }
-    },
-    {
-      name: 'component',
-      path: '/component',
-      component: 'basic',
-      children: [
-        {
-          name: 'component_button',
-          path: '/component/button',
-          component: 'self',
-          meta: {
-            title: '按钮',
-            requiresAuth: true,
-            icon: 'mdi:button-cursor'
-          }
-        },
-        {
-          name: 'component_card',
-          path: '/component/card',
-          component: 'self',
-          meta: {
-            title: '卡片',
-            requiresAuth: true,
-            icon: 'mdi:card-outline'
-          }
-        },
-        {
-          name: 'component_table',
-          path: '/component/table',
-          component: 'self',
-          meta: {
-            title: '表格',
-            requiresAuth: true,
-            icon: 'mdi:table-large'
-          }
-        }
-      ],
-      meta: {
-        title: '组件示例',
-        icon: 'cib:app-store',
-        order: 3
-      }
-    },
-    {
-      name: 'plugin',
-      path: '/plugin',
-      component: 'basic',
-      children: [
-        {
-          name: 'plugin_charts',
-          path: '/plugin/charts',
-          component: 'multi',
-          children: [
-            {
-              name: 'plugin_charts_echarts',
-              path: '/plugin/charts/echarts',
-              component: 'self',
-              meta: {
-                title: 'ECharts',
-                requiresAuth: true,
-                icon: 'simple-icons:apacheecharts'
-              }
-            },
-            {
-              name: 'plugin_charts_antv',
-              path: '/plugin/charts/antv',
-              component: 'self',
-              meta: {
-                title: 'AntV',
-                requiresAuth: true,
-                icon: 'simple-icons:antdesign'
-              }
-            }
-          ],
-          meta: {
-            title: '图表',
-            icon: 'mdi:chart-areaspline'
-          }
-        },
-        {
-          name: 'plugin_map',
-          path: '/plugin/map',
-          component: 'self',
-          meta: {
-            title: '地图',
-            requiresAuth: true,
-            icon: 'mdi:map'
-          }
-        },
-        {
-          name: 'plugin_video',
-          path: '/plugin/video',
-          component: 'self',
-          meta: {
-            title: '视频',
-            requiresAuth: true,
-            icon: 'mdi:video'
-          }
-        },
-        {
-          name: 'plugin_editor',
-          path: '/plugin/editor',
-          component: 'multi',
-          children: [
-            {
-              name: 'plugin_editor_quill',
-              path: '/plugin/editor/quill',
-              component: 'self',
-              meta: {
-                title: '富文本编辑器',
-                requiresAuth: true,
-                icon: 'mdi:file-document-edit-outline'
-              }
-            },
-            {
-              name: 'plugin_editor_markdown',
-              path: '/plugin/editor/markdown',
-              component: 'self',
-              meta: {
-                title: 'markdown编辑器',
-                requiresAuth: true,
-                icon: 'ri:markdown-line'
-              }
-            }
-          ],
-          meta: {
-            title: '编辑器',
-            icon: 'icon-park-outline:editor'
-          }
-        },
-        {
-          name: 'plugin_swiper',
-          path: '/plugin/swiper',
-          component: 'self',
-          meta: {
-            title: 'Swiper插件',
-            requiresAuth: true,
-            icon: 'simple-icons:swiper'
-          }
-        },
-        {
-          name: 'plugin_copy',
-          path: '/plugin/copy',
-          component: 'self',
-          meta: {
-            title: '剪贴板',
-            requiresAuth: true,
-            icon: 'mdi:clipboard-outline'
-          }
-        },
-        {
-          name: 'plugin_icon',
-          path: '/plugin/icon',
-          component: 'self',
-          meta: {
-            title: '图标',
-            requiresAuth: true,
-            localIcon: 'custom-icon'
-          }
-        },
-        {
-          name: 'plugin_print',
-          path: '/plugin/print',
-          component: 'self',
-          meta: {
-            title: '打印',
-            requiresAuth: true,
-            icon: 'mdi:printer'
-          }
-        }
-      ],
-      meta: {
-        title: '插件示例',
-        icon: 'clarity:plugin-line',
-        order: 4
-      }
-    },
-    {
-      name: 'auth-demo',
-      path: '/auth-demo',
-      component: 'basic',
-      children: [
-        {
-          name: 'auth-demo_permission',
-          path: '/auth-demo/permission',
-          component: 'self',
-          meta: {
-            title: '权限切换',
-            requiresAuth: true,
-            icon: 'ic:round-construction'
-          }
-        },
-        {
-          name: 'auth-demo_super',
-          path: '/auth-demo/super',
-          component: 'self',
-          meta: {
-            title: '超级管理员可见',
-            requiresAuth: true,
-            icon: 'ic:round-supervisor-account'
-          }
-        }
-      ],
-      meta: {
-        title: '权限示例',
-        icon: 'ic:baseline-security',
-        order: 5
-      }
-    },
-    {
-      name: 'function',
-      path: '/function',
-      component: 'basic',
-      children: [
-        {
-          name: 'function_tab',
-          path: '/function/tab',
-          component: 'self',
-          meta: {
-            title: 'Tab',
-            requiresAuth: true,
-            icon: 'ic:round-tab'
-          }
-        },
-        {
-          name: 'function_tab-detail',
-          path: '/function/tab-detail',
-          component: 'self',
-          meta: {
-            title: 'Tab Detail',
-            requiresAuth: true,
-            hide: true,
-            activeMenu: 'function_tab',
-            icon: 'ic:round-tab'
-          }
-        },
-        {
-          name: 'function_tab-multi-detail',
-          path: '/function/tab-multi-detail',
-          component: 'self',
-          meta: {
-            title: 'Tab Multi Detail',
-            requiresAuth: true,
-            hide: true,
-            multiTab: true,
-            activeMenu: 'function_tab',
-            icon: 'ic:round-tab'
-          }
-        }
-      ],
-      meta: {
-        title: '功能',
-        icon: 'icon-park-outline:all-application',
-        order: 6
-      }
-    },
-    {
-      name: 'exception',
-      path: '/exception',
-      component: 'basic',
-      children: [
-        {
-          name: 'exception_403',
-          path: '/exception/403',
-          component: 'self',
-          meta: {
-            title: '异常页403',
-            requiresAuth: true,
-            icon: 'ic:baseline-block'
-          }
-        },
-        {
-          name: 'exception_404',
-          path: '/exception/404',
-          component: 'self',
-          meta: {
-            title: '异常页404',
-            requiresAuth: true,
-            icon: 'ic:baseline-web-asset-off'
-          }
-        },
-        {
-          name: 'exception_500',
-          path: '/exception/500',
-          component: 'self',
-          meta: {
-            title: '异常页500',
-            requiresAuth: true,
-            icon: 'ic:baseline-wifi-off'
-          }
-        }
-      ],
-      meta: {
-        title: '异常页',
-        icon: 'ant-design:exception-outlined',
-        order: 7
-      }
-    },
-    {
-      name: 'multi-menu',
-      path: '/multi-menu',
-      component: 'basic',
-      children: [
-        {
-          name: 'multi-menu_first',
-          path: '/multi-menu/first',
-          component: 'multi',
-          children: [
-            {
-              name: 'multi-menu_first_second',
-              path: '/multi-menu/first/second',
-              component: 'self',
-              meta: {
-                title: '二级菜单',
-                requiresAuth: true,
-                icon: 'mdi:menu'
-              }
-            },
-            {
-              name: 'multi-menu_first_second-new',
-              path: '/multi-menu/first/second-new',
-              component: 'multi',
-              children: [
-                {
-                  name: 'multi-menu_first_second-new_third',
-                  path: '/multi-menu/first/second-new/third',
-                  component: 'self',
-                  meta: {
-                    title: '三级菜单',
-                    requiresAuth: true,
-                    icon: 'mdi:menu'
-                  }
-                }
-              ],
-              meta: {
-                title: '二级菜单(有子菜单)',
-                icon: 'mdi:menu'
-              }
-            }
-          ],
-          meta: {
-            title: '一级菜单',
-            icon: 'mdi:menu'
-          }
-        }
-      ],
-      meta: {
-        title: '多级菜单',
-        icon: 'carbon:menu',
-        order: 8
-      }
-    },
-    {
-      name: 'management',
-      path: '/management',
-      component: 'basic',
-      children: [
-        {
-          name: 'management_auth',
-          path: '/management/auth',
-          component: 'self',
-          meta: {
-            title: '权限管理',
-            requiresAuth: true,
-            icon: 'ic:baseline-security'
-          }
-        },
-        {
-          name: 'management_role',
-          path: '/management/role',
-          component: 'self',
-          meta: {
-            title: '角色管理',
-            requiresAuth: true,
-            icon: 'carbon:user-role'
-          }
-        },
-        {
-          name: 'management_user',
-          path: '/management/user',
-          component: 'self',
-          meta: {
-            title: '用户管理',
-            requiresAuth: true,
-            icon: 'ic:round-manage-accounts'
-          }
-        },
-        {
-          name: 'management_route',
-          path: '/management/route',
-          component: 'self',
-          meta: {
-            title: '路由管理',
-            requiresAuth: true,
-            icon: 'material-symbols:route'
-          }
-        }
-      ],
-      meta: {
-        title: '系统管理',
-        icon: 'carbon:cloud-service-management',
-        order: 9
-      }
-    },
-    {
-      name: 'about',
-      path: '/about',
-      component: 'self',
-      meta: {
-        title: '关于',
-        requiresAuth: true,
-        singleLayout: 'basic',
-        icon: 'fluent:book-information-24-regular',
-        order: 10
-      }
-    }
-  ],
-  user: [
-    {
-      name: 'dashboard',
-      path: '/dashboard',
-      component: 'basic',
-      children: [
-        {
-          name: 'dashboard_analysis',
-          path: '/dashboard/analysis',
-          component: 'self',
-          meta: {
-            title: '分析页',
-            requiresAuth: true,
-            icon: 'icon-park-outline:analysis'
-          }
-        },
-        {
-          name: 'dashboard_workbench',
-          path: '/dashboard/workbench',
-          component: 'self',
-          meta: {
-            title: '工作台',
-            requiresAuth: true,
-            icon: 'icon-park-outline:workbench'
-          }
-        }
-      ],
-      meta: {
-        title: '仪表盘',
-        icon: 'mdi:monitor-dashboard',
-        order: 1
-      }
-    },
-    {
-      name: 'document',
-      path: '/document',
-      component: 'basic',
-      children: [
-        {
-          name: 'document_vue',
-          path: '/document/vue',
-          component: 'self',
-          meta: {
-            title: 'vue文档',
-            requiresAuth: true,
-            icon: 'logos:vue'
-          }
-        },
-        {
-          name: 'document_vite',
-          path: '/document/vite',
-          component: 'self',
-          meta: {
-            title: 'vite文档',
-            requiresAuth: true,
-            icon: 'logos:vitejs'
-          }
-        },
-        {
-          name: 'document_naive',
-          path: '/document/naive',
-          component: 'self',
-          meta: {
-            title: 'naive文档',
-            requiresAuth: true,
-            icon: 'logos:naiveui'
-          }
-        },
-        {
-          name: 'document_project',
-          path: '/document/project',
-          component: 'self',
-          meta: {
-            title: '项目文档',
-            requiresAuth: true,
-            localIcon: 'logo'
-          }
-        },
-        {
-          name: 'document_project-link',
-          path: '/document/project-link',
-          meta: {
-            title: '项目文档(外链)',
-            requiresAuth: true,
-            localIcon: 'logo',
-            href: 'https://docs.soybean.pro/'
-          }
-        }
-      ],
-      meta: {
-        title: '文档',
-        icon: 'mdi:file-document-multiple-outline',
-        order: 2
-      }
-    },
-    {
-      name: 'component',
-      path: '/component',
-      component: 'basic',
-      children: [
-        {
-          name: 'component_button',
-          path: '/component/button',
-          component: 'self',
-          meta: {
-            title: '按钮',
-            requiresAuth: true,
-            icon: 'mdi:button-cursor'
-          }
-        },
-        {
-          name: 'component_card',
-          path: '/component/card',
-          component: 'self',
-          meta: {
-            title: '卡片',
-            requiresAuth: true,
-            icon: 'mdi:card-outline'
-          }
-        },
-        {
-          name: 'component_table',
-          path: '/component/table',
-          component: 'self',
-          meta: {
-            title: '表格',
-            requiresAuth: true,
-            icon: 'mdi:table-large'
-          }
-        }
-      ],
-      meta: {
-        title: '组件示例',
-        icon: 'cib:app-store',
-        order: 3
-      }
-    },
-    {
-      name: 'plugin',
-      path: '/plugin',
-      component: 'basic',
-      children: [
-        {
-          name: 'plugin_charts',
-          path: '/plugin/charts',
-          component: 'multi',
-          children: [
-            {
-              name: 'plugin_charts_echarts',
-              path: '/plugin/charts/echarts',
-              component: 'self',
-              meta: {
-                title: 'ECharts',
-                requiresAuth: true,
-                icon: 'simple-icons:apacheecharts'
-              }
-            },
-            {
-              name: 'plugin_charts_antv',
-              path: '/plugin/charts/antv',
-              component: 'self',
-              meta: {
-                title: 'AntV',
-                requiresAuth: true,
-                icon: 'simple-icons:antdesign'
-              }
-            }
-          ],
-          meta: {
-            title: '图表',
-            icon: 'mdi:chart-areaspline'
-          }
-        },
-        {
-          name: 'plugin_map',
-          path: '/plugin/map',
-          component: 'self',
-          meta: {
-            title: '地图',
-            requiresAuth: true,
-            icon: 'mdi:map'
-          }
-        },
-        {
-          name: 'plugin_video',
-          path: '/plugin/video',
-          component: 'self',
-          meta: {
-            title: '视频',
-            requiresAuth: true,
-            icon: 'mdi:video'
-          }
-        },
-        {
-          name: 'plugin_editor',
-          path: '/plugin/editor',
-          component: 'multi',
-          children: [
-            {
-              name: 'plugin_editor_quill',
-              path: '/plugin/editor/quill',
-              component: 'self',
-              meta: {
-                title: '富文本编辑器',
-                requiresAuth: true,
-                icon: 'mdi:file-document-edit-outline'
-              }
-            },
-            {
-              name: 'plugin_editor_markdown',
-              path: '/plugin/editor/markdown',
-              component: 'self',
-              meta: {
-                title: 'markdown编辑器',
-                requiresAuth: true,
-                icon: 'ri:markdown-line'
-              }
-            }
-          ],
-          meta: {
-            title: '编辑器',
-            icon: 'icon-park-outline:editor'
-          }
-        },
-        {
-          name: 'plugin_swiper',
-          path: '/plugin/swiper',
-          component: 'self',
-          meta: {
-            title: 'Swiper插件',
-            requiresAuth: true,
-            icon: 'simple-icons:swiper'
-          }
-        },
-        {
-          name: 'plugin_copy',
-          path: '/plugin/copy',
-          component: 'self',
-          meta: {
-            title: '剪贴板',
-            requiresAuth: true,
-            icon: 'mdi:clipboard-outline'
-          }
-        },
-        {
-          name: 'plugin_icon',
-          path: '/plugin/icon',
-          component: 'self',
-          meta: {
-            title: '图标',
-            requiresAuth: true,
-            localIcon: 'custom-icon'
-          }
-        },
-        {
-          name: 'plugin_print',
-          path: '/plugin/print',
-          component: 'self',
-          meta: {
-            title: '打印',
-            requiresAuth: true,
-            icon: 'mdi:printer'
-          }
-        }
-      ],
-      meta: {
-        title: '插件示例',
-        icon: 'clarity:plugin-line',
-        order: 4
-      }
-    },
-    {
-      name: 'auth-demo',
-      path: '/auth-demo',
-      component: 'basic',
-      children: [
-        {
-          name: 'auth-demo_permission',
-          path: '/auth-demo/permission',
-          component: 'self',
-          meta: {
-            title: '权限切换',
-            requiresAuth: true,
-            icon: 'ic:round-construction'
-          }
-        }
-      ],
-      meta: {
-        title: '权限示例',
-        icon: 'ic:baseline-security',
-        order: 5
-      }
-    },
-    {
-      name: 'function',
-      path: '/function',
-      component: 'basic',
-      children: [
-        {
-          name: 'function_tab',
-          path: '/function/tab',
-          component: 'self',
-          meta: {
-            title: 'Tab',
-            requiresAuth: true,
-            icon: 'ic:round-tab'
-          }
-        },
-        {
-          name: 'function_tab-detail',
-          path: '/function/tab-detail',
-          component: 'self',
-          meta: {
-            title: 'Tab Detail',
-            requiresAuth: true,
-            hide: true,
-            activeMenu: 'function_tab',
-            icon: 'ic:round-tab'
-          }
-        },
-        {
-          name: 'function_tab-multi-detail',
-          path: '/function/tab-multi-detail',
-          component: 'self',
-          meta: {
-            title: 'Tab Multi Detail',
-            requiresAuth: true,
-            hide: true,
-            multiTab: true,
-            activeMenu: 'function_tab',
-            icon: 'ic:round-tab'
-          }
-        }
-      ],
-      meta: {
-        title: '功能',
-        icon: 'icon-park-outline:all-application',
-        order: 6
-      }
-    },
-    {
-      name: 'exception',
-      path: '/exception',
-      component: 'basic',
-      children: [
-        {
-          name: 'exception_403',
-          path: '/exception/403',
-          component: 'self',
-          meta: {
-            title: '异常页403',
-            requiresAuth: true,
-            icon: 'ic:baseline-block'
-          }
-        },
-        {
-          name: 'exception_404',
-          path: '/exception/404',
-          component: 'self',
-          meta: {
-            title: '异常页404',
-            requiresAuth: true,
-            icon: 'ic:baseline-web-asset-off'
-          }
-        },
-        {
-          name: 'exception_500',
-          path: '/exception/500',
-          component: 'self',
-          meta: {
-            title: '异常页500',
-            requiresAuth: true,
-            icon: 'ic:baseline-wifi-off'
-          }
-        }
-      ],
-      meta: {
-        title: '异常页',
-        icon: 'ant-design:exception-outlined',
-        order: 7
-      }
-    },
-    {
-      name: 'multi-menu',
-      path: '/multi-menu',
-      component: 'basic',
-      children: [
-        {
-          name: 'multi-menu_first',
-          path: '/multi-menu/first',
-          component: 'multi',
-          children: [
-            {
-              name: 'multi-menu_first_second',
-              path: '/multi-menu/first/second',
-              component: 'self',
-              meta: {
-                title: '二级菜单',
-                requiresAuth: true,
-                icon: 'mdi:menu'
-              }
-            },
-            {
-              name: 'multi-menu_first_second-new',
-              path: '/multi-menu/first/second-new',
-              component: 'multi',
-              children: [
-                {
-                  name: 'multi-menu_first_second-new_third',
-                  path: '/multi-menu/first/second-new/third',
-                  component: 'self',
-                  meta: {
-                    title: '三级菜单',
-                    requiresAuth: true,
-                    icon: 'mdi:menu'
-                  }
-                }
-              ],
-              meta: {
-                title: '二级菜单(有子菜单)',
-                icon: 'mdi:menu'
-              }
-            }
-          ],
-          meta: {
-            title: '一级菜单',
-            icon: 'mdi:menu'
-          }
-        }
-      ],
-      meta: {
-        title: '多级菜单',
-        icon: 'carbon:menu',
-        order: 8
-      }
-    },
-    {
-      name: 'management',
-      path: '/management',
-      component: 'basic',
-      children: [
-        {
-          name: 'management_auth',
-          path: '/management/auth',
-          component: 'self',
-          meta: {
-            title: '权限管理',
-            requiresAuth: true,
-            icon: 'ic:baseline-security'
-          }
-        },
-        {
-          name: 'management_role',
-          path: '/management/role',
-          component: 'self',
-          meta: {
-            title: '角色管理',
-            requiresAuth: true,
-            icon: 'carbon:user-role'
-          }
-        },
-        {
-          name: 'management_user',
-          path: '/management/user',
-          component: 'self',
-          meta: {
-            title: '用户管理',
-            requiresAuth: true,
-            icon: 'ic:round-manage-accounts'
-          }
-        },
-        {
-          name: 'management_route',
-          path: '/management/route',
-          component: 'self',
-          meta: {
-            title: '路由管理',
-            requiresAuth: true,
-            icon: 'material-symbols:route'
-          }
-        }
-      ],
-      meta: {
-        title: '系统管理',
-        icon: 'carbon:cloud-service-management',
-        order: 9
-      }
-    },
-    {
-      name: 'about',
-      path: '/about',
-      component: 'self',
-      meta: {
-        title: '关于',
-        requiresAuth: true,
-        singleLayout: 'basic',
-        icon: 'fluent:book-information-24-regular',
-        order: 10
-      }
-    }
-  ],
-  member: [
-    {
-      name: 'dashboard',
-      path: '/dashboard',
-      component: 'basic',
-      children: [
-        {
-          name: 'dashboard_analysis',
-          path: '/dashboard/analysis',
-          component: 'self',
-          meta: {
-            title: '分析页',
-            requiresAuth: true,
-            icon: 'icon-park-outline:analysis'
-          }
-        }
-      ],
-      meta: {
-        title: '仪表盘',
-        icon: 'mdi:monitor-dashboard',
-        order: 1
-      }
-    },
-    {
-      name: 'auth-demo',
-      path: '/auth-demo',
-      component: 'basic',
-      children: [
-        {
-          name: 'auth-demo_permission',
-          path: '/auth-demo/permission',
-          component: 'self',
-          meta: {
-            title: '权限切换',
-            requiresAuth: true,
-            icon: 'ic:round-construction'
-          }
-        }
-      ],
-      meta: {
-        title: '权限示例',
-        icon: 'ic:baseline-security',
-        order: 5
-      }
-    },
-    {
-      name: 'multi-menu',
-      path: '/multi-menu',
-      component: 'basic',
-      children: [
-        {
-          name: 'multi-menu_first',
-          path: '/multi-menu/first',
-          component: 'multi',
-          children: [
-            {
-              name: 'multi-menu_first_second',
-              path: '/multi-menu/first/second',
-              component: 'self',
-              meta: {
-                title: '二级菜单',
-                requiresAuth: true,
-                icon: 'mdi:menu'
-              }
-            },
-            {
-              name: 'multi-menu_first_second-new',
-              path: '/multi-menu/first/second-new',
-              component: 'multi',
-              children: [
-                {
-                  name: 'multi-menu_first_second-new_third',
-                  path: '/multi-menu/first/second-new/third',
-                  component: 'self',
-                  meta: {
-                    title: '三级菜单',
-                    requiresAuth: true,
-                    icon: 'mdi:menu'
-                  }
-                }
-              ],
-              meta: {
-                title: '二级菜单(有子菜单)',
-                icon: 'mdi:menu'
-              }
-            }
-          ],
-          meta: {
-            title: '一级菜单',
-            icon: 'mdi:menu'
-          }
-        }
-      ],
-      meta: {
-        title: '多级菜单',
-        icon: 'carbon:menu',
-        order: 7
-      }
-    },
-    {
-      name: 'about',
-      path: '/about',
-      component: 'self',
-      meta: {
-        title: '关于',
-        requiresAuth: true,
-        singleLayout: 'basic',
-        icon: 'fluent:book-information-24-regular',
-        order: 8
-      }
-    }
-  ]
-};

+ 4 - 4
src/composables/system.ts

@@ -34,15 +34,15 @@ export function usePermission() {
   const auth = useAuthStore();
 
   function hasPermission(permission: Auth.RoleType | Auth.RoleType[]) {
-    const { userRole } = auth.userInfo;
+    const { userType } = auth.userInfo;
 
-    let has = userRole === 'admin';
+    let has = userType === 'admin';
     if (!has) {
       if (isArray(permission)) {
-        has = (permission as Auth.RoleType[]).includes(userRole);
+        has = (permission as Auth.RoleType[]).includes(userType);
       }
       if (isString(permission)) {
-        has = (permission as Auth.RoleType) === userRole;
+        has = (permission as Auth.RoleType) === userType;
       }
     }
     return has;

+ 1 - 64
src/locales/lang/en.ts

@@ -8,68 +8,8 @@ const locale: LocaleMessages<I18nType.Schema> = {
     routes: {
       dashboard: {
         dashboard: 'Dashboard',
-        analysis: 'Analysis',
         workbench: 'Workbench'
       },
-      document: {
-        _value: 'Document',
-        vue: 'Vue Document',
-        vite: 'Vite Document',
-        naive: 'NaiveUI Document',
-        project: 'Project Document',
-        'project-link': 'Project Document(href)'
-      },
-      component: {
-        _value: 'Component',
-        button: 'Button',
-        card: 'Card',
-        table: 'Table'
-      },
-      plugin: {
-        _value: 'Plugin',
-        charts: {
-          _value: 'Chart',
-          echarts: 'ECharts',
-          antv: 'AntV'
-        },
-        copy: 'Copy',
-        editor: {
-          _value: 'Editor',
-          quill: 'Quill',
-          markdown: 'Markdown'
-        },
-        icon: 'Icon',
-        map: 'Map',
-        print: 'Print',
-        swiper: 'Swiper',
-        video: 'Video'
-      },
-      'auth-demo': {
-        _value: 'Auth Demo',
-        permission: 'Toggle Permission',
-        super: 'Super Auth'
-      },
-      function: {
-        _value: 'Function',
-        tab: 'System Tab'
-      },
-      exception: {
-        _value: 'Exception',
-        403: '403',
-        404: '404',
-        500: '500'
-      },
-      'multi-menu': {
-        _value: 'Multi Degree Menu',
-        first: {
-          _value: 'First Degree',
-          second: 'Second Degree',
-          'second-new': {
-            _value: 'Second Degree With Children',
-            third: 'Third Degree'
-          }
-        }
-      },
       management: {
         _value: 'System Management',
         auth: 'Auth',
@@ -92,10 +32,7 @@ const locale: LocaleMessages<I18nType.Schema> = {
       },
       archives: {
         _value: 'archives',
-        scores: 'scores',
-        students: 'students base',
-        attendance: 'attendance',
-        other: 'other'
+        students: 'students info'
       },
       about: 'About'
     }

+ 1 - 64
src/locales/lang/zh-cn.ts

@@ -8,68 +8,8 @@ const locale: LocaleMessages<I18nType.Schema> = {
     routes: {
       dashboard: {
         dashboard: '仪表盘',
-        analysis: '分析页',
         workbench: '工作台'
       },
-      document: {
-        _value: '文档',
-        vue: 'Vue文档',
-        vite: 'Vite文档',
-        naive: 'NaiveUI文档',
-        project: '项目文档',
-        'project-link': '项目文档(外链)'
-      },
-      component: {
-        _value: '组件示例',
-        button: '按钮',
-        card: '卡片',
-        table: '表格'
-      },
-      plugin: {
-        _value: '插件示例',
-        charts: {
-          _value: '图表',
-          echarts: 'ECharts',
-          antv: 'AntV'
-        },
-        copy: '剪贴板',
-        editor: {
-          _value: '编辑器',
-          quill: '富文本',
-          markdown: 'Markdown'
-        },
-        icon: '图标',
-        map: '地图',
-        print: '打印',
-        swiper: 'Swiper',
-        video: '视频'
-      },
-      'auth-demo': {
-        _value: '权限示例',
-        permission: '切换权限',
-        super: '超级管理员可见'
-      },
-      function: {
-        _value: '功能',
-        tab: 'Tab页签'
-      },
-      exception: {
-        _value: '异常页',
-        403: '403',
-        404: '404',
-        500: '500'
-      },
-      'multi-menu': {
-        _value: '多级菜单',
-        first: {
-          _value: '一级菜单',
-          second: '二级菜单',
-          'second-new': {
-            _value: '二级菜单(有子菜单)',
-            third: '三级菜单'
-          }
-        }
-      },
       management: {
         _value: '系统管理',
         auth: '权限管理',
@@ -92,10 +32,7 @@ const locale: LocaleMessages<I18nType.Schema> = {
       },
       archives: {
         _value: '档案管理',
-        scores: '学员成绩',
-        students: '基本信息',
-        attendance: '签到信息',
-        other: '其他信息'
+        students: '档案搜索'
       },
       about: '关于'
     }

+ 1 - 1
src/router/guard/permission.ts

@@ -26,7 +26,7 @@ export async function createPermissionGuard(
   const isLogin = Boolean(localStorage.getItem('token'));
   const permissions = to.meta.permissions || [];
   const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length);
-  const hasPermission = !permissions.length || permissions.includes(auth.userInfo.userRole);
+  const hasPermission = !permissions.length || permissions.includes(auth.userInfo.userType);
 
   const actions: Common.StrategyAction[] = [
     // 已登录状态跳转登录页,跳转至首页

+ 1 - 1
src/router/modules/about.ts

@@ -8,7 +8,7 @@ const about1: AuthRoute.Route = {
     requiresAuth: true,
     keepAlive: true,
     singleLayout: 'basic',
-    permissions: ['admin', 'user'],
+    permissions: ['admin', 'teacher'],
     icon: 'fluent:book-information-24-regular',
     order: 10
   }

+ 1 - 34
src/router/modules/archives.ts

@@ -3,49 +3,16 @@ const archives: AuthRoute.Route = {
   path: '/archives',
   component: 'basic',
   children: [
-    {
-      name: 'archives_scores',
-      path: '/archives/scores',
-      component: 'self',
-      meta: {
-        title: '成绩查看',
-        i18nTitle: 'message.routes.archives.scores',
-        requiresAuth: true,
-        icon: 'arcticons:score-sheets'
-      }
-    },
     {
       name: 'archives_students',
       path: '/archives/students',
       component: 'self',
       meta: {
-        title: '资料查看',
+        title: '档案搜索',
         i18nTitle: 'message.routes.archives.students',
         requiresAuth: true,
         icon: 'icons8:student'
       }
-    },
-    {
-      name: 'archives_attendance',
-      path: '/archives/attendance',
-      component: 'self',
-      meta: {
-        title: '考勤查看',
-        i18nTitle: 'message.routes.archives.attendance',
-        requiresAuth: true,
-        icon: 'openmoji:mark'
-      }
-    },
-    {
-      name: 'archives_other',
-      path: '/archives/other',
-      component: 'self',
-      meta: {
-        title: '其他查看',
-        i18nTitle: 'message.routes.archives.other',
-        requiresAuth: true,
-        icon: 'basil:other-1-outline'
-      }
     }
   ],
   meta: {

+ 0 - 38
src/router/modules/auth-demo.ts

@@ -1,38 +0,0 @@
-// const authDemo: AuthRoute.Route = {
-//   name: 'auth-demo',
-//   path: '/auth-demo',
-//   component: 'basic',
-//   children: [
-//     {
-//       name: 'auth-demo_permission',
-//       path: '/auth-demo/permission',
-//       component: 'self',
-//       meta: {
-//         title: '权限切换',
-//         i18nTitle: 'message.routes.auth-demo.permission',
-//         requiresAuth: true,
-//         icon: 'ic:round-construction'
-//       }
-//     },
-//     {
-//       name: 'auth-demo_super',
-//       path: '/auth-demo/super',
-//       component: 'self',
-//       meta: {
-//         title: '超级管理员可见',
-//         i18nTitle: 'message.routes.auth-demo.super',
-//         requiresAuth: true,
-//         permissions: ['admin'],
-//         icon: 'ic:round-supervisor-account'
-//       }
-//     }
-//   ],
-//   meta: {
-//     title: '权限示例',
-//     i18nTitle: 'message.routes.auth-demo._value',
-//     icon: 'ic:baseline-security',
-//     order: 5
-//   }
-// };
-
-// export default authDemo;

+ 0 - 48
src/router/modules/component.ts

@@ -1,48 +0,0 @@
-// const component: AuthRoute.Route = {
-//   name: 'component',
-//   path: '/component',
-//   component: 'basic',
-//   children: [
-//     {
-//       name: 'component_button',
-//       path: '/component/button',
-//       component: 'self',
-//       meta: {
-//         title: '按钮',
-//         i18nTitle: 'message.routes.component.button',
-//         requiresAuth: true,
-//         icon: 'mdi:button-cursor'
-//       }
-//     },
-//     {
-//       name: 'component_card',
-//       path: '/component/card',
-//       component: 'self',
-//       meta: {
-//         title: '卡片',
-//         i18nTitle: 'message.routes.component.card',
-//         requiresAuth: true,
-//         icon: 'mdi:card-outline'
-//       }
-//     },
-//     {
-//       name: 'component_table',
-//       path: '/component/table',
-//       component: 'self',
-//       meta: {
-//         title: '表格',
-//         i18nTitle: 'message.routes.component.table',
-//         requiresAuth: true,
-//         icon: 'mdi:table-large'
-//       }
-//     }
-//   ],
-//   meta: {
-//     title: '组件示例',
-//     i18nTitle: 'message.routes.component._value',
-//     icon: 'cib:app-store',
-//     order: 3
-//   }
-// };
-
-// export default component;

+ 0 - 45
src/router/modules/crud.ts

@@ -1,45 +0,0 @@
-// const component: any = {
-//   name: 'crud',
-//   path: '/crud',
-//   component: 'basic',
-//   meta: {
-//     title: 'CRUD示例',
-//     requiresAuth: true,
-//     icon: 'mdi:table-large',
-//     order: 4
-//   },
-//   children: [
-//     {
-//       name: 'crud_demo',
-//       path: '/crud/demo',
-//       component: 'self',
-//       meta: {
-//         title: '基本示例',
-//         requiresAuth: true,
-//         icon: 'mdi:button-cursor'
-//       }
-//     },
-//     {
-//       name: 'crud_header_group',
-//       path: '/crud/header_group',
-//       component: 'self',
-//       meta: {
-//         title: '多级表头',
-//         requiresAuth: true,
-//         icon: 'mdi:button-cursor'
-//       }
-//     },
-//     {
-//       name: 'crud_doc',
-//       path: '/crud/doc',
-//       component: 'self',
-//       meta: {
-//         title: 'FastCrud文档',
-//         requiresAuth: true,
-//         icon: 'logos:vue'
-//       }
-//     }
-//   ]
-// };
-
-// export default component;

+ 0 - 11
src/router/modules/dashboard.ts

@@ -3,17 +3,6 @@ const dashboard: AuthRoute.Route = {
   path: '/dashboard',
   component: 'basic',
   children: [
-    {
-      name: 'dashboard_analysis',
-      path: '/dashboard/analysis',
-      component: 'self',
-      meta: {
-        title: '分析页',
-        requiresAuth: true,
-        icon: 'icon-park-outline:analysis',
-        i18nTitle: 'message.routes.dashboard.analysis'
-      }
-    },
     {
       name: 'dashboard_workbench',
       path: '/dashboard/workbench',

+ 0 - 70
src/router/modules/document.ts

@@ -1,70 +0,0 @@
-const document: AuthRoute.Route = {
-  name: 'document',
-  path: '/document',
-  component: 'basic',
-  children: [
-    {
-      name: 'document_vue',
-      path: '/document/vue',
-      component: 'self',
-      meta: {
-        title: 'vue文档',
-        i18nTitle: 'message.routes.document.vue',
-        requiresAuth: true,
-        icon: 'logos:vue'
-      }
-    },
-    {
-      name: 'document_vite',
-      path: '/document/vite',
-      component: 'self',
-      meta: {
-        title: 'vite文档',
-        i18nTitle: 'message.routes.document.vite',
-        requiresAuth: true,
-        icon: 'logos:vitejs'
-      }
-    },
-    {
-      name: 'document_naive',
-      path: '/document/naive',
-      component: 'self',
-      meta: {
-        title: 'naive文档',
-        i18nTitle: 'message.routes.document.naive',
-        requiresAuth: true,
-        icon: 'logos:naiveui'
-      }
-    },
-    {
-      name: 'document_project',
-      path: '/document/project',
-      component: 'self',
-      meta: {
-        title: '项目文档',
-        i18nTitle: 'message.routes.document.project',
-        requiresAuth: true,
-        localIcon: 'logo'
-      }
-    },
-    {
-      name: 'document_project-link',
-      path: '/document/project-link',
-      meta: {
-        title: '项目文档(外链)',
-        i18nTitle: 'message.routes.document.project-link',
-        requiresAuth: true,
-        localIcon: 'logo',
-        href: 'https://docs.soybean.pro/'
-      }
-    }
-  ],
-  meta: {
-    title: '文档',
-    i18nTitle: 'message.routes.document._value',
-    icon: 'mdi:file-document-multiple-outline',
-    order: 2
-  }
-};
-
-export default document;

+ 0 - 48
src/router/modules/exception.ts

@@ -1,48 +0,0 @@
-// const exception: AuthRoute.Route = {
-//   name: 'exception',
-//   path: '/exception',
-//   component: 'basic',
-//   children: [
-//     {
-//       name: 'exception_403',
-//       path: '/exception/403',
-//       component: 'self',
-//       meta: {
-//         title: '异常页403',
-//         i18nTitle: 'message.routes.exception.403',
-//         requiresAuth: true,
-//         icon: 'ic:baseline-block'
-//       }
-//     },
-//     {
-//       name: 'exception_404',
-//       path: '/exception/404',
-//       component: 'self',
-//       meta: {
-//         title: '异常页404',
-//         i18nTitle: 'message.routes.exception.404',
-//         requiresAuth: true,
-//         icon: 'ic:baseline-web-asset-off'
-//       }
-//     },
-//     {
-//       name: 'exception_500',
-//       path: '/exception/500',
-//       component: 'self',
-//       meta: {
-//         title: '异常页500',
-//         i18nTitle: 'message.routes.exception.500',
-//         requiresAuth: true,
-//         icon: 'ic:baseline-wifi-off'
-//       }
-//     }
-//   ],
-//   meta: {
-//     i18nTitle: 'message.routes.exception._value',
-//     title: '异常页',
-//     icon: 'ant-design:exception-outlined',
-//     order: 7
-//   }
-// };
-
-// export default exception;

+ 0 - 51
src/router/modules/function.ts

@@ -1,51 +0,0 @@
-// const functionRoute: AuthRoute.Route = {
-//   name: 'function',
-//   path: '/function',
-//   component: 'basic',
-//   children: [
-//     {
-//       name: 'function_tab',
-//       path: '/function/tab',
-//       component: 'self',
-//       meta: {
-//         title: 'Tab',
-//         i18nTitle: 'message.routes.function.tab',
-//         requiresAuth: true,
-//         icon: 'ic:round-tab'
-//       }
-//     },
-//     {
-//       name: 'function_tab-detail',
-//       path: '/function/tab-detail',
-//       component: 'self',
-//       meta: {
-//         title: 'Tab Detail',
-//         requiresAuth: true,
-//         hide: true,
-//         activeMenu: 'function_tab',
-//         icon: 'ic:round-tab'
-//       }
-//     },
-//     {
-//       name: 'function_tab-multi-detail',
-//       path: '/function/tab-multi-detail',
-//       component: 'self',
-//       meta: {
-//         title: 'Tab Multi Detail',
-//         requiresAuth: true,
-//         hide: true,
-//         multiTab: true,
-//         activeMenu: 'function_tab',
-//         icon: 'ic:round-tab'
-//       }
-//     }
-//   ],
-//   meta: {
-//     title: '功能',
-//     i18nTitle: 'message.routes.function._value',
-//     icon: 'icon-park-outline:all-application',
-//     order: 6
-//   }
-// };
-
-// export default functionRoute;

+ 0 - 61
src/router/modules/multi-menu.ts

@@ -1,61 +0,0 @@
-// const multiMenu: AuthRoute.Route = {
-//   name: 'multi-menu',
-//   path: '/multi-menu',
-//   component: 'basic',
-//   children: [
-//     {
-//       name: 'multi-menu_first',
-//       path: '/multi-menu/first',
-//       component: 'multi',
-//       children: [
-//         {
-//           name: 'multi-menu_first_second',
-//           path: '/multi-menu/first/second',
-//           component: 'self',
-//           meta: {
-//             title: '二级菜单',
-//             i18nTitle: 'message.routes.multi-menu.first.second',
-//             requiresAuth: true,
-//             icon: 'mdi:menu'
-//           }
-//         },
-//         {
-//           name: 'multi-menu_first_second-new',
-//           path: '/multi-menu/first/second-new',
-//           component: 'multi',
-//           children: [
-//             {
-//               name: 'multi-menu_first_second-new_third',
-//               path: '/multi-menu/first/second-new/third',
-//               component: 'self',
-//               meta: {
-//                 title: '三级菜单',
-//                 i18nTitle: 'message.routes.multi-menu.first.second-new.third',
-//                 requiresAuth: true,
-//                 icon: 'mdi:menu'
-//               }
-//             }
-//           ],
-//           meta: {
-//             title: '二级菜单(有子菜单)',
-//             i18nTitle: 'message.routes.multi-menu.first.second-new._value',
-//             icon: 'mdi:menu'
-//           }
-//         }
-//       ],
-//       meta: {
-//         title: '一级菜单',
-//         i18nTitle: 'message.routes.multi-menu.first._value',
-//         icon: 'mdi:menu'
-//       }
-//     }
-//   ],
-//   meta: {
-//     title: '多级菜单',
-//     i18nTitle: 'message.routes.multi-menu._value',
-//     icon: 'carbon:menu',
-//     order: 8
-//   }
-// };
-
-// export default multiMenu;

+ 0 - 149
src/router/modules/plugin.ts

@@ -1,149 +0,0 @@
-// const plugin: AuthRoute.Route = {
-//   name: 'plugin',
-//   path: '/plugin',
-//   component: 'basic',
-//   children: [
-//     {
-//       name: 'plugin_charts',
-//       path: '/plugin/charts',
-//       component: 'multi',
-//       children: [
-//         {
-//           name: 'plugin_charts_echarts',
-//           path: '/plugin/charts/echarts',
-//           component: 'self',
-//           meta: {
-//             title: 'ECharts',
-//             i18nTitle: 'message.routes.plugin.charts.echarts',
-//             requiresAuth: true,
-//             icon: 'simple-icons:apacheecharts'
-//           }
-//         },
-//         {
-//           name: 'plugin_charts_antv',
-//           path: '/plugin/charts/antv',
-//           component: 'self',
-//           meta: {
-//             title: 'AntV',
-//             i18nTitle: 'message.routes.plugin.charts.antv',
-//             requiresAuth: true,
-//             icon: 'simple-icons:antdesign'
-//           }
-//         }
-//       ],
-//       meta: {
-//         title: '图表',
-//         i18nTitle: 'message.routes.plugin.charts._value',
-//         icon: 'mdi:chart-areaspline'
-//       }
-//     },
-//     {
-//       name: 'plugin_map',
-//       path: '/plugin/map',
-//       component: 'self',
-//       meta: {
-//         title: '地图',
-//         i18nTitle: 'message.routes.plugin.map',
-//         requiresAuth: true,
-//         icon: 'mdi:map'
-//       }
-//     },
-//     {
-//       name: 'plugin_video',
-//       path: '/plugin/video',
-//       component: 'self',
-//       meta: {
-//         title: '视频',
-//         i18nTitle: 'message.routes.plugin.video',
-//         requiresAuth: true,
-//         icon: 'mdi:video'
-//       }
-//     },
-//     {
-//       name: 'plugin_editor',
-//       path: '/plugin/editor',
-//       component: 'multi',
-//       children: [
-//         {
-//           name: 'plugin_editor_quill',
-//           path: '/plugin/editor/quill',
-//           component: 'self',
-//           meta: {
-//             title: '富文本编辑器',
-//             i18nTitle: 'message.routes.plugin.editor.quill',
-//             requiresAuth: true,
-//             icon: 'mdi:file-document-edit-outline'
-//           }
-//         },
-//         {
-//           name: 'plugin_editor_markdown',
-//           path: '/plugin/editor/markdown',
-//           component: 'self',
-//           meta: {
-//             title: 'markdown编辑器',
-//             i18nTitle: 'message.routes.plugin.editor.markdown',
-//             requiresAuth: true,
-//             icon: 'ri:markdown-line'
-//           }
-//         }
-//       ],
-//       meta: {
-//         title: '编辑器',
-//         i18nTitle: 'message.routes.plugin.editor._value',
-//         icon: 'icon-park-outline:editor'
-//       }
-//     },
-//     {
-//       name: 'plugin_swiper',
-//       path: '/plugin/swiper',
-//       component: 'self',
-//       meta: {
-//         title: 'Swiper插件',
-//         i18nTitle: 'message.routes.plugin.swiper',
-//         requiresAuth: true,
-//         icon: 'simple-icons:swiper'
-//       }
-//     },
-//     {
-//       name: 'plugin_copy',
-//       path: '/plugin/copy',
-//       component: 'self',
-//       meta: {
-//         title: '剪贴板',
-//         i18nTitle: 'message.routes.plugin.copy',
-//         requiresAuth: true,
-//         icon: 'mdi:clipboard-outline'
-//       }
-//     },
-//     {
-//       name: 'plugin_icon',
-//       path: '/plugin/icon',
-//       component: 'self',
-//       meta: {
-//         title: '图标',
-//         i18nTitle: 'message.routes.plugin.icon',
-//         requiresAuth: true,
-//         localIcon: 'custom-icon'
-//       }
-//     },
-//     {
-//       name: 'plugin_print',
-//       path: '/plugin/print',
-//       component: 'self',
-//       meta: {
-//         title: '打印',
-//         i18nTitle: 'message.routes.plugin.print',
-//         requiresAuth: true,
-//         icon: 'mdi:printer'
-//       }
-//     }
-//   ],
-//   meta: {
-//     title: '插件示例',
-//     i18nTitle: 'message.routes.plugin._value',
-//     icon: 'clarity:plugin-line',
-//     order: 4
-//   }
-// };
-
-// export default plugin;

+ 2 - 21
src/service/api/auth.ts

@@ -1,5 +1,4 @@
-// import { localStg } from '~/src/utils';
-import { request, mockRequest } from '../request';
+import { request } from '../request';
 
 /**
  * 获取验证码
@@ -23,16 +22,7 @@ export interface AdminLoginRes {
   msg: string;
   data: Record<string, unknown>;
 }
-// /**
-//  * 管理员登录
-//  * @param {object} params AdminPojo
-//  * @param {string} params.username
-//  * @param {string} params.passwd
-//  * @returns
-//  */
-// export function adminLogin(params: AdminLoginParams) {
-//   return request.post(`/adminLogin`, params);
-// }
+
 /**
  * 登录
  * @param userName - 用户名
@@ -61,15 +51,6 @@ export function fetchUserInfo() {
   return res;
 }
 
-/**
- * 获取用户路由数据
- * @param userId - 用户id
- * @description 后端根据用户id查询到对应的角色类型,并将路由筛选出对应角色的路由数据返回前端
- */
-export function fetchUserRoutes(userId: number) {
-  return mockRequest.post<ApiRoute.Route>('/login/getUserRoutes', { userId });
-}
-
 /**
  * 刷新token
  * @param refreshToken

+ 0 - 1
src/service/api/index.ts

@@ -1,2 +1 @@
 export * from './auth';
-export * from './management';

+ 0 - 9
src/service/api/management.ts

@@ -1,9 +0,0 @@
-import { adapter } from '@/utils';
-import { mockRequest } from '../request';
-import { adapterOfFetchUserList } from './management.adapter';
-
-/** 获取用户列表 */
-export const fetchUserList = async () => {
-  const data = await mockRequest.post<ApiUserManagement.User[] | null>('/getAllUserList');
-  return adapter(adapterOfFetchUserList, data);
-};

+ 1 - 1
src/store/modules/auth/helpers.ts

@@ -14,7 +14,7 @@ export function getUserInfo() {
     email: '',
     permissions: [],
     departments: [],
-    userRole: 'admin'
+    userType: 'admin'
   };
   const userInfo: Auth.UserInfo = localStg.get('userInfo') || emptyInfo;
   return userInfo;

+ 0 - 1
src/store/modules/auth/index.ts

@@ -4,7 +4,6 @@ import { router } from '@/router';
 import type { AdminLoginParams } from '@/service';
 import { fetchLogin, fetchUserInfo, fetchStudentLogin } from '@/service';
 import { useRouterPush } from '@/composables';
-// import { localStg } from '@/utils';
 import { useTabStore } from '../tab';
 import { useRouteStore } from '../route';
 import { getToken, getUserInfo, clearAuthStorage } from './helpers';

+ 15 - 15
src/store/modules/route/index.ts

@@ -1,6 +1,6 @@
 import { defineStore } from 'pinia';
 import { ROOT_ROUTE, constantRoutes, router, routes as staticRoutes } from '@/router';
-import { fetchUserRoutes } from '@/service';
+// import { fetchUserRoutes } from '@/service';
 import {
   filterAuthRoutesByUserPermission,
   getCacheRoutes,
@@ -10,8 +10,7 @@ import {
   transformAuthRouteToMenu,
   transformAuthRouteToSearchMenus,
   transformRouteNameToRoutePath,
-  transformRoutePathToRouteName,
-  sortRoutes
+  transformRoutePathToRouteName
 } from '@/utils';
 import { useAuthStore } from '../auth';
 import { useTabStore } from '../tab';
@@ -106,32 +105,33 @@ export const useRouteStore = defineStore('route-store', {
     /** 初始化动态路由 */
     async initDynamicRoute() {
       const { resetAuthStore } = useAuthStore();
-      const { initHomeTab } = useTabStore();
+      // const { initHomeTab } = useTabStore();
 
       const id = localStorage.getItem('userInfo');
       if (!id) {
         throw new Error('userId 不能为空!');
       }
 
-      const { error, data } = await fetchUserRoutes(Number(id));
+      // const { error, data } = await fetchUserRoutes(Number(id));
 
-      if (!error && data) {
-        this.routeHomeName = data.home;
-        this.handleUpdateRootRedirect(data.home);
-        this.handleAuthRoute(sortRoutes(data.routes));
+      // if (!error && data) {
+      //   this.routeHomeName = data.home;
+      //   this.handleUpdateRootRedirect(data.home);
+      //   this.handleAuthRoute(sortRoutes(data.routes));
 
-        initHomeTab(data.home, router);
+      //   initHomeTab(data.home, router);
 
-        this.isInitAuthRoute = true;
-      } else {
-        resetAuthStore();
-      }
+      //   this.isInitAuthRoute = true;
+      // } else {
+      //   resetAuthStore();
+      // }
+      resetAuthStore();
     },
     /** 初始化静态路由 */
     async initStaticRoute() {
       const { initHomeTab } = useTabStore();
       const auth = useAuthStore();
-      const routes = filterAuthRoutesByUserPermission(staticRoutes, auth.userInfo.userRole);
+      const routes = filterAuthRoutesByUserPermission(staticRoutes, auth.userInfo.userType);
       this.handleAuthRoute(routes);
       initHomeTab(this.routeHomeName, router);
       this.isInitAuthRoute = true;

+ 2 - 2
src/typings/business.d.ts

@@ -6,7 +6,7 @@ declare namespace Auth {
    * - admin: 管理员
    * - user: 用户
    */
-  type RoleType = 'admin' | 'user' | 'member';
+  type RoleType = 'admin' | 'teacher' | 'member';
 
   /** 用户信息 */
   interface UserInfo {
@@ -19,7 +19,7 @@ declare namespace Auth {
     permissions: [];
     departments: [];
     /** 用户角色类型 */
-    userRole: RoleType;
+    userType: RoleType;
   }
 }
 

+ 1 - 73
src/typings/page-route.d.ts

@@ -28,36 +28,12 @@ declare namespace PageRoute {
     | 'archives_scores'
     | 'archives_students'
     | 'archives_students_component'
-    | 'auth-demo'
-    | 'auth-demo_permission'
-    | 'auth-demo_super'
-    | 'component'
-    | 'component_button'
-    | 'component_card'
-    | 'component_table'
-    | 'crud'
-    | 'crud_demo'
-    | 'crud_doc'
-    | 'crud_header'
-    | 'crud_header_group'
-    | 'crud_source'
     | 'dashboard'
-    | 'dashboard_analysis'
     | 'dashboard_workbench'
-    | 'document'
-    | 'document_naive'
-    | 'document_project-link'
-    | 'document_project'
-    | 'document_vite'
-    | 'document_vue'
     | 'exception'
     | 'exception_403'
     | 'exception_404'
     | 'exception_500'
-    | 'function'
-    | 'function_tab-detail'
-    | 'function_tab-multi-detail'
-    | 'function_tab'
     | 'lesson'
     | 'lesson_calendar'
     | 'lesson_checkin'
@@ -73,25 +49,7 @@ declare namespace PageRoute {
     | 'management_route'
     | 'management_sort'
     | 'management_student'
-    | 'management_user'
-    | 'multi-menu'
-    | 'multi-menu_first'
-    | 'multi-menu_first_second-new'
-    | 'multi-menu_first_second-new_third'
-    | 'multi-menu_first_second'
-    | 'plugin'
-    | 'plugin_charts'
-    | 'plugin_charts_antv'
-    | 'plugin_charts_echarts'
-    | 'plugin_copy'
-    | 'plugin_editor'
-    | 'plugin_editor_markdown'
-    | 'plugin_editor_quill'
-    | 'plugin_icon'
-    | 'plugin_map'
-    | 'plugin_print'
-    | 'plugin_swiper'
-    | 'plugin_video';
+    | 'management_user';
 
   /**
    * last degree route key, which has the page file
@@ -110,28 +68,10 @@ declare namespace PageRoute {
     | 'archives_scores'
     | 'archives_students_component'
     | 'archives_students'
-    | 'auth-demo_permission'
-    | 'auth-demo_super'
-    | 'component_button'
-    | 'component_card'
-    | 'component_table'
-    | 'crud_demo'
-    | 'crud_doc'
-    | 'crud_header_group'
-    | 'crud_source'
-    | 'dashboard_analysis'
     | 'dashboard_workbench'
-    | 'document_naive'
-    | 'document_project-link'
-    | 'document_project'
-    | 'document_vite'
-    | 'document_vue'
     | 'exception_403'
     | 'exception_404'
     | 'exception_500'
-    | 'function_tab-detail'
-    | 'function_tab-multi-detail'
-    | 'function_tab'
     | 'lesson_calendar'
     | 'lesson_checkin'
     | 'lesson_classroom'
@@ -146,17 +86,5 @@ declare namespace PageRoute {
     | 'management_sort'
     | 'management_student'
     | 'management_user'
-    | 'multi-menu_first_second-new_third'
-    | 'multi-menu_first_second'
-    | 'plugin_charts_antv'
-    | 'plugin_charts_echarts'
-    | 'plugin_copy'
-    | 'plugin_editor_markdown'
-    | 'plugin_editor_quill'
-    | 'plugin_icon'
-    | 'plugin_map'
-    | 'plugin_print'
-    | 'plugin_swiper'
-    | 'plugin_video'
   >;
 }

+ 0 - 63
src/typings/system.d.ts

@@ -321,68 +321,8 @@ declare namespace I18nType {
     routes: {
       dashboard: {
         dashboard: string;
-        analysis: string;
         workbench: string;
       };
-      document: {
-        _value: string;
-        vue: string;
-        vite: string;
-        naive: string;
-        project: string;
-        'project-link': string;
-      };
-      component: {
-        _value: string;
-        button: string;
-        card: string;
-        table: string;
-      };
-      plugin: {
-        _value: string;
-        charts: {
-          _value: string;
-          antv: string;
-          echarts: string;
-        };
-        copy: string;
-        editor: {
-          _value: string;
-          markdown: string;
-          quill: string;
-        };
-        icon: string;
-        map: string;
-        print: string;
-        swiper: string;
-        video: string;
-      };
-      'auth-demo': {
-        _value: string;
-        permission: string;
-        super: string;
-      };
-      function: {
-        _value: string;
-        tab: string;
-      };
-      exception: {
-        _value: string;
-        403: string;
-        404: string;
-        500: string;
-      };
-      'multi-menu': {
-        _value: string;
-        first: {
-          _value: string;
-          second: string;
-          'second-new': {
-            _value: string;
-            third: string;
-          };
-        };
-      };
       management: {
         _value: string;
         auth: string;
@@ -405,10 +345,7 @@ declare namespace I18nType {
       };
       archives: {
         _value: string;
-        other: string;
-        attendance: string;
         students: string;
-        scores: string;
       };
       about: string;
     };

+ 0 - 49
src/views/auth-demo/permission/index.vue

@@ -1,49 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="权限切换" class="h-full shadow-sm rounded-16px">
-      <div class="pb-12px">
-        <n-gradient-text type="primary" :size="20">当前用户的权限:{{ auth.userInfo.userRole }}</n-gradient-text>
-      </div>
-      <n-select :value="auth.userInfo.userRole" class="w-120px" size="small" />
-      <div class="py-12px">
-        <n-gradient-text type="primary" :size="20">权限指令 v-permission</n-gradient-text>
-      </div>
-      <div>
-        <n-button v-permission="'super'" class="mr-12px">super可见</n-button>
-        <n-button v-permission="'admin'" class="mr-12px">admin可见</n-button>
-        <n-button v-permission="['admin', 'user']">admin和test可见</n-button>
-      </div>
-      <div class="py-12px">
-        <n-gradient-text type="primary" :size="20">权限函数 hasPermission</n-gradient-text>
-      </div>
-      <n-space>
-        <n-button v-if="hasPermission('member')">super可见</n-button>
-        <n-button v-if="hasPermission('admin')">admin可见</n-button>
-        <n-button v-if="hasPermission(['admin', 'user'])">admin和user可见</n-button>
-      </n-space>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { watch } from 'vue';
-// import type { SelectOption } from 'naive-ui';
-// import { userRoleOptions } from '@/constants';
-import { useAppStore, useAuthStore } from '@/store';
-import { usePermission } from '@/composables';
-
-const app = useAppStore();
-const auth = useAuthStore();
-const { hasPermission } = usePermission();
-
-// const options: SelectOption[] = userRoleOptions;
-
-watch(
-  () => auth.userInfo.userRole,
-  async () => {
-    app.reloadPage();
-  }
-);
-</script>
-
-<style scoped></style>

+ 0 - 9
src/views/auth-demo/super/index.vue

@@ -1,9 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="当前页面只有super才能看到" class="h-full shadow-sm rounded-16px"> </n-card>
-  </div>
-</template>
-
-<script setup lang="ts"></script>
-
-<style scoped></style>

+ 0 - 575
src/views/component/button/index.vue

@@ -1,575 +0,0 @@
-<template>
-  <div>
-    <n-card title="按钮" class="h-full shadow-sm rounded-16px">
-      <n-grid cols="s:1 m:2" responsive="screen" :x-gap="16" :y-gap="16">
-        <n-grid-item v-for="item in buttonExample" :key="item.id">
-          <n-card :title="item.label" class="min-h-180px">
-            <p v-if="item.desc" class="pb-16px">{{ item.desc }}</p>
-            <n-space>
-              <n-button
-                v-for="button in item.buttons"
-                :key="button.id"
-                v-bind="button.props"
-                :style="`--icon-margin: ${button.props.circle ? 0 : 6}px`"
-              >
-                <template v-if="button.icon" #icon>
-                  <svg-icon :icon="button.icon" />
-                </template>
-                {{ button.label }}
-              </n-button>
-            </n-space>
-          </n-card>
-        </n-grid-item>
-        <n-grid-item class="h-180px">
-          <n-card title="加载中" class="h-full">
-            <p class="pb-16px">按钮有加载状态。</p>
-            <n-space>
-              <n-button :loading="loading" type="primary" @click="startLoading">开始加载</n-button>
-              <n-button @click="endLoading">取消加载</n-button>
-            </n-space>
-          </n-card>
-        </n-grid-item>
-      </n-grid>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts">
-import type { ButtonProps } from 'naive-ui';
-import { useLoading } from '@/hooks';
-
-interface ButtonDetail {
-  id: number;
-  props: ButtonProps & { href?: string; target?: string };
-  label?: string;
-  icon?: string;
-}
-
-interface ButtonExample {
-  id: number;
-  label: string;
-  buttons: ButtonDetail[];
-  desc?: string;
-}
-
-const { loading, startLoading, endLoading } = useLoading();
-
-const buttonExample: ButtonExample[] = [
-  {
-    id: 0,
-    label: '基础',
-    buttons: [
-      {
-        id: 0,
-        props: {},
-        label: 'Default'
-      },
-      {
-        id: 1,
-        props: { type: 'tertiary' },
-        label: 'Tertiary'
-      },
-      {
-        id: 2,
-        props: { type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 3,
-        props: { type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 4,
-        props: { type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 5,
-        props: { type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 6,
-        props: { type: 'error' },
-        label: 'Error'
-      }
-    ],
-    desc: '按钮的 type 分别为 default、primary、info、success、warning 和 error。'
-  },
-  {
-    id: 1,
-    label: '次要按钮',
-    buttons: [
-      {
-        id: 0,
-        props: { strong: true, secondary: true },
-        label: 'Default'
-      },
-      {
-        id: 1,
-        props: { strong: true, secondary: true, type: 'tertiary' },
-        label: 'Tertiary'
-      },
-      {
-        id: 2,
-        props: { strong: true, secondary: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 3,
-        props: { strong: true, secondary: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 4,
-        props: { strong: true, secondary: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 5,
-        props: { strong: true, secondary: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 6,
-        props: { strong: true, secondary: true, type: 'error' },
-        label: 'Error'
-      },
-      {
-        id: 7,
-        props: { strong: true, secondary: true, round: true },
-        label: 'Default'
-      },
-      {
-        id: 8,
-        props: { strong: true, secondary: true, round: true, type: 'tertiary' },
-        label: 'Tertiary'
-      },
-      {
-        id: 9,
-        props: { strong: true, secondary: true, round: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 10,
-        props: { strong: true, secondary: true, round: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 11,
-        props: { strong: true, secondary: true, round: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 12,
-        props: { strong: true, secondary: true, round: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 13,
-        props: { strong: true, secondary: true, round: true, type: 'error' },
-        label: 'Error'
-      }
-    ]
-  },
-  {
-    id: 2,
-    label: '次次要按钮',
-    buttons: [
-      {
-        id: 0,
-        props: { tertiary: true },
-        label: 'Default'
-      },
-      {
-        id: 1,
-        props: { tertiary: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 2,
-        props: { tertiary: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 3,
-        props: { tertiary: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 4,
-        props: { tertiary: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 5,
-        props: { tertiary: true, type: 'error' },
-        label: 'Error'
-      },
-      {
-        id: 6,
-        props: { tertiary: true, round: true },
-        label: 'Default'
-      },
-      {
-        id: 7,
-        props: { tertiary: true, round: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 8,
-        props: { tertiary: true, round: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 9,
-        props: { tertiary: true, round: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 10,
-        props: { tertiary: true, round: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 11,
-        props: { tertiary: true, round: true, type: 'error' },
-        label: 'Error'
-      }
-    ]
-  },
-  {
-    id: 3,
-    label: '次次次要按钮',
-    buttons: [
-      {
-        id: 0,
-        props: { quaternary: true },
-        label: 'Default'
-      },
-      {
-        id: 1,
-        props: { quaternary: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 2,
-        props: { quaternary: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 3,
-        props: { quaternary: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 4,
-        props: { quaternary: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 5,
-        props: { quaternary: true, type: 'error' },
-        label: 'Error'
-      },
-      {
-        id: 6,
-        props: { quaternary: true, round: true },
-        label: 'Default'
-      },
-      {
-        id: 7,
-        props: { quaternary: true, round: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 8,
-        props: { quaternary: true, round: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 9,
-        props: { quaternary: true, round: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 10,
-        props: { quaternary: true, round: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 11,
-        props: { quaternary: true, round: true, type: 'error' },
-        label: 'Error'
-      }
-    ]
-  },
-  {
-    id: 4,
-    label: '虚线按钮',
-    buttons: [
-      {
-        id: 0,
-        props: { dashed: true },
-        label: 'Default'
-      },
-      {
-        id: 1,
-        props: { dashed: true, type: 'tertiary' },
-        label: 'Tertiary'
-      },
-      {
-        id: 2,
-        props: { dashed: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 3,
-        props: { dashed: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 4,
-        props: { dashed: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 5,
-        props: { dashed: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 6,
-        props: { dashed: true, type: 'error' },
-        label: 'Error'
-      }
-    ]
-  },
-  {
-    id: 5,
-    label: '尺寸',
-    buttons: [
-      {
-        id: 0,
-        props: { size: 'tiny', strong: true },
-        label: '小小'
-      },
-      {
-        id: 1,
-        props: { size: 'small', strong: true },
-        label: '小'
-      },
-      {
-        id: 2,
-        props: { size: 'medium', strong: true },
-        label: '不小'
-      },
-      {
-        id: 3,
-        props: { size: 'large', strong: true },
-        label: '不不小'
-      }
-    ]
-  },
-  {
-    id: 6,
-    label: '文本按钮',
-    buttons: [
-      {
-        id: 0,
-        props: { text: true },
-        label: '那车头依然吐着烟',
-        icon: 'mdi:train'
-      }
-    ]
-  },
-  {
-    id: 7,
-    label: '自定义标签按钮',
-    buttons: [
-      {
-        id: 0,
-        props: {
-          text: true,
-          tag: 'a',
-          href: 'https://github.com/honghuangdc/soybean-admin',
-          target: '_blank',
-          type: 'primary'
-        },
-        label: 'soybean-admin'
-      }
-    ],
-    desc: '你可以把按钮渲染成不同的标签,比如 a标签 。'
-  },
-  {
-    id: 8,
-    label: '按钮禁用',
-    buttons: [
-      {
-        id: 0,
-        props: {
-          disabled: true
-        },
-        label: '不许点'
-      }
-    ],
-    desc: '按钮可以被禁用'
-  },
-  {
-    id: 9,
-    label: '图标按钮',
-    buttons: [
-      {
-        id: 0,
-        props: {
-          secondary: true,
-          strong: true
-        },
-        label: '+100元',
-        icon: 'mdi:cash-100'
-      },
-      {
-        id: 0,
-        props: {
-          iconPlacement: 'right',
-          secondary: true,
-          strong: true
-        },
-        label: '+100元',
-        icon: 'mdi:cash-100'
-      }
-    ],
-    desc: '在按钮上使用图标。'
-  },
-  {
-    id: 10,
-    label: '不同形状按钮',
-    buttons: [
-      {
-        id: 0,
-        props: {
-          circle: true
-        },
-        icon: 'mdi:cash-100'
-      },
-      {
-        id: 1,
-        props: {
-          round: true
-        },
-        label: '圆角'
-      },
-      {
-        id: 2,
-        props: {},
-        label: '方'
-      }
-    ],
-    desc: '按钮拥有不同的形状。'
-  },
-  {
-    id: 11,
-    label: '透明背景按钮',
-    buttons: [
-      {
-        id: 0,
-        props: { ghost: true },
-        label: 'Default'
-      },
-      {
-        id: 1,
-        props: { ghost: true, type: 'tertiary' },
-        label: 'Tertiary'
-      },
-      {
-        id: 2,
-        props: { ghost: true, type: 'primary' },
-        label: 'Primary'
-      },
-      {
-        id: 3,
-        props: { ghost: true, type: 'info' },
-        label: 'Info'
-      },
-      {
-        id: 4,
-        props: { ghost: true, type: 'success' },
-        label: 'Success'
-      },
-      {
-        id: 5,
-        props: { ghost: true, type: 'warning' },
-        label: 'Warning'
-      },
-      {
-        id: 6,
-        props: { ghost: true, type: 'error' },
-        label: 'Error'
-      }
-    ],
-    desc: 'Ghost 按钮有透明的背景。'
-  },
-  {
-    id: 12,
-    label: '自定义颜色',
-    buttons: [
-      {
-        id: 0,
-        props: {
-          color: '#8a2be2'
-        },
-        label: '#8a2be2',
-        icon: 'ic:baseline-color-lens'
-      },
-      {
-        id: 1,
-        props: {
-          color: '#ff69b4'
-        },
-        label: '#ff69b4',
-        icon: 'ic:baseline-color-lens'
-      },
-      {
-        id: 2,
-        props: {
-          color: '#8a2be2',
-          ghost: true
-        },
-        label: '#8a2be2',
-        icon: 'ic:baseline-color-lens'
-      },
-      {
-        id: 3,
-        props: {
-          color: '#ff69b4',
-          ghost: true
-        },
-        label: '#ff69b4',
-        icon: 'ic:baseline-color-lens'
-      },
-      {
-        id: 4,
-        props: {
-          color: '#8a2be2',
-          text: true
-        },
-        label: '#8a2be2',
-        icon: 'ic:baseline-color-lens'
-      },
-      {
-        id: 5,
-        props: {
-          color: '#ff69b4',
-          text: true
-        },
-        label: '#ff69b4',
-        icon: 'ic:baseline-color-lens'
-      }
-    ],
-    desc: '这两个颜色看起来像毒蘑菇。'
-  }
-];
-</script>
-
-<style scoped></style>

+ 0 - 42
src/views/component/card/index.vue

@@ -1,42 +0,0 @@
-<template>
-  <div>
-    <n-card title="卡片" class="h-full shadow-sm rounded-16px">
-      <n-space :vertical="true">
-        <n-card title="基本用法">
-          <p class="pb-16px">基础卡片</p>
-          <n-card title="卡片">卡片内容</n-card>
-        </n-card>
-        <n-card title="尺寸">
-          <p class="pb-16px">卡片有 small、medium、large、huge 尺寸。</p>
-          <n-space vertical>
-            <n-card title="小卡片" size="small">卡片内容</n-card>
-            <n-card title="中卡片" size="medium">卡片内容</n-card>
-            <n-card title="大卡片" size="large">卡片内容</n-card>
-            <n-card title="超大卡片" size="huge">卡片内容</n-card>
-          </n-space>
-        </n-card>
-        <n-card title="文本按钮">
-          <p class="pb-16px">
-            content 和 footer 可以被 hard 或 soft 分段,action 可以被分段。分段分割线会在区域的上方出现。
-          </p>
-          <n-card
-            title="卡片分段示例"
-            :segmented="{
-              content: true,
-              footer: 'soft'
-            }"
-          >
-            <template #header-extra>#header-extra</template>
-            卡片内容
-            <template #footer>#footer</template>
-            <template #action>#action</template>
-          </n-card>
-        </n-card>
-      </n-space>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts"></script>
-
-<style scoped></style>

+ 0 - 107
src/views/component/table/index.vue

@@ -1,107 +0,0 @@
-<template>
-  <div class="h-full overflow-hidden">
-    <n-card title="表格" class="h-full shadow-sm rounded-16px">
-      <n-space :vertical="true">
-        <n-space>
-          <n-button @click="getDataSource">有数据</n-button>
-          <n-button @click="getEmptyDataSource">空数据</n-button>
-        </n-space>
-        <loading-empty-wrapper class="h-480px" :loading="loading" :empty="empty">
-          <n-data-table :columns="columns" :data="dataSource" :flex-height="true" class="h-480px" />
-        </loading-empty-wrapper>
-      </n-space>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="tsx">
-import { onMounted, ref } from 'vue';
-import { NSpace, NButton, NPopconfirm } from 'naive-ui';
-import type { DataTableColumn } from 'naive-ui';
-import { useLoadingEmpty } from '@/hooks';
-import { getRandomInteger } from '@/utils';
-
-interface DataSource {
-  name: string;
-  age: number;
-  address: string;
-}
-
-const { loading, startLoading, endLoading, empty, setEmpty } = useLoadingEmpty();
-
-const columns: DataTableColumn[] = [
-  {
-    title: 'Name',
-    key: 'name',
-    align: 'center'
-  },
-  {
-    title: 'Age',
-    key: 'age',
-    align: 'center'
-  },
-  {
-    title: 'Address',
-    key: 'address',
-    align: 'center'
-  },
-  {
-    key: 'action',
-    title: 'Action',
-    align: 'center',
-    render: () => {
-      return (
-        <NSpace justify={'center'}>
-          <NButton size={'small'} onClick={() => {}}>
-            编辑
-          </NButton>
-          <NPopconfirm onPositiveClick={() => {}}>
-            {{
-              default: () => '确认删除',
-              trigger: () => <NButton size={'small'}>删除</NButton>
-            }}
-          </NPopconfirm>
-        </NSpace>
-      );
-    }
-  }
-];
-
-const dataSource = ref<DataSource[]>([]);
-
-function createDataSource(): DataSource[] {
-  return Array(100)
-    .fill(1)
-    .map((_item, index) => {
-      return {
-        name: `Name${index}`,
-        age: getRandomInteger(30, 20),
-        address: '中国'
-      };
-    });
-}
-
-function getDataSource() {
-  startLoading();
-  setTimeout(() => {
-    dataSource.value = createDataSource();
-    endLoading();
-    setEmpty(!dataSource.value.length);
-  }, 1000);
-}
-
-function getEmptyDataSource() {
-  startLoading();
-  setTimeout(() => {
-    dataSource.value = [];
-    endLoading();
-    setEmpty(!dataSource.value.length);
-  }, 1000);
-}
-
-onMounted(() => {
-  getDataSource();
-});
-</script>
-
-<style scoped></style>

+ 0 - 43
src/views/crud/demo/api.ts

@@ -1,43 +0,0 @@
-import type { UserPageQuery } from '@fast-crud/fast-crud';
-import { mockRequest } from '@/service/request';
-
-const request = mockRequest;
-const apiPrefix = '/crud/demo';
-
-export type DemoRecord = {
-  id: number;
-  [key: string]: any;
-};
-
-function resHandle(res: any) {
-  return res.data;
-}
-export async function GetList(query: UserPageQuery) {
-  const res = await request.post(`${apiPrefix}/page`, query);
-  return resHandle(res);
-}
-
-export async function AddObj(obj: DemoRecord) {
-  const res = await request.post(`${apiPrefix}/add`, obj);
-  return resHandle(res);
-}
-
-export async function UpdateObj(obj: DemoRecord) {
-  const res = await request.post(`${apiPrefix}/update`, obj);
-  return resHandle(res);
-}
-
-export async function DelObj(id: number) {
-  const res = await request.post(`${apiPrefix}/delete`, { id });
-  return resHandle(res);
-}
-
-export async function GetObj(id: number) {
-  const res = await request.get(`${apiPrefix}/info`, { params: { id } });
-  return resHandle(res);
-}
-
-export async function BatchDelete(ids: number[]) {
-  const res = await request.post(`${apiPrefix}/batchDelete`, { ids });
-  return resHandle(res);
-}

+ 0 - 113
src/views/crud/demo/crud.tsx

@@ -1,113 +0,0 @@
-import type { AddReq, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from '@fast-crud/fast-crud';
-import { dict } from '@fast-crud/fast-crud';
-import dayjs from 'dayjs';
-import * as api from './api';
-
-export default function createCrudOptions(): CreateCrudOptionsRet {
-  const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
-    return api.GetList(query);
-  };
-  const editRequest = async (ctx: EditReq) => {
-    const { form, row } = ctx;
-    form.id = row.id;
-    return api.UpdateObj(form);
-  };
-  const delRequest = async (ctx: DelReq) => {
-    const { row } = ctx;
-    return api.DelObj(row.id);
-  };
-
-  const addRequest = async (req: AddReq) => {
-    const { form } = req;
-    return api.AddObj(form);
-  };
-  return {
-    crudOptions: {
-      container: {
-        is: 'fs-layout-card'
-      },
-      request: {
-        pageRequest,
-        addRequest,
-        editRequest,
-        delRequest
-      },
-      columns: {
-        id: {
-          title: 'ID',
-          key: 'id',
-          type: 'number',
-          column: {
-            width: 50
-          },
-          form: {
-            show: false
-          }
-        },
-        datetime: {
-          title: '时间',
-          type: 'datetime',
-          // naive 默认仅支持数字类型时间戳作为日期输入与输出
-          // 字符串类型的时间需要转换格式
-          valueBuilder(context) {
-            const { value, row, key } = context;
-            if (value) {
-              // naive 默认仅支持时间戳作为日期输入与输出
-              row[key] = dayjs(value).valueOf();
-            }
-          },
-          valueResolve(context) {
-            const { value, form, key } = context;
-            if (value) {
-              form[key] = dayjs(value).format('YYYY-MM-DD HH:mm:ss');
-            }
-          }
-        },
-        select: {
-          search: { show: true },
-          type: 'dict-select',
-          dict: dict({
-            url: '/mock/crud/demo/dict'
-          })
-        },
-        text: {
-          title: '文本',
-          type: 'text',
-          search: { show: true }
-        },
-        copyable: {
-          title: '可复制',
-          type: ['text', 'copyable'],
-          search: { show: true }
-        },
-        avatar: {
-          title: '头像裁剪',
-          type: 'cropper-uploader'
-        },
-        upload: {
-          title: '文件上传',
-          type: 'file-uploader'
-        },
-        richtext: {
-          title: '富文本',
-          type: 'editor-wang5',
-          column: {
-            // cell中不显示
-            show: false
-          },
-          form: {
-            col: {
-              // 横跨两列
-              span: 24
-            },
-            component: {
-              style: {
-                height: '300px'
-              }
-            }
-          }
-        }
-      }
-    }
-  };
-}

+ 0 - 28
src/views/crud/demo/index.vue

@@ -1,28 +0,0 @@
-<template>
-  <div class="h-full">
-    <fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
-  </div>
-</template>
-
-<script lang="ts">
-import { defineComponent, onMounted } from 'vue';
-import { useFs } from '@fast-crud/fast-crud';
-import createCrudOptions from './crud';
-
-export default defineComponent({
-  name: 'ComponentCrud',
-  setup() {
-    const { crudRef, crudBinding, crudExpose } = useFs({ createCrudOptions });
-
-    // 页面打开后获取列表数据
-    onMounted(() => {
-      crudExpose.doRefresh();
-    });
-
-    return {
-      crudBinding,
-      crudRef
-    };
-  }
-});
-</script>

+ 0 - 13
src/views/crud/doc/index.vue

@@ -1,13 +0,0 @@
-<template>
-  <div class="h-full">
-    <iframe class="wh-full" :src="src"></iframe>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-const src = ref('http://fast-crud.docmirror.cn/');
-</script>
-
-<style scoped></style>

+ 0 - 43
src/views/crud/header_group/api.ts

@@ -1,43 +0,0 @@
-import type { UserPageQuery } from '@fast-crud/fast-crud';
-import { mockRequest } from '@/service/request';
-
-const request = mockRequest;
-const apiPrefix = '/crud/header-group';
-
-export type HeaderGroupRecord = {
-  id: number;
-  [key: string]: any;
-};
-
-function resHandle(res: any) {
-  return res.data;
-}
-export async function GetList(query: UserPageQuery) {
-  const res = await request.post(`${apiPrefix}/page`, query);
-  return resHandle(res);
-}
-
-export async function AddObj(obj: HeaderGroupRecord) {
-  const res = await request.post(`${apiPrefix}/add`, obj);
-  return resHandle(res);
-}
-
-export async function UpdateObj(obj: HeaderGroupRecord) {
-  const res = await request.post(`${apiPrefix}/update`, obj);
-  return resHandle(res);
-}
-
-export async function DelObj(id: number) {
-  const res = await request.post(`${apiPrefix}/delete`, { id });
-  return resHandle(res);
-}
-
-export async function GetObj(id: number) {
-  const res = await request.get(`${apiPrefix}/info`, { params: { id } });
-  return resHandle(res);
-}
-
-export async function BatchDelete(ids: number[]) {
-  const res = await request.post(`${apiPrefix}/batchDelete`, { ids });
-  return resHandle(res);
-}

+ 0 - 96
src/views/crud/header_group/crud.tsx

@@ -1,96 +0,0 @@
-import type { CreateCrudOptionsRet, UserPageQuery, UserPageRes } from '@fast-crud/fast-crud';
-import type { HeaderGroupRecord } from './api';
-import * as api from './api';
-
-export default function createCrudOptions(): CreateCrudOptionsRet {
-  const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
-    return api.GetList(query);
-  };
-  const editRequest = async (ctx: { form: HeaderGroupRecord; row: HeaderGroupRecord }) => {
-    const { form, row } = ctx;
-    form.id = row.id;
-    return api.UpdateObj(form);
-  };
-  const delRequest = async (ctx: { row: HeaderGroupRecord }) => {
-    const { row } = ctx;
-    return api.DelObj(row.id);
-  };
-
-  const addRequest = async (ctx: { form: HeaderGroupRecord }) => {
-    const { form } = ctx;
-    return api.AddObj(form);
-  };
-  return {
-    crudOptions: {
-      container: {
-        // is: 'fs-layout-card'
-      },
-      request: {
-        pageRequest,
-        addRequest,
-        editRequest,
-        delRequest
-      },
-      form: {
-        layout: 'flex',
-        labelWidth: '100px' // 表单label宽度
-      },
-      table: { size: 'small' },
-      columns: {
-        id: {
-          title: 'ID',
-          key: 'id',
-          type: 'number',
-          column: {
-            width: 50
-          },
-          form: {
-            show: false
-          }
-        },
-        user: {
-          title: '用户信息',
-          children: {
-            name: {
-              title: '姓名',
-              type: 'text'
-            },
-            age: {
-              title: '年龄',
-              type: 'number'
-            }
-          }
-        },
-        address: {
-          title: '地址',
-          children: {
-            area: {
-              title: '地区',
-              children: {
-                province: {
-                  title: '省',
-                  type: 'text',
-                  search: { show: true }
-                },
-                city: {
-                  title: '市',
-                  search: { show: true },
-                  type: 'text'
-                },
-                county: {
-                  title: '区',
-                  search: { show: true },
-                  type: 'text'
-                }
-              }
-            },
-            street: {
-              title: '街道',
-              type: 'text'
-            }
-          }
-        }
-      }
-    }
-  };
-}

+ 0 - 32
src/views/crud/header_group/index.vue

@@ -1,32 +0,0 @@
-<template>
-  <div class="h-full fs-page-header-group">
-    <fs-crud ref="crudRef" v-bind="crudBinding" />
-  </div>
-</template>
-
-<script lang="ts">
-import { defineComponent, onMounted } from 'vue';
-import { useFs } from '@fast-crud/fast-crud';
-import createCrudOptions from './crud';
-
-export default defineComponent({
-  name: 'CrudHeaderGroup',
-  setup() {
-    const { crudRef, crudBinding, crudExpose } = useFs({ createCrudOptions });
-
-    // 页面打开后获取列表数据
-    onMounted(() => {
-      crudExpose.doRefresh();
-    });
-
-    return {
-      crudBinding,
-      crudRef
-    };
-  }
-});
-</script>
-<style lang="scss">
-.fs-page-header-group {
-}
-</style>

+ 0 - 13
src/views/crud/source/index.vue

@@ -1,13 +0,0 @@
-<template>
-  <div class="h-full">
-    <iframe class="wh-full" :src="src"></iframe>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-const src = ref('https://github.com/fast-crud/fast-crud');
-</script>
-
-<style scoped></style>

+ 0 - 136
src/views/dashboard/analysis/components/bottom-part/index.vue

@@ -1,136 +0,0 @@
-<template>
-  <n-grid :x-gap="16" :y-gap="16" :item-responsive="true">
-    <n-grid-item span="0:24 640:24 1024:8">
-      <n-card title="时间线" :bordered="false" class="h-full rounded-16px shadow-sm">
-        <n-timeline>
-          <n-timeline-item v-for="item in timelines" :key="item.type" v-bind="item" />
-        </n-timeline>
-      </n-card>
-    </n-grid-item>
-    <n-grid-item span="0:24 640:24 1024:16">
-      <n-card title="表格" :bordered="false" class="h-full rounded-16px shadow-sm">
-        <n-data-table size="small" :columns="columns" :data="tableData" />
-      </n-card>
-    </n-grid-item>
-  </n-grid>
-</template>
-
-<script setup lang="ts">
-import { h } from 'vue';
-import { NTag } from 'naive-ui';
-
-defineOptions({ name: 'DashboardAnalysisBottomPart' });
-
-interface TimelineData {
-  type: 'default' | 'info' | 'success' | 'warning' | 'error';
-  title: string;
-  content: string;
-  time: string;
-}
-
-interface TableData {
-  key: number;
-  name: string;
-  age: number;
-  address: string;
-  tags: string[];
-}
-
-const timelines: TimelineData[] = [
-  { type: 'default', title: '啊', content: '', time: '2021-10-10 20:46' },
-  { type: 'success', title: '成功', content: '哪里成功', time: '2021-10-10 20:46' },
-  { type: 'error', title: '错误', content: '哪里错误', time: '2021-10-10 20:46' },
-  { type: 'warning', title: '警告', content: '哪里警告', time: '2021-10-10 20:46' },
-  { type: 'info', title: '信息', content: '是的', time: '2021-10-10 20:46' }
-];
-
-const columns = [
-  {
-    title: 'Name',
-    key: 'name'
-  },
-  {
-    title: 'Age',
-    key: 'age'
-  },
-  {
-    title: 'Address',
-    key: 'address'
-  },
-  {
-    title: 'Tags',
-    key: 'tags',
-    render(row: TableData) {
-      const tags = row.tags.map(tagKey => {
-        return h(
-          NTag,
-          {
-            style: {
-              marginRight: '6px'
-            },
-            type: 'info'
-          },
-          {
-            default: () => tagKey
-          }
-        );
-      });
-      return tags;
-    }
-  }
-];
-
-const tableData: TableData[] = [
-  {
-    key: 0,
-    name: 'John Brown',
-    age: 32,
-    address: 'New York No. 1 Lake Park',
-    tags: ['nice', 'developer']
-  },
-  {
-    key: 1,
-    name: 'Jim Green',
-    age: 42,
-    address: 'London No. 1 Lake Park',
-    tags: ['wow']
-  },
-  {
-    key: 2,
-    name: 'Joe Black',
-    age: 32,
-    address: 'Sidney No. 1 Lake Park',
-    tags: ['cool', 'teacher']
-  },
-  {
-    key: 3,
-    name: 'Soybean',
-    age: 25,
-    address: 'China Shenzhen',
-    tags: ['handsome', 'programmer']
-  },
-  {
-    key: 4,
-    name: 'John Brown',
-    age: 32,
-    address: 'New York No. 1 Lake Park',
-    tags: ['nice', 'developer']
-  },
-  {
-    key: 5,
-    name: 'Jim Green',
-    age: 42,
-    address: 'London No. 1 Lake Park',
-    tags: ['wow']
-  },
-  {
-    key: 6,
-    name: 'Joe Black',
-    age: 32,
-    address: 'Sidney No. 1 Lake Park',
-    tags: ['cool', 'teacher']
-  }
-];
-</script>
-
-<style scoped></style>

+ 0 - 25
src/views/dashboard/analysis/components/data-card/components/gradient-bg.vue

@@ -1,25 +0,0 @@
-<template>
-  <div class="p-16px rounded-16px text-white" :style="{ backgroundImage: gradientStyle }">
-    <slot></slot>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { computed } from 'vue';
-
-interface Props {
-  /** 渐变开始的颜色 */
-  startColor?: string;
-  /** 渐变结束的颜色 */
-  endColor?: string;
-}
-
-const props = withDefaults(defineProps<Props>(), {
-  startColor: '#56cdf3',
-  endColor: '#719de3'
-});
-
-const gradientStyle = computed(() => `linear-gradient(to bottom right, ${props.startColor}, ${props.endColor})`);
-</script>
-
-<style scoped></style>

+ 0 - 3
src/views/dashboard/analysis/components/data-card/components/index.ts

@@ -1,3 +0,0 @@
-import GradientBg from './gradient-bg.vue';
-
-export { GradientBg };

+ 0 - 70
src/views/dashboard/analysis/components/data-card/index.vue

@@ -1,70 +0,0 @@
-<template>
-  <n-grid cols="s:1 m:2 l:4" responsive="screen" :x-gap="16" :y-gap="16">
-    <n-grid-item v-for="item in cardData" :key="item.id">
-      <gradient-bg class="h-100px" :start-color="item.colors[0]" :end-color="item.colors[1]">
-        <h3 class="text-16px">{{ item.title }}</h3>
-        <div class="flex justify-between pt-12px">
-          <svg-icon :icon="item.icon" class="text-32px" />
-          <count-to
-            :prefix="item.unit"
-            :start-value="1"
-            :end-value="item.value"
-            class="text-30px text-white dark:text-dark"
-          />
-        </div>
-      </gradient-bg>
-    </n-grid-item>
-  </n-grid>
-</template>
-
-<script setup lang="ts">
-import { GradientBg } from './components';
-
-defineOptions({ name: 'DashboardAnalysisDataCard' });
-
-interface CardData {
-  id: string;
-  title: string;
-  value: number;
-  unit: string;
-  colors: [string, string];
-  icon: string;
-}
-
-const cardData: CardData[] = [
-  {
-    id: 'visit',
-    title: '访问量',
-    value: 1000000,
-    unit: '',
-    colors: ['#ec4786', '#b955a4'],
-    icon: 'ant-design:bar-chart-outlined'
-  },
-  {
-    id: 'amount',
-    title: '成交额',
-    value: 234567.89,
-    unit: '$',
-    colors: ['#865ec0', '#5144b4'],
-    icon: 'ant-design:money-collect-outlined'
-  },
-  {
-    id: 'download',
-    title: '下载数',
-    value: 666666,
-    unit: '',
-    colors: ['#56cdf3', '#719de3'],
-    icon: 'carbon:document-download'
-  },
-  {
-    id: 'trade',
-    title: '成交数',
-    value: 999999,
-    unit: '',
-    colors: ['#fcbc25', '#f68057'],
-    icon: 'ant-design:trademark-circle-outlined'
-  }
-];
-</script>
-
-<style scoped></style>

+ 0 - 5
src/views/dashboard/analysis/components/index.ts

@@ -1,5 +0,0 @@
-import TopChart from './top-chart/index.vue';
-import DataCard from './data-card/index.vue';
-import BottomPart from './bottom-part/index.vue';
-
-export { TopChart, DataCard, BottomPart };

+ 0 - 184
src/views/dashboard/analysis/components/top-chart/index.vue

@@ -1,184 +0,0 @@
-<template>
-  <n-grid :x-gap="16" :y-gap="16" :item-responsive="true">
-    <n-grid-item span="0:24 640:24 1024:6">
-      <n-card :bordered="false" class="rounded-16px shadow-sm">
-        <div class="w-full h-360px py-12px">
-          <h3 class="text-16px font-bold">Dashboard</h3>
-          <p class="text-#aaa">Overview Of Lasted Month</p>
-          <h3 class="pt-32px text-24px font-bold">
-            <count-to prefix="$" :start-value="0" :end-value="7754" />
-          </h3>
-          <p class="text-#aaa">Current Month Earnings</p>
-          <h3 class="pt-32px text-24px font-bold">
-            <count-to :start-value="0" :end-value="1234" />
-          </h3>
-          <p class="text-#aaa">Current Month Sales</p>
-          <n-button class="mt-24px whitespace-pre-wrap" type="primary">Last Month Summary</n-button>
-        </div>
-      </n-card>
-    </n-grid-item>
-    <n-grid-item span="0:24 640:24 1024:10">
-      <n-card :bordered="false" class="rounded-16px shadow-sm">
-        <div ref="lineRef" class="w-full h-360px"></div>
-      </n-card>
-    </n-grid-item>
-    <n-grid-item span="0:24 640:24 1024:8">
-      <n-card :bordered="false" class="rounded-16px shadow-sm">
-        <div ref="pieRef" class="w-full h-360px"></div>
-      </n-card>
-    </n-grid-item>
-  </n-grid>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-import type { Ref } from 'vue';
-import { type ECOption, useEcharts } from '@/composables';
-
-defineOptions({ name: 'DashboardAnalysisTopCard' });
-
-const lineOptions = ref<ECOption>({
-  tooltip: {
-    trigger: 'axis',
-    axisPointer: {
-      type: 'cross',
-      label: {
-        backgroundColor: '#6a7985'
-      }
-    }
-  },
-  legend: {
-    data: ['下载量', '注册数']
-  },
-  grid: {
-    left: '3%',
-    right: '4%',
-    bottom: '3%',
-    containLabel: true
-  },
-  xAxis: [
-    {
-      type: 'category',
-      boundaryGap: false,
-      data: ['06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00', '22:00', '24:00']
-    }
-  ],
-  yAxis: [
-    {
-      type: 'value'
-    }
-  ],
-  series: [
-    {
-      color: '#8e9dff',
-      name: '下载量',
-      type: 'line',
-      smooth: true,
-      stack: 'Total',
-      areaStyle: {
-        color: {
-          type: 'linear',
-          x: 0,
-          y: 0,
-          x2: 0,
-          y2: 1,
-          colorStops: [
-            {
-              offset: 0.25,
-              color: '#8e9dff'
-            },
-            {
-              offset: 1,
-              color: '#fff'
-            }
-          ]
-        }
-      },
-      emphasis: {
-        focus: 'series'
-      },
-      data: [4623, 6145, 6268, 6411, 1890, 4251, 2978, 3880, 3606, 4311]
-    },
-    {
-      color: '#26deca',
-      name: '注册数',
-      type: 'line',
-      smooth: true,
-      stack: 'Total',
-      areaStyle: {
-        color: {
-          type: 'linear',
-          x: 0,
-          y: 0,
-          x2: 0,
-          y2: 1,
-          colorStops: [
-            {
-              offset: 0.25,
-              color: '#26deca'
-            },
-            {
-              offset: 1,
-              color: '#fff'
-            }
-          ]
-        }
-      },
-      emphasis: {
-        focus: 'series'
-      },
-      data: [2208, 2016, 2916, 4512, 8281, 2008, 1963, 2367, 2956, 678]
-    }
-  ]
-}) as Ref<ECOption>;
-const { domRef: lineRef } = useEcharts(lineOptions);
-
-const pieOptions = ref<ECOption>({
-  tooltip: {
-    trigger: 'item'
-  },
-  legend: {
-    bottom: '1%',
-    left: 'center',
-    itemStyle: {
-      borderWidth: 0
-    }
-  },
-  series: [
-    {
-      color: ['#5da8ff', '#8e9dff', '#fedc69', '#26deca'],
-      name: '时间安排',
-      type: 'pie',
-      radius: ['45%', '75%'],
-      avoidLabelOverlap: false,
-      itemStyle: {
-        borderRadius: 10,
-        borderColor: '#fff',
-        borderWidth: 1
-      },
-      label: {
-        show: false,
-        position: 'center'
-      },
-      emphasis: {
-        label: {
-          show: true,
-          fontSize: '12'
-        }
-      },
-      labelLine: {
-        show: false
-      },
-      data: [
-        { value: 20, name: '学习' },
-        { value: 10, name: '娱乐' },
-        { value: 30, name: '工作' },
-        { value: 40, name: '休息' }
-      ]
-    }
-  ]
-}) as Ref<ECOption>;
-const { domRef: pieRef } = useEcharts(pieOptions);
-</script>
-
-<style scoped></style>

+ 0 - 14
src/views/dashboard/analysis/index.vue

@@ -1,14 +0,0 @@
-<template>
-  <n-space :vertical="true" :size="16">
-    <top-chart />
-    <data-card />
-    <div></div>
-    <bottom-part />
-  </n-space>
-</template>
-
-<script lang="ts" setup>
-import { BottomPart, DataCard, TopChart } from './components';
-</script>
-
-<style scoped></style>

+ 0 - 13
src/views/document/naive/index.vue

@@ -1,13 +0,0 @@
-<template>
-  <div class="h-full">
-    <iframe class="wh-full" :src="src"></iframe>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-const src = ref('https://www.naiveui.com/zh-CN/os-theme/docs/introduction');
-</script>
-
-<style scoped></style>

+ 0 - 7
src/views/document/project-link/index.vue

@@ -1,7 +0,0 @@
-<template>
-  <div></div>
-</template>
-
-<script setup lang="ts"></script>
-
-<style scoped></style>

+ 0 - 13
src/views/document/project/index.vue

@@ -1,13 +0,0 @@
-<template>
-  <div class="h-full">
-    <iframe class="wh-full" :src="src"></iframe>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-const src = ref('https://docs.soybean.pro/');
-</script>
-
-<style scoped></style>

+ 0 - 13
src/views/document/vite/index.vue

@@ -1,13 +0,0 @@
-<template>
-  <div class="h-full">
-    <iframe class="wh-full" :src="src"></iframe>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-const src = ref('https://cn.vitejs.dev/');
-</script>
-
-<style scoped></style>

+ 0 - 13
src/views/document/vue/index.vue

@@ -1,13 +0,0 @@
-<template>
-  <div class="h-full">
-    <iframe class="wh-full" :src="src"></iframe>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-
-const src = ref('https://v3.cn.vuejs.org/');
-</script>
-
-<style scoped></style>

+ 0 - 27
src/views/function/tab-detail/index.vue

@@ -1,27 +0,0 @@
-<template>
-  <n-space :vertical="true" :size="16">
-    <n-card title="Tab Detail" :bordered="false" size="small" class="shadow-sm rounded-16px">
-      <n-space :vertical="true" :size="12">
-        <div>当前路由的描述数据(meta):</div>
-        <div>{{ route.meta }}</div>
-        <n-button @click="handleToTab">返回Tab</n-button>
-      </n-space>
-    </n-card>
-  </n-space>
-</template>
-
-<script setup lang="ts">
-import { useRoute } from 'vue-router';
-import { routeName } from '@/router';
-import { useRouterPush } from '@/composables';
-
-const { routerPush } = useRouterPush();
-
-const route = useRoute();
-
-function handleToTab() {
-  routerPush({ name: routeName('function_tab') });
-}
-</script>
-
-<style scoped></style>

+ 0 - 28
src/views/function/tab-multi-detail/index.vue

@@ -1,28 +0,0 @@
-<template>
-  <n-space :vertical="true" :size="16">
-    <n-card title="Tab Detail" :bordered="false" size="small" class="shadow-sm rounded-16px">
-      <n-space :vertical="true" :size="12">
-        <div>当前路由的描述数据(meta):</div>
-        <div>{{ route.meta }}</div>
-        <div>当前路由的查询数据(query):</div>
-        <div>{{ route.query }}</div>
-        <n-button @click="handleToTab">返回Tab</n-button>
-      </n-space>
-    </n-card>
-  </n-space>
-</template>
-
-<script setup lang="ts">
-import { useRoute } from 'vue-router';
-import { routeName } from '@/router';
-import { useRouterPush } from '@/composables';
-
-const route = useRoute();
-const { routerPush } = useRouterPush();
-
-function handleToTab() {
-  routerPush({ name: routeName('function_tab') });
-}
-</script>
-
-<style scoped></style>

+ 0 - 44
src/views/function/tab/index.vue

@@ -1,44 +0,0 @@
-<template>
-  <n-space :vertical="true" :size="16">
-    <n-card title="Tab Home" :bordered="false" size="small" class="shadow-sm rounded-16px">
-      <n-space :vertical="true" :size="12">
-        <n-button @click="handleToTabDetail">跳转Tab Detail</n-button>
-        <n-button @click="handleToTabMultiDetail(1)">跳转Tab Multi Detail 1</n-button>
-        <n-button @click="handleToTabMultiDetail(2)">跳转Tab Multi Detail 2</n-button>
-        <n-input-group>
-          <n-input v-model:value="title" />
-          <n-button type="primary" @click="handleSetTitle">设置当前Tab页标题</n-button>
-        </n-input-group>
-      </n-space>
-    </n-card>
-  </n-space>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-import { routeName } from '@/router';
-import { useTabStore } from '@/store';
-import { useRouterPush } from '@/composables';
-
-const { routerPush } = useRouterPush();
-const tabStore = useTabStore();
-const title = ref('');
-
-function handleToTabDetail() {
-  routerPush({ name: routeName('function_tab-detail'), query: { name: 'abc' }, hash: '#DEMO_HASH' });
-}
-
-function handleToTabMultiDetail(num: number) {
-  routerPush({ name: routeName('function_tab-multi-detail'), query: { name: 'abc', num }, hash: '#DEMO_HASH' });
-}
-
-function handleSetTitle() {
-  if (!title.value) {
-    window.$message?.warning('请输入要设置的标题名称');
-  } else {
-    tabStore.setActiveTabTitle(title.value);
-  }
-}
-</script>
-
-<style scoped></style>

+ 4 - 31
src/views/index.ts

@@ -15,28 +15,13 @@ export const views: Record<
   archives_scores: () => import('./archives/scores/index.vue'),
   archives_students_component: () => import('./archives/students/component/index.vue'),
   archives_students: () => import('./archives/students/index.vue'),
-  'auth-demo_permission': () => import('./auth-demo/permission/index.vue'),
-  'auth-demo_super': () => import('./auth-demo/super/index.vue'),
-  component_button: () => import('./component/button/index.vue'),
-  component_card: () => import('./component/card/index.vue'),
-  component_table: () => import('./component/table/index.vue'),
-  crud_demo: () => import('./crud/demo/index.vue'),
-  crud_doc: () => import('./crud/doc/index.vue'),
-  crud_header_group: () => import('./crud/header_group/index.vue'),
-  crud_source: () => import('./crud/source/index.vue'),
-  dashboard_analysis: () => import('./dashboard/analysis/index.vue'),
+
   dashboard_workbench: () => import('./dashboard/workbench/index.vue'),
-  document_naive: () => import('./document/naive/index.vue'),
-  'document_project-link': () => import('./document/project-link/index.vue'),
-  document_project: () => import('./document/project/index.vue'),
-  document_vite: () => import('./document/vite/index.vue'),
-  document_vue: () => import('./document/vue/index.vue'),
+
   exception_403: () => import('./exception/403/index.vue'),
   exception_404: () => import('./exception/404/index.vue'),
   exception_500: () => import('./exception/500/index.vue'),
-  'function_tab-detail': () => import('./function/tab-detail/index.vue'),
-  'function_tab-multi-detail': () => import('./function/tab-multi-detail/index.vue'),
-  function_tab: () => import('./function/tab/index.vue'),
+
   lesson_calendar: () => import('./lesson/calendar/index.vue'),
   lesson_checkin: () => import('./lesson/checkin/index.vue'),
   lesson_classroom: () => import('./lesson/classroom/index.vue'),
@@ -50,17 +35,5 @@ export const views: Record<
   management_route: () => import('./management/route/index.vue'),
   management_sort: () => import('./management/sort/index.vue'),
   management_student: () => import('./management/student/index.vue'),
-  management_user: () => import('./management/user/index.vue'),
-  'multi-menu_first_second-new_third': () => import('./multi-menu/first/second-new/third/index.vue'),
-  'multi-menu_first_second': () => import('./multi-menu/first/second/index.vue'),
-  plugin_charts_antv: () => import('./plugin/charts/antv/index.vue'),
-  plugin_charts_echarts: () => import('./plugin/charts/echarts/index.vue'),
-  plugin_copy: () => import('./plugin/copy/index.vue'),
-  plugin_editor_markdown: () => import('./plugin/editor/markdown/index.vue'),
-  plugin_editor_quill: () => import('./plugin/editor/quill/index.vue'),
-  plugin_icon: () => import('./plugin/icon/index.vue'),
-  plugin_map: () => import('./plugin/map/index.vue'),
-  plugin_print: () => import('./plugin/print/index.vue'),
-  plugin_swiper: () => import('./plugin/swiper/index.vue'),
-  plugin_video: () => import('./plugin/video/index.vue')
+  management_user: () => import('./management/user/index.vue')
 };

+ 0 - 9
src/views/multi-menu/first/second-new/third/index.vue

@@ -1,9 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="多级菜单 - 三级菜单" class="h-full shadow-sm rounded-16px"></n-card>
-  </div>
-</template>
-
-<script setup lang="ts"></script>
-
-<style scoped></style>

+ 0 - 9
src/views/multi-menu/first/second/index.vue

@@ -1,9 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="多级菜单 - 二级菜单" class="h-full shadow-sm rounded-16px"></n-card>
-  </div>
-</template>
-
-<script setup lang="ts"></script>
-
-<style scoped></style>

+ 0 - 482
src/views/plugin/charts/antv/index.vue

@@ -1,482 +0,0 @@
-<template>
-  <n-space :vertical="true" :size="16">
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="pieRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="lineRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="barRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="scatterRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="areaRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="radarRef" class="h-400px"></div>
-    </n-card>
-  </n-space>
-</template>
-
-<script setup lang="ts">
-import { onMounted, ref } from 'vue';
-import DataSet from '@antv/data-set';
-import { Chart } from '@antv/g2';
-
-const pieRef = ref<HTMLElement>();
-const lineRef = ref<HTMLElement>();
-const barRef = ref<HTMLElement>();
-const scatterRef = ref<HTMLElement>();
-const areaRef = ref<HTMLElement>();
-const radarRef = ref<HTMLElement>();
-
-function renderPieChart() {
-  if (!pieRef.value) return;
-
-  const data = [
-    { item: 'rose 1', count: 40, percent: 0.4 },
-    { item: 'rose 2', count: 40, percent: 0.4 },
-    { item: 'rose 3', count: 40, percent: 0.4 },
-    { item: 'rose 4', count: 40, percent: 0.4 },
-    { item: 'rose 5', count: 21, percent: 0.21 },
-    { item: 'rose 6', count: 17, percent: 0.17 },
-    { item: 'rose 7', count: 13, percent: 0.13 },
-    { item: 'rose 8', count: 9, percent: 0.09 }
-  ];
-
-  const chart = new Chart({
-    container: pieRef.value,
-    autoFit: true
-  });
-
-  chart.data(data);
-
-  chart.coordinate('theta', {
-    radius: 0.85
-  });
-
-  chart.scale('percent', {
-    formatter: (val: number) => `${val * 100}%`
-  });
-  chart.tooltip({
-    showTitle: false,
-    showMarkers: false
-  });
-  chart.legend({ position: 'top' });
-  chart.axis(false); // 关闭坐标轴
-  chart
-    .interval()
-    .adjust('stack')
-    .position('percent')
-    .color('item')
-    .label('percent', {
-      offset: -40,
-      style: {
-        textAlign: 'center',
-        shadowBlur: 2,
-        shadowColor: 'rgba(0, 0, 0, .45)',
-        fill: '#fff'
-      }
-    })
-    .tooltip('item*percent', (item, percent) => {
-      return {
-        name: item,
-        value: `${percent * 100}%`
-      };
-    })
-    .style({
-      lineWidth: 1,
-      stroke: '#fff'
-    });
-  chart.interaction('element-single-selected');
-  chart.render();
-}
-
-function renderLineChart() {
-  fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/terrorism.json')
-    .then(res => res.json())
-    .then(data => {
-      const ds = new DataSet();
-      if (!lineRef.value) return;
-
-      const chart = new Chart({
-        container: lineRef.value,
-        autoFit: true,
-        syncViewPadding: true
-      });
-
-      chart.scale({
-        Deaths: {
-          sync: true,
-          nice: true
-        },
-        death: {
-          sync: true,
-          nice: true
-        }
-      });
-
-      const dv1 = ds.createView().source(data);
-      dv1.transform({
-        type: 'map',
-        callback: (row: any) => {
-          const currentRow = { ...row };
-          if (typeof row.Deaths === 'string') {
-            currentRow.Deaths = row.Deaths.replace(',', '');
-          }
-          currentRow.Deaths = parseInt(row.Deaths, 10);
-          currentRow.death = row.Deaths;
-          currentRow.year = row.Year;
-          return currentRow;
-        }
-      });
-      const view1 = chart.createView();
-      view1.data(dv1.rows);
-      view1.axis('Year', {
-        subTickLine: {
-          count: 3,
-          length: 3
-        },
-        tickLine: {
-          length: 6
-        }
-      });
-      view1.axis('Deaths', {
-        label: {
-          formatter: text => {
-            return text.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
-          }
-        }
-      });
-      view1.line().position('Year*Deaths');
-
-      const dv2 = ds.createView().source(dv1.rows);
-      dv2.transform({
-        type: 'regression',
-        method: 'polynomial',
-        fields: ['year', 'death'],
-        bandwidth: 0.1,
-        as: ['year', 'death']
-      });
-
-      const view2 = chart.createView();
-      view2.axis(false);
-      view2.data(dv2.rows);
-      view2
-        .line()
-        .position('year*death')
-        .style({
-          stroke: '#969696',
-          lineDash: [3, 3]
-        })
-        .tooltip(false);
-      view1.annotation().text({
-        content: '趋势线',
-        position: ['1970', 2500],
-        style: {
-          fill: '#8c8c8c',
-          fontSize: 14,
-          fontWeight: 300
-        },
-        offsetY: -70
-      });
-      chart.render();
-    });
-}
-
-function renderBarChart() {
-  if (!barRef.value) return;
-
-  const data = [
-    { type: '未知', value: 654, percent: 0.02 },
-    { type: '17 岁以下', value: 654, percent: 0.02 },
-    { type: '18-24 岁', value: 4400, percent: 0.2 },
-    { type: '25-29 岁', value: 5300, percent: 0.24 },
-    { type: '30-39 岁', value: 6200, percent: 0.28 },
-    { type: '40-49 岁', value: 3300, percent: 0.14 },
-    { type: '50 岁以上', value: 1500, percent: 0.06 }
-  ];
-
-  const chart = new Chart({
-    container: barRef.value,
-    autoFit: true,
-    height: 500,
-    padding: [50, 20, 50, 20]
-  });
-  chart.data(data);
-  chart.scale('value', {
-    alias: '销售额(万)'
-  });
-
-  chart.axis('type', {
-    tickLine: {
-      alignTick: false
-    }
-  });
-  chart.axis('value', false);
-
-  chart.tooltip({
-    showMarkers: false
-  });
-  chart.interval().position('type*value');
-  chart.interaction('element-active');
-
-  // 添加文本标注
-  data.forEach(item => {
-    chart
-      .annotation()
-      .text({
-        position: [item.type, item.value],
-        content: item.value,
-        style: {
-          textAlign: 'center'
-        },
-        offsetY: -30
-      })
-      .text({
-        position: [item.type, item.value],
-        content: `${(item.percent * 100).toFixed(0)}%`,
-        style: {
-          textAlign: 'center'
-        },
-        offsetY: -12
-      });
-  });
-  chart.render();
-}
-
-function renderScatterChart() {
-  const colorMap = {
-    Asia: '#1890FF',
-    Americas: '#2FC25B',
-    Europe: '#FACC14',
-    Oceania: '#223273'
-  };
-
-  fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/bubble.json')
-    .then(res => res.json())
-    .then(data => {
-      if (!scatterRef.value) return;
-      const chart = new Chart({
-        container: scatterRef.value,
-        autoFit: true,
-        height: 500
-      });
-      chart.data(data);
-      // 为各个字段设置别名
-      chart.scale({
-        LifeExpectancy: {
-          alias: '人均寿命(年)',
-          nice: true
-        },
-        Population: {
-          type: 'pow',
-          alias: '人口总数'
-        },
-        GDP: {
-          alias: '人均国内生产总值($)',
-          nice: true
-        },
-        Country: {
-          alias: '国家/地区'
-        }
-      });
-      chart.axis('GDP', {
-        label: {
-          formatter(value) {
-            return `${(Number(value) / 1000).toFixed(0)}k`;
-          } // 格式化坐标轴的显示
-        }
-      });
-      chart.tooltip({
-        showTitle: false,
-        showMarkers: false
-      });
-      chart.legend('Population', false); // 该图表默认会生成多个图例,设置不展示 Population 和 Country 两个维度的图例
-      chart
-        .point()
-        .position('GDP*LifeExpectancy')
-        .size('Population', [4, 65])
-        .color('continent', val => {
-          const key = val as keyof typeof colorMap;
-          return colorMap[key];
-        })
-        .shape('circle')
-        .tooltip('Country*Population*GDP*LifeExpectancy')
-        .style('continent', val => {
-          const key = val as keyof typeof colorMap;
-          return {
-            lineWidth: 1,
-            strokeOpacity: 1,
-            fillOpacity: 0.3,
-            opacity: 0.65,
-            stroke: colorMap[key]
-          };
-        });
-      chart.interaction('element-active');
-      chart.render();
-    });
-}
-
-function renderAreaChart() {
-  if (!areaRef.value) return;
-
-  const data = [
-    { country: 'Asia', year: '1750', value: 502 },
-    { country: 'Asia', year: '1800', value: 635 },
-    { country: 'Asia', year: '1850', value: 809 },
-    { country: 'Asia', year: '1900', value: 5268 },
-    { country: 'Asia', year: '1950', value: 4400 },
-    { country: 'Asia', year: '1999', value: 3634 },
-    { country: 'Asia', year: '2050', value: 947 },
-    { country: 'Africa', year: '1750', value: 106 },
-    { country: 'Africa', year: '1800', value: 107 },
-    { country: 'Africa', year: '1850', value: 111 },
-    { country: 'Africa', year: '1900', value: 1766 },
-    { country: 'Africa', year: '1950', value: 221 },
-    { country: 'Africa', year: '1999', value: 767 },
-    { country: 'Africa', year: '2050', value: 133 },
-    { country: 'Europe', year: '1750', value: 163 },
-    { country: 'Europe', year: '1800', value: 203 },
-    { country: 'Europe', year: '1850', value: 276 },
-    { country: 'Europe', year: '1900', value: 628 },
-    { country: 'Europe', year: '1950', value: 547 },
-    { country: 'Europe', year: '1999', value: 729 },
-    { country: 'Europe', year: '2050', value: 408 },
-    { country: 'Oceania', year: '1750', value: 200 },
-    { country: 'Oceania', year: '1800', value: 200 },
-    { country: 'Oceania', year: '1850', value: 200 },
-    { country: 'Oceania', year: '1900', value: 460 },
-    { country: 'Oceania', year: '1950', value: 230 },
-    { country: 'Oceania', year: '1999', value: 300 },
-    { country: 'Oceania', year: '2050', value: 300 }
-  ];
-  const chart = new Chart({
-    container: areaRef.value,
-    autoFit: true,
-    height: 500
-  });
-
-  chart.data(data);
-  chart.scale('year', {
-    type: 'linear',
-    tickInterval: 50
-  });
-  chart.scale('value', {
-    nice: true
-  });
-
-  chart.tooltip({
-    showCrosshairs: true,
-    shared: true
-  });
-
-  chart.area().adjust('stack').position('year*value').color('country');
-  chart.line().adjust('stack').position('year*value').color('country');
-
-  chart.interaction('element-highlight');
-
-  chart.render();
-}
-
-function renderRadarChart() {
-  if (!radarRef.value) return;
-
-  const data = [
-    { item: 'Design', a: 70, b: 30 },
-    { item: 'Development', a: 60, b: 70 },
-    { item: 'Marketing', a: 50, b: 60 },
-    { item: 'Users', a: 40, b: 50 },
-    { item: 'Test', a: 60, b: 70 },
-    { item: 'Language', a: 70, b: 50 },
-    { item: 'Technology', a: 50, b: 40 },
-    { item: 'Support', a: 30, b: 40 },
-    { item: 'Sales', a: 60, b: 40 },
-    { item: 'UX', a: 50, b: 60 }
-  ];
-  const { DataView } = DataSet;
-  const dv = new DataView().source(data);
-  dv.transform({
-    type: 'fold',
-    fields: ['a', 'b'], // 展开字段集
-    key: 'user', // key字段
-    value: 'score' // value字段
-  });
-
-  const chart = new Chart({
-    container: radarRef.value,
-    autoFit: true,
-    height: 500
-  });
-  chart.data(dv.rows);
-  chart.scale('score', {
-    min: 0,
-    max: 80
-  });
-  chart.coordinate('polar', {
-    radius: 0.8
-  });
-  chart.tooltip({
-    shared: true,
-    showCrosshairs: true,
-    crosshairs: {
-      line: {
-        style: {
-          lineDash: [4, 4],
-          stroke: '#333'
-        }
-      }
-    }
-  });
-  chart.axis('item', {
-    line: null,
-    tickLine: null,
-    grid: {
-      line: {
-        style: {
-          lineDash: null
-        }
-      }
-    }
-  });
-  chart.axis('score', {
-    line: null,
-    tickLine: null,
-    grid: {
-      line: {
-        type: 'line',
-        style: {
-          lineDash: null
-        }
-      }
-    }
-  });
-
-  chart.line().position('item*score').color('user').size(2);
-  chart.point().position('item*score').color('user').shape('circle').size(4).style({
-    stroke: '#fff',
-    lineWidth: 1,
-    fillOpacity: 1
-  });
-  chart.area().position('item*score').color('user');
-  chart.render();
-}
-
-function init() {
-  renderPieChart();
-  renderLineChart();
-  renderBarChart();
-  renderScatterChart();
-  renderAreaChart();
-  renderRadarChart();
-}
-
-onMounted(() => {
-  init();
-});
-</script>
-
-<style scoped></style>

+ 0 - 783
src/views/plugin/charts/echarts/index.vue

@@ -1,783 +0,0 @@
-<template>
-  <n-space :vertical="true" :size="16">
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="pieRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="lineRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="barRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="pictorialBarRef" class="h-600px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="scatterRef" class="h-600px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="radarRef" class="h-400px"></div>
-    </n-card>
-    <n-card :bordered="false" class="rounded-16px shadow-sm">
-      <div ref="gaugeRef" class="h-640px"></div>
-    </n-card>
-  </n-space>
-</template>
-
-<script setup lang="ts">
-import { onUnmounted, ref } from 'vue';
-import type { Ref } from 'vue';
-import { graphic } from 'echarts';
-import { type ECOption, useEcharts } from '@/composables';
-
-const pieOptions = ref<ECOption>({
-  legend: {},
-  toolbox: {
-    show: true,
-    feature: {
-      mark: { show: true },
-      dataView: { show: true, readOnly: false },
-      restore: { show: true },
-      saveAsImage: { show: true }
-    }
-  },
-  series: [
-    {
-      name: 'Nightingale Chart',
-      type: 'pie',
-      radius: [50, 150],
-      center: ['50%', '50%'],
-      roseType: 'area',
-      itemStyle: {
-        borderRadius: 8
-      },
-      data: [
-        { value: 40, name: 'rose 1' },
-        { value: 38, name: 'rose 2' },
-        { value: 32, name: 'rose 3' },
-        { value: 30, name: 'rose 4' },
-        { value: 28, name: 'rose 5' },
-        { value: 26, name: 'rose 6' },
-        { value: 22, name: 'rose 7' },
-        { value: 18, name: 'rose 8' }
-      ]
-    }
-  ]
-}) as Ref<ECOption>;
-const { domRef: pieRef } = useEcharts(pieOptions);
-
-const lineOptions = ref<ECOption>({
-  tooltip: {
-    trigger: 'axis',
-    axisPointer: {
-      type: 'cross',
-      label: {
-        backgroundColor: '#6a7985'
-      }
-    }
-  },
-  title: {
-    text: 'Stacked Line'
-  },
-  legend: {
-    data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
-  },
-  grid: {
-    left: '3%',
-    right: '4%',
-    bottom: '3%',
-    containLabel: true
-  },
-  toolbox: {
-    feature: {
-      saveAsImage: {}
-    }
-  },
-  xAxis: {
-    type: 'category',
-    boundaryGap: false,
-    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-  },
-  yAxis: {
-    type: 'value'
-  },
-  series: [
-    {
-      color: '#37a2da',
-      name: 'Email',
-      type: 'line',
-      smooth: true,
-      stack: 'Total',
-      areaStyle: {
-        color: {
-          type: 'linear',
-          x: 0,
-          y: 0,
-          x2: 0,
-          y2: 1,
-          colorStops: [
-            {
-              offset: 0.25,
-              color: '#37a2da'
-            },
-            {
-              offset: 1,
-              color: '#fff'
-            }
-          ]
-        }
-      },
-      emphasis: {
-        focus: 'series'
-      },
-      data: [120, 132, 101, 134, 90, 230, 210]
-    },
-    {
-      color: '#9fe6b8',
-      name: 'Union Ads',
-      type: 'line',
-      smooth: true,
-      stack: 'Total',
-      areaStyle: {
-        color: {
-          type: 'linear',
-          x: 0,
-          y: 0,
-          x2: 0,
-          y2: 1,
-          colorStops: [
-            {
-              offset: 0.25,
-              color: '#9fe6b8'
-            },
-            {
-              offset: 1,
-              color: '#fff'
-            }
-          ]
-        }
-      },
-      emphasis: {
-        focus: 'series'
-      },
-      data: [220, 182, 191, 234, 290, 330, 310]
-    },
-    {
-      color: '#fedb5c',
-      name: 'Video Ads',
-      type: 'line',
-      smooth: true,
-      stack: 'Total',
-      areaStyle: {
-        color: {
-          type: 'linear',
-          x: 0,
-          y: 0,
-          x2: 0,
-          y2: 1,
-          colorStops: [
-            {
-              offset: 0.25,
-              color: '#fedb5c'
-            },
-            {
-              offset: 1,
-              color: '#fff'
-            }
-          ]
-        }
-      },
-      emphasis: {
-        focus: 'series'
-      },
-      data: [150, 232, 201, 154, 190, 330, 410]
-    },
-    {
-      color: '#fb7293',
-      name: 'Direct',
-      type: 'line',
-      smooth: true,
-      stack: 'Total',
-      areaStyle: {
-        color: {
-          type: 'linear',
-          x: 0,
-          y: 0,
-          x2: 0,
-          y2: 1,
-          colorStops: [
-            {
-              offset: 0.25,
-              color: '#fb7293'
-            },
-            {
-              offset: 1,
-              color: '#fff'
-            }
-          ]
-        }
-      },
-      emphasis: {
-        focus: 'series'
-      },
-      data: [320, 332, 301, 334, 390, 330, 320]
-    },
-    {
-      color: '#e7bcf3',
-      name: 'Search Engine',
-      type: 'line',
-      smooth: true,
-      stack: 'Total',
-      areaStyle: {
-        color: {
-          type: 'linear',
-          x: 0,
-          y: 0,
-          x2: 0,
-          y2: 1,
-          colorStops: [
-            {
-              offset: 0.25,
-              color: '#e7bcf3'
-            },
-            {
-              offset: 1,
-              color: '#fff'
-            }
-          ]
-        }
-      },
-      emphasis: {
-        focus: 'series'
-      },
-      data: [820, 932, 901, 934, 1290, 1330, 1320]
-    }
-  ]
-}) as Ref<ECOption>;
-const { domRef: lineRef } = useEcharts(lineOptions);
-
-const barOptions = ref<ECOption>({
-  tooltip: {
-    trigger: 'axis',
-    axisPointer: {
-      type: 'cross',
-      label: {
-        backgroundColor: '#6a7985'
-      }
-    }
-  },
-  xAxis: {
-    type: 'category',
-    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-  },
-  yAxis: {
-    type: 'value'
-  },
-  series: [
-    {
-      data: [120, 200, 150, 80, 70, 110, 130],
-      type: 'bar',
-      color: '#8378ea',
-      showBackground: true,
-      barGap: 100,
-      itemStyle: {
-        borderRadius: [40, 40, 0, 0]
-      },
-      backgroundStyle: {
-        color: 'rgba(180, 180, 180, 0.2)'
-      }
-    }
-  ]
-}) as Ref<ECOption>;
-const { domRef: barRef } = useEcharts(barOptions);
-
-const pictorialBarOption = ref<ECOption>(getPictorialBarOption()) as Ref<ECOption>;
-const { domRef: pictorialBarRef } = useEcharts(pictorialBarOption);
-function getPictorialBarOption(): ECOption {
-  const category: string[] = [];
-  let dottedBase = Number(new Date());
-  const lineData: number[] = [];
-  const barData: number[] = [];
-
-  for (let i = 0; i < 20; i += 1) {
-    const date = new Date((dottedBase += 3600 * 24 * 1000));
-    category.push([date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-'));
-    const b = Math.random() * 200;
-    const d = Math.random() * 200;
-    barData.push(b);
-    lineData.push(d + b);
-  }
-
-  const options: ECOption = {
-    backgroundColor: '#0f375f',
-    tooltip: {
-      trigger: 'axis',
-      axisPointer: {
-        type: 'shadow'
-      }
-    },
-    legend: {
-      data: ['line', 'bar'],
-      textStyle: {
-        color: '#ccc'
-      }
-    },
-    xAxis: {
-      data: category,
-      axisLine: {
-        lineStyle: {
-          color: '#ccc'
-        }
-      }
-    },
-    yAxis: {
-      splitLine: { show: false },
-      axisLine: {
-        lineStyle: {
-          color: '#ccc'
-        }
-      }
-    },
-    series: [
-      {
-        name: 'line',
-        type: 'line',
-        smooth: true,
-        showAllSymbol: true,
-        symbol: 'emptyCircle',
-        symbolSize: 15,
-        data: lineData
-      },
-      {
-        name: 'bar',
-        type: 'bar',
-        barWidth: 10,
-        itemStyle: {
-          borderRadius: 5,
-          color: new graphic.LinearGradient(0, 0, 0, 1, [
-            { offset: 0, color: '#14c8d4' },
-            { offset: 1, color: '#43eec6' }
-          ])
-        },
-        data: barData
-      },
-      {
-        name: 'line',
-        type: 'bar',
-        barGap: '-100%',
-        barWidth: 10,
-        itemStyle: {
-          color: new graphic.LinearGradient(0, 0, 0, 1, [
-            { offset: 0, color: 'rgba(20,200,212,0.5)' },
-            { offset: 0.2, color: 'rgba(20,200,212,0.2)' },
-            { offset: 1, color: 'rgba(20,200,212,0)' }
-          ])
-        },
-        z: -12,
-        data: lineData
-      },
-      {
-        name: 'dotted',
-        type: 'pictorialBar',
-        symbol: 'rect',
-        itemStyle: {
-          color: '#0f375f'
-        },
-        symbolRepeat: true,
-        symbolSize: [12, 4],
-        symbolMargin: 1,
-        z: -10,
-        data: lineData
-      }
-    ]
-  };
-
-  return options;
-}
-
-const scatterOptions = ref<ECOption>(getScatterOption()) as Ref<ECOption>;
-const { domRef: scatterRef } = useEcharts(scatterOptions);
-
-function getScatterOption() {
-  // prettier-ignore
-  const hours = ['12a', '1a', '2a', '3a', '4a', '5a', '6a', '7a', '8a', '9a','10a','11a', '12p', '1p', '2p', '3p', '4p', '5p', '6p', '7p', '8p', '9p', '10p', '11p'];
-
-  // prettier-ignore
-  const days = ['Saturday', 'Friday', 'Thursday', 'Wednesday', 'Tuesday', 'Monday', 'Sunday'];
-
-  // prettier-ignore
-  const data: [number, number, number][] = [[0,0,5],[0,1,1],[0,2,0],[0,3,0],[0,4,0],[0,5,0],[0,6,0],[0,7,0],[0,8,0],[0,9,0],[0,10,0],[0,11,2],[0,12,4],[0,13,1],[0,14,1],[0,15,3],[0,16,4],[0,17,6],[0,18,4],[0,19,4],[0,20,3],[0,21,3],[0,22,2],[0,23,5],[1,0,7],[1,1,0],[1,2,0],[1,3,0],[1,4,0],[1,5,0],[1,6,0],[1,7,0],[1,8,0],[1,9,0],[1,10,5],[1,11,2],[1,12,2],[1,13,6],[1,14,9],[1,15,11],[1,16,6],[1,17,7],[1,18,8],[1,19,12],[1,20,5],[1,21,5],[1,22,7],[1,23,2],[2,0,1],[2,1,1],[2,2,0],[2,3,0],[2,4,0],[2,5,0],[2,6,0],[2,7,0],[2,8,0],[2,9,0],[2,10,3],[2,11,2],[2,12,1],[2,13,9],[2,14,8],[2,15,10],[2,16,6],[2,17,5],[2,18,5],[2,19,5],[2,20,7],[2,21,4],[2,22,2],[2,23,4],[3,0,7],[3,1,3],[3,2,0],[3,3,0],[3,4,0],[3,5,0],[3,6,0],[3,7,0],[3,8,1],[3,9,0],[3,10,5],[3,11,4],[3,12,7],[3,13,14],[3,14,13],[3,15,12],[3,16,9],[3,17,5],[3,18,5],[3,19,10],[3,20,6],[3,21,4],[3,22,4],[3,23,1],[4,0,1],[4,1,3],[4,2,0],[4,3,0],[4,4,0],[4,5,1],[4,6,0],[4,7,0],[4,8,0],[4,9,2],[4,10,4],[4,11,4],[4,12,2],[4,13,4],[4,14,4],[4,15,14],[4,16,12],[4,17,1],[4,18,8],[4,19,5],[4,20,3],[4,21,7],[4,22,3],[4,23,0],[5,0,2],[5,1,1],[5,2,0],[5,3,3],[5,4,0],[5,5,0],[5,6,0],[5,7,0],[5,8,2],[5,9,0],[5,10,4],[5,11,1],[5,12,5],[5,13,10],[5,14,5],[5,15,7],[5,16,11],[5,17,6],[5,18,0],[5,19,5],[5,20,3],[5,21,4],[5,22,2],[5,23,0],[6,0,1],[6,1,0],[6,2,0],[6,3,0],[6,4,0],[6,5,0],[6,6,0],[6,7,0],[6,8,0],[6,9,0],[6,10,1],[6,11,0],[6,12,2],[6,13,1],[6,14,3],[6,15,4],[6,16,0],[6,17,0],[6,18,0],[6,19,0],[6,20,1],[6,21,2],[6,22,2],[6,23,6]];
-
-  const title: echarts.TitleComponentOption[] = [];
-  const singleAxis: echarts.SingleAxisComponentOption[] = [];
-  const series: echarts.ScatterSeriesOption[] = [];
-
-  days.forEach((day, idx) => {
-    title.push({
-      textBaseline: 'middle',
-      top: `${((idx + 0.5) * 100) / 7}%`,
-      text: day
-    });
-    singleAxis.push({
-      left: 150,
-      type: 'category',
-      boundaryGap: false,
-      data: hours,
-      top: `${(idx * 100) / 7 + 5}%`,
-      height: `${100 / 7 - 10}%`,
-      axisLabel: {
-        interval: 2
-      }
-    });
-    series.push({
-      singleAxisIndex: idx,
-      coordinateSystem: 'singleAxis',
-      type: 'scatter',
-      data: [],
-      symbolSize(dataItem) {
-        return dataItem[1] * 4;
-      }
-    });
-  });
-
-  data.forEach(dataItem => {
-    (series as any)[dataItem[0]].data.push([dataItem[1], dataItem[2]]);
-  });
-
-  const option: ECOption = {
-    tooltip: {
-      position: 'top'
-    },
-    title,
-    singleAxis,
-    series: series as any
-  };
-
-  return option;
-}
-
-const radarOptions = ref<ECOption>({
-  title: {
-    text: 'Multiple Radar'
-  },
-  tooltip: {
-    trigger: 'axis'
-  },
-  legend: {
-    left: 'center',
-    data: ['A Software', 'A Phone', 'Another Phone', 'Precipitation', 'Evaporation']
-  },
-  radar: [
-    {
-      indicator: [
-        { name: 'Brand', max: 100 },
-        { name: 'Content', max: 100 },
-        { name: 'Usability', max: 100 },
-        { name: 'Function', max: 100 }
-      ],
-      center: ['25%', '40%'],
-      radius: 80
-    },
-    {
-      indicator: [
-        { name: 'Look', max: 100 },
-        { name: 'Photo', max: 100 },
-        { name: 'System', max: 100 },
-        { name: 'Performance', max: 100 },
-        { name: 'Screen', max: 100 }
-      ],
-      radius: 80,
-      center: ['50%', '60%']
-    },
-    {
-      indicator: (() => {
-        const res = [];
-        for (let i = 1; i <= 12; i += 1) {
-          res.push({ name: `${i}月`, max: 100 });
-        }
-        return res;
-      })(),
-      center: ['75%', '40%'],
-      radius: 80
-    }
-  ],
-  series: [
-    {
-      type: 'radar',
-      tooltip: {
-        trigger: 'item'
-      },
-      areaStyle: {},
-      data: [
-        {
-          value: [60, 73, 85, 40],
-          name: 'A Software'
-        }
-      ]
-    },
-    {
-      type: 'radar',
-      radarIndex: 1,
-      areaStyle: {},
-      data: [
-        {
-          value: [85, 90, 90, 95, 95],
-          name: 'A Phone'
-        },
-        {
-          value: [95, 80, 95, 90, 93],
-          name: 'Another Phone'
-        }
-      ]
-    },
-    {
-      type: 'radar',
-      radarIndex: 2,
-      areaStyle: {},
-      data: [
-        {
-          name: 'Precipitation',
-          value: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 75.6, 82.2, 48.7, 18.8, 6.0, 2.3]
-        },
-        {
-          name: 'Evaporation',
-          value: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 35.6, 62.2, 32.6, 20.0, 6.4, 3.3]
-        }
-      ]
-    }
-  ]
-}) as Ref<ECOption>;
-const { domRef: radarRef } = useEcharts(radarOptions);
-
-const gaugeOptions = ref<ECOption>({
-  series: [
-    {
-      name: 'hour',
-      type: 'gauge',
-      startAngle: 90,
-      endAngle: -270,
-      min: 0,
-      max: 12,
-      splitNumber: 12,
-      clockwise: true,
-      axisLine: {
-        lineStyle: {
-          width: 15,
-          color: [[1, 'rgba(0,0,0,0.7)']],
-          shadowColor: 'rgba(0, 0, 0, 0.5)',
-          shadowBlur: 15
-        }
-      },
-      splitLine: {
-        lineStyle: {
-          shadowColor: 'rgba(0, 0, 0, 0.3)',
-          shadowBlur: 3,
-          shadowOffsetX: 1,
-          shadowOffsetY: 2
-        }
-      },
-      axisLabel: {
-        fontSize: 50,
-        distance: 25,
-        formatter(value) {
-          if (value === 0) {
-            return '';
-          }
-          return `${value}`;
-        }
-      },
-      anchor: {
-        show: true,
-        icon: 'path://M532.8,70.8C532.8,70.8,532.8,70.8,532.8,70.8L532.8,70.8C532.7,70.8,532.8,70.8,532.8,70.8z M456.1,49.6c-2.2-6.2-8.1-10.6-15-10.6h-37.5v10.6h37.5l0,0c2.9,0,5.3,2.4,5.3,5.3c0,2.9-2.4,5.3-5.3,5.3v0h-22.5c-1.5,0.1-3,0.4-4.3,0.9c-4.5,1.6-8.1,5.2-9.7,9.8c-0.6,1.7-0.9,3.4-0.9,5.3v16h10.6v-16l0,0l0,0c0-2.7,2.1-5,4.7-5.3h10.3l10.4,21.2h11.8l-10.4-21.2h0c6.9,0,12.8-4.4,15-10.6c0.6-1.7,0.9-3.5,0.9-5.3C457,53,456.7,51.2,456.1,49.6z M388.9,92.1h11.3L381,39h-3.6h-11.3L346.8,92v0h11.3l3.9-10.7h7.3h7.7l3.9-10.6h-7.7h-7.3l7.7-21.2v0L388.9,92.1z M301,38.9h-10.6v53.1H301V70.8h28.4l3.7-10.6H301V38.9zM333.2,38.9v10.6v10.7v31.9h10.6V38.9H333.2z M249.5,81.4L249.5,81.4L249.5,81.4c-2.9,0-5.3-2.4-5.3-5.3h0V54.9h0l0,0c0-2.9,2.4-5.3,5.3-5.3l0,0l0,0h33.6l3.9-10.6h-37.5c-1.9,0-3.6,0.3-5.3,0.9c-4.5,1.6-8.1,5.2-9.7,9.7c-0.6,1.7-0.9,3.5-0.9,5.3l0,0v21.3c0,1.9,0.3,3.6,0.9,5.3c1.6,4.5,5.2,8.1,9.7,9.7c1.7,0.6,3.5,0.9,5.3,0.9h33.6l3.9-10.6H249.5z M176.8,38.9v10.6h49.6l3.9-10.6H176.8z M192.7,81.4L192.7,81.4L192.7,81.4c-2.9,0-5.3-2.4-5.3-5.3l0,0v-5.3h38.9l3.9-10.6h-53.4v10.6v5.3l0,0c0,1.9,0.3,3.6,0.9,5.3c1.6,4.5,5.2,8.1,9.7,9.7c1.7,0.6,3.4,0.9,5.3,0.9h23.4h10.2l3.9-10.6l0,0H192.7z M460.1,38.9v10.6h21.4v42.5h10.6V49.6h17.5l3.8-10.6H460.1z M541.6,68.2c-0.2,0.1-0.4,0.3-0.7,0.4C541.1,68.4,541.4,68.3,541.6,68.2L541.6,68.2z M554.3,60.2h-21.6v0l0,0c-2.9,0-5.3-2.4-5.3-5.3c0-2.9,2.4-5.3,5.3-5.3l0,0l0,0h33.6l3.8-10.6h-37.5l0,0c-6.9,0-12.8,4.4-15,10.6c-0.6,1.7-0.9,3.5-0.9,5.3c0,1.9,0.3,3.7,0.9,5.3c2.2,6.2,8.1,10.6,15,10.6h21.6l0,0c2.9,0,5.3,2.4,5.3,5.3c0,2.9-2.4,5.3-5.3,5.3l0,0h-37.5v10.6h37.5c6.9,0,12.8-4.4,15-10.6c0.6-1.7,0.9-3.5,0.9-5.3c0-1.9-0.3-3.7-0.9-5.3C567.2,64.6,561.3,60.2,554.3,60.2z',
-        showAbove: false,
-        offsetCenter: [0, '-35%'],
-        size: 120,
-        keepAspect: true,
-        itemStyle: {
-          color: '#707177'
-        }
-      },
-      pointer: {
-        icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
-        width: 12,
-        length: '55%',
-        offsetCenter: [0, '8%'],
-        itemStyle: {
-          color: '#C0911F',
-          shadowColor: 'rgba(0, 0, 0, 0.3)',
-          shadowBlur: 8,
-          shadowOffsetX: 2,
-          shadowOffsetY: 4
-        }
-      },
-      detail: {
-        show: false
-      },
-      title: {
-        offsetCenter: [0, '30%']
-      },
-      data: [
-        {
-          value: 0
-        }
-      ]
-    },
-    {
-      name: 'minute',
-      type: 'gauge',
-      startAngle: 90,
-      endAngle: -270,
-      min: 0,
-      max: 60,
-      clockwise: true,
-      axisLine: {
-        show: false
-      },
-      splitLine: {
-        show: false
-      },
-      axisTick: {
-        show: false
-      },
-      axisLabel: {
-        show: false
-      },
-      pointer: {
-        icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
-        width: 8,
-        length: '70%',
-        offsetCenter: [0, '8%'],
-        itemStyle: {
-          color: '#C0911F',
-          shadowColor: 'rgba(0, 0, 0, 0.3)',
-          shadowBlur: 8,
-          shadowOffsetX: 2,
-          shadowOffsetY: 4
-        }
-      },
-      anchor: {
-        show: true,
-        size: 20,
-        showAbove: false,
-        itemStyle: {
-          borderWidth: 15,
-          borderColor: '#C0911F',
-          shadowColor: 'rgba(0, 0, 0, 0.3)',
-          shadowBlur: 8,
-          shadowOffsetX: 2,
-          shadowOffsetY: 4
-        }
-      },
-      detail: {
-        show: false
-      },
-      title: {
-        offsetCenter: ['0%', '-40%']
-      },
-      data: [
-        {
-          value: 0
-        }
-      ]
-    },
-    {
-      name: 'second',
-      type: 'gauge',
-      startAngle: 90,
-      endAngle: -270,
-      min: 0,
-      max: 60,
-      animationEasingUpdate: 'bounceOut',
-      clockwise: true,
-      axisLine: {
-        show: false
-      },
-      splitLine: {
-        show: false
-      },
-      axisTick: {
-        show: false
-      },
-      axisLabel: {
-        show: false
-      },
-      pointer: {
-        icon: 'path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z',
-        width: 4,
-        length: '85%',
-        offsetCenter: [0, '8%'],
-        itemStyle: {
-          color: '#C0911F',
-          shadowColor: 'rgba(0, 0, 0, 0.3)',
-          shadowBlur: 8,
-          shadowOffsetX: 2,
-          shadowOffsetY: 4
-        }
-      },
-      anchor: {
-        show: true,
-        size: 15,
-        showAbove: true,
-        itemStyle: {
-          color: '#C0911F',
-          shadowColor: 'rgba(0, 0, 0, 0.3)',
-          shadowBlur: 8,
-          shadowOffsetX: 2,
-          shadowOffsetY: 4
-        }
-      },
-      detail: {
-        show: false
-      },
-      title: {
-        offsetCenter: ['0%', '-40%']
-      },
-      data: [
-        {
-          value: 0
-        }
-      ]
-    }
-  ]
-}) as Ref<ECOption>;
-
-let intervalId: NodeJS.Timer;
-const { domRef: gaugeRef } = useEcharts(gaugeOptions, chart => {
-  intervalId = setInterval(() => {
-    const date = new Date();
-    const second = date.getSeconds();
-    const minute = date.getMinutes() + second / 60;
-    const hour = (date.getHours() % 12) + minute / 60;
-
-    chart.setOption({
-      animationDurationUpdate: 300,
-      series: [
-        {
-          name: 'hour',
-          animation: hour !== 0,
-          data: [{ value: hour }]
-        },
-        {
-          name: 'minute',
-          animation: minute !== 0,
-          data: [{ value: minute }]
-        },
-        {
-          animation: second !== 0,
-          name: 'second',
-          data: [{ value: second }]
-        }
-      ]
-    });
-  }, 1000);
-});
-function clearClock() {
-  clearInterval(intervalId);
-}
-
-onUnmounted(() => {
-  clearClock();
-});
-</script>
-
-<style scoped></style>

+ 0 - 33
src/views/plugin/copy/index.vue

@@ -1,33 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="文本复制" class="h-full shadow-sm rounded-16px">
-      <n-input-group>
-        <n-input v-model:value="source" placeholder="请输入要复制的内容吧" />
-        <n-button type="primary" @click="handleCopy">复制</n-button>
-      </n-input-group>
-    </n-card>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { ref } from 'vue';
-import { useClipboard } from '@vueuse/core';
-
-const source = ref('');
-const { copy, isSupported } = useClipboard();
-
-function handleCopy() {
-  if (!isSupported) {
-    window.$message?.error('您的浏览器不支持Clipboard API');
-    return;
-  }
-  if (!source.value) {
-    window.$message?.error('请输入要复制的内容');
-    return;
-  }
-  copy(source.value);
-  window.$message?.success(`复制成功:${source.value}`);
-}
-</script>
-
-<style scoped></style>

+ 0 - 50
src/views/plugin/editor/markdown/index.vue

@@ -1,50 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="markdown插件" class="shadow-sm rounded-16px">
-      <div ref="domRef"></div>
-      <template #footer>
-        <github-link link="https://github.com/Vanessa219/vditor" />
-      </template>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { onMounted, onUnmounted, ref, watch } from 'vue';
-import Vditor from 'vditor';
-import 'vditor/dist/index.css';
-import { useThemeStore } from '@/store';
-
-const theme = useThemeStore();
-
-const vditor = ref<Vditor>();
-const domRef = ref<HTMLElement>();
-
-function renderVditor() {
-  if (!domRef.value) return;
-  vditor.value = new Vditor(domRef.value, {
-    minHeight: 400,
-    theme: theme.darkMode ? 'dark' : 'classic',
-    icon: 'material',
-    cache: { enable: false }
-  });
-}
-
-const stopHandle = watch(
-  () => theme.darkMode,
-  newValue => {
-    const themeMode = newValue ? 'dark' : 'classic';
-    vditor.value?.setTheme(themeMode);
-  }
-);
-
-onMounted(() => {
-  renderVditor();
-});
-
-onUnmounted(() => {
-  stopHandle();
-});
-</script>
-
-<style scoped></style>

+ 0 - 45
src/views/plugin/editor/quill/index.vue

@@ -1,45 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="富文本插件" class="shadow-sm rounded-16px">
-      <div ref="domRef" class="bg-white dark:bg-dark"></div>
-      <template #footer>
-        <github-link link="https://github.com/wangeditor-team/wangEditor" />
-      </template>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { onMounted, ref } from 'vue';
-import WangEditor from 'wangeditor';
-
-const editor = ref<WangEditor>();
-const domRef = ref<HTMLElement>();
-
-function renderWangEditor() {
-  editor.value = new WangEditor(domRef.value);
-  setEditorConfig();
-  editor.value.create();
-}
-
-function setEditorConfig() {
-  if (editor.value?.config?.zIndex) {
-    editor.value.config.zIndex = 10;
-  }
-}
-
-onMounted(() => {
-  renderWangEditor();
-});
-</script>
-
-<style scoped>
-:deep(.w-e-toolbar) {
-  background: inherit !important;
-  border-color: #999 !important;
-}
-:deep(.w-e-text-container) {
-  background: inherit;
-  border-color: #999 !important;
-}
-</style>

+ 0 - 32
src/views/plugin/icon/icons.ts

@@ -1,32 +0,0 @@
-export const icons = [
-  'mdi:emoticon',
-  'mdi:ab-testing',
-  'ph:alarm',
-  'ph:android-logo',
-  'ph:align-bottom',
-  'ph:archive-box-light',
-  'uil:basketball',
-  'uil:brightness-plus',
-  'uil:capture',
-  'mdi:apps-box',
-  'mdi:alert',
-  'mdi:airballoon',
-  'mdi:airplane-edit',
-  'mdi:alpha-f-box-outline',
-  'mdi:arm-flex-outline',
-  'ic:baseline-10mp',
-  'ic:baseline-access-time',
-  'ic:baseline-brightness-4',
-  'ic:baseline-brightness-5',
-  'ic:baseline-credit-card',
-  'ic:baseline-filter-1',
-  'ic:baseline-filter-2',
-  'ic:baseline-filter-3',
-  'ic:baseline-filter-4',
-  'ic:baseline-filter-5',
-  'ic:baseline-filter-6',
-  'ic:baseline-filter-7',
-  'ic:baseline-filter-8',
-  'ic:baseline-filter-9',
-  'ic:baseline-filter-9-plus'
-];

+ 0 - 51
src/views/plugin/icon/index.vue

@@ -1,51 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="Icon组件示例" class="shadow-sm rounded-16px">
-      <div class="grid grid-cols-10">
-        <template v-for="item in icons" :key="item">
-          <div class="mt-5px flex-x-center">
-            <svg-icon :icon="item" class="text-30px" />
-          </div>
-        </template>
-      </div>
-      <div class="mt-50px">
-        <h1 class="mb-20px text-18px font-500">Icon图标选择器</h1>
-        <icon-select v-model:value="selectValue" :icons="icons" />
-      </div>
-      <template #footer>
-        <web-site-link label="iconify地址:" link="https://icones.js.org/" class="mt-10px" />
-      </template>
-    </n-card>
-    <n-card title="自定义图标示例" class="mt-10px shadow-sm rounded-16px">
-      <div class="pb-12px text-16px">
-        在src/assets/svg-icon文件夹下的svg文件,通过在template里面以 icon-local-{文件名} 直接渲染,
-        其中icon-local为.env文件里的 VITE_ICON_LOCAL_PREFFIX
-      </div>
-      <div class="grid grid-cols-10">
-        <div class="mt-5px flex-x-center">
-          <icon-local-activity class="text-40px text-success" />
-        </div>
-        <div class="mt-5px flex-x-center">
-          <icon-local-cast class="text-20px text-error" />
-        </div>
-      </div>
-      <div class="py-12px text-16px">通过SvgIcon组件动态渲染, 菜单通过meta的localIcon属性渲染自定义图标</div>
-      <div class="grid grid-cols-10">
-        <div v-for="(fileName, index) in localIcons" :key="index" class="mt-5px flex-x-center">
-          <svg-icon :local-icon="fileName" class="text-30px text-primary" />
-        </div>
-      </div>
-    </n-card>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { ref } from 'vue';
-import { icons } from './icons';
-
-const selectValue = ref('');
-
-const localIcons = ['custom-icon', 'activity', 'at-sign', 'cast', 'chrome', 'copy', 'wind'];
-</script>
-
-<style scoped></style>

+ 0 - 30
src/views/plugin/map/components/baidu-map.vue

@@ -1,30 +0,0 @@
-<template>
-  <div ref="domRef" class="w-full h-full"></div>
-</template>
-
-<script setup lang="ts">
-import { onMounted, ref } from 'vue';
-import { useScriptTag } from '@vueuse/core';
-import { BAIDU_MAP_SDK_URL } from '@/config';
-
-defineOptions({ name: 'BaiduMap' });
-
-const { load } = useScriptTag(BAIDU_MAP_SDK_URL);
-
-const domRef = ref<HTMLDivElement>();
-
-async function renderMap() {
-  await load(true);
-  if (!domRef.value) return;
-  const map = new BMap.Map(domRef.value);
-  const point = new BMap.Point(114.05834626586915, 22.546789983033168);
-  map.centerAndZoom(point, 15);
-  map.enableScrollWheelZoom();
-}
-
-onMounted(() => {
-  renderMap();
-});
-</script>
-
-<style scoped></style>

+ 0 - 32
src/views/plugin/map/components/gaode-map.vue

@@ -1,32 +0,0 @@
-<template>
-  <div ref="domRef" class="w-full h-full"></div>
-</template>
-
-<script setup lang="ts">
-import { onMounted, ref } from 'vue';
-import { useScriptTag } from '@vueuse/core';
-import { GAODE_MAP_SDK_URL } from '@/config';
-
-defineOptions({ name: 'GaodeMap' });
-
-const { load } = useScriptTag(GAODE_MAP_SDK_URL);
-
-const domRef = ref<HTMLDivElement>();
-
-async function renderMap() {
-  await load(true);
-  if (!domRef.value) return;
-  const map = new AMap.Map(domRef.value, {
-    zoom: 11,
-    center: [114.05834626586915, 22.546789983033168],
-    viewMode: '3D'
-  });
-  map.getCenter();
-}
-
-onMounted(() => {
-  renderMap();
-});
-</script>
-
-<style scoped></style>

+ 0 - 5
src/views/plugin/map/components/index.ts

@@ -1,5 +0,0 @@
-import BaiduMap from './baidu-map.vue';
-import GaodeMap from './gaode-map.vue';
-import TencentMap from './tencent-map.vue';
-
-export { BaiduMap, GaodeMap, TencentMap };

+ 0 - 32
src/views/plugin/map/components/tencent-map.vue

@@ -1,32 +0,0 @@
-<template>
-  <div ref="domRef" class="w-full h-full"></div>
-</template>
-
-<script setup lang="ts">
-import { onMounted, ref } from 'vue';
-import { useScriptTag } from '@vueuse/core';
-import { TENCENT_MAP_SDK_URL } from '@/config';
-
-defineOptions({ name: 'TencentMap' });
-
-const { load } = useScriptTag(TENCENT_MAP_SDK_URL);
-
-const domRef = ref<HTMLDivElement | null>(null);
-
-async function renderMap() {
-  await load(true);
-  if (!domRef.value) return;
-  // eslint-disable-next-line no-new
-  new TMap.Map(domRef.value, {
-    center: new TMap.LatLng(39.98412, 116.307484),
-    zoom: 11,
-    viewMode: '3D'
-  });
-}
-
-onMounted(() => {
-  renderMap();
-});
-</script>
-
-<style scoped></style>

+ 0 - 30
src/views/plugin/map/index.vue

@@ -1,30 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="地图插件" class="h-full shadow-sm rounded-16px" content-style="overflow:hidden">
-      <n-tabs type="line" class="flex-col-stretch h-full" pane-class="flex-1-hidden">
-        <n-tab-pane v-for="item in maps" :key="item.id" :name="item.id" :tab="item.label">
-          <component :is="item.component" />
-        </n-tab-pane>
-      </n-tabs>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts">
-import type { Component } from 'vue';
-import { BaiduMap, GaodeMap, TencentMap } from './components';
-
-interface Map {
-  id: string;
-  label: string;
-  component: Component;
-}
-
-const maps: Map[] = [
-  { id: 'gaode', label: '高德地图', component: GaodeMap },
-  { id: 'tencent', label: '腾讯地图', component: TencentMap },
-  { id: 'baidu', label: '百度地图', component: BaiduMap }
-];
-</script>
-
-<style scoped></style>

+ 0 - 39
src/views/plugin/print/index.vue

@@ -1,39 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="打印" class="shadow-sm rounded-16px">
-      <n-button type="primary" class="mr-10px" @click="printTable">打印表格</n-button>
-      <n-button type="primary" @click="printImage">打印图片</n-button>
-      <template #footer>
-        <github-link label="printJS:" link="https://github.com/crabbly/Print.js" class="mt-10px" />
-      </template>
-    </n-card>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import printJS from 'print-js';
-
-function printTable() {
-  printJS({
-    printable: [
-      { name: 'soybean', wechat: 'honghuangdc', remark: '欢迎来技术交流' },
-      { name: 'soybean', wechat: 'honghuangdc', remark: '欢迎来技术交流' }
-    ],
-    properties: ['name', 'wechat', 'remark'],
-    type: 'json'
-  });
-}
-function printImage() {
-  printJS({
-    printable: [
-      'https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg',
-      'https://i.loli.net/2021/11/24/1J6REWXiHomU2kM.jpg'
-    ],
-    type: 'image',
-    header: 'Multiple Images',
-    imageStyle: 'width:100%;'
-  });
-}
-</script>
-
-<style scoped></style>

+ 0 - 109
src/views/plugin/swiper/index.vue

@@ -1,109 +0,0 @@
-<template>
-  <div>
-    <n-card title="Swiper插件" class="shadow-sm rounded-16px">
-      <n-space :vertical="true">
-        <github-link link="https://github.com/nolimits4web/swiper" />
-        <web-site-link label="vue3版文档地址:" link="https://swiperjs.com/vue" />
-        <web-site-link label="插件demo地址:" link="https://swiperjs.com/demos" />
-      </n-space>
-      <n-space :vertical="true">
-        <div v-for="item in swiperExample" :key="item.id">
-          <h3 class="py-24px text-24px font-bold">{{ item.label }}</h3>
-          <swiper v-bind="item.options">
-            <swiper-slide v-for="i in 5" :key="i">
-              <div class="flex-center h-240px border-1px border-#999 text-18px font-bold">Slide{{ i }}</div>
-            </swiper-slide>
-          </swiper>
-        </div>
-      </n-space>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts">
-import SwiperCore, { Navigation, Pagination } from 'swiper';
-import { Swiper, SwiperSlide } from 'swiper/vue';
-import type { SwiperOptions } from 'swiper';
-
-type SwiperExampleOptions = Pick<
-  SwiperOptions,
-  'navigation' | 'pagination' | 'scrollbar' | 'slidesPerView' | 'slidesPerGroup' | 'spaceBetween' | 'direction' | 'loop'
->;
-
-interface SwiperExample {
-  id: number;
-  label: string;
-  options: Partial<SwiperExampleOptions>;
-}
-
-SwiperCore.use([Navigation, Pagination]);
-
-const swiperExample: SwiperExample[] = [
-  { id: 0, label: 'Default', options: {} },
-  {
-    id: 1,
-    label: 'Navigation',
-    options: {
-      navigation: true
-    }
-  },
-  {
-    id: 2,
-    label: 'Pagination',
-    options: {
-      pagination: true
-    }
-  },
-  {
-    id: 3,
-    label: 'Pagination dynamic',
-    options: {
-      pagination: { dynamicBullets: true }
-    }
-  },
-  {
-    id: 4,
-    label: 'Pagination progress',
-    options: {
-      navigation: true,
-      pagination: {
-        type: 'progressbar'
-      }
-    }
-  },
-  {
-    id: 5,
-    label: 'Pagination fraction',
-    options: {
-      navigation: true,
-      pagination: {
-        type: 'fraction'
-      }
-    }
-  },
-  {
-    id: 6,
-    label: 'Slides per view',
-    options: {
-      pagination: {
-        clickable: true
-      },
-      slidesPerView: 3,
-      spaceBetween: 30
-    }
-  },
-  {
-    id: 7,
-    label: 'Infinite loop',
-    options: {
-      navigation: true,
-      pagination: {
-        clickable: true
-      },
-      loop: true
-    }
-  }
-];
-</script>
-
-<style scoped></style>

+ 0 - 39
src/views/plugin/video/index.vue

@@ -1,39 +0,0 @@
-<template>
-  <div class="h-full">
-    <n-card title="视频播放器插件" class="h-full shadow-sm rounded-16px">
-      <div ref="domRef" class=""></div>
-    </n-card>
-  </div>
-</template>
-
-<script setup lang="ts">
-import { onMounted, onUnmounted, ref } from 'vue';
-import Player from 'xgplayer';
-
-const domRef = ref<HTMLElement>();
-const player = ref<Player>();
-
-function renderXgPlayer() {
-  if (!domRef.value) return;
-  const url = 'https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/byted-player-videos/1.0.0/xgplayer-demo.mp4';
-  player.value = new Player({
-    el: domRef.value,
-    url,
-    playbackRate: [0.5, 0.75, 1, 1.5, 2],
-    fluid: true
-  });
-}
-function destroyXgPlayer() {
-  player.value?.destroy();
-}
-
-onMounted(() => {
-  renderXgPlayer();
-});
-
-onUnmounted(() => {
-  destroyXgPlayer();
-});
-</script>
-
-<style scoped></style>