From 0752efd3ffdfcba0a2d52c8312a3f5bb9853af15 Mon Sep 17 00:00:00 2001 From: chenhao <852066789@qq.com> Date: Thu, 28 Aug 2025 14:31:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E5=AE=9E=E7=8E=B0=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E7=99=BB=E5=BD=95=E5=92=8C=E6=9D=83=E9=99=90=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增登录页面和相关逻辑 - 添加全局权限控制守卫 - 更新订单列表和详情页面,优化用户体验- 重构部分代码以支持新功能 --- components.d.ts | 3 +++ src/api/order.ts | 12 +++++++++++- src/main.ts | 7 +++++-- src/router/index.ts | 40 ++++++++++++++++++++++++++++++++++---- src/types/index.ts | 7 +++++++ src/utils/http.ts | 10 +++++++++- src/views/Detail/index.vue | 22 +++++++++++++-------- src/views/List/index.vue | 4 ++-- 8 files changed, 87 insertions(+), 18 deletions(-) diff --git a/components.d.ts b/components.d.ts index 13e3588..9109a6f 100644 --- a/components.d.ts +++ b/components.d.ts @@ -10,8 +10,11 @@ declare module 'vue' { RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] VanButton: typeof import('vant/es')['Button'] + VanCellGroup: typeof import('vant/es')['CellGroup'] + VanCheckbox: typeof import('vant/es')['Checkbox'] VanEmpty: typeof import('vant/es')['Empty'] VanField: typeof import('vant/es')['Field'] + VanForm: typeof import('vant/es')['Form'] VanIcon: typeof import('vant/es')['Icon'] VanList: typeof import('vant/es')['List'] VanLoading: typeof import('vant/es')['Loading'] diff --git a/src/api/order.ts b/src/api/order.ts index 6c6cf60..df1d381 100644 --- a/src/api/order.ts +++ b/src/api/order.ts @@ -38,7 +38,17 @@ export const submitApproval = (params: any): Promise { if (params[key] !== undefined && params[key] !== null) { - formData.append(key, params[key].toString()) + // 特殊处理variables参数,它应该是一个对象 + if (key === 'variables' && typeof params[key] === 'object' && params[key] !== null) { + // 将variables对象的每个属性单独添加到FormData中 + Object.keys(params[key]).forEach(variableKey => { + if (params[key][variableKey] !== undefined && params[key][variableKey] !== null) { + formData.append(`variables[${variableKey}]`, params[key][variableKey].toString()) + } + }) + } else { + formData.append(key, params[key].toString()) + } } }) diff --git a/src/main.ts b/src/main.ts index 835e083..8afecc5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ import { createApp } from 'vue' import App from './App.vue' import router from './router' -import { createPinia } from 'pinia' +import { store, initStores } from './store' // Vant样式 import 'vant/lib/index.css' @@ -13,7 +13,10 @@ import '@/styles/index.scss' const app = createApp(App) -app.use(createPinia()) +app.use(store) app.use(router) +// 初始化 stores +initStores() + app.mount('#app') \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts index ed7d1c1..90a1f5c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,17 +1,29 @@ import { createRouter, createWebHistory } from 'vue-router' import type { RouteRecordRaw } from 'vue-router' +import { useAuthStore } from '@/store/auth' +import { store } from '@/store' const routes: RouteRecordRaw[] = [ { path: '/', - redirect: '/list' + redirect: '/login' + }, + { + path: '/login', + name: 'Login', + component: () => import('@/views/Login/index.vue'), + meta: { + title: '系统登录', + requiresAuth: false + } }, { path: '/list', name: 'OrderList', component: () => import('@/views/List/index.vue'), meta: { - title: '订单列表' + title: '订单列表', + requiresAuth: true } }, { @@ -19,7 +31,8 @@ const routes: RouteRecordRaw[] = [ name: 'OrderDetail', component: () => import('@/views/Detail/index.vue'), meta: { - title: '订单详情' + title: '订单详情', + requiresAuth: true } } ] @@ -38,7 +51,26 @@ router.beforeEach((to, from, next) => { if (to.meta?.title) { document.title = to.meta.title as string } - next() + + // 检查是否需要认证 + const requiresAuth = to.matched.some(record => record.meta.requiresAuth !== false) + + // 获取认证状态 + const authStore = useAuthStore(store) + const isAuthenticated = authStore.isAuthenticated || localStorage.getItem('isAuthenticated') === 'true' + + // 如果需要认证但未登录,重定向到登录页 + if (requiresAuth && !isAuthenticated) { + next('/login') + } + // 如果已登录且访问登录页,重定向到列表页 + else if (to.path === '/login' && isAuthenticated) { + next('/list') + } + // 其他情况正常跳转 + else { + next() + } }) export default router \ No newline at end of file diff --git a/src/types/index.ts b/src/types/index.ts index de3d60a..279ff25 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -6,6 +6,13 @@ export interface ApiResponse { total?: number } +// 登录参数类型 +export interface LoginParams { + username: string + password: string + rememberMe?: boolean +} + // 订单状态类型 export type OrderStatus = '0' | '1' | '2' // 待审批、已审批、已拒绝 diff --git a/src/utils/http.ts b/src/utils/http.ts index 95225bb..3207a32 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -54,7 +54,9 @@ class HttpClient { switch (status) { case 401: message = '未授权,请重新登录' - // 这里可以处理登录跳转逻辑 + // 清除认证信息并跳转到登录页 + localStorage.removeItem('isAuthenticated') + window.location.href = '/login' break case 403: message = '拒绝访问' @@ -62,6 +64,12 @@ class HttpClient { case 404: message = '请求地址不存在' break + case 302: + // 处理302重定向到登录页 + message = '会话已过期,请重新登录' + localStorage.removeItem('isAuthenticated') + window.location.href = '/login' + break case 500: message = '服务器内部错误' break diff --git a/src/views/Detail/index.vue b/src/views/Detail/index.vue index 5d59086..f8d8e22 100644 --- a/src/views/Detail/index.vue +++ b/src/views/Detail/index.vue @@ -51,11 +51,11 @@
BG - {{ currentOrderInfo.bgProperty || '' }} + {{ currentOrderInfo.bgPropertyDesc || '' }}
行业 - {{ currentOrderInfo.industryType || '' }} + {{ currentOrderInfo.industryTypeDesc || '' }}
代表处 @@ -83,7 +83,7 @@
币种 - {{ currentOrderInfo.currencyType || '' }} + {{ currentOrderInfo.currencyTypeDesc || '' }}
@@ -100,11 +100,11 @@
公司直发 - {{ currentOrderInfo.companyDelivery}} + {{ currentOrderInfo.companyDeliveryDesc}}
下单通路 - {{ currentOrderInfo.orderChannel}} + {{ currentOrderInfo.orderChannelDesc}}
供货商 {{ currentOrderInfo.supplier}} @@ -113,7 +113,7 @@ {{ currentOrderInfo.partnerName}}
进货商类型 - {{ currentOrderInfo.level}} + {{ currentOrderInfo.levelDesc}}
进货商联系人 {{ currentOrderInfo.partnerUserName}} @@ -579,8 +579,14 @@ const submitApproval = async () => { showSuccessToast(currentApprovalStatus.value === 0 ? '驳回成功' : '审批通过') approvalDialogVisible.value = false - // 重新加载详情 - await orderStore.fetchOrderDetail(route.params.id as string) + // 如果是审批通过,跳转到列表页面 + if (currentApprovalStatus.value !== 0) { + // 跳转到列表页面 + router.push('/list') + } else { + // 驳回情况下重新加载详情 + await orderStore.fetchOrderDetail(route.params.id as string) + } } catch (error) { console.error('提交审批失败:', error) showToast('提交审批失败') diff --git a/src/views/List/index.vue b/src/views/List/index.vue index 77e59dc..9abe162 100644 --- a/src/views/List/index.vue +++ b/src/views/List/index.vue @@ -20,8 +20,8 @@
{{ order.orderCode }}
-
- {{ formatOrderStatus(order.orderStatus) }} +
+ 待审批