From acaed047ce9a18a3bf37d4f00830b1aa5c645fc6 Mon Sep 17 00:00:00 2001 From: sunzhuangzhuang <961120009@qq.com> Date: Wed, 3 Sep 2025 09:13:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/index.js | 21 ++ src/stores/user.js | 53 ++++- src/utils/api.js | 7 + src/views/Login.vue | 10 + src/views/Payment.vue | 446 +++++++++++++++++++++++++++++++++++++++++ src/views/Register.vue | 44 ++-- 6 files changed, 550 insertions(+), 31 deletions(-) create mode 100644 src/views/Payment.vue diff --git a/src/router/index.js b/src/router/index.js index 4310392..ab052ad 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -131,6 +131,15 @@ const routes = [ hideForAuth: true } }, + { + path: '/payment', + name: 'Payment', + component: () => import('@/views/Payment.vue'), + meta: { + title: '支付激活', + requiresAuth: true + } + }, { path: '/profile', name: 'Profile', @@ -357,6 +366,18 @@ router.beforeEach(async (to, from, next) => { return } } + + // 检查支付状态(管理员除外) + if (userStore.user && userStore.user.role !== 'admin' && userStore.user.payment_status === 'unpaid') { + // 如果当前不在支付页面,静默重定向到支付页面(不显示额外通知) + if (to.name !== 'Payment') { + next({ + name: 'Payment', + query: { redirect: to.fullPath } + }) + return + } + } } } diff --git a/src/stores/user.js b/src/stores/user.js index d35ac56..75a8b20 100644 --- a/src/stores/user.js +++ b/src/stores/user.js @@ -41,15 +41,37 @@ export const useUserStore = defineStore('user', () => { loading.value = true const response = await api.post('/auth/login', credentials) - if (response.data.token) { + if (response.data.success && response.data.token) { setToken(response.data.token) setUser(response.data.user) startStatusCheck() // 登录成功后开始状态检查 ElMessage.success(response.data.message || '登录成功') return { success: true, data: response.data } + } else if (response.data.needPayment) { + // 用户需要支付激活,不显示错误消息,由前端页面处理 + return { + success: false, + needPayment: true, + userId: response.data.userId, + message: response.data.message + } + } else { + const message = response.data.message || '登录失败' + ElMessage.error(message) + return { success: false, message } } } catch (error) { - const message = error.response?.data?.message || '登录失败' + const errorData = error.response?.data + if (errorData?.needPayment) { + // 处理403状态码返回的需要支付情况 + return { + success: false, + needPayment: true, + userId: errorData.userId, + message: errorData.message + } + } + const message = errorData?.message || '登录失败' ElMessage.error(message) return { success: false, message } } finally { @@ -63,11 +85,28 @@ export const useUserStore = defineStore('user', () => { loading.value = true const response = await api.post('/auth/register', userData) - if (response.data.token) { - setToken(response.data.token) - setUser(response.data.user) - ElMessage.success(response.data.message || '注册成功') - return { success: true, data: response.data } + if (response.data.success) { + // 检查是否需要支付 + if (response.data.needPayment) { + // 需要支付的情况,返回成功状态和支付相关信息 + return { + success: true, + needPayment: true, + token: response.data.token, + user: response.data.user, + message: response.data.message + } + } else { + // 直接注册成功的情况 + setToken(response.data.token) + setUser(response.data.user) + ElMessage.success(response.data.message || '注册成功') + return { success: true, data: response.data } + } + } else { + const message = response.data.message || '注册失败' + ElMessage.error(message) + return { success: false, message } } } catch (error) { const message = error.response?.data?.message || '注册失败' diff --git a/src/utils/api.js b/src/utils/api.js index 564d2c9..2c64765 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -88,6 +88,13 @@ api.interceptors.response.use( delete api.defaults.headers.common['Authorization'] router.push({ name: 'Login' }) ElMessage.error(data.message || '账户已被拉黑,请联系管理员') + } else if (data.code === 'PAYMENT_REQUIRED') { + // 需要支付,跳转到支付页面 + // 只在不是支付页面时才跳转和显示消息,避免重复通知 + if (router.currentRoute.value.name !== 'Payment') { + router.push({ name: 'Payment' }) + ElMessage.warning(data.message || '您的账户尚未激活,请完成支付后再使用') + } } else { ElMessage.error(data.message || '权限不足') } diff --git a/src/views/Login.vue b/src/views/Login.vue index 7003c9e..28e0f7e 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -179,6 +179,16 @@ const handleLogin = async () => { // 登录成功,跳转到目标页面或转账管理 const redirectPath = route.query.redirect || '/transfers' router.push(redirectPath) + } else if (result.needPayment) { + // 用户需要支付激活,直接跳转到支付页面 + ElMessage.info('账户尚未激活,正在跳转到支付页面...') + router.push({ + path: '/payment', + query: { + userId: result.userId, + from: 'login' + } + }) } } catch (error) { console.error('登录失败:', error) diff --git a/src/views/Payment.vue b/src/views/Payment.vue new file mode 100644 index 0000000..427565a --- /dev/null +++ b/src/views/Payment.vue @@ -0,0 +1,446 @@ + + + + + \ No newline at end of file diff --git a/src/views/Register.vue b/src/views/Register.vue index c8be449..01820a4 100644 --- a/src/views/Register.vue +++ b/src/views/Register.vue @@ -57,15 +57,7 @@ - - - + { const registerData = { username: registerForm.username, phone: registerForm.phone, - registrationCode: registerForm.registrationCode, city: registerForm.city, district_id: registerForm.district_id, password: registerForm.password, @@ -453,8 +441,21 @@ const handleRegister = async () => { const result = await userStore.register(registerData) if (result.success) { - ElMessage.success('注册成功!请登录') - router.push('/login') + // 检查是否需要支付 + if (result.needPayment) { + ElMessage.success('用户信息创建成功,请完成支付以激活账户') + // 跳转到支付页面 + router.push({ + path: '/payment', + query: { + token: result.token, + userId: result.user.id + } + }) + } else { + ElMessage.success('注册成功!请登录') + router.push('/login') + } } } catch (error) { console.error('注册失败:', error) @@ -524,12 +525,7 @@ onMounted(() => { router.push(redirectPath) } - // 从URL参数中获取邀请码并自动填入 - const inviteCode = route.query.code - if (inviteCode) { - registerForm.registrationCode = inviteCode - ElMessage.success('已自动填入邀请码') - } + // 获取地区数据 fetchRegions()