feat: 更新环境配置和错误处理逻辑
- 更新后端端口号和环境配置,添加Redis支持 - 改进错误处理,添加带消息的未授权和禁止访问错误 - 优化前端登录流程和错误提示 - 更新前端页面标题和欢迎信息 - 清理未使用的代码模块
This commit is contained in:
@ -90,7 +90,7 @@ export default function Dashboard() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<PageHeader items={["首页"]} title="首页" />
|
||||
{/* <PageHeader items={["首页"]} title="" /> */}
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col xs={12} sm={12} md={6}>
|
||||
<Card loading={loading}>
|
||||
@ -163,7 +163,7 @@ export default function Dashboard() {
|
||||
|
||||
<Card style={{ marginTop: 16 }}>
|
||||
<Typography.Paragraph>
|
||||
欢迎使用 道友Admin。当前首页展示了若干概览与示例报表,真实数据以接口返回为准。
|
||||
欢迎使用 道友管理后台。当前首页展示了若干概览与示例报表,真实数据以接口返回为准。
|
||||
</Typography.Paragraph>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { LockOutlined, UserOutlined } from '@ant-design/icons'
|
||||
import { Button, Card, Form, Input, message, Typography } from 'antd'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import api from '../utils/axios'
|
||||
import api, { type ApiResp } from '../utils/axios'
|
||||
import { setToken, setUser } from '../utils/token'
|
||||
import './login.css'
|
||||
|
||||
@ -11,26 +11,27 @@ export default function Login() {
|
||||
|
||||
const onFinish = async (values: any) => {
|
||||
try {
|
||||
const { data } = await api.post('/auth/login', values)
|
||||
const { data } = await api.post<ApiResp<{ access_token: string; user: any }>>('/auth/login', values)
|
||||
if (data?.code === 0) {
|
||||
const token = data.data.access_token
|
||||
const token = data.data!.access_token
|
||||
setToken(token)
|
||||
setUser(data.data.user)
|
||||
setUser(data.data!.user)
|
||||
message.success('登录成功')
|
||||
navigate('/', { replace: true })
|
||||
} else {
|
||||
throw new Error(data?.message || '登录失败')
|
||||
}
|
||||
} catch (e: any) {
|
||||
message.error(e.message || '登录失败')
|
||||
const serverMsg = e?.response?.data?.message
|
||||
message.error(serverMsg || e.message || '登录失败')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="login-wrap">
|
||||
<Card className="login-card" variant="outlined">
|
||||
<Typography.Title level={3} style={{ textAlign: 'center', marginBottom: 24 }}>Udmin 管理后台</Typography.Title>
|
||||
<Form form={form} onFinish={onFinish} layout="vertical" initialValues={{ username: 'admin', password: 'Admin@123' }}>
|
||||
<Typography.Title level={3} style={{ textAlign: 'center', marginBottom: 24 }}>道友 管理后台</Typography.Title>
|
||||
<Form form={form} onFinish={onFinish} layout="vertical" initialValues={{ username: 'admin', password: '123456' }}>
|
||||
<Form.Item name="username" label="用户名" rules={[{ required: true }]}>
|
||||
<Input size="large" prefix={<UserOutlined />} placeholder="用户名" />
|
||||
</Form.Item>
|
||||
|
||||
@ -33,8 +33,34 @@ api.interceptors.response.use(
|
||||
(r: AxiosResponse) => r,
|
||||
async (error: AxiosError<ApiResp<unknown>>) => {
|
||||
const original = (error.config || {}) as RetryConfig
|
||||
if (error.response?.status === 401 && !original._retry) {
|
||||
const status = error.response?.status
|
||||
if (status === 401) {
|
||||
const reqUrl = (original?.url || '').toString()
|
||||
const resp = error.response?.data as ApiResp<unknown> | undefined
|
||||
|
||||
// 登录接口返回 401:不做 refresh,不跳转,直接把服务端消息抛给调用方
|
||||
if (reqUrl.includes('/auth/login')) {
|
||||
const msg = resp?.message || '用户名或密码错误'
|
||||
return Promise.reject(new Error(msg))
|
||||
}
|
||||
|
||||
// 已经重试过了,直接拒绝
|
||||
if (original._retry) {
|
||||
return Promise.reject(error)
|
||||
}
|
||||
original._retry = true
|
||||
|
||||
const hasToken = !!getToken()
|
||||
if (!hasToken) {
|
||||
// 没有 token 的 401:如果不在登录页,则跳转到登录页;否则仅抛错以便界面提示
|
||||
if (typeof window !== 'undefined' && window.location.pathname !== '/login') {
|
||||
window.location.href = '/login'
|
||||
}
|
||||
const msg = resp?.message || '未登录或登录已过期'
|
||||
return Promise.reject(new Error(msg))
|
||||
}
|
||||
|
||||
// 有 token 的 401:尝试刷新
|
||||
if (!isRefreshing) {
|
||||
isRefreshing = true
|
||||
try {
|
||||
@ -50,7 +76,7 @@ api.interceptors.response.use(
|
||||
pendingQueue.forEach(p => p.reject(e))
|
||||
pendingQueue = []
|
||||
clearToken()
|
||||
if (typeof window !== 'undefined') {
|
||||
if (typeof window !== 'undefined' && window.location.pathname !== '/login') {
|
||||
window.location.href = '/login'
|
||||
}
|
||||
return Promise.reject(e)
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
// 前端系统配置常量
|
||||
export const APP_CONFIG = {
|
||||
// 网站标题配置
|
||||
SITE_NAME: '道友管理系统',
|
||||
SITE_NAME_SHORT: '道友',
|
||||
SITE_NAME: '道友',
|
||||
SITE_NAME_SHORT: '道',
|
||||
|
||||
// 其他系统配置可以在这里添加
|
||||
// 如: API_VERSION: 'v1', DEFAULT_PAGE_SIZE: 10 等
|
||||
|
||||
Reference in New Issue
Block a user