Files
shz-admin/src/utils/jobPortalAuth.ts
francis-fh 134c1ecece
Some checks failed
Node CI / build (14.x, macOS-latest) (push) Has been cancelled
Node CI / build (14.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (14.x, windows-latest) (push) Has been cancelled
Node CI / build (16.x, macOS-latest) (push) Has been cancelled
Node CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node CI / build (16.x, windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
coverage CI / build (push) Has been cancelled
Node pnpm CI / build (16.x, macOS-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, ubuntu-latest) (push) Has been cancelled
Node pnpm CI / build (16.x, windows-latest) (push) Has been cancelled
111
2026-06-04 18:47:59 +08:00

192 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Modal, message } from 'antd';
import { getAccessToken } from '@/access';
import { getAppUserInfo } from '@/services/jobportal/user';
/** 人社门户登录页 */
export const PORTAL_LOGIN_URL = 'http://218.31.252.15:9081/hrss-web-vue/login';
/** /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);
}
}
/** 清除 getInfo 缓存 */
export function clearGetInfoCache(): void {
localStorage.removeItem(GET_INFO_CACHE_KEY);
}
/** 从本地缓存读取求职者 userId同步 */
export const getJobPortalUserId = (): number | null => {
try {
const cached = localStorage.getItem('userInfo');
if (cached) {
const userInfo = JSON.parse(cached);
const raw = userInfo?.userId ?? userInfo?.id;
if (raw != null && raw !== '') {
const n = Number(raw);
if (!Number.isNaN(n) && n > 0) return n;
}
}
} catch {
// ignore
}
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();
}
};
/** 未登录时弹窗提示并跳转登录页,已登录返回 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;
};
/** 收藏/申请等需要 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;
};