From 48d2f6122313db6eb18cd7684376541725d7eaee Mon Sep 17 00:00:00 2001 From: landaiqing <3517283258@qq.com> Date: Wed, 14 Aug 2024 00:08:37 +0800 Subject: [PATCH] :art: complete SMS login function --- src/api/user/index.ts | 45 ++++++++++++++- src/locales/language/en.ts | 5 +- src/locales/language/zh.ts | 4 ++ src/store/modules/userStore.ts | 27 +++------ src/types/user.d.ts | 7 --- .../adapter/localforageStorageAdapter.ts | 2 +- src/utils/alova/service.ts | 21 ++++--- src/views/Forget/ForgetPage.vue | 8 +-- src/views/Login/LoginPage.vue | 55 +++++++++++++++---- 9 files changed, 119 insertions(+), 55 deletions(-) diff --git a/src/api/user/index.ts b/src/api/user/index.ts index 5e18300..ffda278 100644 --- a/src/api/user/index.ts +++ b/src/api/user/index.ts @@ -1,22 +1,61 @@ import {service} from "@/utils/alova/service.ts"; +import {PhoneLogin} from "@/types/user"; - +/** + * 获取用户信息 + */ export const getUserInfo = () => { return service.Get('/api/auth/user/List', { meta: { ignoreToken: false }, + cacheFor: 1000 * 60 }); }; - +/** + * 刷新token + * @param refreshToken + */ export const refreshToken = (refreshToken: string) => { return service.Get('/api/auth/token/refresh', { params: { refresh_token: refreshToken }, meta: { - authRole: 'refreshToken' + authRole: 'refreshToken', + ignoreToken: false } }); }; +/** + * 发送短信验证码 + * @param phone + */ +export const sendMessage = (phone: string) => { + return service.Get('/api/sms/test/send', { + params: { + phone: phone + }, + meta: { + ignoreToken: true + } + }); +}; +/** + * 手机登录 + * @param param + */ +export const phoneLoginApi = (param: PhoneLogin) => { + return service.Post('/api/user/phone_login', { + phone: param.phone, + captcha: param.captcha, + }, + { + meta: { + ignoreToken: true, + authRole: 'login' + } + } + ); +}; diff --git a/src/locales/language/en.ts b/src/locales/language/en.ts index d79ea87..1cd828a 100644 --- a/src/locales/language/en.ts +++ b/src/locales/language/en.ts @@ -34,7 +34,10 @@ export default { rotateCaptchaTitle: "Please drag the slider to complete the puzzle", systemError: "System error, please try again later", captchaExpired: "captcha expired, please try again", - + sendCaptchaSuccess: "captcha sent successfully, please check your phone!", + sendCaptchaError: "captcha sending failed, please try again later", + loginSuccess: "login success!", + loginError: "login failed!", }, error: { networkError: 'Network error, please try again later', diff --git a/src/locales/language/zh.ts b/src/locales/language/zh.ts index e495828..775c88d 100644 --- a/src/locales/language/zh.ts +++ b/src/locales/language/zh.ts @@ -34,6 +34,10 @@ export default { rotateCaptchaTitle: "请拖动滑块完成拼图", systemError: "系统错误!请稍后再试!", captchaExpired: "验证码已过期,请重新获取!", + sendCaptchaSuccess: "验证码已发送,请注意查收!", + sendCaptchaError: "验证码发送失败,请稍后再试!", + loginSuccess: "登录成功!", + loginError: "登录失败!", }, diff --git a/src/store/modules/userStore.ts b/src/store/modules/userStore.ts index ef77ef0..da95c55 100644 --- a/src/store/modules/userStore.ts +++ b/src/store/modules/userStore.ts @@ -1,30 +1,19 @@ import {defineStore} from 'pinia'; -import {ref} from 'vue'; -import {User} from "@/types/user"; +import {reactive} from 'vue'; export const useAuthStore = defineStore( 'user', () => { - const user = ref(); - - function setUser(data: User) { - user.value = data; - } - - function getUser() { - return user.value; - } - - function clearUser() { - user.value = void 0; - } + const user: any = reactive({ + accessToken: '', + userId: '', + refreshToken: '', + expiresAt: 0, + }); return { user, - setUser, - getUser, - clearUser }; }, { @@ -32,7 +21,7 @@ export const useAuthStore = defineStore( persist: { key: 'user', storage: localStorage, - paths: ["user"], + paths: ['user'], } } ); diff --git a/src/types/user.d.ts b/src/types/user.d.ts index 5f259d9..ae2e55d 100644 --- a/src/types/user.d.ts +++ b/src/types/user.d.ts @@ -1,10 +1,3 @@ -export interface User { - accessToken?: string - userId?: string - refreshToken?: string - expiresAt?: number - -} export interface AccountLogin { account?: string diff --git a/src/utils/alova/adapter/localforageStorageAdapter.ts b/src/utils/alova/adapter/localforageStorageAdapter.ts index d00037d..eff7e1f 100644 --- a/src/utils/alova/adapter/localforageStorageAdapter.ts +++ b/src/utils/alova/adapter/localforageStorageAdapter.ts @@ -8,7 +8,7 @@ export const localforageStorageAdapter = { get(key: string) { let value: any; localforage.getItem(key).then((res: any) => { - if (res === null || res === undefined) { + if (res === null || res === undefined || res === "") { value = ""; } else { value = res; diff --git a/src/utils/alova/service.ts b/src/utils/alova/service.ts index 7d572b7..c720c10 100644 --- a/src/utils/alova/service.ts +++ b/src/utils/alova/service.ts @@ -24,15 +24,18 @@ const {onAuthRequired, onResponseRefreshToken} = createServerTokenAuthentication handler: async () => { try { const user = useStore().user; - const res: any = await refreshToken(user.getUser()?.refreshToken || ''); + const res: any = await refreshToken(user.user?.refreshToken || ''); if (res.code === 0 && res.data) { - user.setUser({ - userId: res.data.userId, - accessToken: res.data.access_token, - refreshToken: res.data.refresh_token, - expiresAt: res.data.expires_at, - }); + const {uid, access_token, refresh_token, expires_at} = res.data; + user.user.userId = uid; + user.user.accessToken = access_token; + user.user.refreshToken = refresh_token; + user.user.expiresAt = expires_at; } + // else { + // message.error(res.message); + // await router.push('/login'); + // } } catch (error) { // token刷新失败,跳转回登录页 message.error(i18n.global.t('error.authTokenError')).then(); @@ -55,10 +58,10 @@ export const service = createAlova({ beforeRequest: onAuthRequired(async (method: any) => { if (!method.meta?.ignoreToken) { const user = useStore().user; - method.config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${user.getUser()?.accessToken}`; + method.config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${user.user.accessToken}`; } const lang = useStore().lang; - method.config.headers['Accept-Language'] = lang.lang|| 'zh'; + method.config.headers['Accept-Language'] = lang.lang || 'zh'; }), // 响应拦截器 responded: onResponseRefreshToken({ diff --git a/src/views/Forget/ForgetPage.vue b/src/views/Forget/ForgetPage.vue index e389cce..5668baf 100644 --- a/src/views/Forget/ForgetPage.vue +++ b/src/views/Forget/ForgetPage.vue @@ -142,7 +142,7 @@ const state = reactive({ * 验证码发送倒计时 */ const countDown = () => { - const startTime = localStorage.getItem('startTimeSendCaptcha'); + const startTime = localStorage.getItem('start_time_send_captcha'); const nowTime = new Date().getTime(); let surplus: number = 60; let timer: any; @@ -150,7 +150,7 @@ const countDown = () => { surplus = 60 - Math.floor((nowTime - Number(startTime)) / 1000); surplus = surplus <= 0 ? 0 : surplus; } else { - localStorage.setItem('startTimeSendCaptcha', String(nowTime)); + localStorage.setItem('start_time_send_captcha', String(nowTime)); } state.countDownTime = surplus; @@ -160,7 +160,7 @@ const countDown = () => { } timer = setInterval(() => { if (state.countDownTime <= 0) { - localStorage.removeItem('startTimeSendCaptcha'); + localStorage.removeItem('start_time_send_captcha'); clearInterval(timer); state.countDownTime = 60; state.showCountDown = false; @@ -171,7 +171,7 @@ const countDown = () => { }, 1000); }; onMounted(() => { - const sendEndTime = localStorage.getItem('startTimeSendCaptcha'); + const sendEndTime = localStorage.getItem('start_time_send_captcha'); if (sendEndTime) { state.showCountDown = true; countDown(); diff --git a/src/views/Login/LoginPage.vue b/src/views/Login/LoginPage.vue index a7e4632..09fbec7 100644 --- a/src/views/Login/LoginPage.vue +++ b/src/views/Login/LoginPage.vue @@ -21,6 +21,7 @@ {{ t("login.phone") }} - +