hookehuyr

refactor(登录认证): 重构登录认证流程并简化照片查询入口

移除照片查询页面的登录校验,改为统一由路由守卫处理
重构登录跳转逻辑,增加安全导航函数处理重定向
将token有效期从7天改为3天
/*
* @Date: 2025-10-30 10:29:15
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-11-11 12:56:04
* @LastEditTime: 2025-11-11 22:10:22
* @FilePath: /stdj_h5/src/router/index.js
* @Description: 文件描述
*/
......@@ -98,14 +98,18 @@ router.beforeEach((to, from, next) => {
}
/**
* 访问控制:仅在进入 /studentInfo 时校验登录状态
* 访问控制:除首页('/')与登录页外,其余页面均需登录
* 说明:优先读取 Cookie 中的 token;若不存在则回退读取本地存储 token,避免重复登录。
*/
const has_token_cookie = !!Cookies.get('token-stdj')
const is_login = has_token_cookie
const token_cookie = Cookies.get('token-stdj')
const is_login = !!(token_cookie)
if (to.path === '/studentInfo' && !is_login) {
// 关键:在重定向前关闭或重置上一跳的loading,避免计数残留
// 白名单:无需登录校验的路径
const white_list = ['/', '/login']
const need_auth = !white_list.includes(to.path)
if (need_auth && !is_login) {
// 在重定向前关闭或重置上一跳的loading,避免计数残留
try {
const loading = useLoadingStore()
loading.reset()
......@@ -116,7 +120,6 @@ router.beforeEach((to, from, next) => {
return
}
// 其他页面不做登录校验
next()
})
......
......@@ -125,7 +125,7 @@
<div class="photo-section" @click="handlePhotoClick">
<div class="photo-content">
<div class="photo-title">照片查询下载</div>
<div class="more-button"><span class="more-text">身份验证</span></div>
<div class="more-button"><span class="more-text">进入</span></div>
</div>
</div>
</div>
......@@ -184,7 +184,6 @@ import VideoPlayer from '@/components/VideoPlayer.vue'
import { useTitle } from '@vueuse/core';
import { useRouter } from 'vue-router'
import { showToast } from 'vant'
import Cookies from 'js-cookie'
// 导入接口
import { homePageAPI } from '@/api/index.js'
......@@ -653,16 +652,9 @@ const dismissSwipeHint = () => {
* 说明:未登录跳转登录页;已登录进入戒子信息页面。
* @returns {void}
*/
// 登录状态获取
const hasLogin = computed(() => Boolean(Cookies.get('token-stdj')))
const handlePhotoClick = () => {
// 判断是否已登录
if (hasLogin.value) {
router.push('/studentInfo')
} else {
router.push('/login')
}
router.push('/studentInfo')
}
</script>
......
<!--
* @Date: 2025-11-10 18:08:59
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-11-11 15:51:10
* @LastEditTime: 2025-11-11 22:45:33
* @FilePath: /stdj_h5/src/views/Login.vue
* @Description: 登录页
-->
......@@ -162,6 +162,24 @@ const on_send_sms = async function () {
}
}
const safe_navigate = function () {
// 跳转目标处理:兼容 redirect 携带 query/hash 的场景
// 说明:当地址形如 /login?redirect=/masters?pid=3651943 时,使用字符串导航更安全;
// 同时解析并保留查询与哈希,避免对象形式 path 丢失查询参数。
const redirect_raw = String(route.query.redirect || '').trim()
let redirect_target = '/home'
if (redirect_raw) {
try {
const url = new URL(redirect_raw, window.location.origin)
redirect_target = url.pathname + url.search + url.hash
} catch (err) {
// 若不是标准URL(仅相对路径),直接使用或回退到默认页
redirect_target = redirect_raw.startsWith('/') ? redirect_raw : '/home'
}
}
router.replace(redirect_target)
}
/**
* 登录
* @returns {Promise<void>}
......@@ -181,10 +199,12 @@ const on_login = async function () {
const { code, data } = await loginAPI({ mobile: phone.value, code: code.value })
if (code) {
// 登录成功后,将token存储到cookie中
Cookies.set('token-stdj', data.token, { expires: 7 })
Cookies.set('token-stdj', data.token, { expires: 3 })
showSuccessToast('登录成功')
// 跳转戒子详情页
router.replace({ path: route.query.redirect })
setTimeout(() => {
// 登录成功后,跳转至 redirect 目标页或默认首页
safe_navigate()
}, 1000)
}
} catch (e) {
showFailToast('网络异常,请稍后重试')
......