diff --git a/apps/web-antd/src/views/_core/authentication/social-login.vue b/apps/web-antd/src/views/_core/authentication/social-login.vue index 1052a9a18..a5847c81c 100644 --- a/apps/web-antd/src/views/_core/authentication/social-login.vue +++ b/apps/web-antd/src/views/_core/authentication/social-login.vue @@ -12,12 +12,15 @@ import { $t } from '@vben/locales'; import { useAccessStore } from '@vben/stores'; import { getUrlValue } from '@vben/utils'; +import { message } from 'ant-design-vue'; + import { checkCaptcha, getCaptcha, getTenantByWebsite, getTenantSimpleList, } from '#/api/core/auth'; +import { socialBind } from '#/api/system/social/user'; import { useAuthStore } from '#/store'; defineOptions({ name: 'SocialLogin' }); @@ -69,11 +72,35 @@ async function fetchTenantList() { } } -/** 尝试登录:当账号已经绑定,socialLogin 会直接获得 token */ +/** 尝试登录或绑定 */ const socialType = Number(getUrlValue('type')); const redirect = getUrlValue('redirect'); const socialCode = query?.code as string; const socialState = query?.state as string; + +// 检查是否为绑定操作(从个人中心发起) +const bindAction = sessionStorage.getItem('socialBindAction'); +const bindType = sessionStorage.getItem('socialBindType'); + +async function tryBind() { + const type = Number(bindType); + sessionStorage.removeItem('socialBindAction'); + sessionStorage.removeItem('socialBindType'); + if (!type || !socialCode) { + message.error('绑定失败:缺少参数'); + await router.replace('/profile'); + return; + } + try { + await socialBind({ type, code: socialCode, state: socialState }); + message.success('绑定成功'); + } catch (error) { + console.error('社交绑定失败:', error); + message.error('绑定失败,请重试'); + } + await router.replace('/profile'); +} + async function tryLogin() { // 用于登录后,基于 redirect 的重定向 if (redirect) { @@ -125,10 +152,13 @@ async function handleVerifySuccess({ captchaVerification }: any) { } } -/** 组件挂载时获取租户信息 */ +/** 组件挂载时:绑定操作走绑定流程,否则走登录流程 */ onMounted(async () => { + if (bindAction === 'bind') { + await tryBind(); + return; + } await fetchTenantList(); - await tryLogin(); }); diff --git a/apps/web-antd/src/views/_core/profile/modules/user-social.vue b/apps/web-antd/src/views/_core/profile/modules/user-social.vue index d2621cdd9..41ad0401a 100644 --- a/apps/web-antd/src/views/_core/profile/modules/user-social.vue +++ b/apps/web-antd/src/views/_core/profile/modules/user-social.vue @@ -2,29 +2,21 @@ import type { SystemSocialUserApi } from '#/api/system/social/user'; import { computed, onMounted, ref } from 'vue'; -import { useRoute } from 'vue-router'; import { confirm } from '@vben/common-ui'; import { DICT_TYPE, SystemUserSocialTypeEnum } from '@vben/constants'; import { getDictLabel } from '@vben/hooks'; import { $t } from '@vben/locales'; -import { formatDateTime, getUrlValue } from '@vben/utils'; +import { formatDateTime } from '@vben/utils'; import { Avatar, Button, Image, message, Tag, Tooltip } from 'ant-design-vue'; import { socialAuthRedirect } from '#/api/core/auth'; import { getBindSocialUserList, - socialBind, socialUnbind, } from '#/api/system/social/user'; -const emit = defineEmits<{ - (e: 'update:activeName', v: string): void; -}>(); - -const route = useRoute(); - /** 已经绑定的平台 */ const bindList = ref([]); @@ -77,47 +69,19 @@ async function onBind(bind: SocialBindItem) { return; } try { - // 将 type 存入 sessionStorage,避免放入 redirect_uri 导致参数被截断 + // 标记为绑定操作,回调走 /auth/social-login(核心路由,始终可用) sessionStorage.setItem('socialBindType', String(type)); - const redirectUri = `${location.origin}/profile`; + sessionStorage.setItem('socialBindAction', 'bind'); + const redirectUri = `${location.origin}/auth/social-login`; window.location.href = await socialAuthRedirect(type, redirectUri); } catch (error) { console.error('社交绑定处理失败:', error); } } -/** 监听路由变化,处理社交绑定回调 */ -async function bindSocial() { - const code = route.query.code as string; - const state = route.query.state as string; - if (!code) { - return; - } - // 优先从 sessionStorage 获取 type,兼容从 URL 参数获取 - const storedType = sessionStorage.getItem('socialBindType'); - const type = storedType ? Number(storedType) : Number(getUrlValue('type')); - sessionStorage.removeItem('socialBindType'); - if (!type) { - message.error('绑定失败:缺少社交平台类型'); - return; - } - try { - await socialBind({ type, code, state }); - message.success('绑定成功'); - emit('update:activeName', 'userSocial'); - await loadBindList(); - } catch (error) { - console.error('社交绑定失败:', error); - message.error('绑定失败,请重试'); - } finally { - window.history.replaceState({}, '', location.pathname); - } -} - /** 初始化 */ onMounted(async () => { await loadBindList(); - await bindSocial(); });