hookehuyr

feat(登录): 调整微信授权为手动触发方式

将微信授权逻辑从自动检查改为用户点击触发
- 移除路由守卫中的自动微信授权检查
- 新增手动触发授权方法 startWxAuth
- 登录页微信图标添加点击事件绑定
- 优化授权回跳后的登录态处理流程
...@@ -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>
......