various fix
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
let allLabels = [];
|
||||
let selectedConsumables = new Set();
|
||||
let lastVideoBatchDoctorDisplay = "";
|
||||
let videoVisToken = 0;
|
||||
const webcamSlotState = {};
|
||||
|
||||
const baseUrl = () => $("base-url").value.trim().replace(/\/+$/, "");
|
||||
@@ -299,6 +300,7 @@
|
||||
: mode === "live-simulated"
|
||||
? "链路 2 · 模拟实时"
|
||||
: "链路 3 · 离线精确";
|
||||
if (mode !== "offline-batch") hideVideoBatchVisualization();
|
||||
refreshRecordingModesStatus();
|
||||
}
|
||||
|
||||
@@ -358,39 +360,119 @@
|
||||
}
|
||||
}
|
||||
|
||||
function hideVideoBatchVisualization() {
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
function cancelVideoBatchVisualization() {
|
||||
videoVisToken += 1;
|
||||
const wrap = $("video-batch-vis");
|
||||
const player = $("video-batch-vis-player");
|
||||
const hint = $("video-batch-vis-hint");
|
||||
if (wrap) wrap.classList.add("hidden");
|
||||
if (player) {
|
||||
player.onerror = null;
|
||||
player.onloadeddata = null;
|
||||
player.removeAttribute("src");
|
||||
player.load();
|
||||
}
|
||||
if (hint) hint.textContent = "";
|
||||
}
|
||||
|
||||
function showVideoBatchVisualization(sid, urlPath, doctorDisplay) {
|
||||
function hideVideoBatchVisualization() {
|
||||
cancelVideoBatchVisualization();
|
||||
}
|
||||
|
||||
function revealVideoBatchVisualization() {
|
||||
const wrap = $("video-batch-vis");
|
||||
if (wrap) wrap.classList.remove("hidden");
|
||||
}
|
||||
|
||||
function loadVideoWhenReady(player, src, token, timeoutMs = 15000) {
|
||||
return new Promise((resolve) => {
|
||||
if (token !== videoVisToken) {
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
let settled = false;
|
||||
const finish = (ok) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
player.onerror = null;
|
||||
player.onloadeddata = null;
|
||||
if (!ok) {
|
||||
player.removeAttribute("src");
|
||||
player.load();
|
||||
}
|
||||
resolve(ok);
|
||||
};
|
||||
const timer = setTimeout(() => finish(false), timeoutMs);
|
||||
player.onerror = () => finish(false);
|
||||
player.onloadeddata = () => finish(true);
|
||||
player.src = src;
|
||||
player.load();
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForVideoBatchVisualization(sid, urlPath, doctorDisplay) {
|
||||
const wrap = $("video-batch-vis");
|
||||
const player = $("video-batch-vis-player");
|
||||
const hint = $("video-batch-vis-hint");
|
||||
if (!wrap || !player) return;
|
||||
|
||||
const token = ++videoVisToken;
|
||||
const path = urlPath || `/internal/demo/offline-batch/${sid}/visualization`;
|
||||
const src = baseUrl() + path + "?t=" + Date.now();
|
||||
wrap.classList.remove("hidden");
|
||||
const docEl = $("video-batch-doctor-info");
|
||||
const text = (doctorDisplay || lastVideoBatchDoctorDisplay || "").trim();
|
||||
if (docEl) {
|
||||
docEl.textContent = text ? "识别医生:" + text : "";
|
||||
docEl.style.display = text ? "block" : "none";
|
||||
const base = baseUrl() + path;
|
||||
const pollIntervalMs = 3000;
|
||||
const maxAttempts = 120;
|
||||
|
||||
wrap.classList.add("hidden");
|
||||
showVideoBatchDoctorInfo(doctorDisplay || lastVideoBatchDoctorDisplay);
|
||||
if (hint) hint.textContent = "";
|
||||
|
||||
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
||||
if (token !== videoVisToken) return;
|
||||
const src = base + "?t=" + Date.now();
|
||||
const loaded = await loadVideoWhenReady(player, src, token);
|
||||
if (token !== videoVisToken) return;
|
||||
if (loaded) {
|
||||
revealVideoBatchVisualization();
|
||||
if (hint) hint.textContent = "标注视频已加载";
|
||||
player.onerror = () => {
|
||||
if (hint) {
|
||||
hint.textContent = "视频加载失败,请稍后重试或新标签页打开链接。";
|
||||
}
|
||||
};
|
||||
showBanner("标注视频已就绪", "ok");
|
||||
return;
|
||||
}
|
||||
if (attempt === 0) {
|
||||
showBanner("标注视频生成中,就绪后自动展示…", "info");
|
||||
}
|
||||
await sleep(pollIntervalMs);
|
||||
}
|
||||
player.onerror = () => {
|
||||
if (hint) hint.textContent = "视频加载失败,请稍后重试或新标签页打开链接。";
|
||||
};
|
||||
player.onloadeddata = () => {
|
||||
if (hint) hint.textContent = "标注视频已加载";
|
||||
};
|
||||
player.src = src;
|
||||
player.load();
|
||||
if (hint) hint.textContent = "正在加载…";
|
||||
|
||||
if (token === videoVisToken) {
|
||||
showBanner("标注视频尚未就绪,请稍后点击「查询结果」重试", "warn");
|
||||
}
|
||||
}
|
||||
|
||||
function showVideoBatchDoctorInfo(displayText) {
|
||||
const el = $("video-batch-doctor-info");
|
||||
if (!el) return;
|
||||
const text = (displayText || "").trim();
|
||||
if (!text) {
|
||||
el.textContent = "";
|
||||
el.style.display = "none";
|
||||
return;
|
||||
}
|
||||
el.textContent = "识别医生:" + text;
|
||||
el.style.display = "block";
|
||||
}
|
||||
|
||||
function showVideoBatchVisualization(sid, urlPath, doctorDisplay) {
|
||||
void waitForVideoBatchVisualization(sid, urlPath, doctorDisplay);
|
||||
}
|
||||
|
||||
function getDebugStreamCount() {
|
||||
@@ -563,9 +645,12 @@
|
||||
lastVideoBatchDoctorDisplay = body?.doctor_display || "";
|
||||
if ($("offline-batch-include-vis")?.checked && body?.visualization_url) {
|
||||
showVideoBatchVisualization(sid, body.visualization_url, lastVideoBatchDoctorDisplay);
|
||||
} else hideVideoBatchVisualization();
|
||||
} else {
|
||||
hideVideoBatchVisualization();
|
||||
showVideoBatchDoctorInfo(lastVideoBatchDoctorDisplay);
|
||||
}
|
||||
showBanner("离线处理完成,正在查询结果…", "ok");
|
||||
await handleResult();
|
||||
await handleResult({ skipVisualization: true });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -647,10 +732,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function handleResult() {
|
||||
async function handleResult(options = {}) {
|
||||
const sid = ensureSurgeryId();
|
||||
if (!sid) return;
|
||||
if (getRunMode() === "offline-batch" && $("offline-batch-include-vis")?.checked) {
|
||||
if (
|
||||
!options.skipVisualization &&
|
||||
getRunMode() === "offline-batch" &&
|
||||
$("offline-batch-include-vis")?.checked
|
||||
) {
|
||||
showVideoBatchVisualization(sid, null);
|
||||
} else if (getRunMode() !== "offline-batch") {
|
||||
hideVideoBatchVisualization();
|
||||
@@ -664,6 +753,9 @@
|
||||
return;
|
||||
}
|
||||
const { details = [], summary = [] } = body;
|
||||
if (getRunMode() === "offline-batch") {
|
||||
showVideoBatchDoctorInfo(details[0]?.doctor_id || lastVideoBatchDoctorDisplay);
|
||||
}
|
||||
const renderTable = (title, rows, cols) => {
|
||||
const h = document.createElement("h3");
|
||||
h.textContent = title;
|
||||
@@ -686,11 +778,13 @@
|
||||
};
|
||||
renderTable("消耗明细", details, [
|
||||
{ key: "timestamp", label: "时间" },
|
||||
{ key: "item_id", label: "耗材 ID" },
|
||||
{ key: "item_name", label: "耗材" },
|
||||
{ key: "qty", label: "数量" },
|
||||
{ key: "doctor_id", label: "医生" },
|
||||
{ key: "doctor_id", label: "医生(姓名+ID)" },
|
||||
]);
|
||||
renderTable("汇总", summary, [
|
||||
{ key: "item_id", label: "耗材 ID" },
|
||||
{ key: "item_name", label: "耗材" },
|
||||
{ key: "total_quantity", label: "合计" },
|
||||
]);
|
||||
|
||||
@@ -191,8 +191,8 @@
|
||||
|
||||
<section class="card">
|
||||
<h2>结果</h2>
|
||||
<p id="video-batch-doctor-info" class="labels-meta"></p>
|
||||
<div id="video-batch-vis" class="vis-block hidden">
|
||||
<p id="video-batch-doctor-info" class="labels-meta"></p>
|
||||
<video id="video-batch-vis-player" controls playsinline></video>
|
||||
<p id="video-batch-vis-hint" class="stream-hint"></p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user