From 796047fbe84d51816f44be535501415d3c66dd9d Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期日, 21 六月 2026 23:24:37 +0800
Subject: [PATCH] yxh
---
big.html | 563 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 446 insertions(+), 117 deletions(-)
diff --git a/big.html b/big.html
index 54c827d..a2fb0ab 100644
--- a/big.html
+++ b/big.html
@@ -1,9 +1,10 @@
-<!doctype html>
+锘�<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi" />
+ <meta name="viewport"
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>澶у巺</title>
<style>
@@ -11,7 +12,8 @@
margin: 0;
padding: 0;
box-sizing: border-box;
- /* Android 6 鍙敤涓枃瀛椾綋 */;
+ /* Android 6 鍙敤涓枃瀛椾綋 */
+ ;
font-family: "Droid Sans Fallback", "Noto Sans CJK SC", "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
}
@@ -64,10 +66,43 @@
}
.top-header .time-info {
- font-size: 24px;
+ font-size: 20px;
color: #aaa;
margin-left: auto;
z-index: 2;
+ text-align: right;
+ line-height: 1.3;
+ }
+
+ .time-info-inner {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: flex;
+ -webkit-box-align: center;
+ -webkit-align-items: center;
+ align-items: center;
+ }
+
+ .time-left {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ text-align: right;
+ line-height: 1.3;
+ }
+
+ .time-right {
+ margin-left: 8px;
+ }
+
+ .top-header .time-info .time-clock {
+ font-size: 36px;
+ font-weight: bold;
+ color: #ffcc00;
+ line-height: 1.1;
}
/* 3. 涓讳綋鍐呭锛坓ap 鏇挎崲涓� margin 鍏煎鏃� Chrome锛� */
@@ -78,20 +113,35 @@
display: -webkit-box;
display: -webkit-flex;
display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -webkit-flex-direction: column;
+ flex-direction: column;
padding: 15px 20px;
overflow: hidden;
}
- .main-content > .column-box {
- margin-left: 5px;
- margin-right: 5px;
+ /* 鍒楄瀹瑰櫒 */
+ .columns-row {
+ -webkit-box-flex: 1;
+ -webkit-flex: 1;
+ flex: 1;
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: flex;
+ overflow: hidden;
}
- .main-content > .column-box:first-child {
+ .columns-row>.column-box {
+ margin-left: 3px;
+ margin-right: 3px;
+ }
+
+ .columns-row>.column-box:first-child {
margin-left: 0;
}
- .main-content > .column-box:last-child {
+ .columns-row>.column-box:last-child {
margin-right: 0;
}
@@ -106,7 +156,7 @@
flex-direction: column;
background: rgba(10, 40, 80, 0.5);
border-radius: 0;
- padding: 10px;
+ padding: 6px;
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
@@ -128,16 +178,13 @@
/* 鏍囬琛� */
.col-title-line {
- font-size: 22px;
+ font-size: 28px;
font-weight: bold;
color: #4da6ff;
text-align: center;
}
.col-title {
- font-size: 22px;
- font-weight: bold;
- color: #4da6ff;
padding-bottom: 8px;
border-bottom: 1px solid #003366;
margin-bottom: 10px;
@@ -145,9 +192,14 @@
}
.col-subtitle {
- font-size: 14px;
- color: #999;
+ font-size: 24px;
+ font-weight: bold;
+ color: #ffcc00;
text-align: center;
+ min-height: 20px;
+ /* 鍗充娇涓虹┖涔熶繚鐣欓珮搴︼紝闃叉鏍囬鏍忛珮浣庝笉骞� */
+ line-height: 1.4;
+ word-break: keep-all;
}
/* 鎮h�呭垪琛� */
@@ -156,34 +208,41 @@
-webkit-flex: 1;
flex: 1;
overflow-y: auto;
- padding-right: 5px;
- }
-
- /* 绗�1鏍忥細涓�琛屼袱涓� */
- #col-0 {
+ padding-right: 2px;
display: -webkit-box;
display: -webkit-flex;
display: flex;
- -webkit-flex-wrap: wrap;
- flex-wrap: wrap;
-webkit-align-content: flex-start;
align-content: flex-start;
}
- .col-normal .patient-list {
- display: -webkit-box;
- display: -webkit-flex;
- display: flex;
+ /* 涓�琛屼袱涓紙甯歌蹇冪數鍥俱�佸姩鎬佸績鐢碉級 */
+ .patient-list.two-per-row {
+ -webkit-flex-wrap: wrap;
+ flex-wrap: wrap;
+ }
+
+ .patient-list.two-per-row .patient-item {
+ width: 46%;
+ margin: 0 2%;
+ }
+
+ /* 涓�琛屼竴涓� */
+ .patient-list.one-per-row {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
flex-direction: column;
}
+ .patient-list.one-per-row .patient-item {
+ width: 100%;
+ }
+
/* 鎮h�呴」鐩� */
.patient-item {
- font-size: 22px;
- padding: 8px 5px;
+ font-size: 28px;
+ padding: 4px 3px;
display: -webkit-box;
display: -webkit-flex;
display: flex;
@@ -194,19 +253,22 @@
line-height: 1.4;
}
- #col-0 .patient-item {
- width: 45%;
- font-size: 20px;
- margin: 0 2.5%;
- }
-
.p-number {
color: #ffcc00;
font-weight: bold;
- margin-right: 8px;
+ margin-right: 6px;
+ -webkit-flex-shrink: 0;
+ flex-shrink: 0;
}
.p-name {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ font-weight: bold;
+ }
+
+ .p-name-wrap {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
@@ -218,8 +280,31 @@
.p-room {
color: #4da6ff;
font-weight: bold;
- font-size: 18px;
- margin-left: 5px;
+ font-size: 22px;
+ margin-left: 4px;
+ -webkit-flex-shrink: 0;
+ flex-shrink: 0;
+ }
+
+ /* 杩囧彿鎮h�咃細鎺掑湪鍒楀唴锛岃瑙夊急鍖� */
+ .patient-item.missed {
+ color: #aa8888;
+ }
+
+ .patient-item.missed .p-number {
+ color: #cc9966;
+ }
+
+ .patient-item.missed .p-name {
+ color: #aa8888;
+ }
+
+ .patient-item.missed .p-missed-tag {
+ color: #ff6666;
+ font-size: 22px;
+ margin-left: 4px;
+ -webkit-flex-shrink: 0;
+ flex-shrink: 0;
}
/* 搴曢儴鏍� */
@@ -245,10 +330,30 @@
text-align: center;
}
+ /* 娴嬭瘯璇煶鎸夐挳 */
+ #test-voice-btn {
+ margin-left: 20px;
+ background-color: #007bff;
+ color: white;
+ border: none;
+ padding: 10px 20px;
+ border-radius: 6px;
+ font-size: 16px;
+ cursor: pointer;
+ font-weight: bold;
+ -webkit-flex-shrink: 0;
+ flex-shrink: 0;
+ }
+
+ #test-voice-btn:hover {
+ background-color: #0056b3;
+ }
+
/* 婊氬姩鏉� */
.patient-list::-webkit-scrollbar {
width: 4px;
}
+
.patient-list::-webkit-scrollbar-thumb {
background: #444;
border-radius: 2px;
@@ -256,14 +361,21 @@
/* 璋冭瘯闈㈡澘 */
.debug-panel {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -webkit-flex-direction: column;
+ flex-direction: column;
position: fixed;
right: 15px;
bottom: 70px;
- width: 350px;
- height: 200px;
- background: rgba(0, 0, 0, 0.9);
+ width: 380px;
+ height: 220px;
+ background: rgba(0, 0, 0, 0.92);
color: #0f0;
- border-radius: 4px;
+ border-radius: 6px;
font-family: monospace;
font-size: 12px;
z-index: 9999;
@@ -322,7 +434,7 @@
<!-- 椤堕儴鏍� -->
<div class="top-header">
<img src="logo.png" alt="logo" />
- <span class="title-text">鏈嶅姟澶у巺鎺掑垪</span>
+ <span class="title-text">蹇冪數璇婂尯澶у巺</span>
<span class="time-info" id="headerTime"></span>
</div>
@@ -331,11 +443,12 @@
<!-- 搴曢儴鏍� -->
<div class="bottom-footer">
- <div class="footer-tip">娓╅Θ鎻愮ず锛氳鍚埌鍛煎彨鍚庡墠寰�瀵瑰簲璇婂</div>
+ <div class="footer-tip">娓╅Θ鎻愮ず锛氬惉鍒板懠鍙悗璇峰墠寰�瀵瑰簲璇婂锛岃繃鍙锋偅鑰呭埌瀵艰瘖鍙板鐞嗭紒</div>
+ <button id="test-voice-btn" onclick="testVoice()">娴嬭瘯璇煶</button>
</div>
<!-- 璋冭瘯闈㈡澘 -->
- <div class="debug-panel" id="debugPanel">
+ <div class="debug-panel" id="debugPanel" >
<div class="debug-header">
<span>[璋冭瘯] 杩愯鏃ュ織</span>
<button onclick="document.getElementById('debugBody').innerHTML=''">娓呯┖</button>
@@ -355,61 +468,125 @@
var body = document.getElementById("debugBody");
if (body) {
body.insertAdjacentHTML("beforeend", logHtml);
- body.scrollTop = body.scrollHeight;
+ // requestAnimationFrame 纭繚 DOM 鏇存柊鍚庡啀婊氬姩
+ requestAnimationFrame(function () {
+ body.scrollTop = body.scrollHeight;
+ });
}
}
// ================= 搴旂敤鐘舵�� =================
+ // 鍛煎彨鍙彿娆℃暟鍙傛暟锛氬懠鍙偅鑰呭氨璇婃椂閲嶅鎾姤鐨勬鏁帮紝榛樿 2 娆�
+ var CALL_TIMES = 2;
+ // 涓�琛屼袱涓偅鑰呯殑鍒楃储寮曪紙甯歌蹇冪數鍥俱�佸姩鎬佸績鐢碉級
+ var TWO_PER_ROW_COLS = [0, 1];
+ // 椋熼亾鐢电敓鐞嗘槸鍚︽樉绀猴紙false 闅愯棌锛宼rue 鏄剧ず锛�
+ var SHOW_COL_ESOPHAGEAL = false;
var appState = {
- columnTitles: ["甯歌蹇冪數鍥�", "鍔ㄦ�佸績鐢�", "骞虫澘杩愬姩蹇冪數", "椋熼亾鐢电敓鐞�", "鍔ㄨ剦纭寲鐩戞祴"],
- columnSubTitles: ["搴婅竟蹇冪數鍥�(甯歌+棰戣氨)M / 蹇冪數鍚戦噺鍥綨", "鍔ㄦ�佽鍘婥", "", "", ""],
+ columnTitles: ["甯歌蹇冪數鍥�/蹇冪數鍚戦噺鍥�", "鍔ㄦ�佸績鐢�/琛�鍘�", "骞虫澘杩愬姩蹇冪數", "椋熼亾鐢电敓鐞�", "鍔ㄨ剦纭寲鐩戞祴"],
+ columnSubTitles: ["1鍙�-2鍙疯瘖瀹�", "2鍙疯瘖瀹�", "4鍙疯瘖瀹�", "6鍙疯瘖瀹�", "5鍙疯瘖瀹�"],
patients: [],
- apiBaseUrl: "http://192.168.100.110/admin-api",
+ // apiBaseUrl: "http://192.168.3.12/admin-api",
+ apiBaseUrl: "http://10.0.2.193/admin-api",
pollTimer: null,
- callRepeatTimes: 2,
spokenPatients: {},
ttsQueue: [],
- isSpeaking: false
+ isSpeaking: false,
+ };
+
+ var patStatus = {
+ 3: "宸茶繃鍙�-鎺掗槦", 5: "宸茶繃鍙�", 7: "宸茶繃鍙�-瀹夎", 10: "鎺掗槦涓�", 12: "浜插拰",
+ 13: "浜插拰-瀹夎", 15: "宸插彫鍥�", 20: "鍊欒瘖涓�", 30: "灏辫瘖涓�", 33: "宸查鐢�",
+ 34: "宸插彫鍥�-瀹夎", 36: "瀹夎涓�", 40: "宸插氨璇�"
};
// ================= 璇煶鎾姤 =================
+ // Android WebView GC 淇濇姢锛氬叏灞�鎸佹湁 utterance 寮曠敤锛岄槻姝㈣鍥炴敹瀵艰嚧鏃犲0
+ var _gCurrentUtterance = null;
+
function processTtsQueue() {
if (appState.isSpeaking || appState.ttsQueue.length === 0) return;
appState.isSpeaking = true;
var text = appState.ttsQueue.shift();
logDebug("[鎾姤] " + text);
- var utterance = new SpeechSynthesisUtterance(text);
- // Android 6 榛樿璇�熷彲鑳藉緢蹇紝閫傚綋璋冩參
- utterance.rate = 0.85;
- utterance.onend = function () {
- appState.isSpeaking = false;
- processTtsQueue();
- };
- utterance.onerror = function (e) {
- logDebug("[TTS閿欒] " + (e.error || "unknown"));
- appState.isSpeaking = false;
- processTtsQueue();
- };
-
- // 浼樺厛灏濊瘯璁惧鍘熺敓 TTS 鎺ュ彛
+ // 浼樺厛灏濊瘯璁惧鍘熺敓 TTS 鎺ュ彛 (wowjoy)
if (typeof wowjoy !== 'undefined' && typeof wowjoy.speek === 'function') {
try {
wowjoy.speek(text);
+ logDebug("[鎾姤] wowjoy.speek 宸茶皟鐢�");
setTimeout(function () { appState.isSpeaking = false; processTtsQueue(); }, 4000);
return;
} catch (e) { logDebug("[wowjoy澶辫触] " + e.message); }
}
- if (window.speechSynthesis) {
- // Android 6 WebView 鏈夋椂闇�瑕佸厛 cancel 鍐� speak
- window.speechSynthesis.cancel();
- window.speechSynthesis.speak(utterance);
- } else {
+ if (!window.speechSynthesis) {
logDebug("[TTS] 娴忚鍣ㄤ笉鏀寔璇煶鍚堟垚");
appState.isSpeaking = false;
processTtsQueue();
+ return;
}
+
+ // 浠呭湪鏈夎闊虫鍦ㄦ挱鏀炬椂鎵� cancel锛岄伩鍏嶄笉蹇呰鐨勪腑鏂�
+ if (window.speechSynthesis.speaking) {
+ logDebug("[鎾姤] cancel 褰撳墠鎾斁");
+ window.speechSynthesis.cancel();
+ }
+
+ var utterance = new SpeechSynthesisUtterance(text);
+ utterance.rate = 0.85;
+ utterance.volume = 1.0;
+ // Android WebView GC 淇濇姢锛氬瓨鍏ㄥ眬寮曠敤
+ _gCurrentUtterance = utterance;
+
+ utterance.onstart = function () {
+ logDebug("[鎾姤] onstart 瑙﹀彂");
+ };
+ utterance.onend = function () {
+ logDebug("[鎾姤] onend 瑙﹀彂");
+ _gCurrentUtterance = null;
+ appState.isSpeaking = false;
+ // 寤惰繜涓�涓嬭寮曟搸瀹屽叏閲婃斁
+ setTimeout(function () { processTtsQueue(); }, 200);
+ };
+ utterance.onerror = function (e) {
+ logDebug("[TTS閿欒] " + (e.error || "unknown"));
+ _gCurrentUtterance = null;
+ appState.isSpeaking = false;
+ setTimeout(function () { processTtsQueue(); }, 200);
+ };
+
+ // 纭繚璇煶鍖呭凡鍔犺浇 (Android 涓� getVoices 鍙兘鍒濆涓虹┖)
+ var voices = window.speechSynthesis.getVoices();
+ if (voices.length > 0) {
+ utterance.voice = voices[0];
+ logDebug("[鎾姤] 浣跨敤璇煶: " + voices[0].name + " lang=" + voices[0].lang);
+ } else {
+ logDebug("[鎾姤] getVoices 涓虹┖, 绛夊緟 voiceschanged 浜嬩欢");
+ var voicesLoaded = false;
+ var onVoicesChange = function () {
+ if (voicesLoaded) return;
+ voicesLoaded = true;
+ var v2 = window.speechSynthesis.getVoices();
+ if (v2.length > 0) {
+ utterance.voice = v2[0];
+ logDebug("[鎾姤] 璇煶鍔犺浇瀹屾垚: " + v2[0].name);
+ }
+ window.speechSynthesis.speak(utterance);
+ };
+ window.speechSynthesis.addEventListener('voiceschanged', onVoicesChange);
+ // 濡傛灉 1s 鍐呮病瑙﹀彂锛岀洿鎺� speak
+ setTimeout(function () {
+ if (!voicesLoaded) {
+ logDebug("[鎾姤] voiceschanged 瓒呮椂, 鐩存帴 speak");
+ window.speechSynthesis.speak(utterance);
+ }
+ }, 1000);
+ return;
+ }
+
+ window.speechSynthesis.speak(utterance);
+ logDebug("[鎾姤] speak 宸茶皟鐢�");
}
function speak(text) {
@@ -418,47 +595,179 @@
processTtsQueue();
}
- // ================= 娓叉煋 =================
- function renderMainContent() {
- var main = document.getElementById("mainContent");
- main.innerHTML = "";
+ // ================= 璇煶娴嬭瘯 =================
+ function testVoice() {
+ logDebug("[璇煶娴嬭瘯] ========== 寮�濮� ==========");
+ var testText = "娴嬭瘯璇煶鎾姤";
- for (var i = 0; i < appState.columnTitles.length; i++) {
- var titleHtml = '<div class="col-title-line">' + appState.columnTitles[i] + '</div>';
- if (appState.columnSubTitles[i]) {
- titleHtml += '<div class="col-subtitle">' + appState.columnSubTitles[i] + '</div>';
+ // 1. 妫�娴� wowjoy 鍘熺敓鎺ュ彛
+ var hasWowjoy = (typeof wowjoy !== 'undefined');
+ logDebug("[璇煶娴嬭瘯] wowjoy 瀵硅薄瀛樺湪=" + hasWowjoy);
+ if (hasWowjoy) {
+ logDebug("[璇煶娴嬭瘯] wowjoy.speek 绫诲瀷=" + (typeof wowjoy.speek));
+ if (typeof wowjoy.speek === 'function') {
+ try {
+ wowjoy.speek(testText);
+ logDebug("[璇煶娴嬭瘯] wowjoy.speek 宸茶皟鐢紝娉ㄦ剰鍚澶囧0闊�");
+ } catch (e) {
+ logDebug("[璇煶娴嬭瘯] wowjoy.speek 寮傚父: " + e.message);
+ }
+ }
+ }
+
+ // 2. 妫�娴� SpeechSynthesis
+ var hasSpeech = (typeof window.speechSynthesis !== 'undefined');
+ logDebug("[璇煶娴嬭瘯] speechSynthesis 瀵硅薄瀛樺湪=" + hasSpeech);
+
+ if (hasSpeech) {
+ var syn = window.speechSynthesis;
+ logDebug("[璇煶娴嬭瘯] speaking=" + syn.speaking + " pending=" + syn.pending + " paused=" + syn.paused);
+
+ var voices = syn.getVoices();
+ logDebug("[璇煶娴嬭瘯] getVoices 杩斿洖 " + voices.length + " 涓闊冲寘");
+ for (var v = 0; v < Math.min(voices.length, 5); v++) {
+ logDebug("[璇煶娴嬭瘯] 璇煶[" + v + "] " + voices[v].name + " lang=" + voices[v].lang + " local=" + voices[v].localService);
}
- var colClass = (i === 0) ? 'col-wide' : 'col-normal';
- var colHtml = '<div class="column-box ' + colClass + '">' +
- '<div class="col-title">' + titleHtml + '</div>' +
- '<div class="patient-list" id="col-' + i + '"></div>' +
- '</div>';
- main.insertAdjacentHTML("beforeend", colHtml);
+ // 濡傛灉 voices 涓虹┖锛岀瓑寰呭姞杞藉悗鍐嶆挱
+ function doSpeakTest() {
+ var v2 = syn.getVoices();
+ var u = new SpeechSynthesisUtterance(testText);
+ u.rate = 0.85;
+ u.volume = 1.0;
+ if (v2.length > 0) {
+ u.voice = v2[0];
+ logDebug("[璇煶娴嬭瘯] 閫夋嫨璇煶: " + v2[0].name);
+ }
+ // GC 淇濇姢
+ window._testUtterance = u;
+ u.onstart = function() { logDebug("[璇煶娴嬭瘯] onstart 瑙﹀彂 鉁�"); };
+ u.onend = function() { logDebug("[璇煶娴嬭瘯] onend 瑙﹀彂 鉁�"); window._testUtterance = null; };
+ u.onerror = function(e) { logDebug("[璇煶娴嬭瘯] onerror: " + (e.error || "unknown")); window._testUtterance = null; };
+
+ if (syn.speaking) {
+ logDebug("[璇煶娴嬭瘯] 鏈夎闊虫鍦ㄦ挱鏀撅紝鍏� cancel");
+ syn.cancel();
+ setTimeout(function () { syn.speak(u); logDebug("[璇煶娴嬭瘯] speak 宸茶皟鐢�(寤惰繜)"); }, 300);
+ } else {
+ syn.speak(u);
+ logDebug("[璇煶娴嬭瘯] speak 宸茶皟鐢�");
+ }
+ }
+
+ if (voices.length === 0) {
+ logDebug("[璇煶娴嬭瘯] 璇煶鍒楄〃涓虹┖锛岀瓑寰� voiceschanged...");
+ var loaded = false;
+ var handler = function () {
+ if (loaded) return;
+ loaded = true;
+ logDebug("[璇煶娴嬭瘯] voiceschanged 瑙﹀彂, 璇煶鏁�=" + syn.getVoices().length);
+ doSpeakTest();
+ };
+ syn.addEventListener('voiceschanged', handler);
+ setTimeout(function () {
+ if (!loaded) {
+ logDebug("[璇煶娴嬭瘯] voiceschanged 瓒呮椂(2s), 寮哄埗娴嬭瘯");
+ doSpeakTest();
+ }
+ }, 2000);
+ } else {
+ doSpeakTest();
+ }
}
+
+ if (!hasWowjoy && !hasSpeech) {
+ logDebug("[璇煶娴嬭瘯] 鏃犱换浣� TTS 寮曟搸鍙敤锛�");
+ }
+ logDebug("[璇煶娴嬭瘯] ========== 缁撴潫 ==========");
}
- function renderPatients() {
- for (var i = 0; i < appState.columnTitles.length; i++) {
- var col = document.getElementById("col-" + i);
- if (col) col.innerHTML = "";
- }
+ // ================= 娓叉煋锛氭爣棰樻鏋讹紙浠呭垵濮嬪寲涓�娆★級=================
+ function initLayout() {
+ logDebug("[甯冨眬] initLayout 寮�濮�, 鍒楁暟=" + appState.columnTitles.length);
+ var main = document.getElementById("mainContent");
+ if (!main) { logDebug("[甯冨眬] mainContent 鍏冪礌鏈壘鍒�!"); return; }
+ var html = '<div class="columns-row">';
+ var visibleCount = 0;
- for (var c = 0; c < appState.patients.length; c++) {
- var colData = appState.patients[c];
- if (Array.isArray(colData)) {
- var col = document.getElementById("col-" + c);
- if (!col) continue;
- for (var p = 0; p < colData.length; p++) {
- var pat = colData[p];
- var roomHtml = pat.roomName ? '<span class="p-room">(' + pat.roomName + ')</span>' : '';
- var itemHtml = '<div class="patient-item">' +
- '<span class="p-number">' + (pat.bookSeqNum || '') + '</span>' +
- '<span class="p-name">' + (pat.patName || '') + '</span>' +
- roomHtml +
- '</div>';
- col.insertAdjacentHTML("beforeend", itemHtml);
- }
+ for (var i = 0; i < appState.columnTitles.length; i++) {
+ // 椋熼亾鐢电敓鐞嗭細閫氳繃 SHOW_COL_ESOPHAGEAL 鎺у埗鏄鹃殣
+ if (i === 3 && !SHOW_COL_ESOPHAGEAL) {
+ logDebug("[甯冨眬] 鍒�" + i + " 椋熼亾鐢电敓鐞� 宸查殣钘�");
+ continue;
+ }
+
+ var subtitle = appState.columnSubTitles[i] || " ";
+ // 涓�琛屼袱涓殑鍒楃敤 col-wide锛屽惁鍒� col-normal
+ var isTwoPerRow = TWO_PER_ROW_COLS.indexOf(i) !== -1;
+ var colClass = isTwoPerRow ? 'col-wide' : 'col-normal';
+ var rowClass = isTwoPerRow ? 'two-per-row' : 'one-per-row';
+ logDebug("[甯冨眬] 鍒�" + i + " " + appState.columnTitles[i] + " class=" + colClass + " row=" + rowClass);
+ html += '<div class="column-box ' + colClass + '">' +
+ '<div class="col-title">' +
+ '<div class="col-title-line">' + appState.columnTitles[i] + '</div>' +
+ '<div class="col-subtitle">' + subtitle + '</div>' +
+ '</div>' +
+ '<div class="patient-list ' + rowClass + '" id="col-' + i + '"></div>' +
+ '</div>';
+ visibleCount++;
+ }
+ html += '</div>';
+ main.innerHTML = html;
+ logDebug("[甯冨眬] initLayout 瀹屾垚, 鍙鍒�=" + visibleCount);
+ }
+
+ // ================= 娓叉煋锛氭偅鑰呭垪琛紙diff 鏇存柊锛屽彧鏀瑰彉鍖栫殑鍒楋級=================
+ function desensitizeName(name) {
+ if (!name || name.length < 2) return name || '';
+ return name.charAt(0) + '*' + name.substring(2);
+ }
+
+ function isMissedStatus(status) {
+ var s = parseInt(status, 10);
+ return s === 3 || s === 5 || s === 7;
+ }
+
+ function buildColumnHtml(colData) {
+ if (!Array.isArray(colData) || colData.length === 0) return "";
+ var h = "";
+ for (var p = 0; p < colData.length; p++) {
+ var pat = colData[p];
+ var missedClass = isMissedStatus(pat.status) ? ' missed' : '';
+ var roomHtml = (!isMissedStatus(pat.status) && pat.roomName) ? '<span class="p-room">' + pat.roomName + '</span>' : '';
+ h += '<div class="patient-item' + missedClass + '">' +
+ '<span class="p-number">' + (pat.seqNum || '') + '</span>' +
+ '<span class="p-name-wrap"><span class="p-name">' + desensitizeName(pat.patName) + '</span>' + roomHtml +
+ (missedClass ? '<span class="p-missed-tag">杩囧彿</span>' : '') + '</span>' +
+ '</div>';
+ }
+ return h;
+ }
+ function isSameColumn(a, b) {
+ if (!Array.isArray(a) || !Array.isArray(b)) return a === b;
+ if (a.length !== b.length) return false;
+ for (var i = 0; i < a.length; i++) {
+ if (a[i].patId !== b[i].patId) return false;
+ if (a[i].roomName !== b[i].roomName) return false;
+ if (parseInt(a[i].status, 10) !== parseInt(b[i].status, 10)) return false;
+ }
+ return true;
+ }
+
+ function updatePatients(dataList) {
+ for (var i = 0; i < appState.columnTitles.length; i++) {
+ var newData = (dataList && dataList[i]) ? dataList[i] : [];
+ var oldData = appState.patients[i];
+
+ // diff锛氭暟鎹湭鍙樺寲鍒欒烦杩囪鍒� DOM 鎿嶄綔
+ if (isSameColumn(oldData, newData)) continue;
+
+ var col = document.getElementById("col-" + i);
+ if (col) {
+ col.innerHTML = buildColumnHtml(newData);
+ logDebug("[鏇存柊] 鍒�" + i + " " + appState.columnTitles[i] + " 鍒锋柊 " + newData.length + " 浜�");
+ } else {
+ logDebug("[鏇存柊] 鍒�" + i + " DOM涓嶅瓨鍦�(鍙兘宸查殣钘�)");
}
}
}
@@ -485,10 +794,10 @@
}
if (!oldPat || !oldPat.roomName) {
var repeatText = "";
- for (var r = 0; r < appState.callRepeatTimes; r++) {
- repeatText += "璇� " + newPat.bookSeqNum + " 鍙� " + newPat.patName + " 鍒� " + newPat.roomName + " 灏辫瘖銆�";
- }
- speak(repeatText);
+ repeatText += "璇� " + newPat.seqNum + " 鍙� " + newPat.patName + " 鍒� " + newPat.roomName + " 灏辫瘖銆�";
+ for (var r = 0; r < CALL_TIMES; r++) {
+ speak(repeatText);
+ }
appState.spokenPatients[newPat.patId] = true;
logDebug("[鎺掗槦] " + newPat.patName + " -> " + newPat.roomName);
}
@@ -501,22 +810,28 @@
// ================= 鏁版嵁鑾峰彇 =================
function fetchQueueData() {
var url = appState.apiBaseUrl + "/ecg/screen/big-screen-data";
+ logDebug("[璇锋眰] GET " + url);
$.ajax({
url: url,
type: "GET",
dataType: "json",
timeout: 5000,
success: function (res) {
+ logDebug("[鍝嶅簲] code=" + (res ? res.code : "null"));
var dataList = [];
if (res && res.code === 0 && res.data) {
for (var i = 0; i < appState.columnTitles.length; i++) {
var key = i.toString();
dataList[i] = (res.data[key] && Array.isArray(res.data[key])) ? res.data[key] : [];
+ logDebug("[鏁版嵁] 鍒�" + i + " " + appState.columnTitles[i] + " 鎮h�呮暟=" + dataList[i].length);
}
+ } else {
+ logDebug("[鍝嶅簲] 寮傚父 code=" + (res ? res.code : "null") + " msg=" + (res ? res.msg : ""));
}
+ // 鍏� diff 鏇存柊 DOM锛屽啀鎾姤锛屾渶鍚庝繚瀛樻暟鎹敤浜庝笅娆″姣�
+ updatePatients(dataList);
checkAndSpeakNewRooms(appState.patients, dataList);
appState.patients = dataList;
- renderPatients();
// Android 6 WebView 閫氬父涓嶆敮鎸� performance.memory锛屽畨鍏ㄥ畧鍗�
try {
@@ -524,43 +839,57 @@
var usedMB = (window.performance.memory.usedJSHeapSize / 1048576).toFixed(2);
logDebug("[鍐呭瓨] " + usedMB + " MB");
}
- } catch (e) {}
+ } catch (e) { }
},
error: function (err) {
- logDebug("[璇锋眰澶辫触] " + (err.statusText || "缃戠粶閿欒"));
+ logDebug("[璇锋眰澶辫触] status=" + err.status + " " + (err.statusText || "缃戠粶閿欒") + " url=" + url);
}
});
}
// ================= 鍒濆鍖� =================
function onReady() {
- renderMainContent();
+ logDebug("[鍒濆鍖朷 onReady 寮�濮�");
+ logDebug("[鐜] speechSynthesis=" + (typeof window.speechSynthesis !== 'undefined') + " wowjoy=" + (typeof wowjoy !== 'undefined'));
+ try {
+ initLayout();
+ logDebug("[鍒濆鍖朷 initLayout 瀹屾垚");
+ } catch (e) { logDebug("[鍒濆鍖朷 initLayout 寮傚父: " + e.message); }
updateHeaderTime();
setInterval(updateHeaderTime, 1000);
- fetchQueueData();
+ try {
+ fetchQueueData();
+ logDebug("[鍒濆鍖朷 棣栨 fetchQueueData 宸插彂璧�");
+ } catch (e) { logDebug("[鍒濆鍖朷 fetchQueueData 寮傚父: " + e.message); }
appState.pollTimer = setInterval(fetchQueueData, 5000);
- logDebug("[绯荤粺] 鍚姩瀹屾垚 - Android 6.0.1");
+ logDebug("[绯荤粺] 鍚姩瀹屾垚 - Android 6.0.1 杞闂撮殧5s");
}
function updateHeaderTime() {
var now = new Date();
var weekDays = ["鏄熸湡鏃�", "鏄熸湡涓�", "鏄熸湡浜�", "鏄熸湡涓�", "鏄熸湡鍥�", "鏄熸湡浜�", "鏄熸湡鍏�"];
function padZero(num) { return num < 10 ? '0' + num : '' + num; }
- var dateStr = now.getFullYear() + "骞�" + padZero(now.getMonth() + 1) + "鏈�" + padZero(now.getDate()) + "鏃� " + weekDays[now.getDay()];
+ var dateStr = now.getFullYear() + "骞�" + padZero(now.getMonth() + 1) + "鏈�" + padZero(now.getDate()) + "鏃�";
+ var weekStr = weekDays[now.getDay()];
var timeStr = padZero(now.getHours()) + ":" + padZero(now.getMinutes());
var el = document.getElementById("headerTime");
- if (el) el.textContent = dateStr + " " + timeStr;
+ // 鏄熸湡鍜屾棩鏈熷悇鍗犱竴琛屽湪宸︼紝鏃堕棿澶у瓧鍦ㄥ彸璺ㄤ袱琛�
+ if (el) el.innerHTML = '<div class="time-info-inner"><div class="time-left"><div>' + weekStr + '</div><div>' + dateStr + '</div></div><div class="time-right"><span class="time-clock">' + timeStr + '</span></div></div>';
}
// 鍏煎 DOM ready锛圓ndroid 6 鏌愪簺 WebView 鍙兘娌℃湁 $锛�
+ logDebug("[鍏ュ彛] readyState=" + document.readyState + " jQuery=" + (typeof $ !== 'undefined'));
if (typeof $ !== 'undefined') {
+ logDebug("[鍏ュ彛] 浣跨敤 jQuery.ready");
$(document).ready(onReady);
} else if (document.readyState === 'complete' || document.readyState === 'interactive') {
+ logDebug("[鍏ュ彛] DOM宸插氨缁�, setTimeout瑙﹀彂");
setTimeout(onReady, 1);
} else {
+ logDebug("[鍏ュ彛] 鐩戝惉 DOMContentLoaded");
document.addEventListener('DOMContentLoaded', onReady);
}
</script>
</body>
-</html>
+</html>
\ No newline at end of file
--
Gitblit v1.9.3