34 changed files with 6 additions and 1770 deletions
			
			
		@ -1,19 +0,0 @@
					 | 
				
			||||
/** | 
				
			||||
 * Mock plugin for development and production. | 
				
			||||
 * https://github.com/anncwb/vite-plugin-mock
 | 
				
			||||
 */ | 
				
			||||
import { viteMockServe } from 'vite-plugin-mock' | 
				
			||||
 | 
				
			||||
export function configMockPlugin(isBuild: boolean) { | 
				
			||||
  return viteMockServe({ | 
				
			||||
    ignore: /^\_/, | 
				
			||||
    mockPath: 'mock', | 
				
			||||
    localEnabled: !isBuild, | 
				
			||||
    prodEnabled: isBuild, | 
				
			||||
    injectCode: ` | 
				
			||||
      import { setupProdMockServer } from '../mock/_createProductionServer'; | 
				
			||||
 | 
				
			||||
      setupProdMockServer(); | 
				
			||||
      ` | 
				
			||||
  }) | 
				
			||||
} | 
				
			||||
@ -1,34 +0,0 @@
					 | 
				
			||||
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer' | 
				
			||||
 | 
				
			||||
// 问题描述
 | 
				
			||||
// 1. `import.meta.globEager` 已被弃用, 需要升级vite版本,有兼容问题
 | 
				
			||||
// 2. `vite-plugin-mock` 插件问题 https://github.com/vbenjs/vite-plugin-mock/issues/56
 | 
				
			||||
 | 
				
			||||
// const modules: Record<string, any> = import.meta.glob("./**/*.ts", {
 | 
				
			||||
//   import: "default",
 | 
				
			||||
//   eager: true,
 | 
				
			||||
// });
 | 
				
			||||
 | 
				
			||||
// const mockModules = Object.keys(modules).reduce((pre, key) => {
 | 
				
			||||
//   if (!key.includes("/_")) {
 | 
				
			||||
//     pre.push(...(modules as Recordable)[key]);
 | 
				
			||||
//   }
 | 
				
			||||
//   return pre;
 | 
				
			||||
// }, [] as any[]);
 | 
				
			||||
 | 
				
			||||
const modules = import.meta.globEager('./**/*.ts') | 
				
			||||
 | 
				
			||||
const mockModules: any[] = [] | 
				
			||||
Object.keys(modules).forEach((key) => { | 
				
			||||
  if (key.includes('/_')) { | 
				
			||||
    return | 
				
			||||
  } | 
				
			||||
  mockModules.push(...(modules as Recordable)[key].default) | 
				
			||||
}) | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Used in a production environment. Need to manually import all modules
 | 
				
			||||
 */ | 
				
			||||
export function setupProdMockServer() { | 
				
			||||
  createProdMockServer(mockModules) | 
				
			||||
} | 
				
			||||
@ -1,52 +0,0 @@
					 | 
				
			||||
// Interface data format used to return a unified format
 | 
				
			||||
import { ResultEnum } from '@/enums/httpEnum' | 
				
			||||
 | 
				
			||||
export function resultSuccess<T = Recordable>(result: T, { message = 'ok' } = {}) { | 
				
			||||
  return { | 
				
			||||
    code: ResultEnum.SUCCESS, | 
				
			||||
    result, | 
				
			||||
    message, | 
				
			||||
    type: 'success' | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export function resultPageSuccess<T = any>(page: number, pageSize: number, list: T[], { message = 'ok' } = {}) { | 
				
			||||
  const pageData = pagination(page, pageSize, list) | 
				
			||||
 | 
				
			||||
  return { | 
				
			||||
    ...resultSuccess({ | 
				
			||||
      items: pageData, | 
				
			||||
      total: list.length | 
				
			||||
    }), | 
				
			||||
    message | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export function resultError(message = 'Request failed', { code = ResultEnum.ERROR, result = null } = {}) { | 
				
			||||
  return { | 
				
			||||
    code, | 
				
			||||
    result, | 
				
			||||
    message, | 
				
			||||
    type: 'error' | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export function pagination<T = any>(pageNo: number, pageSize: number, array: T[]): T[] { | 
				
			||||
  const offset = (pageNo - 1) * Number(pageSize) | 
				
			||||
  return offset + Number(pageSize) >= array.length ? array.slice(offset, array.length) : array.slice(offset, offset + Number(pageSize)) | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export interface requestParams { | 
				
			||||
  method: string | 
				
			||||
  body: any | 
				
			||||
  headers?: { authorization?: string } | 
				
			||||
  query: any | 
				
			||||
} | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * @description 本函数用于从request数据中获取token,请根据项目的实际情况修改 | 
				
			||||
 * | 
				
			||||
 */ | 
				
			||||
export function getRequestToken({ headers }: requestParams): string | undefined { | 
				
			||||
  return headers?.authorization | 
				
			||||
} | 
				
			||||
@ -1,71 +0,0 @@
					 | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { resultSuccess, resultError } from '../_util' | 
				
			||||
import { ResultEnum } from '../../src/enums/httpEnum' | 
				
			||||
 | 
				
			||||
const userInfo = { | 
				
			||||
  name: 'Vben', | 
				
			||||
  userid: '00000001', | 
				
			||||
  email: 'test@gmail.com', | 
				
			||||
  signature: '海纳百川,有容乃大', | 
				
			||||
  introduction: '微笑着,努力着,欣赏着', | 
				
			||||
  title: '交互专家', | 
				
			||||
  group: '某某某事业群-某某平台部-某某技术部-UED', | 
				
			||||
  tags: [ | 
				
			||||
    { | 
				
			||||
      key: '0', | 
				
			||||
      label: '很有想法的' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      key: '1', | 
				
			||||
      label: '专注设计' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      key: '2', | 
				
			||||
      label: '辣~' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      key: '3', | 
				
			||||
      label: '大长腿' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      key: '4', | 
				
			||||
      label: '川妹子' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      key: '5', | 
				
			||||
      label: '海纳百川' | 
				
			||||
    } | 
				
			||||
  ], | 
				
			||||
  notifyCount: 12, | 
				
			||||
  unreadCount: 11, | 
				
			||||
  country: 'China', | 
				
			||||
  address: 'Xiamen City 77', | 
				
			||||
  phone: '0592-268888888' | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export default [ | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/account/getAccountInfo', | 
				
			||||
    timeout: 1000, | 
				
			||||
    method: 'get', | 
				
			||||
    response: () => { | 
				
			||||
      return resultSuccess(userInfo) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/user/sessionTimeout', | 
				
			||||
    method: 'post', | 
				
			||||
    statusCode: 401, | 
				
			||||
    response: () => { | 
				
			||||
      return resultError() | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/user/tokenExpired', | 
				
			||||
    method: 'post', | 
				
			||||
    statusCode: 200, | 
				
			||||
    response: () => { | 
				
			||||
      return resultError('Token Expired!', { code: ResultEnum.TIMEOUT as number }) | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,325 +0,0 @@
					 | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { resultSuccess } from '../_util' | 
				
			||||
 | 
				
			||||
const areaList: any[] = [ | 
				
			||||
  { | 
				
			||||
    id: '530825900854620160', | 
				
			||||
    code: '430000', | 
				
			||||
    parentCode: '100000', | 
				
			||||
    levelType: 1, | 
				
			||||
    name: '湖南省', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: null, | 
				
			||||
    district: null, | 
				
			||||
    town: null, | 
				
			||||
    village: null, | 
				
			||||
    parentPath: '430000', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 16:33:42', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530825900883980288', | 
				
			||||
    code: '430100', | 
				
			||||
    parentCode: '430000', | 
				
			||||
    levelType: 2, | 
				
			||||
    name: '长沙市', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: null, | 
				
			||||
    town: null, | 
				
			||||
    village: null, | 
				
			||||
    parentPath: '430000,430100', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 16:33:42', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530825900951089152', | 
				
			||||
    code: '430102', | 
				
			||||
    parentCode: '430100', | 
				
			||||
    levelType: 3, | 
				
			||||
    name: '芙蓉区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '芙蓉区', | 
				
			||||
    town: null, | 
				
			||||
    village: null, | 
				
			||||
    parentPath: '430000,430100,430102', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 16:33:42', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530825901014003712', | 
				
			||||
    code: '430104', | 
				
			||||
    parentCode: '430100', | 
				
			||||
    levelType: 3, | 
				
			||||
    name: '岳麓区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '岳麓区', | 
				
			||||
    town: null, | 
				
			||||
    village: null, | 
				
			||||
    parentPath: '430000,430100,430104', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 16:33:42', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530825900988837888', | 
				
			||||
    code: '430103', | 
				
			||||
    parentCode: '430100', | 
				
			||||
    levelType: 3, | 
				
			||||
    name: '天心区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: null, | 
				
			||||
    village: null, | 
				
			||||
    parentPath: '430000,430100,430103', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 16:33:42', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530826672489115648', | 
				
			||||
    code: '430103002', | 
				
			||||
    parentCode: '430103', | 
				
			||||
    levelType: 4, | 
				
			||||
    name: '坡子街街道', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: null, | 
				
			||||
    parentPath: '430000,430100,430103,430103002', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-12-14 15:26:43', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241171607552', | 
				
			||||
    code: '430103002001', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '八角亭社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '八角亭社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002001', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2021-01-20 14:07:23', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241200967680', | 
				
			||||
    code: '430103002002', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '西牌楼社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '西牌楼社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002002', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241230327808', | 
				
			||||
    code: '430103002003', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '太平街社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '太平街社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002003', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241259687936', | 
				
			||||
    code: '430103002005', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '坡子街社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '坡子街社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002005', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241284853760', | 
				
			||||
    code: '430103002006', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '青山祠社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '青山祠社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002006', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241310019584', | 
				
			||||
    code: '430103002007', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '沙河社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '沙河社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002007', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241381322752', | 
				
			||||
    code: '430103002008', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '碧湘社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '碧湘社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002008', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241410682880', | 
				
			||||
    code: '430103002009', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '创远社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '创远社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002009', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241431654400', | 
				
			||||
    code: '430103002010', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '楚湘社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '楚湘社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002010', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241465208832', | 
				
			||||
    code: '430103002011', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '西湖社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '西湖社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002011', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241502957568', | 
				
			||||
    code: '430103002012', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '登仁桥社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '登仁桥社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002012', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    id: '530840241553289216', | 
				
			||||
    code: '430103002013', | 
				
			||||
    parentCode: '430103002', | 
				
			||||
    levelType: 5, | 
				
			||||
    name: '文庙坪社区', | 
				
			||||
    province: '湖南省', | 
				
			||||
    city: '长沙市', | 
				
			||||
    district: '天心区', | 
				
			||||
    town: '坡子街街道', | 
				
			||||
    village: '文庙坪社区', | 
				
			||||
    parentPath: '430000,430100,430103,430103002,430103002013', | 
				
			||||
    createTime: '2020-11-30 15:47:31', | 
				
			||||
    updateTime: '2020-11-30 17:30:41', | 
				
			||||
    customized: false, | 
				
			||||
    usable: true | 
				
			||||
  } | 
				
			||||
] | 
				
			||||
export default [ | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/cascader/getAreaRecord', | 
				
			||||
    timeout: 1000, | 
				
			||||
    method: 'post', | 
				
			||||
    response: ({ body }) => { | 
				
			||||
      const { parentCode } = body || {} | 
				
			||||
      if (!parentCode) { | 
				
			||||
        return resultSuccess(areaList.filter((it) => it.code === '430000')) | 
				
			||||
      } | 
				
			||||
      return resultSuccess(areaList.filter((it) => it.parentCode === parentCode)) | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,28 +0,0 @@
					 | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { resultSuccess } from '../_util' | 
				
			||||
 | 
				
			||||
const demoList = (keyword, count = 20) => { | 
				
			||||
  const result = { | 
				
			||||
    list: [] as any[] | 
				
			||||
  } | 
				
			||||
  for (let index = 0; index < count; index++) { | 
				
			||||
    result.list.push({ | 
				
			||||
      name: `${keyword ?? ''}选项${index}`, | 
				
			||||
      id: `${index}` | 
				
			||||
    }) | 
				
			||||
  } | 
				
			||||
  return result | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export default [ | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/select/getDemoOptions', | 
				
			||||
    timeout: 1000, | 
				
			||||
    method: 'get', | 
				
			||||
    response: ({ query }) => { | 
				
			||||
      const { keyword, count } = query | 
				
			||||
      console.log(keyword) | 
				
			||||
      return resultSuccess(demoList(keyword, count)) | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,194 +0,0 @@
					 | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { resultError, resultPageSuccess, resultSuccess } from '../_util' | 
				
			||||
 | 
				
			||||
const accountList = (() => { | 
				
			||||
  const result: any[] = [] | 
				
			||||
  for (let index = 0; index < 20; index++) { | 
				
			||||
    result.push({ | 
				
			||||
      id: `${index}`, | 
				
			||||
      account: '@first', | 
				
			||||
      email: '@email', | 
				
			||||
      nickname: '@cname()', | 
				
			||||
      role: '@first', | 
				
			||||
      createTime: '@datetime', | 
				
			||||
      remark: '@cword(10,20)', | 
				
			||||
      'status|1': ['0', '1'] | 
				
			||||
    }) | 
				
			||||
  } | 
				
			||||
  return result | 
				
			||||
})() | 
				
			||||
 | 
				
			||||
const roleList = (() => { | 
				
			||||
  const result: any[] = [] | 
				
			||||
  for (let index = 0; index < 4; index++) { | 
				
			||||
    result.push({ | 
				
			||||
      id: index + 1, | 
				
			||||
      orderNo: `${index + 1}`, | 
				
			||||
      roleName: ['超级管理员', '管理员', '文章管理员', '普通用户'][index], | 
				
			||||
      roleValue: '@first', | 
				
			||||
      createTime: '@datetime', | 
				
			||||
      remark: '@cword(10,20)', | 
				
			||||
      menu: [['0', '1', '2'], ['0', '1'], ['0', '2'], ['2']][index], | 
				
			||||
      'status|1': ['0', '1'] | 
				
			||||
    }) | 
				
			||||
  } | 
				
			||||
  return result | 
				
			||||
})() | 
				
			||||
 | 
				
			||||
const deptList = (() => { | 
				
			||||
  const result: any[] = [] | 
				
			||||
  for (let index = 0; index < 3; index++) { | 
				
			||||
    result.push({ | 
				
			||||
      id: `${index}`, | 
				
			||||
      deptName: ['华东分部', '华南分部', '西北分部'][index], | 
				
			||||
      orderNo: index + 1, | 
				
			||||
      createTime: '@datetime', | 
				
			||||
      remark: '@cword(10,20)', | 
				
			||||
      'status|1': ['0', '0', '1'], | 
				
			||||
      children: (() => { | 
				
			||||
        const children: any[] = [] | 
				
			||||
        for (let j = 0; j < 4; j++) { | 
				
			||||
          children.push({ | 
				
			||||
            id: `${index}-${j}`, | 
				
			||||
            deptName: ['研发部', '市场部', '商务部', '财务部'][j], | 
				
			||||
            orderNo: j + 1, | 
				
			||||
            createTime: '@datetime', | 
				
			||||
            remark: '@cword(10,20)', | 
				
			||||
            'status|1': ['0', '1'], | 
				
			||||
            parentDept: `${index}`, | 
				
			||||
            children: undefined | 
				
			||||
          }) | 
				
			||||
        } | 
				
			||||
        return children | 
				
			||||
      })() | 
				
			||||
    }) | 
				
			||||
  } | 
				
			||||
  return result | 
				
			||||
})() | 
				
			||||
 | 
				
			||||
const menuList = (() => { | 
				
			||||
  const result: any[] = [] | 
				
			||||
  for (let index = 0; index < 3; index++) { | 
				
			||||
    result.push({ | 
				
			||||
      id: `${index}`, | 
				
			||||
      icon: ['ion:layers-outline', 'ion:git-compare-outline', 'ion:tv-outline'][index], | 
				
			||||
      component: 'LAYOUT', | 
				
			||||
      type: '0', | 
				
			||||
      menuName: ['Dashboard', '权限管理', '功能'][index], | 
				
			||||
      permission: '', | 
				
			||||
      orderNo: index + 1, | 
				
			||||
      createTime: '@datetime', | 
				
			||||
      'status|1': ['0', '0', '1'], | 
				
			||||
      children: (() => { | 
				
			||||
        const children: any[] = [] | 
				
			||||
        for (let j = 0; j < 4; j++) { | 
				
			||||
          children.push({ | 
				
			||||
            id: `${index}-${j}`, | 
				
			||||
            type: '1', | 
				
			||||
            menuName: ['菜单1', '菜单2', '菜单3', '菜单4'][j], | 
				
			||||
            icon: 'ion:document', | 
				
			||||
            permission: ['menu1:view', 'menu2:add', 'menu3:update', 'menu4:del'][index], | 
				
			||||
            component: ['/dashboard/welcome/index', '/dashboard/analysis/index', '/dashboard/workbench/index', '/dashboard/test/index'][j], | 
				
			||||
            orderNo: j + 1, | 
				
			||||
            createTime: '@datetime', | 
				
			||||
            'status|1': ['0', '1'], | 
				
			||||
            parentMenu: `${index}`, | 
				
			||||
            children: (() => { | 
				
			||||
              const children: any[] = [] | 
				
			||||
              for (let k = 0; k < 4; k++) { | 
				
			||||
                children.push({ | 
				
			||||
                  id: `${index}-${j}-${k}`, | 
				
			||||
                  type: '2', | 
				
			||||
                  menuName: '按钮' + (j + 1) + '-' + (k + 1), | 
				
			||||
                  icon: '', | 
				
			||||
                  permission: ['menu1:view', 'menu2:add', 'menu3:update', 'menu4:del'][index] + ':btn' + (k + 1), | 
				
			||||
                  component: [ | 
				
			||||
                    '/dashboard/welcome/index', | 
				
			||||
                    '/dashboard/analysis/index', | 
				
			||||
                    '/dashboard/workbench/index', | 
				
			||||
                    '/dashboard/test/index' | 
				
			||||
                  ][j], | 
				
			||||
                  orderNo: j + 1, | 
				
			||||
                  createTime: '@datetime', | 
				
			||||
                  'status|1': ['0', '1'], | 
				
			||||
                  parentMenu: `${index}-${j}`, | 
				
			||||
                  children: undefined | 
				
			||||
                }) | 
				
			||||
              } | 
				
			||||
              return children | 
				
			||||
            })() | 
				
			||||
          }) | 
				
			||||
        } | 
				
			||||
        return children | 
				
			||||
      })() | 
				
			||||
    }) | 
				
			||||
  } | 
				
			||||
  return result | 
				
			||||
})() | 
				
			||||
 | 
				
			||||
export default [ | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/system/getAccountList', | 
				
			||||
    timeout: 100, | 
				
			||||
    method: 'get', | 
				
			||||
    response: ({ query }) => { | 
				
			||||
      const { page = 1, pageSize = 20 } = query | 
				
			||||
      return resultPageSuccess(page, pageSize, accountList) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/system/getRoleListByPage', | 
				
			||||
    timeout: 100, | 
				
			||||
    method: 'get', | 
				
			||||
    response: ({ query }) => { | 
				
			||||
      const { page = 1, pageSize = 20 } = query | 
				
			||||
      return resultPageSuccess(page, pageSize, roleList) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/system/setRoleStatus', | 
				
			||||
    timeout: 500, | 
				
			||||
    method: 'post', | 
				
			||||
    response: ({ query }) => { | 
				
			||||
      const { id, status } = query | 
				
			||||
      return resultSuccess({ id, status }) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/system/getAllRoleList', | 
				
			||||
    timeout: 100, | 
				
			||||
    method: 'get', | 
				
			||||
    response: () => { | 
				
			||||
      return resultSuccess(roleList) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/system/getDeptList', | 
				
			||||
    timeout: 100, | 
				
			||||
    method: 'get', | 
				
			||||
    response: () => { | 
				
			||||
      return resultSuccess(deptList) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/system/getMenuList', | 
				
			||||
    timeout: 100, | 
				
			||||
    method: 'get', | 
				
			||||
    response: () => { | 
				
			||||
      return resultSuccess(menuList) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/system/accountExist', | 
				
			||||
    timeout: 500, | 
				
			||||
    method: 'post', | 
				
			||||
    response: ({ body }) => { | 
				
			||||
      const { account } = body || {} | 
				
			||||
      if (account && account.indexOf('admin') !== -1) { | 
				
			||||
        return resultError('该字段不能包含admin') | 
				
			||||
      } else { | 
				
			||||
        return resultSuccess(`${account} can use`) | 
				
			||||
      } | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,55 +0,0 @@
					 | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { Random } from 'mockjs' | 
				
			||||
import { resultPageSuccess } from '../_util' | 
				
			||||
 | 
				
			||||
function getRandomPics(count = 10): string[] { | 
				
			||||
  const arr: string[] = [] | 
				
			||||
  for (let i = 0; i < count; i++) { | 
				
			||||
    arr.push(Random.image('800x600', Random.color(), Random.color(), Random.title())) | 
				
			||||
  } | 
				
			||||
  return arr | 
				
			||||
} | 
				
			||||
 | 
				
			||||
const demoList = (() => { | 
				
			||||
  const result: any[] = [] | 
				
			||||
  for (let index = 0; index < 200; index++) { | 
				
			||||
    result.push({ | 
				
			||||
      id: `${index}`, | 
				
			||||
      beginTime: '@datetime', | 
				
			||||
      endTime: '@datetime', | 
				
			||||
      address: '@city()', | 
				
			||||
      name: '@cname()', | 
				
			||||
      name1: '@cname()', | 
				
			||||
      name2: '@cname()', | 
				
			||||
      name3: '@cname()', | 
				
			||||
      name4: '@cname()', | 
				
			||||
      name5: '@cname()', | 
				
			||||
      name6: '@cname()', | 
				
			||||
      name7: '@cname()', | 
				
			||||
      name8: '@cname()', | 
				
			||||
      radio1: `选项${index + 1}`, | 
				
			||||
      radio2: `选项${index + 1}`, | 
				
			||||
      radio3: `选项${index + 1}`, | 
				
			||||
      avatar: Random.image('400x400', Random.color(), Random.color(), Random.first()), | 
				
			||||
      imgArr: getRandomPics(Math.ceil(Math.random() * 3) + 1), | 
				
			||||
      imgs: getRandomPics(Math.ceil(Math.random() * 3) + 1), | 
				
			||||
      date: `@date('yyyy-MM-dd')`, | 
				
			||||
      time: `@time('HH:mm')`, | 
				
			||||
      'no|100000-10000000': 100000, | 
				
			||||
      'status|1': ['normal', 'enable', 'disable'] | 
				
			||||
    }) | 
				
			||||
  } | 
				
			||||
  return result | 
				
			||||
})() | 
				
			||||
 | 
				
			||||
export default [ | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/table/getDemoList', | 
				
			||||
    timeout: 100, | 
				
			||||
    method: 'get', | 
				
			||||
    response: ({ query }) => { | 
				
			||||
      const { page = 1, pageSize = 20 } = query | 
				
			||||
      return resultPageSuccess(page, pageSize, demoList) | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,38 +0,0 @@
					 | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { resultSuccess } from '../_util' | 
				
			||||
 | 
				
			||||
const demoTreeList = (keyword) => { | 
				
			||||
  const result = { | 
				
			||||
    list: [] as Recordable[] | 
				
			||||
  } | 
				
			||||
  for (let index = 0; index < 5; index++) { | 
				
			||||
    const children: Recordable[] = [] | 
				
			||||
    for (let j = 0; j < 3; j++) { | 
				
			||||
      children.push({ | 
				
			||||
        title: `${keyword ?? ''}选项${index}-${j}`, | 
				
			||||
        value: `${index}-${j}`, | 
				
			||||
        key: `${index}-${j}` | 
				
			||||
      }) | 
				
			||||
    } | 
				
			||||
    result.list.push({ | 
				
			||||
      title: `${keyword ?? ''}选项${index}`, | 
				
			||||
      value: `${index}`, | 
				
			||||
      key: `${index}`, | 
				
			||||
      children | 
				
			||||
    }) | 
				
			||||
  } | 
				
			||||
  return result | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export default [ | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/tree/getDemoOptions', | 
				
			||||
    timeout: 1000, | 
				
			||||
    method: 'get', | 
				
			||||
    response: ({ query }) => { | 
				
			||||
      const { keyword } = query | 
				
			||||
      console.log(keyword) | 
				
			||||
      return resultSuccess(demoTreeList(keyword)) | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,270 +0,0 @@
					 | 
				
			||||
import { resultSuccess, resultError, getRequestToken, requestParams } from '../_util' | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { createFakeUserList } from './user' | 
				
			||||
 | 
				
			||||
// single
 | 
				
			||||
const dashboardRoute = { | 
				
			||||
  path: '/dashboard', | 
				
			||||
  name: 'Dashboard', | 
				
			||||
  component: 'LAYOUT', | 
				
			||||
  redirect: '/dashboard/analysis', | 
				
			||||
  meta: { | 
				
			||||
    title: 'routes.dashboard.dashboard', | 
				
			||||
    hideChildrenInMenu: true, | 
				
			||||
    icon: 'bx:bx-home' | 
				
			||||
  }, | 
				
			||||
  children: [ | 
				
			||||
    { | 
				
			||||
      path: 'analysis', | 
				
			||||
      name: 'Analysis', | 
				
			||||
      component: '/dashboard/analysis/index', | 
				
			||||
      meta: { | 
				
			||||
        hideMenu: true, | 
				
			||||
        hideBreadcrumb: true, | 
				
			||||
        title: 'routes.dashboard.analysis', | 
				
			||||
        currentActiveMenu: '/dashboard', | 
				
			||||
        icon: 'bx:bx-home' | 
				
			||||
      } | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'workbench', | 
				
			||||
      name: 'Workbench', | 
				
			||||
      component: '/dashboard/workbench/index', | 
				
			||||
      meta: { | 
				
			||||
        hideMenu: true, | 
				
			||||
        hideBreadcrumb: true, | 
				
			||||
        title: 'routes.dashboard.workbench', | 
				
			||||
        currentActiveMenu: '/dashboard', | 
				
			||||
        icon: 'bx:bx-home' | 
				
			||||
      } | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
 | 
				
			||||
const backRoute = { | 
				
			||||
  path: 'back', | 
				
			||||
  name: 'PermissionBackDemo', | 
				
			||||
  meta: { | 
				
			||||
    title: 'routes.demo.permission.back' | 
				
			||||
  }, | 
				
			||||
 | 
				
			||||
  children: [ | 
				
			||||
    { | 
				
			||||
      path: 'page', | 
				
			||||
      name: 'BackAuthPage', | 
				
			||||
      component: '/demo/permission/back/index', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.permission.backPage' | 
				
			||||
      } | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'btn', | 
				
			||||
      name: 'BackAuthBtn', | 
				
			||||
      component: '/demo/permission/back/Btn', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.permission.backBtn' | 
				
			||||
      } | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
 | 
				
			||||
const authRoute = { | 
				
			||||
  path: '/permission', | 
				
			||||
  name: 'Permission', | 
				
			||||
  component: 'LAYOUT', | 
				
			||||
  redirect: '/permission/front/page', | 
				
			||||
  meta: { | 
				
			||||
    icon: 'carbon:user-role', | 
				
			||||
    title: 'routes.demo.permission.permission' | 
				
			||||
  }, | 
				
			||||
  children: [backRoute] | 
				
			||||
} | 
				
			||||
 | 
				
			||||
const levelRoute = { | 
				
			||||
  path: '/level', | 
				
			||||
  name: 'Level', | 
				
			||||
  component: 'LAYOUT', | 
				
			||||
  redirect: '/level/menu1/menu1-1', | 
				
			||||
  meta: { | 
				
			||||
    icon: 'carbon:user-role', | 
				
			||||
    title: 'routes.demo.level.level' | 
				
			||||
  }, | 
				
			||||
 | 
				
			||||
  children: [ | 
				
			||||
    { | 
				
			||||
      path: 'menu1', | 
				
			||||
      name: 'Menu1Demo', | 
				
			||||
      meta: { | 
				
			||||
        title: 'Menu1' | 
				
			||||
      }, | 
				
			||||
      children: [ | 
				
			||||
        { | 
				
			||||
          path: 'menu1-1', | 
				
			||||
          name: 'Menu11Demo', | 
				
			||||
          meta: { | 
				
			||||
            title: 'Menu1-1' | 
				
			||||
          }, | 
				
			||||
          children: [ | 
				
			||||
            { | 
				
			||||
              path: 'menu1-1-1', | 
				
			||||
              name: 'Menu111Demo', | 
				
			||||
              component: '/demo/level/Menu111', | 
				
			||||
              meta: { | 
				
			||||
                title: 'Menu111' | 
				
			||||
              } | 
				
			||||
            } | 
				
			||||
          ] | 
				
			||||
        }, | 
				
			||||
        { | 
				
			||||
          path: 'menu1-2', | 
				
			||||
          name: 'Menu12Demo', | 
				
			||||
          component: '/demo/level/Menu12', | 
				
			||||
          meta: { | 
				
			||||
            title: 'Menu1-2' | 
				
			||||
          } | 
				
			||||
        } | 
				
			||||
      ] | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'menu2', | 
				
			||||
      name: 'Menu2Demo', | 
				
			||||
      component: '/demo/level/Menu2', | 
				
			||||
      meta: { | 
				
			||||
        title: 'Menu2' | 
				
			||||
      } | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
 | 
				
			||||
const sysRoute = { | 
				
			||||
  path: '/system', | 
				
			||||
  name: 'System', | 
				
			||||
  component: 'LAYOUT', | 
				
			||||
  redirect: '/system/account', | 
				
			||||
  meta: { | 
				
			||||
    icon: 'ion:settings-outline', | 
				
			||||
    title: 'routes.demo.system.moduleName' | 
				
			||||
  }, | 
				
			||||
  children: [ | 
				
			||||
    { | 
				
			||||
      path: 'account', | 
				
			||||
      name: 'AccountManagement', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.system.account', | 
				
			||||
        ignoreKeepAlive: true | 
				
			||||
      }, | 
				
			||||
      component: '/demo/system/account/index' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'account_detail/:id', | 
				
			||||
      name: 'AccountDetail', | 
				
			||||
      meta: { | 
				
			||||
        hideMenu: true, | 
				
			||||
        title: 'routes.demo.system.account_detail', | 
				
			||||
        ignoreKeepAlive: true, | 
				
			||||
        showMenu: false, | 
				
			||||
        currentActiveMenu: '/system/account' | 
				
			||||
      }, | 
				
			||||
      component: '/demo/system/account/AccountDetail' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'role', | 
				
			||||
      name: 'RoleManagement', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.system.role', | 
				
			||||
        ignoreKeepAlive: true | 
				
			||||
      }, | 
				
			||||
      component: '/demo/system/role/index' | 
				
			||||
    }, | 
				
			||||
 | 
				
			||||
    { | 
				
			||||
      path: 'menu', | 
				
			||||
      name: 'MenuManagement', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.system.menu', | 
				
			||||
        ignoreKeepAlive: true | 
				
			||||
      }, | 
				
			||||
      component: '/demo/system/menu/index' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'dept', | 
				
			||||
      name: 'DeptManagement', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.system.dept', | 
				
			||||
        ignoreKeepAlive: true | 
				
			||||
      }, | 
				
			||||
      component: '/demo/system/dept/index' | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'changePassword', | 
				
			||||
      name: 'ChangePassword', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.system.password', | 
				
			||||
        ignoreKeepAlive: true | 
				
			||||
      }, | 
				
			||||
      component: '/demo/system/password/index' | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
 | 
				
			||||
const linkRoute = { | 
				
			||||
  path: '/link', | 
				
			||||
  name: 'Link', | 
				
			||||
  component: 'LAYOUT', | 
				
			||||
  meta: { | 
				
			||||
    icon: 'ion:tv-outline', | 
				
			||||
    title: 'routes.demo.iframe.frame' | 
				
			||||
  }, | 
				
			||||
  children: [ | 
				
			||||
    { | 
				
			||||
      path: 'doc', | 
				
			||||
      name: 'Doc', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.iframe.doc', | 
				
			||||
        frameSrc: 'https://doc.vvbin.cn/' | 
				
			||||
      } | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      path: 'https://doc.vvbin.cn/', | 
				
			||||
      name: 'DocExternal', | 
				
			||||
      component: 'LAYOUT', | 
				
			||||
      meta: { | 
				
			||||
        title: 'routes.demo.iframe.docExternal' | 
				
			||||
      } | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export default [ | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/getMenuList', | 
				
			||||
    timeout: 1000, | 
				
			||||
    method: 'get', | 
				
			||||
    response: (request: requestParams) => { | 
				
			||||
      const token = getRequestToken(request) | 
				
			||||
      if (!token) { | 
				
			||||
        return resultError('Invalid token!') | 
				
			||||
      } | 
				
			||||
      const checkUser = createFakeUserList().find((item) => item.token === token) | 
				
			||||
      if (!checkUser) { | 
				
			||||
        return resultError('Invalid user token!') | 
				
			||||
      } | 
				
			||||
      const id = checkUser.userId | 
				
			||||
      let menu: Object[] | 
				
			||||
      switch (id) { | 
				
			||||
        case '1': | 
				
			||||
          dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[0].path | 
				
			||||
          menu = [dashboardRoute, authRoute, levelRoute, sysRoute, linkRoute] | 
				
			||||
          break | 
				
			||||
        case '2': | 
				
			||||
          dashboardRoute.redirect = dashboardRoute.path + '/' + dashboardRoute.children[1].path | 
				
			||||
          menu = [dashboardRoute, authRoute, levelRoute, linkRoute] | 
				
			||||
          break | 
				
			||||
        default: | 
				
			||||
          menu = [] | 
				
			||||
      } | 
				
			||||
 | 
				
			||||
      return resultSuccess(menu) | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,120 +0,0 @@
					 | 
				
			||||
import { MockMethod } from 'vite-plugin-mock' | 
				
			||||
import { resultError, resultSuccess, getRequestToken, requestParams } from '../_util' | 
				
			||||
 | 
				
			||||
export function createFakeUserList() { | 
				
			||||
  return [ | 
				
			||||
    { | 
				
			||||
      userId: '1', | 
				
			||||
      username: 'vben', | 
				
			||||
      realName: 'Vben Admin', | 
				
			||||
      avatar: '', | 
				
			||||
      desc: 'manager', | 
				
			||||
      password: '123456', | 
				
			||||
      token: 'fakeToken1', | 
				
			||||
      homePath: '/dashboard/analysis', | 
				
			||||
      roles: [ | 
				
			||||
        { | 
				
			||||
          roleName: 'Super Admin', | 
				
			||||
          value: 'super' | 
				
			||||
        } | 
				
			||||
      ] | 
				
			||||
    }, | 
				
			||||
    { | 
				
			||||
      userId: '2', | 
				
			||||
      username: 'test', | 
				
			||||
      password: '123456', | 
				
			||||
      realName: 'test user', | 
				
			||||
      avatar: '', | 
				
			||||
      desc: 'tester', | 
				
			||||
      token: 'fakeToken2', | 
				
			||||
      homePath: '/dashboard/workbench', | 
				
			||||
      roles: [ | 
				
			||||
        { | 
				
			||||
          roleName: 'Tester', | 
				
			||||
          value: 'test' | 
				
			||||
        } | 
				
			||||
      ] | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
 | 
				
			||||
const fakeCodeList: any = { | 
				
			||||
  '1': ['1000', '3000', '5000'], | 
				
			||||
 | 
				
			||||
  '2': ['2000', '4000', '6000'] | 
				
			||||
} | 
				
			||||
export default [ | 
				
			||||
  // mock user login
 | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/login', | 
				
			||||
    timeout: 200, | 
				
			||||
    method: 'post', | 
				
			||||
    response: ({ body }) => { | 
				
			||||
      const { username, password } = body | 
				
			||||
      const checkUser = createFakeUserList().find((item) => item.username === username && password === item.password) | 
				
			||||
      if (!checkUser) { | 
				
			||||
        return resultError('Incorrect account or password!') | 
				
			||||
      } | 
				
			||||
      const { userId, username: _username, token, realName, desc, roles } = checkUser | 
				
			||||
      return resultSuccess({ | 
				
			||||
        roles, | 
				
			||||
        userId, | 
				
			||||
        username: _username, | 
				
			||||
        token, | 
				
			||||
        realName, | 
				
			||||
        desc | 
				
			||||
      }) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/getUserInfo', | 
				
			||||
    method: 'get', | 
				
			||||
    response: (request: requestParams) => { | 
				
			||||
      const token = getRequestToken(request) | 
				
			||||
      if (!token) return resultError('Invalid token') | 
				
			||||
      const checkUser = createFakeUserList().find((item) => item.token === token) | 
				
			||||
      if (!checkUser) { | 
				
			||||
        return resultError('The corresponding user information was not obtained!') | 
				
			||||
      } | 
				
			||||
      return resultSuccess(checkUser) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/getPermCode', | 
				
			||||
    timeout: 200, | 
				
			||||
    method: 'get', | 
				
			||||
    response: (request: requestParams) => { | 
				
			||||
      const token = getRequestToken(request) | 
				
			||||
      if (!token) return resultError('Invalid token') | 
				
			||||
      const checkUser = createFakeUserList().find((item) => item.token === token) | 
				
			||||
      if (!checkUser) { | 
				
			||||
        return resultError('Invalid token!') | 
				
			||||
      } | 
				
			||||
      const codeList = fakeCodeList[checkUser.userId] | 
				
			||||
 | 
				
			||||
      return resultSuccess(codeList) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/logout', | 
				
			||||
    timeout: 200, | 
				
			||||
    method: 'get', | 
				
			||||
    response: (request: requestParams) => { | 
				
			||||
      const token = getRequestToken(request) | 
				
			||||
      if (!token) return resultError('Invalid token') | 
				
			||||
      const checkUser = createFakeUserList().find((item) => item.token === token) | 
				
			||||
      if (!checkUser) { | 
				
			||||
        return resultError('Invalid token!') | 
				
			||||
      } | 
				
			||||
      return resultSuccess(undefined, { message: 'Token has been destroyed' }) | 
				
			||||
    } | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    url: '/basic-api/testRetry', | 
				
			||||
    statusCode: 405, | 
				
			||||
    method: 'get', | 
				
			||||
    response: () => { | 
				
			||||
      return resultError('Error!') | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
] as MockMethod[] | 
				
			||||
@ -1,15 +0,0 @@
					 | 
				
			||||
# Test Server | 
				
			||||
 | 
				
			||||
It is used to start the test interface service, which can test the upload, websocket, login and other interfaces. | 
				
			||||
 | 
				
			||||
## Usage | 
				
			||||
 | 
				
			||||
```bash | 
				
			||||
 | 
				
			||||
cd ./test/server | 
				
			||||
 | 
				
			||||
pnpm install | 
				
			||||
 | 
				
			||||
pnpm run start | 
				
			||||
 | 
				
			||||
``` | 
				
			||||
@ -1,18 +0,0 @@
					 | 
				
			||||
import FileService from '../service/FileService' | 
				
			||||
 | 
				
			||||
class FileController { | 
				
			||||
  private service: FileService = new FileService() | 
				
			||||
 | 
				
			||||
  upload = async (ctx) => { | 
				
			||||
    const files = ctx.request.files.file | 
				
			||||
    console.log(files) | 
				
			||||
 | 
				
			||||
    if (files.length === undefined) { | 
				
			||||
      this.service.upload(ctx, files, false) | 
				
			||||
    } else { | 
				
			||||
      this.service.upload(ctx, files, true) | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export default new FileController() | 
				
			||||
@ -1,15 +0,0 @@
					 | 
				
			||||
import UserService from '../service/UserService' | 
				
			||||
 | 
				
			||||
class UserController { | 
				
			||||
  private service: UserService = new UserService() | 
				
			||||
 | 
				
			||||
  login = async (ctx) => { | 
				
			||||
    ctx.body = await this.service.login() | 
				
			||||
  } | 
				
			||||
 | 
				
			||||
  getUserInfoById = async (ctx) => { | 
				
			||||
    ctx.body = await this.service.getUserInfoById() | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
 | 
				
			||||
export default new UserController() | 
				
			||||
@ -1,18 +0,0 @@
					 | 
				
			||||
const { name } = require('./package.json') | 
				
			||||
const path = require('path') | 
				
			||||
 | 
				
			||||
module.exports = { | 
				
			||||
  apps: [ | 
				
			||||
    { | 
				
			||||
      name, | 
				
			||||
      script: path.resolve(__dirname, './dist/index.js'), | 
				
			||||
      instances: require('os').cpus().length, | 
				
			||||
      autorestart: true, | 
				
			||||
      watch: true, | 
				
			||||
      env_production: { | 
				
			||||
        NODE_ENV: 'production', | 
				
			||||
        PORT: 8080 | 
				
			||||
      } | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
@ -1,63 +0,0 @@
					 | 
				
			||||
import Koa from 'koa' | 
				
			||||
import path from 'path' | 
				
			||||
import Router from 'koa-router' | 
				
			||||
import body from 'koa-body' | 
				
			||||
import cors from 'koa2-cors' | 
				
			||||
import koaStatic from 'koa-static' | 
				
			||||
import websockify from 'koa-websocket' | 
				
			||||
import route from 'koa-route' | 
				
			||||
 | 
				
			||||
import AppRoutes from './routes' | 
				
			||||
 | 
				
			||||
const PORT = 3300 | 
				
			||||
 | 
				
			||||
const app = websockify(new Koa()) | 
				
			||||
 | 
				
			||||
app.ws.use(function (ctx, next) { | 
				
			||||
  ctx.websocket.send('connection succeeded!') | 
				
			||||
  return next(ctx) | 
				
			||||
}) | 
				
			||||
 | 
				
			||||
app.ws.use( | 
				
			||||
  route.all('/test', function (ctx) { | 
				
			||||
    // ctx.websocket.send('Hello World');
 | 
				
			||||
    ctx.websocket.on('message', function (message) { | 
				
			||||
      // do something with the message from client
 | 
				
			||||
 | 
				
			||||
      if (message !== 'ping') { | 
				
			||||
        const data = JSON.stringify({ | 
				
			||||
          id: Math.ceil(Math.random() * 1000), | 
				
			||||
          time: new Date().getTime(), | 
				
			||||
          res: `${message}` | 
				
			||||
        }) | 
				
			||||
        ctx.websocket.send(data) | 
				
			||||
      } | 
				
			||||
      console.log(message) | 
				
			||||
    }) | 
				
			||||
  }) | 
				
			||||
) | 
				
			||||
 | 
				
			||||
const router = new Router() | 
				
			||||
 | 
				
			||||
// router
 | 
				
			||||
AppRoutes.forEach((route) => router[route.method](route.path, route.action)) | 
				
			||||
 | 
				
			||||
app.use(cors()) | 
				
			||||
app.use( | 
				
			||||
  body({ | 
				
			||||
    encoding: 'gzip', | 
				
			||||
    multipart: true, | 
				
			||||
    formidable: { | 
				
			||||
      // uploadDir: path.join(__dirname, '/upload/'), // 设置文件上传目录
 | 
				
			||||
      keepExtensions: true, | 
				
			||||
      maxFieldsSize: 20 * 1024 * 1024 | 
				
			||||
    } | 
				
			||||
  }) | 
				
			||||
) | 
				
			||||
app.use(router.routes()) | 
				
			||||
app.use(router.allowedMethods()) | 
				
			||||
app.use(koaStatic(path.join(__dirname))) | 
				
			||||
 | 
				
			||||
app.listen(PORT, () => { | 
				
			||||
  console.log(`Application started successfully: http://localhost:${PORT}`) | 
				
			||||
}) | 
				
			||||
@ -1,8 +0,0 @@
					 | 
				
			||||
{ | 
				
			||||
  "watch": ["src"], | 
				
			||||
  "ext": "ts", | 
				
			||||
  "exec": "ts-node -r tsconfig-paths/register index.ts", | 
				
			||||
  "events": { | 
				
			||||
    "restart": "clear" | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
@ -1,36 +0,0 @@
					 | 
				
			||||
{ | 
				
			||||
  "name": "server", | 
				
			||||
  "version": "1.0.0", | 
				
			||||
  "license": "MIT", | 
				
			||||
  "scripts": { | 
				
			||||
    "start": "nodemon", | 
				
			||||
    "build": "rimraf ./dist && tsup ./index.ts --dts --format cjs,esm  ", | 
				
			||||
    "prod": "npx pm2 start ecosystem.config.js --env production", | 
				
			||||
    "restart": "pm2 restart ecosystem.config.js --env production", | 
				
			||||
    "stop": "npx pm2 stop ecosystem.config.js" | 
				
			||||
  }, | 
				
			||||
  "dependencies": { | 
				
			||||
    "fs-extra": "^10.0.1", | 
				
			||||
    "koa": "^2.13.4", | 
				
			||||
    "koa-body": "^4.2.0", | 
				
			||||
    "koa-bodyparser": "^4.3.0", | 
				
			||||
    "koa-route": "^3.2.0", | 
				
			||||
    "koa-router": "^10.1.1", | 
				
			||||
    "koa-static": "^5.0.0", | 
				
			||||
    "koa-websocket": "^6.0.0", | 
				
			||||
    "koa2-cors": "^2.0.6" | 
				
			||||
  }, | 
				
			||||
  "devDependencies": { | 
				
			||||
    "@types/koa": "^2.13.4", | 
				
			||||
    "@types/koa-bodyparser": "^5.0.2", | 
				
			||||
    "@types/koa-router": "^7.4.4", | 
				
			||||
    "@types/node": "^17.0.21", | 
				
			||||
    "nodemon": "^2.0.15", | 
				
			||||
    "pm2": "^5.2.0", | 
				
			||||
    "rimraf": "^3.0.2", | 
				
			||||
    "ts-node": "^10.7.0", | 
				
			||||
    "tsconfig-paths": "^3.14.0", | 
				
			||||
    "tsup": "^5.12.1", | 
				
			||||
    "typescript": "^4.6.2" | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
@ -1,23 +0,0 @@
					 | 
				
			||||
import UserController from './controller/UserController' | 
				
			||||
import FileController from './controller/FileController' | 
				
			||||
 | 
				
			||||
export default [ | 
				
			||||
  // user
 | 
				
			||||
  { | 
				
			||||
    path: '/login', | 
				
			||||
    method: 'post', | 
				
			||||
    action: UserController.login | 
				
			||||
  }, | 
				
			||||
  { | 
				
			||||
    path: '/getUserInfoById', | 
				
			||||
    method: 'get', | 
				
			||||
    action: UserController.getUserInfoById | 
				
			||||
  }, | 
				
			||||
 | 
				
			||||
  // file
 | 
				
			||||
  { | 
				
			||||
    path: '/upload', | 
				
			||||
    method: 'post', | 
				
			||||
    action: FileController.upload | 
				
			||||
  } | 
				
			||||
] | 
				
			||||
@ -1,54 +0,0 @@
					 | 
				
			||||
import path from 'path' | 
				
			||||
import fs from 'fs-extra' | 
				
			||||
 | 
				
			||||
const uploadUrl = 'http://localhost:3300/static/upload' | 
				
			||||
const filePath = path.join(__dirname, '../static/upload/') | 
				
			||||
 | 
				
			||||
fs.ensureDir(filePath) | 
				
			||||
export default class UserService { | 
				
			||||
  async upload(ctx, files, isMultiple) { | 
				
			||||
    let fileReader, fileResource, writeStream | 
				
			||||
 | 
				
			||||
    const fileFunc = function (file) { | 
				
			||||
      fileReader = fs.createReadStream(file.path) | 
				
			||||
      fileResource = filePath + `/${file.name}` | 
				
			||||
      console.log(fileResource) | 
				
			||||
 | 
				
			||||
      writeStream = fs.createWriteStream(fileResource) | 
				
			||||
      fileReader.pipe(writeStream) | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    const returnFunc = function (flag) { | 
				
			||||
      if (flag) { | 
				
			||||
        let url = '' | 
				
			||||
        for (let i = 0; i < files.length; i++) { | 
				
			||||
          url += uploadUrl + `/${files[i].name},` | 
				
			||||
        } | 
				
			||||
        url = url.replace(/,$/gi, '') | 
				
			||||
        ctx.body = { | 
				
			||||
          url: url, | 
				
			||||
          code: 0, | 
				
			||||
          message: 'upload Success!' | 
				
			||||
        } | 
				
			||||
      } else { | 
				
			||||
        ctx.body = { | 
				
			||||
          url: uploadUrl + `/${files.name}`, | 
				
			||||
          code: 0, | 
				
			||||
          message: 'upload Success!' | 
				
			||||
        } | 
				
			||||
      } | 
				
			||||
    } | 
				
			||||
    console.log(isMultiple, files.length) | 
				
			||||
 | 
				
			||||
    if (isMultiple) { | 
				
			||||
      for (let i = 0; i < files.length; i++) { | 
				
			||||
        const f1 = files[i] | 
				
			||||
        fileFunc(f1) | 
				
			||||
      } | 
				
			||||
    } else { | 
				
			||||
      fileFunc(files) | 
				
			||||
    } | 
				
			||||
    fs.ensureDir(filePath) | 
				
			||||
    returnFunc(isMultiple) | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
@ -1,25 +0,0 @@
					 | 
				
			||||
import { Result } from '../utils' | 
				
			||||
 | 
				
			||||
const fakeUserInfo = { | 
				
			||||
  userId: '1', | 
				
			||||
  username: 'vben', | 
				
			||||
  realName: 'Vben Admin', | 
				
			||||
  desc: 'manager', | 
				
			||||
  password: '123456', | 
				
			||||
  token: 'fakeToken1', | 
				
			||||
  roles: [ | 
				
			||||
    { | 
				
			||||
      roleName: 'Super Admin', | 
				
			||||
      value: 'super' | 
				
			||||
    } | 
				
			||||
  ] | 
				
			||||
} | 
				
			||||
export default class UserService { | 
				
			||||
  async login() { | 
				
			||||
    return Result.success(fakeUserInfo) | 
				
			||||
  } | 
				
			||||
 | 
				
			||||
  async getUserInfoById() { | 
				
			||||
    return Result.success(fakeUserInfo) | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
@ -1,15 +0,0 @@
					 | 
				
			||||
{ | 
				
			||||
  "compilerOptions": { | 
				
			||||
    "module": "commonjs", | 
				
			||||
    "declaration": false, | 
				
			||||
    "removeComments": true, | 
				
			||||
    "emitDecoratorMetadata": true, | 
				
			||||
    "experimentalDecorators": true, | 
				
			||||
    "target": "es6", | 
				
			||||
    "sourceMap": false, | 
				
			||||
    "esModuleInterop": true, | 
				
			||||
    "outDir": "./dist", | 
				
			||||
    "baseUrl": "./" | 
				
			||||
  }, | 
				
			||||
  "exclude": ["node_modules"] | 
				
			||||
} | 
				
			||||
@ -1,9 +0,0 @@
					 | 
				
			||||
export class Result { | 
				
			||||
  static success(data: any) { | 
				
			||||
    return { | 
				
			||||
      code: 0, | 
				
			||||
      success: true, | 
				
			||||
      result: data | 
				
			||||
    } | 
				
			||||
  } | 
				
			||||
} | 
				
			||||
		Reference in new issue