You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.6 KiB
TypeScript
127 lines
3.6 KiB
TypeScript
import { http } from "../utils/service";
|
|
|
|
const VIDEO_LIST_PATH = "/notice/videolist";
|
|
const TICKET_LIST_PATH = "/notice/ticketlist";
|
|
|
|
let cachedVideoUrls: string[] = [];
|
|
let videoListPromise: Promise<string[]> | 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<string, unknown>;
|
|
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<string, unknown>;
|
|
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<string, unknown>;
|
|
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<string[]> {
|
|
const data = await http.get<unknown>(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<NoticeTicketListData> {
|
|
const data = await http.get<unknown>(TICKET_LIST_PATH);
|
|
return normalizeTicketListData(data);
|
|
}
|
|
|
|
export function getCachedNoticeVideoUrls(): string[] {
|
|
return [...cachedVideoUrls];
|
|
}
|
|
|
|
/** 客户端打开时拉取宣传视频列表(结果缓存,重复调用复用同一请求)。 */
|
|
export async function loadNoticeVideoListOnOpen(force = false): Promise<string[]> {
|
|
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;
|
|
}
|