fix: 增加重新登录意社区
This commit is contained in:
@@ -16,10 +16,8 @@ VITE_WEB_BASE_API = '/dev-api'
|
|||||||
VITE_API_URL=http://data.ccnetcore.com:19001/api/app
|
VITE_API_URL=http://data.ccnetcore.com:19001/api/app
|
||||||
|
|
||||||
# SSO单点登录url
|
# SSO单点登录url
|
||||||
VITE_SSO_SEVER_URL='http://localhost:18001'
|
VITE_SSO_SEVER_URL=http://localhost:18001
|
||||||
# SSO_SEVER_URL='http://ccnetcore.com'
|
# 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'
|
||||||
|
|||||||
@@ -17,10 +17,8 @@ VITE_API_URL = http://data.ccnetcore.com:19001/api/app
|
|||||||
VITE_BUILD_COMPRESS = gzip
|
VITE_BUILD_COMPRESS = gzip
|
||||||
|
|
||||||
# SSO单点登录url
|
# SSO单点登录url
|
||||||
VITE_SSO_SEVER_URL='https://ccnetcore.com'
|
VITE_SSO_SEVER_URL=https://ccnetcore.com
|
||||||
# SSO单点登录项目标识
|
|
||||||
VITE_SSO_CLIENT_ID='YiXin-Ai';
|
|
||||||
# 版本号
|
# 版本号
|
||||||
VITE_APP_VERSION='1.0.6';
|
VITE_APP_VERSION='1.0.7'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
"ComputedRef": true,
|
"ComputedRef": true,
|
||||||
"DirectiveBinding": true,
|
"DirectiveBinding": true,
|
||||||
"EffectScope": true,
|
"EffectScope": true,
|
||||||
|
"ElMessage": true,
|
||||||
|
"ElMessageBox": true,
|
||||||
"ExtractDefaultPropTypes": true,
|
"ExtractDefaultPropTypes": true,
|
||||||
"ExtractPropTypes": true,
|
"ExtractPropTypes": true,
|
||||||
"ExtractPublicPropTypes": true,
|
"ExtractPublicPropTypes": true,
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import { useRouter } from 'vue-router';
|
|||||||
import { getUserInfo } from '@/api';
|
import { getUserInfo } from '@/api';
|
||||||
import logoPng from '@/assets/images/logo.png';
|
import logoPng from '@/assets/images/logo.png';
|
||||||
import SvgIcon from '@/components/SvgIcon/index.vue';
|
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 { useUserStore } from '@/stores';
|
||||||
import { useLoginFormStore } from '@/stores/modules/loginForm';
|
import { useLoginFormStore } from '@/stores/modules/loginForm';
|
||||||
import { useSessionStore } from '@/stores/modules/session.ts';
|
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`);
|
const redirectUri = encodeURIComponent(`${window.location.origin}/chat`);
|
||||||
|
console.log('cccc', type);
|
||||||
const popup = window.open(
|
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',
|
'SSOLogin',
|
||||||
'width=1000,height=800',
|
'width=1000,height=800',
|
||||||
);
|
);
|
||||||
@@ -110,14 +115,67 @@ function handleThirdPartyLogin() {
|
|||||||
}, 60 * 1000); // 60分钟超时关闭
|
}, 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(
|
const wxSrc = computed(
|
||||||
() => `${import.meta.env.VITE_WEB_BASE_API}/wwwroot/aihub/wx.png`,
|
() => `${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 wxGroupQD = `${import.meta.env.VITE_WEB_BASE_API}/wwwroot/aihub/jlq.png`;
|
||||||
const srcList = [
|
|
||||||
wxGroupQD,
|
|
||||||
];
|
|
||||||
function openContact() {
|
function openContact() {
|
||||||
ElMessageBox.alert(
|
ElMessageBox.alert(
|
||||||
`
|
`
|
||||||
@@ -251,11 +309,24 @@ function openContact() {
|
|||||||
</el-divider>
|
</el-divider>
|
||||||
<div class="third-party-buttons">
|
<div class="third-party-buttons">
|
||||||
<el-tooltip content="使用意社区账号登录" placement="top">
|
<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="">
|
<img :src="logoPng" class="third-party-icon" alt="">
|
||||||
</div>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</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">
|
<el-divider class="w-max">
|
||||||
<p class="w-max">
|
<p class="w-max">
|
||||||
如遇问题,请联系我们
|
如遇问题,请联系我们
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
// 三方登录
|
// 三方登录
|
||||||
// export const SSO_SEVER_URL: string = 'https://ccnetcore.com';
|
// 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_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';
|
||||||
|
|||||||
27
Yi.Ai.Vue3/types/components.d.ts
vendored
27
Yi.Ai.Vue3/types/components.d.ts
vendored
@@ -11,6 +11,30 @@ declare module 'vue' {
|
|||||||
AccountPassword: typeof import('./../src/components/LoginDialog/components/FormLogin/AccountPassword.vue')['default']
|
AccountPassword: typeof import('./../src/components/LoginDialog/components/FormLogin/AccountPassword.vue')['default']
|
||||||
APIKeyManagement: typeof import('./../src/components/userPersonalCenter/components/APIKeyManagement.vue')['default']
|
APIKeyManagement: typeof import('./../src/components/userPersonalCenter/components/APIKeyManagement.vue')['default']
|
||||||
DeepThinking: typeof import('./../src/components/DeepThinking/index.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']
|
FilesSelect: typeof import('./../src/components/FilesSelect/index.vue')['default']
|
||||||
IconSelect: typeof import('./../src/components/IconSelect/index.vue')['default']
|
IconSelect: typeof import('./../src/components/IconSelect/index.vue')['default']
|
||||||
Indexl: typeof import('./../src/components/SupportModelProducts/indexl.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']
|
VerificationCode: typeof import('./../src/components/LoginDialog/components/FormLogin/VerificationCode.vue')['default']
|
||||||
WelecomeText: typeof import('./../src/components/WelecomeText/index.vue')['default']
|
WelecomeText: typeof import('./../src/components/WelecomeText/index.vue')['default']
|
||||||
}
|
}
|
||||||
|
export interface GlobalDirectives {
|
||||||
|
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
Yi.Ai.Vue3/types/import_meta.d.ts
vendored
1
Yi.Ai.Vue3/types/import_meta.d.ts
vendored
@@ -8,7 +8,6 @@ interface ImportMetaEnv {
|
|||||||
readonly VITE_API_URL: string;
|
readonly VITE_API_URL: string;
|
||||||
readonly VITE_BUILD_COMPRESS: string;
|
readonly VITE_BUILD_COMPRESS: string;
|
||||||
readonly VITE_SSO_SEVER_URL: string;
|
readonly VITE_SSO_SEVER_URL: string;
|
||||||
readonly VITE_SSO_CLIENT_ID: string;
|
|
||||||
readonly VITE_APP_VERSION: string;
|
readonly VITE_APP_VERSION: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ NProgress.configure({ showSpinner: false });
|
|||||||
const { getToken, logoutFun ,getRefreshToken} = useAuths();
|
const { getToken, logoutFun ,getRefreshToken} = useAuths();
|
||||||
const whiteList = ["/login", "/auth-redirect", "/bind", "/register"];
|
const whiteList = ["/login", "/auth-redirect", "/bind", "/register"];
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
NProgress.start();
|
NProgress.start();
|
||||||
const hasToken = getToken();
|
const hasToken = getToken();
|
||||||
const refreshToken = getRefreshToken();
|
const refreshToken = getRefreshToken();
|
||||||
@@ -18,8 +18,12 @@ router.beforeEach((to, from, next) => {
|
|||||||
const isPopup = window.opener && window.opener !== window;
|
const isPopup = window.opener && window.opener !== window;
|
||||||
const clientId = urlParams.get('client_id');
|
const clientId = urlParams.get('client_id');
|
||||||
const redirectUri = urlParams.get('redirect_uri');
|
const redirectUri = urlParams.get('redirect_uri');
|
||||||
// 检查是否已经处理过SSO登录(防重复)
|
// ➤ 如果是弹窗+LoginAgain,执行登出再跳转回 login 页面
|
||||||
if (isPopup && clientId && redirectUri ) {
|
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) {
|
if (hasToken) {
|
||||||
// 发送消息给父窗口
|
// 发送消息给父窗口
|
||||||
const targetOrigin = new URL(decodeURIComponent(redirectUri)).origin;
|
const targetOrigin = new URL(decodeURIComponent(redirectUri)).origin;
|
||||||
@@ -30,6 +34,7 @@ router.beforeEach((to, from, next) => {
|
|||||||
}, targetOrigin);
|
}, targetOrigin);
|
||||||
// 立即关闭窗口
|
// 立即关闭窗口
|
||||||
setTimeout(() => window.close(), 100);
|
setTimeout(() => window.close(), 100);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,22 +42,22 @@ router.beforeEach((to, from, next) => {
|
|||||||
if (hasToken) {
|
if (hasToken) {
|
||||||
if (to.path === "/login") {
|
if (to.path === "/login") {
|
||||||
// 已经登陆跳转到首页
|
// 已经登陆跳转到首页
|
||||||
next({ path: "/" });
|
next({path: "/"});
|
||||||
NProgress.done();
|
NProgress.done();
|
||||||
} else {
|
} else {
|
||||||
if (useUserStore().roles.length === 0) {
|
if (useUserStore().roles.length === 0) {
|
||||||
// 判断当前用户是否已拉取完user_info信息
|
// 判断当前用户是否已拉取完user_info信息
|
||||||
useUserStore()
|
useUserStore()
|
||||||
.getInfo()
|
.getInfo()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
next({ ...to, replace: true });
|
next({...to, replace: true});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
logoutFun.then(() => {
|
logoutFun.then(() => {
|
||||||
ElMessage.error(err);
|
ElMessage.error(err);
|
||||||
next({ path: "/" });
|
next({path: "/"});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user