diff --git a/src/api/oauth/gitee.ts b/src/api/oauth/gitee.ts deleted file mode 100644 index 4d0fa1e..0000000 --- a/src/api/oauth/gitee.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {service} from "@/utils/alova/service.ts"; - -/** - * 获取Gitee登录链接 - */ -export const getGiteeUrl = () => { - return service.Get('/api/oauth/gitee/url', - { - meta: { - ignoreToken: true, - }, - cacheFor: { - mode: "restore", - expire: 1000 * 60 * 60 * 24 - } - } - ); -}; diff --git a/src/api/oauth/github.ts b/src/api/oauth/github.ts deleted file mode 100644 index 12ae33c..0000000 --- a/src/api/oauth/github.ts +++ /dev/null @@ -1,21 +0,0 @@ -import {service} from "@/utils/alova/service.ts"; - -/** - * Get Github OAuth URL - */ -export const getGithubUrl = (state: string) => { - return service.Get('/api/oauth/github/url', - { - params: { - state: state - }, - meta: { - ignoreToken: true, - }, - cacheFor: { - mode: "restore", - expire: 1000 * 60 * 60 * 24 - } - } - ); -}; diff --git a/src/api/oauth/index.ts b/src/api/oauth/index.ts new file mode 100644 index 0000000..7cafaa6 --- /dev/null +++ b/src/api/oauth/index.ts @@ -0,0 +1,57 @@ +import {service} from "@/utils/alova/service.ts"; + +/** + * 获取Gitee登录链接 + */ +export const getGiteeUrl = () => { + return service.Get('/api/oauth/gitee/url', + { + meta: { + ignoreToken: true, + }, + cacheFor: { + mode: "restore", + expire: 1000 * 60 * 60 * 24 + } + } + ); +}; + + +/** + * Get Github OAuth URL + */ +export const getGithubUrl = (state: string) => { + return service.Get('/api/oauth/github/url', + { + params: { + state: state + }, + meta: { + ignoreToken: true, + }, + cacheFor: { + mode: "restore", + expire: 1000 * 60 * 60 * 24 + } + } + ); +}; + + +export const getQQUrl = (state: string) => { + return service.Get('/api/oauth/qq/url', + { + params: { + state: state + }, + meta: { + ignoreToken: true, + }, + cacheFor: { + mode: "restore", + expire: 1000 * 60 * 60 * 24 + } + } + ); +}; diff --git a/src/api/oauth/qq.ts b/src/api/oauth/qq.ts deleted file mode 100644 index 7ae99df..0000000 --- a/src/api/oauth/qq.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {service} from "@/utils/alova/service.ts"; - -export const getQQUrl = (state: string) => { - return service.Get('/api/oauth/qq/url', - { - params: { - state: state - }, - meta: { - ignoreToken: true, - }, - cacheFor: { - mode: "restore", - expire: 1000 * 60 * 60 * 24 - } - } - ); -}; diff --git a/src/api/oauth/wechat.ts b/src/api/oauth/wechat.ts deleted file mode 100644 index a85912b..0000000 --- a/src/api/oauth/wechat.ts +++ /dev/null @@ -1,20 +0,0 @@ -import {service} from "@/utils/alova/service.ts"; - -/** - * 获取临时二维码 - * @param clientId - */ -export const generateQrCode = (clientId: string) => { - return service.Get('/api/oauth/wechat/qrcode', - { - params: { - client_id: clientId - }, - cacheFor: null, - meta: { - ignoreToken: true, - }, - } - ); -}; - diff --git a/src/api/user/index.ts b/src/api/user/index.ts index aad9459..82c8d09 100644 --- a/src/api/user/index.ts +++ b/src/api/user/index.ts @@ -1,5 +1,5 @@ import {service} from "@/utils/alova/service.ts"; -import {AccountLogin, PhoneLogin, ResetPassword} from "@/types/user"; +import {AccountLogin, PhoneLogin, ResetPassword, WechatOffiaccountLogin} from "@/types/user"; /** * 刷新token @@ -8,7 +8,7 @@ export const refreshToken = () => { return service.Post('/api/auth/token/refresh', {}, { meta: { authRole: 'refreshToken', - ignoreToken: true, + ignoreToken: false, signature: true } }); @@ -89,16 +89,14 @@ export const resetPasswordApi = (param: ResetPassword) => { } ); }; - - /** - * 获取用户设备信息 - * @param access_token + * 微信扫码登录 + * @param param */ -export const getUserDevice = (access_token: string) => { - return service.Post('/api/user/device', - { - access_token: access_token, +export const wechatOffiaccountLoginApi = (param: WechatOffiaccountLogin) => { + return service.Post('/api/user/wechat/offiaccount/login', { + openid: param.openid, + client_id: param.client_id, }, { meta: { @@ -108,3 +106,21 @@ export const getUserDevice = (access_token: string) => { } ); }; + + +/** + * 获取临时二维码 + * @param clientId + */ +export const generateQrCode = (clientId: string) => { + return service.Post('/api/user/wechat/offiaccount/qrcode', { + client_id: clientId + }, { + cacheFor: 60 * 60 * 24, + meta: { + ignoreToken: true, + signature: true + }, + } + ); +}; diff --git a/src/router/router.ts b/src/router/router.ts index d37998d..9761ac8 100644 --- a/src/router/router.ts +++ b/src/router/router.ts @@ -29,7 +29,7 @@ const router: Router = createRouter({ router.beforeEach((to, _from, next) => { // start(); const user = useStore().user; - const token: string | undefined = user.user.access_token; + const token: string | undefined = user.token; const userId: string | undefined = user.user.uid; // 检查用户是否已登录 diff --git a/src/store/modules/userStore.ts b/src/store/modules/userStore.ts index 07272e7..dcb50d0 100644 --- a/src/store/modules/userStore.ts +++ b/src/store/modules/userStore.ts @@ -1,24 +1,20 @@ import {defineStore} from 'pinia'; -import {reactive} from 'vue'; import {generateClientId} from "@/api/client"; -import {getGithubUrl} from "@/api/oauth/github.ts"; -import {getQQUrl} from "@/api/oauth/qq.ts"; -import {getGiteeUrl} from "@/api/oauth/gitee.ts"; -import {getUserDevice} from "@/api/user"; import {message} from "ant-design-vue"; import {useI18n} from "vue-i18n"; +import {getGiteeUrl, getGithubUrl, getQQUrl} from "@/api/oauth"; export const useAuthStore = defineStore( 'user', () => { const user: any = reactive({ - access_token: '', uid: '', username: '', nickname: '', avatar: '', status: '', }); + const token: any = ref(''); const clientId = ref(''); const githubRedirectUrl = ref(''); const giteeRedirectUrl = ref(''); @@ -74,14 +70,13 @@ export const useAuthStore = defineStore( if (typeof e.data === 'string') { const res: any = JSON.parse(e.data); if (res && res.code === 200) { - const {data} = res; - user.uid = data.uid; - user.access_token = data.access_token; - user.username = data.username; - user.avatar = data.avatar; - user.nickname = data.nickname; - user.status = data.status; - await getUserDevice(data.access_token); + const {uid, access_token, username, avatar, nickname, status} = res.data; + user.uid = uid; + user.username = username; + user.avatar = avatar; + user.nickname = nickname; + user.status = status; + token.value = access_token; message.success(t('login.loginSuccess')); window.removeEventListener("message", messageHandler); setTimeout(() => { @@ -130,9 +125,19 @@ export const useAuthStore = defineStore( window.addEventListener("message", messageHandler); } + function clear() { + token.value = ""; + user.avatar = ""; + user.uid = ""; + user.username = ""; + user.nickname = ""; + user.status = ""; + } + return { user, + token, clientId, getGithubRedirectUrl, getGiteeRedirectUrl, @@ -141,6 +146,7 @@ export const useAuthStore = defineStore( openGithubUrl, openGiteeUrl, openQQUrl, + clear }; }, { @@ -154,7 +160,7 @@ export const useAuthStore = defineStore( persist: true, storage: localStorage, key: 'user', - includePaths: ['user', "clientId", "githubRedirectUrl", "giteeRedirectUrl", "qqRedirectUrl"] + includePaths: ['user', 'token', "clientId"] } } ); diff --git a/src/types/user.d.ts b/src/types/user.d.ts index 2dbb43c..9542310 100644 --- a/src/types/user.d.ts +++ b/src/types/user.d.ts @@ -18,3 +18,8 @@ export interface ResetPassword { password?: string; repassword?: string; } + +export interface WechatOffiaccountLogin { + openid:string; + client_id:string; +} diff --git a/src/utils/alova/service.ts b/src/utils/alova/service.ts index 853dfc0..0bf4b15 100644 --- a/src/utils/alova/service.ts +++ b/src/utils/alova/service.ts @@ -28,7 +28,7 @@ const {onAuthRequired, onResponseRefreshToken} = createServerTokenAuthentication const user = useStore().user; const res: any = await refreshToken(); if (res && res.code === 200) { - user.user.access_token = res.data; + user.token = res.data; } } } @@ -46,7 +46,8 @@ 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.user.access_token}`; + method.config.headers.Authorization = `${import.meta.env.VITE_APP_TOKEN_KEY} ${user.token}`; + method.config.headers['X-UID'] = user.user.uid; } const lang = useStore().lang; method.config.headers['Accept-Language'] = lang.lang || 'zh'; @@ -72,11 +73,9 @@ export const service = createAlova({ }, 1000); }, }); - return Promise.reject(response.data); + return Promise.reject(); } return response.data; - - }, onError: (error: AxiosError, _method: any) => { diff --git a/src/utils/websocket/websocket.ts b/src/utils/websocket/websocket.ts index 61685f1..da1cd74 100644 --- a/src/utils/websocket/websocket.ts +++ b/src/utils/websocket/websocket.ts @@ -53,7 +53,7 @@ export class WebSocketService { }; private handleMessage = (event: MessageEvent): void => { - const {data} = event; + const data = JSON.parse(event.data); if (this.callbacks.message) { this.callbacks.message.forEach((cb) => (cb as MessageCallback)(data)); } diff --git a/src/views/Login/LoginPage.vue b/src/views/Login/LoginPage.vue index 34e313f..5877c03 100644 --- a/src/views/Login/LoginPage.vue +++ b/src/views/Login/LoginPage.vue @@ -374,11 +374,11 @@ async function phoneLoginSubmit() { const res: any = await phoneLoginApi(phoneLoginForm); if (res && res.code === 200) { userStore.user.uid = res.data.uid; - userStore.user.access_token = res.data.access_token; userStore.user.username = res.data.username; userStore.user.avatar = res.data.avatar; userStore.user.nickname = res.data.nickname; userStore.user.status = res.data.status; + userStore.token = res.data.access_token; message.success(t('login.loginSuccess')); loginLoading.value = false; setTimeout(() => { @@ -461,11 +461,11 @@ async function checkAccountLoginCaptcha(angle: number) { const res: any = await accountLoginApi(params); if (res && res.code === 200) { userStore.user.uid = res.data.uid; - userStore.user.access_token = res.data.access_token; userStore.user.username = res.data.username; userStore.user.avatar = res.data.avatar; userStore.user.nickname = res.data.nickname; userStore.user.status = res.data.status; + userStore.token = res.data.access_token; message.success(t('login.loginSuccess')); loginLoading.value = false; showAccountRotateCaptcha.value = false; diff --git a/src/views/QRLogin/QRLogin.vue b/src/views/QRLogin/QRLogin.vue index 4bb0d07..17fcc75 100644 --- a/src/views/QRLogin/QRLogin.vue +++ b/src/views/QRLogin/QRLogin.vue @@ -21,7 +21,7 @@ class="qrlogin-card-qr" :size="280" :error-level="'H'" - :status="status" + :status="qrStatus" @refresh="getQrCode" :value=qrcode :icon="logo" @@ -46,20 +46,20 @@ import {useI18n} from "vue-i18n"; import BoxDog from "@/components/BoxDog/BoxDog.vue"; import QRLoginFooter from "@/views/QRLogin/QRLoginFooter.vue"; import {useRouter} from 'vue-router'; -import {generateQrCode} from "@/api/oauth/wechat.ts"; import logo from "@/assets/svgs/logo-album.svg"; import useStore from "@/store"; import {message} from "ant-design-vue"; -import {getUserDevice} from "@/api/user"; import BackgroundAnimation from "@/components/BackgroundAnimation/BackgroundAnimation.vue"; +import {generateQrCode, wechatOffiaccountLoginApi} from "@/api/user"; +import {WechatOffiaccountLogin} from "@/types/user"; const {t} = useI18n(); const router = useRouter(); const qrcode = ref(''); -const status = ref('loading'); +const qrStatus = ref('loading'); const websocket = useStore().websocket; const userStore = useStore().user; @@ -73,7 +73,7 @@ async function getQrCode() { qrcode.value = res.data; await handleListenMessage(); } else { - status.value = 'expired'; + qrStatus.value = 'expired'; } } @@ -92,15 +92,20 @@ async function handleListenMessage() { // 注册消息接收处理函数 websocket.on('message', async (res: any) => { if (res && res.code === 200) { - status.value = 'scanned'; - const {data} = res; - userStore.user.uid = data.uid; - userStore.user.access_token = data.access_token; - userStore.user.username = data.username; - userStore.user.avatar = data.avatar; - userStore.user.nickname = data.nickname; - userStore.user.status = data.status; - await getUserDevice(data.access_token); + qrStatus.value = 'scanned'; + const {openid, client_id } = res.data; + const param: WechatOffiaccountLogin = { + openid: openid, + client_id: client_id + }; + const response: any = await wechatOffiaccountLoginApi(param); + const {uid, access_token, username, avatar, nickname, status} = response.data; + userStore.user.uid = uid; + userStore.user.username = username; + userStore.user.avatar = avatar; + userStore.user.nickname = nickname; + userStore.user.status = status; + userStore.token = access_token; message.success(t('login.loginSuccess')); setTimeout(() => { router.push('/main/photo/all'); @@ -122,9 +127,9 @@ watch( () => websocket.readyState, (newStatus) => { if (newStatus === WebSocket.OPEN) { - status.value = 'active'; + qrStatus.value = 'active'; } else { - status.value = 'expired'; + qrStatus.value = 'expired'; } } ); diff --git a/src/views/Upscale/index.vue b/src/views/Upscale/index.vue index 9092d06..45a406f 100644 --- a/src/views/Upscale/index.vue +++ b/src/views/Upscale/index.vue @@ -29,7 +29,7 @@ const upscale = useStore().upscale; const img = new Image(); const wsOptions = { url: import.meta.env.VITE_FILE_SOCKET_URL + "?user_id=" + user.user.uid, - protocols: [user.user.access_token], + protocols: [user.token], }; onMounted(() => {