From 39542b378f623e1ecb32bb7ae532975e9abea200 Mon Sep 17 00:00:00 2001 From: LuRuiqian <2632862493@qq.com> Date: Fri, 17 Apr 2026 11:44:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=92=8CAPI=E7=BB=93=E6=9E=84=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=A8=E6=80=81=E8=8F=9C=E5=8D=95=E5=92=8C?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E6=9D=83=E9=99=90=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构登录页面为简洁风格,移除动画角色,优化表单验证和错误提示 - 重新组织API模块结构,拆分为system和user子模块 - 添加动态菜单获取和路由权限控制功能 - 实现404页面和错误处理 - 更新环境配置文件,区分开发、测试和生产环境 - 优化请求拦截器,处理token和错误响应 - 添加菜单状态管理,支持动态路由生成和权限验证 - 更新主布局,支持动态菜单渲染和响应式设计 - 优化首页样式和组件结构 --- .env.development | 11 + .env.production | 11 + .env.test | 11 + src/api/index.ts | 4 + src/api/request.ts | 16 +- src/api/system/loginApi.ts | 24 + src/api/system/menuApi.ts | 9 + src/api/user/userApi.ts | 45 ++ src/api/userApi.ts | 23 - src/layouts/MainLayout.vue | 139 +++++- src/router/index.ts | 67 ++- src/stores/menuStore.ts | 143 ++++++ src/views/error/404.vue | 76 ++++ src/views/home/index.vue | 27 +- src/views/login/index.vue | 885 +++++++++++++------------------------ vite.config.ts | 7 + 16 files changed, 847 insertions(+), 651 deletions(-) create mode 100644 .env.development create mode 100644 .env.production create mode 100644 .env.test create mode 100644 src/api/index.ts create mode 100644 src/api/system/loginApi.ts create mode 100644 src/api/system/menuApi.ts create mode 100644 src/api/user/userApi.ts delete mode 100644 src/api/userApi.ts create mode 100644 src/stores/menuStore.ts create mode 100644 src/views/error/404.vue diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..59802bd --- /dev/null +++ b/.env.development @@ -0,0 +1,11 @@ +# 开发环境配置 +NODE_ENV=development + +# 后端API基础地址(代理用) +VITE_API_BASE_URL=/api + +# 系统名称 +VITE_APP_TITLE=后台管理系统(开发版) + +# 是否开启mock数据 +VITE_USE_MOCK=true diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..ed3ba0f --- /dev/null +++ b/.env.production @@ -0,0 +1,11 @@ +# 生产环境配置 +NODE_ENV=production + +# 后端API基础地址 +VITE_API_BASE_URL=https://api.example.com + +# 系统名称 +VITE_APP_TITLE=后台管理系统 + +# 是否开启mock数据 +VITE_USE_MOCK=false diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..836e3ba --- /dev/null +++ b/.env.test @@ -0,0 +1,11 @@ +# 测试环境配置 +NODE_ENV=production + +# 后端API基础地址 +VITE_API_BASE_URL=http://test-api.example.com + +# 系统名称 +VITE_APP_TITLE=后台管理系统(测试版) + +# 是否开启mock数据 +VITE_USE_MOCK=false diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..2fefdf5 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,4 @@ +// API 统一出口 +export * from './system/loginApi' +export * from './system/menuApi' +export * from './user/userApi' diff --git a/src/api/request.ts b/src/api/request.ts index a1a2182..735d566 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -14,8 +14,11 @@ request.interceptors.request.use( (config) => { const userStore = useUserStore() if (userStore.token) { - config.headers.Authorization = `Bearer ${userStore.token}` + config.headers.token = userStore.token } + // 删除 Cookie 和 Authorization + delete config.headers.Cookie + delete config.headers.Authorization return config }, (error) => { @@ -26,11 +29,12 @@ request.interceptors.request.use( request.interceptors.response.use( (response: AxiosResponse) => { const { data } = response - if (data.code !== 200) { - ElMessage.error(data.message || '请求失败') - return Promise.reject(new Error(data.message)) + // code 为 0 或 200 表示成功 + if (data.code !== 0 && data.code !== 200) { + ElMessage.error(data.msg || '请求失败') + return Promise.reject(new Error(data.msg || '请求失败')) } - return data + return data.data }, (error) => { const { response } = error @@ -39,7 +43,7 @@ request.interceptors.response.use( userStore.clearUser() window.location.href = '/login' } - ElMessage.error(response?.data?.message || '网络错误') + ElMessage.error(response?.data?.msg || '网络错误') return Promise.reject(error) } ) diff --git a/src/api/system/loginApi.ts b/src/api/system/loginApi.ts new file mode 100644 index 0000000..148d7e5 --- /dev/null +++ b/src/api/system/loginApi.ts @@ -0,0 +1,24 @@ +import request from '../request' + +// 登录接口 +export function login(data: { username: string; password: string; captcha: string; uuid: string }) { + return request({ + url: '/login', + method: 'post', + data, + }) +} + +// 获取验证码 +export function getCaptchaUrl(uuid: string) { + const baseUrl = import.meta.env.VITE_API_BASE_URL || '/api' + return `${baseUrl}/captcha?uuid=${uuid}&t=${Date.now()}` +} + +// 退出登录 +export function logout() { + return request({ + url: '/sys/logout', + method: 'post', + }) +} diff --git a/src/api/system/menuApi.ts b/src/api/system/menuApi.ts new file mode 100644 index 0000000..53fdf43 --- /dev/null +++ b/src/api/system/menuApi.ts @@ -0,0 +1,9 @@ +import request from '../request' + +// 获取动态菜单 +export function getNavMenu() { + return request({ + url: '/sys/menu/nav', + method: 'get', + }) +} diff --git a/src/api/user/userApi.ts b/src/api/user/userApi.ts new file mode 100644 index 0000000..ef2f26e --- /dev/null +++ b/src/api/user/userApi.ts @@ -0,0 +1,45 @@ +import request from '../request' + +// 获取用户信息 +export function getUserInfo() { + return request({ + url: '/sys/user/info', + method: 'get', + }) +} + +// 获取用户列表 +export function getUserList(params: { page: number; limit: number; username?: string }) { + return request({ + url: '/sys/user/list', + method: 'get', + params, + }) +} + +// 新增用户 +export function addUser(data: Record) { + return request({ + url: '/sys/user/save', + method: 'post', + data, + }) +} + +// 修改用户 +export function updateUser(data: Record) { + return request({ + url: '/sys/user/update', + method: 'post', + data, + }) +} + +// 删除用户 +export function deleteUser(ids: number[]) { + return request({ + url: '/sys/user/delete', + method: 'post', + data: ids, + }) +} diff --git a/src/api/userApi.ts b/src/api/userApi.ts deleted file mode 100644 index 2b2bf6b..0000000 --- a/src/api/userApi.ts +++ /dev/null @@ -1,23 +0,0 @@ -import request from './request' - -export interface LoginParams { - username: string - password: string -} - -export interface LoginResult { - token: string - userInfo: Record -} - -export function login(data: LoginParams) { - return request.post('/user/login', data) -} - -export function getUserInfo() { - return request.get('/user/info') -} - -export function logout() { - return request.post('/user/logout') -} diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 32c5d57..e43756b 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -1,7 +1,9 @@ + + diff --git a/src/views/home/index.vue b/src/views/home/index.vue index a24d661..b145554 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -1,5 +1,5 @@ - - diff --git a/vite.config.ts b/vite.config.ts index 1071f07..c27a92d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -13,5 +13,12 @@ export default defineConfig({ server: { port: 3000, open: true, + proxy: { + '/api': { + target: 'http://localhost:8080/', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, ''), + }, + }, }, })