修复:补齐多项目公屏叫号播报
需求:管理员公屏在员工叫号后需播放项目名与号码。 实现:复用单项目号码播报格式,按项目跟踪新批次并播报项目名加号码,补充回归测试。
This commit is contained in:
@@ -1,13 +1,48 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { api } from "../api";
|
||||
import { FeedbackBanner, FreshnessBanner, LoadingState } from "../components/Feedback";
|
||||
import { usePollingResource } from "../hooks/usePollingResource";
|
||||
import { isTimestampStale } from "../lib/format";
|
||||
import { formatCallAnnouncement, isTimestampStale } from "../lib/format";
|
||||
import type { CallBatchDto } from "../types";
|
||||
import { DisplayCenter } from "./AdminPage";
|
||||
|
||||
function projectCurrentBatch(value: unknown): CallBatchDto | null {
|
||||
return value && typeof value === "object" ? value as CallBatchDto : null;
|
||||
}
|
||||
|
||||
export function PublicDisplayCenterPage() {
|
||||
const resource = usePollingResource((signal) => api.displayOverview(signal), { intervalMs: 5_000 });
|
||||
const data = resource.data;
|
||||
const stale = Boolean(data) && isTimestampStale(resource.lastClientSuccessAt, 30_000);
|
||||
const lastCallsRef = useRef<Map<string, string | null> | null>(null);
|
||||
useEffect(() => {
|
||||
if (!data) return;
|
||||
const previousCalls = lastCallsRef.current;
|
||||
const nextCalls = new Map<string, string | null>();
|
||||
const announcements: string[] = [];
|
||||
for (const project of data.projects) {
|
||||
const batch = projectCurrentBatch(project.current_batch);
|
||||
const key = batch ? `${batch.batch_number}:${batch.called_at ?? ""}` : null;
|
||||
nextCalls.set(project.id, key);
|
||||
if (!previousCalls?.has(project.id) || !key || previousCalls.get(project.id) === key) continue;
|
||||
const announcement = formatCallAnnouncement(batch);
|
||||
if (announcement) announcements.push(`${project.name},${announcement}`);
|
||||
}
|
||||
lastCallsRef.current = nextCalls;
|
||||
if (
|
||||
!announcements.length
|
||||
|| !("speechSynthesis" in window)
|
||||
|| typeof SpeechSynthesisUtterance === "undefined"
|
||||
) return;
|
||||
|
||||
window.speechSynthesis.cancel();
|
||||
for (const announcement of announcements) {
|
||||
const utterance = new SpeechSynthesisUtterance(announcement);
|
||||
utterance.lang = "zh-CN";
|
||||
utterance.rate = 0.9;
|
||||
window.speechSynthesis.speak(utterance);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<div className="app-shell app-shell--admin app-shell--no-primary-action">
|
||||
|
||||
Reference in New Issue
Block a user