2026-05-26 17:06:53 +08:00
|
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
|
|
import { Spin, message } from 'antd';
|
|
|
|
|
|
import { history, useLocation, useModel } from '@umijs/max';
|
2026-06-04 16:25:38 +08:00
|
|
|
|
import { clearAllClientStorage, getAccessToken } from '@/access';
|
2026-05-26 17:06:53 +08:00
|
|
|
|
import { getRoutersInfo, setRemoteMenu } from '@/services/session';
|
|
|
|
|
|
import { flushSync } from 'react-dom';
|
|
|
|
|
|
|
|
|
|
|
|
/** 过渡页文案:避免「登录」表述,强调无缝进入 */
|
|
|
|
|
|
const STATUS_TEXT = {
|
|
|
|
|
|
entering: '正在进入系统…',
|
|
|
|
|
|
verifying: '正在核验访问信息…',
|
|
|
|
|
|
preparing: '正在准备页面…',
|
|
|
|
|
|
loadingProfile: '正在加载您的资料…',
|
|
|
|
|
|
noCredential: '未检测到有效访问凭证,请从原系统入口进入',
|
|
|
|
|
|
credentialInvalid: '访问凭证已失效,请从原系统重新进入',
|
|
|
|
|
|
profileFailed: '暂时无法加载您的信息,请稍后重试',
|
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
|
|
const HINT_TEXT = '请稍候,页面即将呈现';
|
|
|
|
|
|
|
|
|
|
|
|
const pageStyle: React.CSSProperties = {
|
|
|
|
|
|
display: 'flex',
|
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
|
minHeight: '100vh',
|
|
|
|
|
|
padding: '24px',
|
|
|
|
|
|
background: 'linear-gradient(180deg, #f0f5ff 0%, #f5f7fa 48%, #fafafa 100%)',
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const cardStyle: React.CSSProperties = {
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
maxWidth: 420,
|
|
|
|
|
|
padding: '48px 40px 40px',
|
|
|
|
|
|
borderRadius: 16,
|
|
|
|
|
|
background: '#fff',
|
|
|
|
|
|
boxShadow: '0 8px 24px rgba(0, 0, 0, 0.06)',
|
|
|
|
|
|
border: '1px solid rgba(0, 0, 0, 0.04)',
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const titleStyle: React.CSSProperties = {
|
|
|
|
|
|
marginTop: 28,
|
|
|
|
|
|
marginBottom: 0,
|
|
|
|
|
|
fontSize: 20,
|
|
|
|
|
|
fontWeight: 600,
|
|
|
|
|
|
color: 'rgba(0, 0, 0, 0.88)',
|
|
|
|
|
|
lineHeight: 1.4,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const statusStyle: React.CSSProperties = {
|
|
|
|
|
|
marginTop: 12,
|
|
|
|
|
|
marginBottom: 0,
|
|
|
|
|
|
fontSize: 15,
|
|
|
|
|
|
color: 'rgba(0, 0, 0, 0.65)',
|
|
|
|
|
|
lineHeight: 1.6,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const hintStyle: React.CSSProperties = {
|
|
|
|
|
|
marginTop: 8,
|
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
|
color: 'rgba(0, 0, 0, 0.45)',
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export default function ThirdPartyRedirect() {
|
|
|
|
|
|
const location = useLocation();
|
|
|
|
|
|
const { initialState, setInitialState } = useModel('@@initialState');
|
|
|
|
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
|
|
const [status, setStatus] = useState<string>(STATUS_TEXT.entering);
|
|
|
|
|
|
const [isError, setIsError] = useState(false);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
handleLoginRedirect();
|
|
|
|
|
|
}, [location.search]);
|
|
|
|
|
|
|
|
|
|
|
|
const fetchUserInfo = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const userInfo = await initialState?.fetchUserInfo?.();
|
|
|
|
|
|
if (userInfo) {
|
|
|
|
|
|
console.log('userInfo', userInfo);
|
|
|
|
|
|
console.log('user roles:', userInfo?.roles);
|
|
|
|
|
|
console.log('first role:', userInfo?.roles?.[0]);
|
|
|
|
|
|
flushSync(() => {
|
|
|
|
|
|
setInitialState((s) => ({
|
|
|
|
|
|
...s,
|
|
|
|
|
|
currentUser: userInfo,
|
|
|
|
|
|
}));
|
|
|
|
|
|
});
|
2026-05-29 15:23:27 +08:00
|
|
|
|
console.log('userType---', userInfo?.userType);
|
|
|
|
|
|
if (userInfo?.userType === 'common') {
|
2026-05-26 17:06:53 +08:00
|
|
|
|
const params = new URLSearchParams(location.search);
|
|
|
|
|
|
const pageName = params.get('pageName');
|
|
|
|
|
|
console.log('userType value:', userInfo?.userType, 'type:', typeof userInfo?.userType);
|
|
|
|
|
|
if (!pageName) {
|
|
|
|
|
|
history.replace(`/job-portal`);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pageName === 'message') {
|
|
|
|
|
|
history.replace(`/job-portal/${pageName}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pageName === 'jobDetail') {
|
|
|
|
|
|
history.replace(`/job-portal/detail/${params.get('jobId')}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pageName === 'personal-center') {
|
|
|
|
|
|
history.replace(`/job-portal/${pageName}`);
|
|
|
|
|
|
}
|
2026-06-04 16:25:38 +08:00
|
|
|
|
if (pageName === 'policy') {
|
|
|
|
|
|
history.replace(`/job-portal/${pageName}`);
|
|
|
|
|
|
}
|
2026-05-26 17:06:53 +08:00
|
|
|
|
return;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
const menus = await getRoutersInfo();
|
|
|
|
|
|
console.log('userType value:', userInfo?.userType, 'type:', typeof userInfo?.userType);
|
2026-05-29 15:23:27 +08:00
|
|
|
|
if (menus && menus.length > 0 && userInfo?.userType !== 'common') {
|
2026-05-26 17:06:53 +08:00
|
|
|
|
setRemoteMenu(menus);
|
2026-06-16 19:11:36 +08:00
|
|
|
|
window.location.replace('http://39.98.44.136:6024/shihezi/management/management/list/index?type=1')
|
2026-05-26 17:06:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
message.error('暂时无法加载您的信息');
|
|
|
|
|
|
setIsError(true);
|
|
|
|
|
|
setStatus(STATUS_TEXT.profileFailed);
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
setIsError(true);
|
|
|
|
|
|
setStatus(STATUS_TEXT.profileFailed);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-06-04 16:25:38 +08:00
|
|
|
|
/** URL 未带 token 时清除本地登录态(与退出登录一致) */
|
|
|
|
|
|
const performLogout = () => {
|
|
|
|
|
|
clearAllClientStorage();
|
|
|
|
|
|
setRemoteMenu(null);
|
|
|
|
|
|
flushSync(() => {
|
|
|
|
|
|
setInitialState((s) => ({
|
|
|
|
|
|
...s,
|
|
|
|
|
|
currentUser: undefined,
|
|
|
|
|
|
}));
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const redirectByPageName = (params: URLSearchParams, pageName: string | null) => {
|
|
|
|
|
|
if (!pageName) {
|
|
|
|
|
|
history.replace('/job-portal');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (pageName === 'jobDetail') {
|
|
|
|
|
|
history.replace(`/job-portal/detail/${params.get('jobId')}`);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
history.replace(`/job-portal/${pageName}`);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-05-26 17:06:53 +08:00
|
|
|
|
const handleLoginRedirect = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setIsError(false);
|
|
|
|
|
|
const params = new URLSearchParams(location.search);
|
|
|
|
|
|
const code = params.get('code');
|
|
|
|
|
|
const token = params.get('token');
|
|
|
|
|
|
const pageName = params.get('pageName');
|
|
|
|
|
|
|
2026-06-04 16:25:38 +08:00
|
|
|
|
// token 与 code 互斥,仅其一用于 SSO 换票
|
|
|
|
|
|
if (token || code) {
|
2026-05-26 17:06:53 +08:00
|
|
|
|
const sessionToken = getAccessToken();
|
|
|
|
|
|
if (!sessionToken) {
|
|
|
|
|
|
setIsError(true);
|
|
|
|
|
|
setStatus(STATUS_TEXT.credentialInvalid);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
setStatus(STATUS_TEXT.loadingProfile);
|
|
|
|
|
|
await fetchUserInfo();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-06-04 16:25:38 +08:00
|
|
|
|
|
|
|
|
|
|
// URL 无 token/code:退出登录后跳转(无 pageName 则去求职门户首页)
|
|
|
|
|
|
performLogout();
|
|
|
|
|
|
redirectByPageName(params, pageName);
|
2026-05-26 17:06:53 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('单点进入失败:', error);
|
|
|
|
|
|
setIsError(true);
|
|
|
|
|
|
message.error('进入系统失败,请稍后重试');
|
|
|
|
|
|
setStatus(STATUS_TEXT.credentialInvalid);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={pageStyle}>
|
|
|
|
|
|
<div style={cardStyle}>
|
|
|
|
|
|
<Spin size="large" spinning={loading && !isError} />
|
|
|
|
|
|
{!loading && isError && (
|
|
|
|
|
|
<div
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: 48,
|
|
|
|
|
|
height: 48,
|
|
|
|
|
|
margin: '0 auto',
|
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
|
background: '#fff2f0',
|
|
|
|
|
|
color: '#ff4d4f',
|
|
|
|
|
|
fontSize: 24,
|
|
|
|
|
|
lineHeight: '48px',
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
!
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
<h1 style={titleStyle}>{isError ? '暂时无法进入' : '正在进入系统'}</h1>
|
|
|
|
|
|
<p style={statusStyle}>{status}</p>
|
|
|
|
|
|
{!isError && <p style={hintStyle}>{HINT_TEXT}</p>}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|