李金
7 months ago
15 changed files with 646 additions and 486 deletions
-
1package.json
-
12src/components/switch/index.tsx
-
5src/locales/lang/zh-CN.ts
-
54src/pages/system/menus/index.tsx
-
112src/pages/system/menus/store.ts
-
10src/pages/system/menus/style.ts
-
413src/pages/system/roles/index.tsx
-
90src/pages/system/roles/store.ts
-
177src/request.ts
-
8src/service/base.ts
-
2src/types.d.ts
-
35src/types/roles.d.ts
-
158src/utils/index.ts
-
8src/vite-env.d.ts
-
47vite.config.ts
@ -0,0 +1,12 @@ |
|||
import { convertToBool } from '@/utils' |
|||
import { Switch as AntSwitch, SwitchProps } from 'antd' |
|||
|
|||
|
|||
export const Switch = ({ value, ...props }: SwitchProps) => { |
|||
console.log(value, props) |
|||
return ( |
|||
<AntSwitch {...props} value={convertToBool(value)}/> |
|||
) |
|||
} |
|||
|
|||
export default Switch |
@ -1,99 +1,140 @@ |
|||
import { getToken, setToken } from '@/store/system.ts' |
|||
import { IApiResult } from '@/types' |
|||
import { Record } from '@icon-park/react' |
|||
import { message } from 'antd' |
|||
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios' |
|||
import axios, { |
|||
AxiosRequestConfig, |
|||
AxiosInstance, AxiosResponse, |
|||
} from 'axios' |
|||
|
|||
|
|||
export type { AxiosRequestConfig } |
|||
type FetchMethod = <T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>) => Promise<IApiResult<T>> |
|||
|
|||
interface RequestMethods extends Pick<AxiosInstance, 'get' | 'post' | 'put' | 'delete' | 'request' | 'postForm' | 'patch' | 'patchForm' | 'putForm' | 'options'> { |
|||
} |
|||
|
|||
export const request = axios.create({ |
|||
baseURL: '/api/v1', |
|||
// timeout: 1000,
|
|||
headers: { |
|||
'Content-Type': 'application/json', |
|||
}, |
|||
|
|||
const axiosInstance = axios.create({ |
|||
baseURL: '/api/v1', |
|||
// timeout: 1000,
|
|||
headers: { |
|||
'Content-Type': 'application/json', |
|||
}, |
|||
}) |
|||
|
|||
//拦截request,添加token
|
|||
request.interceptors.request.use((config) => { |
|||
axiosInstance.interceptors.request.use((config) => { |
|||
|
|||
const token = getToken() |
|||
if (token) { |
|||
config.headers.Authorization = `Bearer ${token}` |
|||
} |
|||
const token = getToken() |
|||
if (token) { |
|||
config.headers.Authorization = `Bearer ${token}` |
|||
} |
|||
|
|||
return config |
|||
return config |
|||
}, (error) => { |
|||
console.log('error', error) |
|||
return Promise.reject(error) |
|||
console.log('error', error) |
|||
return Promise.reject(error) |
|||
}) |
|||
|
|||
|
|||
//拦截response,返回data
|
|||
request.interceptors.response.use((response: AxiosResponse) => { |
|||
axiosInstance.interceptors.response.use( |
|||
(response) => { |
|||
// console.log('response', response.data)
|
|||
|
|||
message.destroy() |
|||
|
|||
switch (response.data.code) { |
|||
case 200: |
|||
//login
|
|||
if (response.config.url?.includes('/sys/login')) { |
|||
setToken(response.data.data.token) |
|||
} |
|||
return response.data |
|||
case 401: |
|||
setToken('') |
|||
if (window.location.pathname === '/login') { |
|||
return |
|||
} |
|||
|
|||
|
|||
// 401: 未登录
|
|||
message.error('登录失败,跳转重新登录') |
|||
// eslint-disable-next-line no-case-declarations
|
|||
const search = new URLSearchParams(window.location.search) |
|||
// eslint-disable-next-line no-case-declarations
|
|||
let redirect = window.location.pathname |
|||
if (search.toString() !== '') { |
|||
redirect = window.location.pathname + '?=' + search.toString() |
|||
} |
|||
window.location.href = `/login?redirect=${encodeURIComponent(redirect)}` |
|||
return |
|||
default: |
|||
message.error(response.data.message) |
|||
return Promise.reject(response) |
|||
const result = response.data as IApiResult |
|||
|
|||
switch (result.code) { |
|||
case 200: |
|||
//login
|
|||
if (response.config.url?.includes('/sys/login')) { |
|||
setToken(result.data.token) |
|||
} |
|||
return response |
|||
case 401: |
|||
setToken('') |
|||
if (window.location.pathname === '/login') { |
|||
return Promise.reject(new Error('to login')) |
|||
} |
|||
|
|||
|
|||
// 401: 未登录
|
|||
message.error('登录失败,跳转重新登录') |
|||
// eslint-disable-next-line no-case-declarations
|
|||
const search = new URLSearchParams(window.location.search) |
|||
// eslint-disable-next-line no-case-declarations
|
|||
let redirect = window.location.pathname |
|||
if (search.toString() !== '') { |
|||
redirect = window.location.pathname + '?=' + search.toString() |
|||
} |
|||
window.location.href = `/login?redirect=${encodeURIComponent(redirect)}` |
|||
return Promise.reject(new Error('to login')) |
|||
default: |
|||
message.error(result.message ?? '请求失败') |
|||
return Promise.reject(response) |
|||
} |
|||
|
|||
}, (error) => { |
|||
}, (error) => { |
|||
// console.log('error', error)
|
|||
const { response } = error |
|||
if (response) { |
|||
switch (response.status) { |
|||
case 401: |
|||
if (window.location.pathname === '/login') { |
|||
return |
|||
} |
|||
|
|||
setToken('') |
|||
// 401: 未登录
|
|||
message.error('登录失败,跳转重新登录') |
|||
// eslint-disable-next-line no-case-declarations
|
|||
const search = new URLSearchParams(window.location.search) |
|||
// eslint-disable-next-line no-case-declarations
|
|||
let redirect = window.location.pathname |
|||
if (search.toString() !== '') { |
|||
redirect = window.location.pathname + '?=' + search.toString() |
|||
} |
|||
window.location.href = `/login?redirect=${encodeURIComponent(redirect)}` |
|||
return |
|||
default: |
|||
message.error(response.data.message) |
|||
return Promise.reject(response) |
|||
} |
|||
switch (response.status) { |
|||
case 401: |
|||
if (window.location.pathname === '/login') { |
|||
return |
|||
} |
|||
|
|||
setToken('') |
|||
// 401: 未登录
|
|||
message.error('登录失败,跳转重新登录') |
|||
// eslint-disable-next-line no-case-declarations
|
|||
const search = new URLSearchParams(window.location.search) |
|||
// eslint-disable-next-line no-case-declarations
|
|||
let redirect = window.location.pathname |
|||
if (search.toString() !== '') { |
|||
redirect = window.location.pathname + '?=' + search.toString() |
|||
} |
|||
window.location.href = `/login?redirect=${encodeURIComponent(redirect)}` |
|||
return |
|||
default: |
|||
message.error(response.data.message) |
|||
return Promise.reject(response) |
|||
} |
|||
} |
|||
|
|||
return Promise.reject(error) |
|||
}) |
|||
}) |
|||
|
|||
|
|||
export const createFetchMethods = () => { |
|||
const methods = {} |
|||
|
|||
for (const method of Object.keys(axiosInstance)) { |
|||
methods[method] = <T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>) => { |
|||
if (config && data) { |
|||
config = { |
|||
...config, |
|||
data, |
|||
} |
|||
} |
|||
return axiosInstance[method](url, config) |
|||
.then((response: AxiosResponse<IApiResult<T>>) => { |
|||
if (response.data.code !== 200) { |
|||
throw new Error(response.data.message) |
|||
} |
|||
return response.data as IApiResult<T> |
|||
}) |
|||
.catch((err) => { |
|||
throw err |
|||
}) |
|||
} |
|||
} |
|||
|
|||
return methods as Record<keyof RequestMethods, FetchMethod> |
|||
} |
|||
|
|||
export const request = createFetchMethods() |
|||
export default request |
@ -1 +1,9 @@ |
|||
/// <reference types="vite/client" />
|
|||
interface ImportMetaEnv { |
|||
readonly API_URL: string |
|||
// 更多环境变量...
|
|||
} |
|||
|
|||
interface ImportMeta { |
|||
readonly env: ImportMetaEnv |
|||
} |
@ -1,36 +1,43 @@ |
|||
import { defineConfig } from 'vite' |
|||
import { defineConfig, loadEnv } from 'vite' |
|||
import react from '@vitejs/plugin-react' |
|||
import { viteMockServe } from 'vite-plugin-mock' |
|||
|
|||
//import { TanStackRouterVite } from '@tanstack/router-vite-plugin'
|
|||
|
|||
|
|||
// https://vitejs.dev/config/
|
|||
export default defineConfig({ |
|||
export default defineConfig(({ mode }) => { |
|||
|
|||
// 根据当前工作目录中的 `mode` 加载 .env 文件
|
|||
// 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
|
|||
const env = loadEnv(mode, process.cwd(), '') |
|||
return { |
|||
//定义别名的路径
|
|||
resolve: { |
|||
alias: { |
|||
'@': '/src', |
|||
}, |
|||
alias: { |
|||
'@': '/src', |
|||
}, |
|||
}, |
|||
server: { |
|||
proxy: { |
|||
'/api': { |
|||
target: 'http://47.113.117.106:8000', |
|||
changeOrigin: true, |
|||
rewrite: (path) => path |
|||
} |
|||
proxy: { |
|||
'/api': { |
|||
target: env.API_URL, |
|||
changeOrigin: true, |
|||
rewrite: (path) => path |
|||
} |
|||
} |
|||
}, |
|||
plugins: [ |
|||
react(), |
|||
viteMockServe({ |
|||
// 是否启用 mock 功能(默认值:process.env.NODE_ENV !== 'production')
|
|||
enable: false, |
|||
react(), |
|||
viteMockServe({ |
|||
// 是否启用 mock 功能(默认值:process.env.NODE_ENV !== 'production')
|
|||
enable: false, |
|||
|
|||
// mock 文件的根路径,默认值:'mocks'
|
|||
mockPath: 'mock', |
|||
logger: true, |
|||
}), |
|||
//TanStackRouterVite(),
|
|||
// mock 文件的根路径,默认值:'mocks'
|
|||
mockPath: 'mock', |
|||
logger: true, |
|||
}), |
|||
//TanStackRouterVite(),
|
|||
], |
|||
} |
|||
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue