import { http } from "../utils/service"; const VIDEO_LIST_PATH = "/notice/videolist"; const TICKET_LIST_PATH = "/notice/ticketlist"; let cachedVideoUrls: string[] = []; let videoListPromise: Promise | null = null; export interface NoticeCallingItem { ticketId: string; winName: string; isTransfer?: boolean; } export interface NoticeTicketListData { total: number; waitingNum: number; completedNum: number; dealingNum: number; callinglist: NoticeCallingItem[]; abandonedlist: string[]; waitinglist: string[]; } function normalizeCallingItem(raw: unknown): NoticeCallingItem | null { if (!raw || typeof raw !== "object") { return null; } const item = raw as Record; const ticketId = item.ticketId ?? item.ticket_id; const winName = item.winName ?? item.win_name; if (ticketId == null || winName == null) { return null; } const isTransfer = item.isTransfer ?? item.is_transfer; return { ticketId: String(ticketId), winName: String(winName), isTransfer: Boolean(isTransfer), }; } function normalizeTicketIdFromListItem(raw: unknown): string | null { if (raw == null) { return null; } if (typeof raw === "string" || typeof raw === "number") { const value = String(raw).trim(); return value.length > 0 ? value : null; } if (typeof raw === "object") { const item = raw as Record; const ticketId = item.ticketId ?? item.ticket_id; if (ticketId == null) { return null; } const value = String(ticketId).trim(); return value.length > 0 ? value : null; } return null; } function normalizeTicketIdList(raw: unknown): string[] { if (!Array.isArray(raw)) { return []; } return raw .map(normalizeTicketIdFromListItem) .filter((ticketId): ticketId is string => ticketId !== null); } function normalizeTicketListData(raw: unknown): NoticeTicketListData { const data = (raw ?? {}) as Record; const callingRaw = Array.isArray(data.callinglist) ? data.callinglist : []; const callinglist = callingRaw .map(normalizeCallingItem) .filter((item): item is NoticeCallingItem => item !== null); return { total: Number(data.total ?? 0), waitingNum: Number(data.waitingNum ?? data.waiting_num ?? 0), completedNum: Number(data.completedNum ?? data.completed_num ?? 0), dealingNum: Number(data.dealingNum ?? data.dealing_num ?? 0), callinglist, abandonedlist: normalizeTicketIdList(data.abandonedlist), waitinglist: normalizeTicketIdList(data.waitinglist), }; } export async function fetchNoticeVideoList(): Promise { const data = await http.get(VIDEO_LIST_PATH); if (!Array.isArray(data)) { return []; } return data.map((url) => String(url)).filter((url) => url.trim().length > 0); } export async function fetchNoticeTicketList(): Promise { const data = await http.get(TICKET_LIST_PATH); return normalizeTicketListData(data); } export function getCachedNoticeVideoUrls(): string[] { return [...cachedVideoUrls]; } /** 客户端打开时拉取宣传视频列表(结果缓存,重复调用复用同一请求)。 */ export async function loadNoticeVideoListOnOpen(force = false): Promise { if (!force && cachedVideoUrls.length > 0) { return [...cachedVideoUrls]; } if (!force && videoListPromise) { return videoListPromise; } videoListPromise = fetchNoticeVideoList() .then((urls) => { cachedVideoUrls = urls; return [...urls]; }) .finally(() => { videoListPromise = null; }); return videoListPromise; }