2026-06-04 18:47:59 +08:00
|
|
|
|
import { Modal, message } from 'antd';
|
2026-06-04 16:25:38 +08:00
|
|
|
|
import { getAccessToken } from '@/access';
|
2026-06-04 18:47:59 +08:00
|
|
|
|
import { getAppUserInfo } from '@/services/jobportal/user';
|
2026-06-04 16:25:38 +08:00
|
|
|
|
|
|
|
|
|
|
/** 人社门户登录页 */
|
|
|
|
|
|
export const PORTAL_LOGIN_URL = 'http://218.31.252.15:9081/hrss-web-vue/login';
|
|
|
|
|
|
|
2026-06-04 18:47:59 +08:00
|
|
|
|
/** /api/getInfo 缓存结构(不含 msg、code) */
|
|
|
|
|
|
export interface GetInfoCache {
|
|
|
|
|
|
permissions?: string[];
|
|
|
|
|
|
roles?: string[];
|
|
|
|
|
|
user?: Record<string, unknown>;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const GET_INFO_CACHE_KEY = 'getInfoCache';
|
|
|
|
|
|
const DEFAULT_AVATAR =
|
|
|
|
|
|
'https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png';
|
|
|
|
|
|
|
|
|
|
|
|
let appUserInfoPromise: Promise<number | null> | null = null;
|
|
|
|
|
|
|
|
|
|
|
|
/** 读取 /api/getInfo 完整缓存 */
|
|
|
|
|
|
export function getGetInfoCache(): GetInfoCache | null {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const cached = localStorage.getItem(GET_INFO_CACHE_KEY);
|
|
|
|
|
|
if (cached) {
|
|
|
|
|
|
return JSON.parse(cached) as GetInfoCache;
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 将 /api/getInfo 返回体(除 msg、code)写入 localStorage */
|
|
|
|
|
|
export function saveGetInfoCache(response: Record<string, unknown>): void {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const { msg: _msg, code: _code, ...rest } = response;
|
|
|
|
|
|
const user = rest.user
|
|
|
|
|
|
? { ...(rest.user as Record<string, unknown>) }
|
|
|
|
|
|
: undefined;
|
|
|
|
|
|
|
|
|
|
|
|
if (user && (user.avatar === '' || user.avatar == null)) {
|
|
|
|
|
|
user.avatar = DEFAULT_AVATAR;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const payload: GetInfoCache = {
|
|
|
|
|
|
permissions: (rest.permissions as string[]) ?? [],
|
|
|
|
|
|
roles: (rest.roles as string[]) ?? [],
|
|
|
|
|
|
user,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
localStorage.setItem(GET_INFO_CACHE_KEY, JSON.stringify(payload));
|
|
|
|
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
|
|
const raw = user.appUserId ?? user.userId;
|
|
|
|
|
|
if (raw != null && raw !== '') {
|
|
|
|
|
|
const n = Number(raw);
|
|
|
|
|
|
if (!Number.isNaN(n) && n > 0) {
|
|
|
|
|
|
localStorage.setItem('appUserId', String(n));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('保存 getInfo 缓存失败:', error);
|
2026-06-04 16:25:38 +08:00
|
|
|
|
}
|
2026-06-04 18:47:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 清除 getInfo 缓存 */
|
|
|
|
|
|
export function clearGetInfoCache(): void {
|
|
|
|
|
|
localStorage.removeItem(GET_INFO_CACHE_KEY);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** 从本地缓存读取求职者 userId(同步) */
|
|
|
|
|
|
export const getJobPortalUserId = (): number | null => {
|
2026-06-04 16:25:38 +08:00
|
|
|
|
try {
|
|
|
|
|
|
const cached = localStorage.getItem('userInfo');
|
|
|
|
|
|
if (cached) {
|
|
|
|
|
|
const userInfo = JSON.parse(cached);
|
2026-06-04 18:47:59 +08:00
|
|
|
|
const raw = userInfo?.userId ?? userInfo?.id;
|
|
|
|
|
|
if (raw != null && raw !== '') {
|
|
|
|
|
|
const n = Number(raw);
|
|
|
|
|
|
if (!Number.isNaN(n) && n > 0) return n;
|
|
|
|
|
|
}
|
2026-06-04 16:25:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
}
|
2026-06-04 18:47:59 +08:00
|
|
|
|
|
|
|
|
|
|
const getInfo = getGetInfoCache();
|
|
|
|
|
|
const sessionUser = getInfo?.user;
|
|
|
|
|
|
if (sessionUser) {
|
|
|
|
|
|
const raw = sessionUser.appUserId ?? sessionUser.userId;
|
|
|
|
|
|
if (raw != null && raw !== '') {
|
|
|
|
|
|
const n = Number(raw);
|
|
|
|
|
|
if (!Number.isNaN(n) && n > 0) return n;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
const appUserId = localStorage.getItem('appUserId');
|
|
|
|
|
|
if (appUserId) {
|
|
|
|
|
|
const n = Number(appUserId);
|
|
|
|
|
|
if (!Number.isNaN(n) && n > 0) return n;
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
// ignore
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export const isJobPortalLoggedIn = (): boolean => {
|
|
|
|
|
|
if (getAccessToken()) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return !!getJobPortalUserId();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 已登录但本地无 userId 时,拉取 appUser 信息并写入 userInfo
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const ensureJobPortalUserId = async (): Promise<number | null> => {
|
|
|
|
|
|
const cached = getJobPortalUserId();
|
|
|
|
|
|
if (cached) return cached;
|
|
|
|
|
|
|
|
|
|
|
|
if (!getAccessToken()) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!appUserInfoPromise) {
|
|
|
|
|
|
appUserInfoPromise = (async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await getAppUserInfo();
|
|
|
|
|
|
if (response?.code === 200 && response?.data) {
|
|
|
|
|
|
localStorage.setItem('userInfo', JSON.stringify(response.data));
|
|
|
|
|
|
const raw = response.data.userId ?? (response.data as { id?: number }).id;
|
|
|
|
|
|
if (raw != null && raw !== '') {
|
|
|
|
|
|
const n = Number(raw);
|
|
|
|
|
|
if (!Number.isNaN(n) && n > 0) {
|
|
|
|
|
|
localStorage.setItem('appUserId', String(n));
|
|
|
|
|
|
return n;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取求职者用户信息失败:', error);
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
})().finally(() => {
|
|
|
|
|
|
appUserInfoPromise = null;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return appUserInfoPromise;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 门户进入后预拉求职者信息,避免有 token 无 userId */
|
|
|
|
|
|
export const prefetchJobPortalUserInfo = (): void => {
|
|
|
|
|
|
if (getAccessToken() && !getJobPortalUserId()) {
|
|
|
|
|
|
void ensureJobPortalUserId();
|
|
|
|
|
|
}
|
2026-06-04 16:25:38 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** 未登录时弹窗提示并跳转登录页,已登录返回 true */
|
|
|
|
|
|
export const ensureJobPortalLogin = (actionHint = '该操作'): boolean => {
|
|
|
|
|
|
if (isJobPortalLoggedIn()) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
|
title: '请先登录',
|
|
|
|
|
|
content: `登录后才可${actionHint},是否前往登录?`,
|
|
|
|
|
|
okText: '去登录',
|
|
|
|
|
|
cancelText: '取消',
|
|
|
|
|
|
onOk: () => {
|
|
|
|
|
|
window.location.href = PORTAL_LOGIN_URL;
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
return false;
|
|
|
|
|
|
};
|
2026-06-04 18:47:59 +08:00
|
|
|
|
|
|
|
|
|
|
/** 收藏/申请等需要 userId 的操作:先校验登录,再确保 userId 可用 */
|
|
|
|
|
|
export const requireJobPortalUserId = async (actionHint: string): Promise<number | null> => {
|
|
|
|
|
|
if (!ensureJobPortalLogin(actionHint)) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
const userId = await ensureJobPortalUserId();
|
|
|
|
|
|
if (!userId) {
|
|
|
|
|
|
message.warning('无法获取用户信息,请稍后重试');
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
return userId;
|
|
|
|
|
|
};
|