fix(auth): 修复登录、注册和忘记密码页面的功能实现
- 移除登录页面的默认手机号和密码 - 更新用户信息接口和重置密码接口的请求方法为POST - 实现发送验证码、注册和重置密码的API调用 - 优化路由守卫逻辑,简化登录检查流程
Showing
7 changed files
with
68 additions
and
53 deletions
| ... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
| 2 | VITE_BASE = / | 2 | VITE_BASE = / |
| 3 | 3 | ||
| 4 | # 测试open-id | 4 | # 测试open-id |
| 5 | -VITE_OPENID = api-test-openid | 5 | +# VITE_OPENID = api-test-openid |
| 6 | # VITE_OPENID = o8BRf1gLDWieH3Y3JvbrI_4IjaME | 6 | # VITE_OPENID = o8BRf1gLDWieH3Y3JvbrI_4IjaME |
| 7 | # VITE_OPENID = oJLZq5t9PIKLW9tm1oSUNAuPwssA | 7 | # VITE_OPENID = oJLZq5t9PIKLW9tm1oSUNAuPwssA |
| 8 | # VITE_OPENID = oJLZq5uT_6GwIh2tQWh1F9IoHZ3U | 8 | # VITE_OPENID = oJLZq5uT_6GwIh2tQWh1F9IoHZ3U | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-03-20 19:53:12 | 2 | * @Date: 2025-03-20 19:53:12 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-03-25 14:31:15 | 4 | + * @LastEditTime: 2025-03-26 11:30:48 |
| 5 | * @FilePath: /mlaj/src/App.vue | 5 | * @FilePath: /mlaj/src/App.vue |
| 6 | * @Description: 入口文件 | 6 | * @Description: 入口文件 |
| 7 | --> | 7 | --> | ... | ... |
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-03-23 23:45:53 | 2 | * @Date: 2025-03-23 23:45:53 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-03-26 00:41:11 | 4 | + * @LastEditTime: 2025-03-26 12:24:03 |
| 5 | * @FilePath: /mlaj/src/api/users.js | 5 | * @FilePath: /mlaj/src/api/users.js |
| 6 | * @Description: 用户相关接口 | 6 | * @Description: 用户相关接口 |
| 7 | */ | 7 | */ |
| ... | @@ -43,7 +43,7 @@ export const getUserInfoAPI = () => fn(fetch.get(Api.USER_INFO)); | ... | @@ -43,7 +43,7 @@ export const getUserInfoAPI = () => fn(fetch.get(Api.USER_INFO)); |
| 43 | * @param: name 用户名称 | 43 | * @param: name 用户名称 |
| 44 | * @param: avatar 头像 | 44 | * @param: avatar 头像 |
| 45 | */ | 45 | */ |
| 46 | -export const updateUserInfoAPI = (params) => fn(fetch.put(Api.USER_UPDATE, params)); | 46 | +export const updateUserInfoAPI = (params) => fn(fetch.post(Api.USER_UPDATE, params)); |
| 47 | 47 | ||
| 48 | /** | 48 | /** |
| 49 | * @description: 忘记密码 | 49 | * @description: 忘记密码 |
| ... | @@ -51,4 +51,4 @@ export const updateUserInfoAPI = (params) => fn(fetch.put(Api.USER_UPDATE, param | ... | @@ -51,4 +51,4 @@ export const updateUserInfoAPI = (params) => fn(fetch.put(Api.USER_UPDATE, param |
| 51 | * @param: sms_code 短信验证码 | 51 | * @param: sms_code 短信验证码 |
| 52 | * @param: password 密码 | 52 | * @param: password 密码 |
| 53 | */ | 53 | */ |
| 54 | -export const resetPasswordAPI = (params) => fn(fetch.put(Api.USER_PASSWORD, params)); | 54 | +export const resetPasswordAPI = (params) => fn(fetch.post(Api.USER_PASSWORD, params)); | ... | ... |
| 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-03-26 10:07:48 | 4 | + * @LastEditTime: 2025-03-26 11:21:05 |
| 5 | * @FilePath: /mlaj/src/router/guards.js | 5 | * @FilePath: /mlaj/src/router/guards.js |
| 6 | * @Description: 路由守卫逻辑 | 6 | * @Description: 路由守卫逻辑 |
| 7 | */ | 7 | */ |
| 8 | import { getAuthInfoAPI } from '@/api/auth' | 8 | import { getAuthInfoAPI } from '@/api/auth' |
| 9 | -import { getUserInfoAPI } from '@/api/users' | 9 | +import { wxInfo } from "@/utils/tools" |
| 10 | -import { wxInfo } from '@/utils/tools' | 10 | +import { useRoute } from 'vue-router' |
| 11 | 11 | ||
| 12 | +const $route = useRoute(); | ||
| 12 | // 需要登录才能访问的路由 | 13 | // 需要登录才能访问的路由 |
| 13 | export const authRequiredRoutes = [ | 14 | export const authRequiredRoutes = [ |
| 14 | { | 15 | { |
| ... | @@ -29,23 +30,14 @@ export const authRequiredRoutes = [ | ... | @@ -29,23 +30,14 @@ export const authRequiredRoutes = [ |
| 29 | export const checkWxAuth = async () => { | 30 | export const checkWxAuth = async () => { |
| 30 | if (!import.meta.env.DEV && wxInfo().isWeiXin) { | 31 | if (!import.meta.env.DEV && wxInfo().isWeiXin) { |
| 31 | try { | 32 | try { |
| 32 | - const { code, data } = await getAuthInfoAPI() | 33 | + const { code, data } = await getAuthInfoAPI(); |
| 33 | if (code && !data.openid_has) { | 34 | if (code && !data.openid_has) { |
| 34 | // 直接在这里处理授权跳转 | 35 | // 直接在这里处理授权跳转 |
| 35 | - const params = new URLSearchParams({ | 36 | + let raw_url = encodeURIComponent(location.origin + location.pathname + $route.query.href); // 未授权的地址 |
| 36 | - f: 'behalo', | 37 | + const short_url = `/srv/?f=behalo&a=openid&res=${raw_url}`; |
| 37 | - a: 'openid', | 38 | + location.href = short_url; |
| 38 | - res: encodeURIComponent( | ||
| 39 | - location.origin + location.pathname + location.hash, | ||
| 40 | - ), | ||
| 41 | - }) | ||
| 42 | 39 | ||
| 43 | - if (import.meta.env.DEV) { | 40 | + return false; |
| 44 | - params.append('test_openid', import.meta.env.VITE_OPENID) | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - location.href = `/srv/?${params.toString()}` | ||
| 48 | - return false | ||
| 49 | } | 41 | } |
| 50 | } catch (error) { | 42 | } catch (error) { |
| 51 | console.error('微信授权检查失败:', error) | 43 | console.error('微信授权检查失败:', error) |
| ... | @@ -55,7 +47,9 @@ export const checkWxAuth = async () => { | ... | @@ -55,7 +47,9 @@ export const checkWxAuth = async () => { |
| 55 | } | 47 | } |
| 56 | 48 | ||
| 57 | // 登录权限检查 | 49 | // 登录权限检查 |
| 58 | -export const checkAuth = async (to) => { | 50 | +export const checkAuth = (to) => { |
| 51 | + const currentUser = JSON.parse(localStorage.getItem('currentUser')) | ||
| 52 | + | ||
| 59 | // 检查当前路由是否需要认证 | 53 | // 检查当前路由是否需要认证 |
| 60 | const needAuth = authRequiredRoutes.some((route) => { | 54 | const needAuth = authRequiredRoutes.some((route) => { |
| 61 | // 如果是正则匹配模式 | 55 | // 如果是正则匹配模式 |
| ... | @@ -70,21 +64,8 @@ export const checkAuth = async (to) => { | ... | @@ -70,21 +64,8 @@ export const checkAuth = async (to) => { |
| 70 | return to.path.startsWith(route.path) | 64 | return to.path.startsWith(route.path) |
| 71 | }) | 65 | }) |
| 72 | 66 | ||
| 73 | - // 如果路由需要认证,则尝试获取用户信息 | 67 | + if (needAuth && !currentUser) { |
| 74 | - if (needAuth) { | 68 | + // 未登录时重定向到登录页面 |
| 75 | - try { | ||
| 76 | - // 请求用户信息接口 | ||
| 77 | - const { code, data } = await getUserInfoAPI() | ||
| 78 | - if (code) { | ||
| 79 | - // 如果成功获取用户信息,更新currentUser并允许访问 | ||
| 80 | - localStorage.setItem('currentUser', JSON.stringify(data)) | ||
| 81 | - return true | ||
| 82 | - } | ||
| 83 | - } catch (error) { | ||
| 84 | - console.error('获取用户信息失败:', error) | ||
| 85 | - } | ||
| 86 | - | ||
| 87 | - // 如果接口请求失败或返回401,直接重定向到登录页面 | ||
| 88 | return { path: '/login', query: { redirect: to.fullPath } } | 69 | return { path: '/login', query: { redirect: to.fullPath } } |
| 89 | } | 70 | } |
| 90 | 71 | ... | ... |
| ... | @@ -110,6 +110,9 @@ | ... | @@ -110,6 +110,9 @@ |
| 110 | import { ref, reactive } from 'vue' | 110 | import { ref, reactive } from 'vue' |
| 111 | import { useRouter } from 'vue-router' | 111 | import { useRouter } from 'vue-router' |
| 112 | import FrostedGlass from '@/components/ui/FrostedGlass.vue' | 112 | import FrostedGlass from '@/components/ui/FrostedGlass.vue' |
| 113 | +import { smsAPI } from '@/api/common'; | ||
| 114 | +import { resetPasswordAPI } from '@/api/users'; | ||
| 115 | +import { showToast } from 'vant'; | ||
| 113 | 116 | ||
| 114 | const router = useRouter() | 117 | const router = useRouter() |
| 115 | const error = ref('') | 118 | const error = ref('') |
| ... | @@ -157,8 +160,13 @@ const sendVerificationCode = async () => { | ... | @@ -157,8 +160,13 @@ const sendVerificationCode = async () => { |
| 157 | } | 160 | } |
| 158 | 161 | ||
| 159 | try { | 162 | try { |
| 160 | - // TODO: 调用发送验证码API | 163 | + // TAG: 调用发送验证码API |
| 161 | - startCountdown() | 164 | + const { code } = await smsAPI({ mobile: formData.phone }) |
| 165 | + if (code) { | ||
| 166 | + showToast('验证码已发送') | ||
| 167 | + startCountdown() | ||
| 168 | + return | ||
| 169 | + } | ||
| 162 | } catch (err) { | 170 | } catch (err) { |
| 163 | console.error('Send verification code error:', err) | 171 | console.error('Send verification code error:', err) |
| 164 | error.value = '发送验证码失败,请稍后重试' | 172 | error.value = '发送验证码失败,请稍后重试' |
| ... | @@ -175,10 +183,19 @@ const handleSubmit = async () => { | ... | @@ -175,10 +183,19 @@ const handleSubmit = async () => { |
| 175 | error.value = '' | 183 | error.value = '' |
| 176 | loading.value = true | 184 | loading.value = true |
| 177 | 185 | ||
| 178 | - // TODO: 调用重置密码API | 186 | + // TAG: 调用重置密码API |
| 187 | + const { code } = await resetPasswordAPI({ | ||
| 188 | + mobile: formData.phone, | ||
| 189 | + sms_code: formData.verificationCode, | ||
| 190 | + password: formData.password | ||
| 191 | + }) | ||
| 192 | + | ||
| 193 | + if (code) { | ||
| 194 | + showToast('密码重置成功') | ||
| 195 | + // 重置成功后跳转到登录页 | ||
| 196 | + router.push('/login') | ||
| 197 | + } | ||
| 179 | 198 | ||
| 180 | - // 重置成功后跳转到登录页 | ||
| 181 | - router.push('/login') | ||
| 182 | } catch (err) { | 199 | } catch (err) { |
| 183 | console.error('Reset password error:', err) | 200 | console.error('Reset password error:', err) |
| 184 | error.value = '重置密码失败,请稍后重试' | 201 | error.value = '重置密码失败,请稍后重试' | ... | ... |
| ... | @@ -123,8 +123,8 @@ useTitle($route.meta.title); | ... | @@ -123,8 +123,8 @@ useTitle($route.meta.title); |
| 123 | const router = useRouter() | 123 | const router = useRouter() |
| 124 | const { login } = useAuth() | 124 | const { login } = useAuth() |
| 125 | 125 | ||
| 126 | -const mobile = ref('13761653761') | 126 | +const mobile = ref('') |
| 127 | -const password = ref('password123') | 127 | +const password = ref('') |
| 128 | const error = ref('') | 128 | const error = ref('') |
| 129 | const loading = ref(false) | 129 | const loading = ref(false) |
| 130 | 130 | ... | ... |
| ... | @@ -185,6 +185,9 @@ import FrostedGlass from '@/components/ui/FrostedGlass.vue' | ... | @@ -185,6 +185,9 @@ import FrostedGlass from '@/components/ui/FrostedGlass.vue' |
| 185 | import TermsPopup from '@/components/ui/TermsPopup.vue' | 185 | import TermsPopup from '@/components/ui/TermsPopup.vue' |
| 186 | import { useAuth } from '@/contexts/auth' | 186 | import { useAuth } from '@/contexts/auth' |
| 187 | import { useTitle } from '@vueuse/core'; | 187 | import { useTitle } from '@vueuse/core'; |
| 188 | +import { smsAPI } from '@/api/common'; | ||
| 189 | +import { registerAPI } from '@/api/users'; | ||
| 190 | +import { showToast } from 'vant'; | ||
| 188 | 191 | ||
| 189 | const $route = useRoute(); | 192 | const $route = useRoute(); |
| 190 | useTitle($route.meta.title); | 193 | useTitle($route.meta.title); |
| ... | @@ -240,8 +243,13 @@ const sendVerificationCode = async () => { | ... | @@ -240,8 +243,13 @@ const sendVerificationCode = async () => { |
| 240 | } | 243 | } |
| 241 | 244 | ||
| 242 | try { | 245 | try { |
| 243 | - // TODO: 调用发送验证码API | 246 | + // TAG: 调用发送验证码API |
| 244 | - startCountdown() | 247 | + const { code } = await smsAPI({ mobile: formData.phone }) |
| 248 | + if (code) { | ||
| 249 | + showToast('验证码已发送') | ||
| 250 | + startCountdown() | ||
| 251 | + return | ||
| 252 | + } | ||
| 245 | } catch (err) { | 253 | } catch (err) { |
| 246 | console.error('Send verification code error:', err) | 254 | console.error('Send verification code error:', err) |
| 247 | error.value = '发送验证码失败,请稍后重试' | 255 | error.value = '发送验证码失败,请稍后重试' |
| ... | @@ -273,14 +281,23 @@ const handleSubmit = async () => { | ... | @@ -273,14 +281,23 @@ const handleSubmit = async () => { |
| 273 | error.value = '' | 281 | error.value = '' |
| 274 | loading.value = true | 282 | loading.value = true |
| 275 | 283 | ||
| 276 | - // 使用auth.js中的login函数 | 284 | + // 调用注册接口 |
| 277 | - const success = login({ | 285 | + const { code } = await registerAPI({ |
| 278 | name: formData.name, | 286 | name: formData.name, |
| 279 | - avatar: 'https://cdn.ipadbiz.cn/mlaj/images/user-avatar-3.jpg' | 287 | + mobile: formData.phone, |
| 288 | + sms_code: formData.verificationCode, | ||
| 289 | + password: formData.password, | ||
| 280 | }) | 290 | }) |
| 281 | - | 291 | + if (code) { |
| 282 | - if (success) { | 292 | + // 使用auth.js中的login函数 |
| 283 | - router.push('/') | 293 | + const success = login({ |
| 294 | + name: formData.name, | ||
| 295 | + mobile: formData.phone, | ||
| 296 | + avatar: '' | ||
| 297 | + }) | ||
| 298 | + if (success) { | ||
| 299 | + router.push('/') | ||
| 300 | + } | ||
| 284 | } else { | 301 | } else { |
| 285 | error.value = '注册失败,请稍后再试' | 302 | error.value = '注册失败,请稍后再试' |
| 286 | } | 303 | } | ... | ... |
-
Please register or login to post a comment