feat(登录): 调整微信授权为手动触发方式
将微信授权逻辑从自动检查改为用户点击触发 - 移除路由守卫中的自动微信授权检查 - 新增手动触发授权方法 startWxAuth - 登录页微信图标添加点击事件绑定 - 优化授权回跳后的登录态处理流程
Showing
4 changed files
with
118 additions
and
30 deletions
| ... | @@ -19,3 +19,8 @@ https://oa-dev.onwall.cn/f/mlaj | ... | @@ -19,3 +19,8 @@ https://oa-dev.onwall.cn/f/mlaj |
| 19 | - 学习详情页标签指示条修复:`/src/views/profile/StudyCoursePage.vue` | 19 | - 学习详情页标签指示条修复:`/src/views/profile/StudyCoursePage.vue` |
| 20 | - 现象:首次进入且存在“打卡互动”时,底部绿色指示条定位错误。 | 20 | - 现象:首次进入且存在“打卡互动”时,底部绿色指示条定位错误。 |
| 21 | - 修复:新增标签容器 `ref` 与 `ResizeObserver`,按栏目数量对容器进行等分,指示条宽度与位移按分段和索引计算,异步加载第三个栏目时不再错位。 | 21 | - 修复:新增标签容器 `ref` 与 `ResizeObserver`,按栏目数量对容器进行等分,指示条宽度与位移按分段和索引计算,异步加载第三个栏目时不再错位。 |
| 22 | + - 登录逻辑调整:仅在登录页微信图标点击时触发授权 | ||
| 23 | + - 变更文件:`/src/views/auth/LoginPage.vue`、`/src/router/guards.js`、`/src/router/index.js` | ||
| 24 | + - 路由守卫:移除自动微信授权检查,新增 `startWxAuth` 供手动触发。 | ||
| 25 | + - 登录页:微信图标绑定点击事件,非微信环境提示“请在微信内打开”。 | ||
| 26 | + - 使用方式:进入登录页,点击微信图标进行授权登录。 | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-03-20 20:36:36 | 2 | * @Date: 2025-03-20 20:36:36 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-11-19 20:37:35 | 4 | + * @LastEditTime: 2025-12-04 11:08:58 |
| 5 | * @FilePath: /mlaj/src/router/guards.js | 5 | * @FilePath: /mlaj/src/router/guards.js |
| 6 | * @Description: 路由守卫逻辑 | 6 | * @Description: 路由守卫逻辑 |
| 7 | */ | 7 | */ |
| ... | @@ -32,30 +32,65 @@ export const authRequiredRoutes = [ | ... | @@ -32,30 +32,65 @@ export const authRequiredRoutes = [ |
| 32 | }, | 32 | }, |
| 33 | ] | 33 | ] |
| 34 | 34 | ||
| 35 | -// TAG: 微信授权检查 | 35 | +/** |
| 36 | + * @description 兼容旧逻辑的微信授权检查(不再自动跳转) | ||
| 37 | + * @returns {boolean} 始终返回true,不在路由守卫内自动触发授权 | ||
| 38 | + */ | ||
| 36 | export const checkWxAuth = async () => { | 39 | export const checkWxAuth = async () => { |
| 37 | - if (!import.meta.env.DEV && wxInfo().isWeiXin) { | 40 | + // 说明:根据新业务需求,微信授权不应在路由守卫中自动触发 |
| 41 | + // 此函数保留以兼容旧代码调用,但不再进行重定向 | ||
| 38 | try { | 42 | try { |
| 39 | - const { code, data } = await getAuthInfoAPI(); | 43 | + if (!import.meta.env.DEV && wxInfo().isWeiXin) { |
| 40 | - if (code && !data.openid_has) { | 44 | + // 仅做一次授权状态探测,避免无意义请求 |
| 41 | - // 直接在这里处理授权跳转 | 45 | + await getAuthInfoAPI(); |
| 42 | - let raw_url = encodeURIComponent(location.href); // 未授权的地址 | ||
| 43 | - const short_url = `/srv/?f=behalo&a=openid&res=${raw_url}`; | ||
| 44 | - location.href = short_url; | ||
| 45 | - | ||
| 46 | - return false; | ||
| 47 | } | 46 | } |
| 48 | } catch (error) { | 47 | } catch (error) { |
| 49 | - console.error('微信授权检查失败:', error) | 48 | + // 忽略授权探测错误,不影响后续流程 |
| 50 | } | 49 | } |
| 50 | + return true; | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +/** | ||
| 54 | + * @description 手动发起微信授权登录(仅在用户点击微信图标时触发) | ||
| 55 | + * @returns {void} | ||
| 56 | + */ | ||
| 57 | +export const startWxAuth = async () => { | ||
| 58 | + // 开发环境不触发微信授权 | ||
| 59 | + if (import.meta.env.DEV) { | ||
| 60 | + // 开发环境下不触发微信授权登录 | ||
| 61 | + return; | ||
| 51 | } | 62 | } |
| 52 | - return true | 63 | + |
| 64 | + const info = wxInfo(); | ||
| 65 | + // 非微信环境不进行授权跳转 | ||
| 66 | + if (!info.isWeiXin) { | ||
| 67 | + return; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + // 如果已授权则不跳转;否则进入授权页 | ||
| 71 | + try { | ||
| 72 | + const { code, data } = await getAuthInfoAPI(); | ||
| 73 | + if (code && data.openid_has) { | ||
| 74 | + return; | ||
| 75 | + } | ||
| 76 | + } catch (e) { | ||
| 77 | + // 探测失败不影响授权流程,继续跳转 | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + // 跳转到微信授权地址 | ||
| 81 | + const raw_url = encodeURIComponent(location.href); | ||
| 82 | + const short_url = `/srv/?f=behalo&a=openid&res=${raw_url}`; | ||
| 83 | + location.href = short_url; | ||
| 53 | } | 84 | } |
| 54 | 85 | ||
| 55 | // 检查用户是否已登录 | 86 | // 检查用户是否已登录 |
| 56 | 87 | ||
| 57 | 88 | ||
| 58 | -// 登录权限检查 | 89 | +/** |
| 90 | + * @description 登录权限检查,未登录时重定向到登录页 | ||
| 91 | + * @param {*} to 目标路由对象 | ||
| 92 | + * @returns {true|Object} 允许通过或返回重定向对象 | ||
| 93 | + */ | ||
| 59 | export const checkAuth = (to) => { | 94 | export const checkAuth = (to) => { |
| 60 | const currentUser = JSON.parse(localStorage.getItem('currentUser')) | 95 | const currentUser = JSON.parse(localStorage.getItem('currentUser')) |
| 61 | 96 | ||
| ... | @@ -80,7 +115,6 @@ export const checkAuth = (to) => { | ... | @@ -80,7 +115,6 @@ export const checkAuth = (to) => { |
| 80 | if (needAuth && !currentUser) { | 115 | if (needAuth && !currentUser) { |
| 81 | // 未登录时重定向到登录页面 | 116 | // 未登录时重定向到登录页面 |
| 82 | return { path: '/login', query: { redirect: to.fullPath } } | 117 | return { path: '/login', query: { redirect: to.fullPath } } |
| 83 | - // return { path: '/login' } | ||
| 84 | } | 118 | } |
| 85 | 119 | ||
| 86 | return true | 120 | return true | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-03-20 20:36:36 | 2 | * @Date: 2025-03-20 20:36:36 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-08-26 09:43:50 | 4 | + * @LastEditTime: 2025-12-04 11:25:22 |
| 5 | * @FilePath: /mlaj/src/router/index.js | 5 | * @FilePath: /mlaj/src/router/index.js |
| 6 | * @Description: 路由实例创建和导出 | 6 | * @Description: 路由实例创建和导出 |
| 7 | */ | 7 | */ |
| 8 | import { createRouter, createWebHashHistory } from 'vue-router' | 8 | import { createRouter, createWebHashHistory } from 'vue-router' |
| 9 | import { routes } from './routes' | 9 | import { routes } from './routes' |
| 10 | -import { checkWxAuth, checkAuth } from './guards' | 10 | +import { checkAuth } from './guards' |
| 11 | +import { getUserIsLoginAPI } from '@/api/auth' | ||
| 12 | +import { getUserInfoAPI } from '@/api/users' | ||
| 11 | 13 | ||
| 12 | const router = createRouter({ | 14 | const router = createRouter({ |
| 13 | history: createWebHashHistory(import.meta.env.VITE_BASE || '/'), | 15 | history: createWebHashHistory(import.meta.env.VITE_BASE || '/'), |
| ... | @@ -20,29 +22,52 @@ const router = createRouter({ | ... | @@ -20,29 +22,52 @@ const router = createRouter({ |
| 20 | 22 | ||
| 21 | // 导航守卫 | 23 | // 导航守卫 |
| 22 | router.beforeEach(async (to, from, next) => { | 24 | router.beforeEach(async (to, from, next) => { |
| 23 | - // 微信授权检查 | ||
| 24 | - const wxAuthResult = await checkWxAuth() | ||
| 25 | - if (wxAuthResult !== true) { | ||
| 26 | - next(wxAuthResult) | ||
| 27 | - return | ||
| 28 | - } | ||
| 29 | - | ||
| 30 | // 检查用户是否已登录 | 25 | // 检查用户是否已登录 |
| 31 | const currentUser = JSON.parse(localStorage.getItem('currentUser') || 'null') | 26 | const currentUser = JSON.parse(localStorage.getItem('currentUser') || 'null') |
| 27 | + const redirectRaw = to.query && to.query.redirect | ||
| 32 | 28 | ||
| 33 | - // 登录权限检查 | 29 | + // 登录权限检查(不再自动触发微信授权) |
| 34 | const authResult = checkAuth(to) | 30 | const authResult = checkAuth(to) |
| 35 | if (authResult !== true) { | 31 | if (authResult !== true) { |
| 36 | next(authResult) | 32 | next(authResult) |
| 37 | return | 33 | return |
| 38 | } | 34 | } |
| 39 | 35 | ||
| 40 | - // 如果用户已经在登录页面,但已经登录了,重定向到首页 | 36 | + // 登录页统一处理授权回跳与默认重定向 |
| 41 | - if (to.path === '/login' && currentUser) { | 37 | + if (to.path === '/login') { |
| 42 | - next('/') | 38 | + /** |
| 39 | + * 情况1:本地已有登录态 | ||
| 40 | + * - 有 redirect:跳回来源页 | ||
| 41 | + * - 无 redirect:默认跳首页 | ||
| 42 | + */ | ||
| 43 | + if (currentUser) { | ||
| 44 | + const redirect = redirectRaw ? decodeURIComponent(redirectRaw) : '/' | ||
| 45 | + next(redirect) | ||
| 43 | return | 46 | return |
| 44 | } | 47 | } |
| 45 | 48 | ||
| 49 | + /** | ||
| 50 | + * 情况2:授权回跳但本地未写入登录态 | ||
| 51 | + * - 统一在路由层探测登录 | ||
| 52 | + * - 登录为真:写入用户信息,并按 redirect 或首页跳转 | ||
| 53 | + */ | ||
| 54 | + try { | ||
| 55 | + const { code, data } = await getUserIsLoginAPI() | ||
| 56 | + if (code && data && data.is_login) { | ||
| 57 | + const { code: uiCode, data: uiData } = await getUserInfoAPI() | ||
| 58 | + if (uiCode) { | ||
| 59 | + const mergedUser = { ...uiData.user, ...uiData.checkin } | ||
| 60 | + localStorage.setItem('currentUser', JSON.stringify(mergedUser)) | ||
| 61 | + } | ||
| 62 | + const redirect = redirectRaw ? decodeURIComponent(redirectRaw) : '/' | ||
| 63 | + next(redirect) | ||
| 64 | + return | ||
| 65 | + } | ||
| 66 | + } catch (e) { | ||
| 67 | + // 静默失败,进入登录页 | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 46 | next() | 71 | next() |
| 47 | }) | 72 | }) |
| 48 | 73 | ... | ... |
| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | class="min-h-screen flex flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 py-8 px-4 sm:px-6 lg:px-8" | 3 | class="min-h-screen flex flex-col bg-gradient-to-br from-green-50 via-teal-50 to-blue-50 py-8 px-4 sm:px-6 lg:px-8" |
| 4 | > | 4 | > |
| 5 | <div class="sm:mx-auto sm:w-full sm:max-w-md text-center"> | 5 | <div class="sm:mx-auto sm:w-full sm:max-w-md text-center"> |
| 6 | - <van-icon name="https://cdn.ipadbiz.cn/mlaj/icon/behalo-logo-1.png" size="10rem" style="margin-bottom: 0.5rem;" /> | 6 | + <van-icon name="https://cdn.ipadbiz.cn/mlaj/icon/behalo-logo-1.png?imageMogr2/thumbnail/200x/strip/quality/70" size="10rem" style="margin-bottom: 0.5rem;" /> |
| 7 | <h1 class="text-center text-3xl font-bold text-gray-800 mb-2">美乐爱觉教育</h1> | 7 | <h1 class="text-center text-3xl font-bold text-gray-800 mb-2">美乐爱觉教育</h1> |
| 8 | <!-- <h2 class="text-center text-xl font-medium text-gray-600">欢迎回来</h2> --> | 8 | <!-- <h2 class="text-center text-xl font-medium text-gray-600">欢迎回来</h2> --> |
| 9 | </div> | 9 | </div> |
| ... | @@ -173,7 +173,7 @@ | ... | @@ -173,7 +173,7 @@ |
| 173 | <div class="mt-6 flex justify-center items-center gap-4" style="flex-direction: column;"> | 173 | <div class="mt-6 flex justify-center items-center gap-4" style="flex-direction: column;"> |
| 174 | <div class="text-sm font-medium text-gray-600">其他登录方式</div> | 174 | <div class="text-sm font-medium text-gray-600">其他登录方式</div> |
| 175 | <div> | 175 | <div> |
| 176 | - <img :src="weixinLogo" alt="微信登录" style="width: 40px; height: 40px; border-radius: 8px;"> | 176 | + <img :src="weixinLogo" alt="微信登录" style="width: 40px; height: 40px; border-radius: 8px;" @click="handleWxLoginClick"> |
| 177 | </div> | 177 | </div> |
| 178 | </div> | 178 | </div> |
| 179 | </FrostedGlass> | 179 | </FrostedGlass> |
| ... | @@ -193,6 +193,8 @@ import { showToast } from "vant"; | ... | @@ -193,6 +193,8 @@ import { showToast } from "vant"; |
| 193 | import UserAgreement from "@/components/ui/UserAgreement.vue"; | 193 | import UserAgreement from "@/components/ui/UserAgreement.vue"; |
| 194 | import { setAuthHeaders } from "@/utils/axios"; | 194 | import { setAuthHeaders } from "@/utils/axios"; |
| 195 | import weixinLogo from '@/assets/images/weixin_logo_lg.jpeg' | 195 | import weixinLogo from '@/assets/images/weixin_logo_lg.jpeg' |
| 196 | +import { startWxAuth } from '@/router/guards' | ||
| 197 | +import { wxInfo } from '@/utils/tools' | ||
| 196 | 198 | ||
| 197 | const userAgreementRef = ref(null); | 199 | const userAgreementRef = ref(null); |
| 198 | 200 | ||
| ... | @@ -248,6 +250,26 @@ const startCountdown = () => { | ... | @@ -248,6 +250,26 @@ const startCountdown = () => { |
| 248 | }, 1000); | 250 | }, 1000); |
| 249 | }; | 251 | }; |
| 250 | 252 | ||
| 253 | +/** | ||
| 254 | + * @description 点击微信图标触发微信授权登录 | ||
| 255 | + * @returns {void} | ||
| 256 | + */ | ||
| 257 | +const handleWxLoginClick = async () => { | ||
| 258 | + // 非微信环境提示并不触发授权 | ||
| 259 | + if (!import.meta.env.DEV && !wxInfo().isWeiXin) { | ||
| 260 | + showToast('请在微信内打开以完成微信授权登录'); | ||
| 261 | + return; | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + try { | ||
| 265 | + // 手动发起微信授权流程(guards.js中实现) | ||
| 266 | + await startWxAuth(); | ||
| 267 | + } catch (e) { | ||
| 268 | + console.error('微信授权触发失败:', e); | ||
| 269 | + showToast('微信授权失败,请稍后重试'); | ||
| 270 | + } | ||
| 271 | +}; | ||
| 272 | + | ||
| 251 | const sendVerificationCode = async () => { | 273 | const sendVerificationCode = async () => { |
| 252 | if (!isPhoneValid.value) { | 274 | if (!isPhoneValid.value) { |
| 253 | return; | 275 | return; |
| ... | @@ -321,4 +343,6 @@ const handleSubmit = async () => { | ... | @@ -321,4 +343,6 @@ const handleSubmit = async () => { |
| 321 | loading.value = false; | 343 | loading.value = false; |
| 322 | } | 344 | } |
| 323 | }; | 345 | }; |
| 346 | + | ||
| 347 | +// 说明:授权回跳的重定向处理已移动到路由层 | ||
| 324 | </script> | 348 | </script> | ... | ... |
-
Please register or login to post a comment