消息角标开发
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
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

This commit is contained in:
francis-fh
2026-07-20 20:50:35 +08:00
parent dfe22c6307
commit 86e70a38d0
5 changed files with 99 additions and 2 deletions

View File

@@ -0,0 +1,72 @@
import React from 'react';
import { getInterviewBadgeCount } from './list';
let badgeCount = 0;
let subscribers: Array<(count: number) => void> = [];
/** 获取当前角标数量 */
export function getBadgeCount(): number {
return badgeCount;
}
/** 订阅角标数量变化,返回取消订阅函数 */
export function subscribeBadgeCount(fn: (count: number) => void): () => void {
subscribers.push(fn);
return () => {
subscribers = subscribers.filter((s) => s !== fn);
};
}
function notifySubscribers() {
subscribers.forEach((fn) => fn(badgeCount));
}
/** 从接口获取并更新角标数量 */
export async function fetchAndUpdateBadge() {
try {
const res = await getInterviewBadgeCount();
if (res.code === 200 && res.data) {
badgeCount = (res.data.jss ?? 0) + (res.data.jjs ?? 0);
notifySubscribers();
}
} catch (e) {
console.error('获取面试角标失败', e);
}
}
/** 清除角标数量(退出登录时) */
export function clearBadgeCount() {
badgeCount = 0;
notifySubscribers();
}
/** 递归遍历菜单树,给面试列表菜单项的 name 注入红色角标 JSX */
export function patchMenuBadge(menuData: any[]): any[] {
if (!menuData) return menuData;
return menuData.map((item: any) => {
const patched: any = { ...item };
if (item.path === 'interview-list' || (item.path && item.path.endsWith('/interview-list'))) {
const originalName = item._originalName || item.name;
patched._originalName = originalName;
if (badgeCount > 0) {
patched.name = (
<span style={{ whiteSpace: 'nowrap' }}>
{originalName}
<span style={{ color: '#ff4d4f', fontWeight: 500, marginLeft: 4 }}>
({badgeCount})
</span>
</span>
);
} else {
patched.name = originalName;
}
}
if (item.routes) {
patched.routes = patchMenuBadge(item.routes);
}
if (item.children) {
patched.children = patchMenuBadge(item.children);
}
return patched;
});
}

View File

@@ -155,3 +155,16 @@ export async function getAppSkillList(params?: { userId?: number }) {
params,
});
}
// ========== 面试消息角标 APIs ==========
/** 获取面试消息角标数量(后台管理端菜单角标) */
export async function getInterviewBadgeCount() {
return request<{
msg: string;
code: number;
data: { total: number; jss: number; jjs: number };
}>('/api/cms/interview/msyyhbs', {
method: 'GET',
});
}