fix: 增加重新登录意社区

This commit is contained in:
Gsh
2025-07-15 00:54:34 +08:00
parent cab0b61ee0
commit 0d1ee18da0
8 changed files with 133 additions and 30 deletions

View File

@@ -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'

View File

@@ -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'

View File

@@ -5,6 +5,8 @@
"ComputedRef": true,
"DirectiveBinding": true,
"EffectScope": true,
"ElMessage": true,
"ElMessageBox": true,
"ExtractDefaultPropTypes": true,
"ExtractPropTypes": true,
"ExtractPublicPropTypes": true,

View File

@@ -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() {
</el-divider>
<div class="third-party-buttons">
<el-tooltip content="使用意社区账号登录" placement="top">
<div class="third-party-btn" @click="handleThirdPartyLogin">
<div class="third-party-btn" @click="handleThirdPartyLogin(SSO_CLIENT_LOGIN)">
<img :src="logoPng" class="third-party-icon" alt="">
</div>
</el-tooltip>
</div>
<el-divider content-position="center">
<p class="w-max">
开通Vip后点击下方重新登录意社区
</p>
</el-divider>
<el-button
class="w-full"
type="primary"
size="large"
@click="handleThirdPartyLogin(SSO_CLIENT_LOGIN_AGAIN)"
>
意社区重新登录
</el-button>
<el-divider class="w-max">
<p class="w-max">
如遇问题请联系我们

View File

@@ -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';

View File

@@ -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']
}
}

View File

@@ -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;
}

View File

@@ -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();
}