From 0d1ee18da0245d82f6d5b78b6bdeb1a7d489ed98 Mon Sep 17 00:00:00 2001 From: Gsh <15170702455@163.com> Date: Tue, 15 Jul 2025 00:54:34 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=20=E5=A2=9E=E5=8A=A0=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E7=99=BB=E5=BD=95=E6=84=8F=E7=A4=BE=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Yi.Ai.Vue3/.env.development | 6 +- Yi.Ai.Vue3/.env.production | 6 +- Yi.Ai.Vue3/.eslintrc-auto-import.json | 2 + .../src/components/LoginDialog/index.vue | 85 +++++++++++++++++-- Yi.Ai.Vue3/src/config/sso.ts | 5 +- Yi.Ai.Vue3/types/components.d.ts | 27 ++++++ Yi.Ai.Vue3/types/import_meta.d.ts | 1 - Yi.Bbs.Vue3/src/permission.js | 31 ++++--- 8 files changed, 133 insertions(+), 30 deletions(-) diff --git a/Yi.Ai.Vue3/.env.development b/Yi.Ai.Vue3/.env.development index fd80b18c..04164444 100644 --- a/Yi.Ai.Vue3/.env.development +++ b/Yi.Ai.Vue3/.env.development @@ -16,10 +16,8 @@ VITE_WEB_BASE_API = '/dev-api' VITE_API_URL=http://data.ccnetcore.com:19001/api/app # SSO单点登录url -VITE_SSO_SEVER_URL='http://localhost:18001' +VITE_SSO_SEVER_URL=http://localhost:18001 # SSO_SEVER_URL='http://ccnetcore.com' -# SSO单点登录项目标识 -VITE_SSO_CLIENT_ID='YiXin-Ai'; # 版本号 -VITE_APP_VERSION='1.0.0'; +VITE_APP_VERSION='1.0.0' diff --git a/Yi.Ai.Vue3/.env.production b/Yi.Ai.Vue3/.env.production index 10f4606f..b2929308 100644 --- a/Yi.Ai.Vue3/.env.production +++ b/Yi.Ai.Vue3/.env.production @@ -17,10 +17,8 @@ VITE_API_URL = http://data.ccnetcore.com:19001/api/app VITE_BUILD_COMPRESS = gzip # SSO单点登录url -VITE_SSO_SEVER_URL='https://ccnetcore.com' -# SSO单点登录项目标识 -VITE_SSO_CLIENT_ID='YiXin-Ai'; +VITE_SSO_SEVER_URL=https://ccnetcore.com # 版本号 -VITE_APP_VERSION='1.0.6'; +VITE_APP_VERSION='1.0.7' diff --git a/Yi.Ai.Vue3/.eslintrc-auto-import.json b/Yi.Ai.Vue3/.eslintrc-auto-import.json index af1083b7..313e6711 100644 --- a/Yi.Ai.Vue3/.eslintrc-auto-import.json +++ b/Yi.Ai.Vue3/.eslintrc-auto-import.json @@ -5,6 +5,8 @@ "ComputedRef": true, "DirectiveBinding": true, "EffectScope": true, + "ElMessage": true, + "ElMessageBox": true, "ExtractDefaultPropTypes": true, "ExtractPropTypes": true, "ExtractPublicPropTypes": true, diff --git a/Yi.Ai.Vue3/src/components/LoginDialog/index.vue b/Yi.Ai.Vue3/src/components/LoginDialog/index.vue index 0864a526..18358c61 100644 --- a/Yi.Ai.Vue3/src/components/LoginDialog/index.vue +++ b/Yi.Ai.Vue3/src/components/LoginDialog/index.vue @@ -5,7 +5,11 @@ import { useRouter } from 'vue-router'; import { getUserInfo } from '@/api'; import logoPng from '@/assets/images/logo.png'; import SvgIcon from '@/components/SvgIcon/index.vue'; -import { SSO_CLIENT_ID, SSO_SEVER_URL } from '@/config/sso.ts'; +import { + SSO_CLIENT_LOGIN, + SSO_CLIENT_LOGIN_AGAIN, + SSO_SEVER_URL, +} from '@/config/sso.ts'; import { useUserStore } from '@/stores'; import { useLoginFormStore } from '@/stores/modules/loginForm'; import { useSessionStore } from '@/stores/modules/session.ts'; @@ -56,10 +60,11 @@ function onAfterLeave() { } } -function handleThirdPartyLogin() { +function handleThirdPartyLogin(type: any) { const redirectUri = encodeURIComponent(`${window.location.origin}/chat`); + console.log('cccc', type); const popup = window.open( - `${SSO_SEVER_URL}/login?client_id=${SSO_CLIENT_ID}&redirect_uri=${redirectUri}`, + `${SSO_SEVER_URL}/login?client_id=${type}&redirect_uri=${redirectUri}`, 'SSOLogin', 'width=1000,height=800', ); @@ -110,14 +115,67 @@ function handleThirdPartyLogin() { }, 60 * 1000); // 60分钟超时关闭 } +// 让意社区重新登录,先让意社区退出登录,再重新登录 +function handleLoginAgainYi() { + const redirectUri = encodeURIComponent(`${window.location.origin}/chat`); + const popup = window.open( + `http://localhost:18001/login?client_id=${SSO_CLIENT_LOGIN_AGAIN}&redirect_uri=${redirectUri}`, + 'SSOLogin', + 'width=1000,height=800', + ); + + // 使用标志位防止重复执行 + let isHandled = false; + + const messageHandler = async (event: any) => { + if (event.origin === new URL(SSO_SEVER_URL).origin + && event.data.type === 'SSO_LOGIN_SUCCESS' + && !isHandled) { + isHandled = true; + console.log('111'); + try { + // 清理监听 + window.removeEventListener('message', messageHandler); + const { token, refreshToken } = event.data; + userStore.setToken(token, refreshToken); + const resUserInfo = await getUserInfo(); + userStore.setUserInfo(resUserInfo.data); + // 关闭弹窗 + if (popup && !popup.closed) + popup.close(); + // 后续逻辑 + ElMessage.success('登录成功'); + userStore.closeLoginDialog(); + await sessionStore.requestSessionList(1, true); + await router.replace('/'); + } + catch (error) { + console.error('登录处理失败:', error); + ElMessage.error('登录失败'); + } + } + }; + + // 先移除旧监听,再添加新监听 + window.removeEventListener('message', messageHandler); + window.addEventListener('message', messageHandler); + + // 超时自动清理 + setTimeout(() => { + if (!isHandled) { + window.removeEventListener('message', messageHandler); + if (popup && !popup.closed) + popup.close(); + ElMessage.warning('登录超时'); + } + }, 60 * 1000); // 60分钟超时关闭 +} + const wxSrc = computed( () => `${import.meta.env.VITE_WEB_BASE_API}/wwwroot/aihub/wx.png`, ); // 微信群二维码 const wxGroupQD = `${import.meta.env.VITE_WEB_BASE_API}/wwwroot/aihub/jlq.png`; -const srcList = [ - wxGroupQD, -]; function openContact() { ElMessageBox.alert( ` @@ -251,11 +309,24 @@ function openContact() {
-
+
+ +

+ 开通Vip后,点击下方重新登录意社区 +

+
+ + 意社区重新登录 +

如遇问题,请联系我们 diff --git a/Yi.Ai.Vue3/src/config/sso.ts b/Yi.Ai.Vue3/src/config/sso.ts index 8e92f5d7..a7f87ece 100644 --- a/Yi.Ai.Vue3/src/config/sso.ts +++ b/Yi.Ai.Vue3/src/config/sso.ts @@ -1,4 +1,7 @@ // 三方登录 // export const SSO_SEVER_URL: string = 'https://ccnetcore.com'; export const SSO_SEVER_URL: string = import.meta.env.VITE_SSO_SEVER_URL || 'http://ccnetcore.com'; -export const SSO_CLIENT_ID: string = import.meta.env.VITE_SSO_CLIENT_ID || 'YiXin-Ai'; +// export const SSO_SEVER_URL: string = 'http://localhost:18001'; +export const SSO_CLIENT_LOGIN: string = 'YiXinAi-Login'; +// 意社区重新登录标识 +export const SSO_CLIENT_LOGIN_AGAIN: string = 'LoginAgain'; diff --git a/Yi.Ai.Vue3/types/components.d.ts b/Yi.Ai.Vue3/types/components.d.ts index dde73646..54986c6c 100644 --- a/Yi.Ai.Vue3/types/components.d.ts +++ b/Yi.Ai.Vue3/types/components.d.ts @@ -11,6 +11,30 @@ declare module 'vue' { AccountPassword: typeof import('./../src/components/LoginDialog/components/FormLogin/AccountPassword.vue')['default'] APIKeyManagement: typeof import('./../src/components/userPersonalCenter/components/APIKeyManagement.vue')['default'] DeepThinking: typeof import('./../src/components/DeepThinking/index.vue')['default'] + ElAlert: typeof import('element-plus/es')['ElAlert'] + ElAvatar: typeof import('element-plus/es')['ElAvatar'] + ElButton: typeof import('element-plus/es')['ElButton'] + ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup'] + ElCard: typeof import('element-plus/es')['ElCard'] + ElCollapse: typeof import('element-plus/es')['ElCollapse'] + ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] + ElContainer: typeof import('element-plus/es')['ElContainer'] + ElDialog: typeof import('element-plus/es')['ElDialog'] + ElDivider: typeof import('element-plus/es')['ElDivider'] + ElEmpty: typeof import('element-plus/es')['ElEmpty'] + ElForm: typeof import('element-plus/es')['ElForm'] + ElFormItem: typeof import('element-plus/es')['ElFormItem'] + ElHeader: typeof import('element-plus/es')['ElHeader'] + ElIcon: typeof import('element-plus/es')['ElIcon'] + ElImage: typeof import('element-plus/es')['ElImage'] + ElInput: typeof import('element-plus/es')['ElInput'] + ElMain: typeof import('element-plus/es')['ElMain'] + ElMenu: typeof import('element-plus/es')['ElMenu'] + ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] + ElPagination: typeof import('element-plus/es')['ElPagination'] + ElTable: typeof import('element-plus/es')['ElTable'] + ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] FilesSelect: typeof import('./../src/components/FilesSelect/index.vue')['default'] IconSelect: typeof import('./../src/components/IconSelect/index.vue')['default'] Indexl: typeof import('./../src/components/SupportModelProducts/indexl.vue')['default'] @@ -29,4 +53,7 @@ declare module 'vue' { VerificationCode: typeof import('./../src/components/LoginDialog/components/FormLogin/VerificationCode.vue')['default'] WelecomeText: typeof import('./../src/components/WelecomeText/index.vue')['default'] } + export interface GlobalDirectives { + vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + } } diff --git a/Yi.Ai.Vue3/types/import_meta.d.ts b/Yi.Ai.Vue3/types/import_meta.d.ts index 9b14b379..d8a60d41 100644 --- a/Yi.Ai.Vue3/types/import_meta.d.ts +++ b/Yi.Ai.Vue3/types/import_meta.d.ts @@ -8,7 +8,6 @@ interface ImportMetaEnv { readonly VITE_API_URL: string; readonly VITE_BUILD_COMPRESS: string; readonly VITE_SSO_SEVER_URL: string; - readonly VITE_SSO_CLIENT_ID: string; readonly VITE_APP_VERSION: string; } diff --git a/Yi.Bbs.Vue3/src/permission.js b/Yi.Bbs.Vue3/src/permission.js index e9670f15..0aa8f20a 100644 --- a/Yi.Bbs.Vue3/src/permission.js +++ b/Yi.Bbs.Vue3/src/permission.js @@ -9,7 +9,7 @@ NProgress.configure({ showSpinner: false }); const { getToken, logoutFun ,getRefreshToken} = useAuths(); const whiteList = ["/login", "/auth-redirect", "/bind", "/register"]; -router.beforeEach((to, from, next) => { +router.beforeEach(async (to, from, next) => { NProgress.start(); const hasToken = getToken(); const refreshToken = getRefreshToken(); @@ -18,8 +18,12 @@ router.beforeEach((to, from, next) => { const isPopup = window.opener && window.opener !== window; const clientId = urlParams.get('client_id'); const redirectUri = urlParams.get('redirect_uri'); - // 检查是否已经处理过SSO登录(防重复) - if (isPopup && clientId && redirectUri ) { + // ➤ 如果是弹窗+LoginAgain,执行登出再跳转回 login 页面 + if (clientId === 'LoginAgain' && isPopup && hasToken) { + await logoutFun() + next({ path: '/login', query: { client_id: 'YiXinAi-Login', redirect_uri: redirectUri } }); + return; + } else if (isPopup && clientId === 'YiXinAi-Login' && redirectUri) { if (hasToken) { // 发送消息给父窗口 const targetOrigin = new URL(decodeURIComponent(redirectUri)).origin; @@ -30,6 +34,7 @@ router.beforeEach((to, from, next) => { }, targetOrigin); // 立即关闭窗口 setTimeout(() => window.close(), 100); + return; } } } @@ -37,22 +42,22 @@ router.beforeEach((to, from, next) => { if (hasToken) { if (to.path === "/login") { // 已经登陆跳转到首页 - next({ path: "/" }); + next({path: "/"}); NProgress.done(); } else { if (useUserStore().roles.length === 0) { // 判断当前用户是否已拉取完user_info信息 useUserStore() - .getInfo() - .then(() => { - next({ ...to, replace: true }); - }) - .catch((err) => { - logoutFun.then(() => { - ElMessage.error(err); - next({ path: "/" }); + .getInfo() + .then(() => { + next({...to, replace: true}); + }) + .catch((err) => { + logoutFun.then(() => { + ElMessage.error(err); + next({path: "/"}); + }); }); - }); } else { next(); }