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 |  823 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 823 insertions(+), 0 deletions(-)

diff --git "a/big\346\273\232\345\212\250.html" "b/big\346\273\232\345\212\250.html"
new file mode 100644
index 0000000..c4b8d04
--- /dev/null
+++ "b/big\346\273\232\345\212\250.html"
@@ -0,0 +1,823 @@
+<!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 http-equiv="X-UA-Compatible" content="IE=edge" />
+    <title>澶у巺</title>
+    <style>
+        * {
+            margin: 0;
+            padding: 0;
+            box-sizing: border-box;
+            /* Android 6 鍙敤涓枃瀛椾綋 */;
+            font-family: "Droid Sans Fallback", "Noto Sans CJK SC", "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
+        }
+
+        /* 1. 鍏ㄥ眬娣辫壊鑳屾櫙 */
+        body {
+            background: #001f3f;
+            color: #fff;
+            height: 100vh;
+            overflow: hidden;
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            -webkit-box-orient: vertical;
+            -webkit-box-direction: normal;
+            -webkit-flex-direction: column;
+            flex-direction: column;
+            font-size: 14px;
+        }
+
+        /* 2. 椤堕儴鏍� */
+        .top-header {
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            -webkit-box-align: center;
+            -webkit-align-items: center;
+            align-items: center;
+            padding: 15px 30px;
+            background: rgba(0, 30, 60, 0.9);
+            white-space: nowrap;
+            position: relative;
+            border-bottom: 1px solid #003366;
+        }
+
+        .top-header img {
+            height: 50px;
+            margin-right: 20px;
+            z-index: 2;
+        }
+
+        .top-header .title-text {
+            position: absolute;
+            left: 50%;
+            -webkit-transform: translateX(-50%);
+            transform: translateX(-50%);
+            font-size: 32px;
+            font-weight: bold;
+            color: #fff;
+            z-index: 1;
+        }
+
+        .top-header .time-info {
+            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锛� */
+        .main-content {
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+            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;
+        }
+
+        /* 鍒楄瀹瑰櫒 */
+        .columns-row {
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            overflow: hidden;
+        }
+
+        .columns-row > .column-box {
+            margin-left: 5px;
+            margin-right: 5px;
+        }
+
+        .columns-row > .column-box:first-child {
+            margin-left: 0;
+        }
+
+        .columns-row > .column-box:last-child {
+            margin-right: 0;
+        }
+
+        /* 鍒楀鍣� */
+        .column-box {
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            -webkit-box-orient: vertical;
+            -webkit-box-direction: normal;
+            -webkit-flex-direction: column;
+            flex-direction: column;
+            background: rgba(10, 40, 80, 0.5);
+            border-radius: 0;
+            padding: 10px;
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+            min-width: 0;
+            border: 1px solid #003366;
+        }
+
+        .column-box.col-wide {
+            -webkit-box-flex: 2.5;
+            -webkit-flex: 2.5;
+            flex: 2.5;
+        }
+
+        .column-box.col-normal {
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+        }
+
+        /* 鏍囬琛� */
+        .col-title-line {
+            font-size: 22px;
+            font-weight: bold;
+            color: #4da6ff;
+            text-align: center;
+        }
+
+        .col-title {
+            padding-bottom: 8px;
+            border-bottom: 1px solid #003366;
+            margin-bottom: 10px;
+            text-align: center;
+        }
+
+        .col-subtitle {
+            font-size: 14px;
+            color: #999;
+            text-align: center;
+            min-height: 20px;
+            /* 鍗充娇涓虹┖涔熶繚鐣欓珮搴︼紝闃叉鏍囬鏍忛珮浣庝笉骞� */;
+            line-height: 1.4;
+            word-break: keep-all;
+        }
+
+        /* 鎮h�呭垪琛� */
+        .patient-list {
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+            overflow-y: auto;
+            padding-right: 5px;
+        }
+
+        /* 绗�1鏍忥細涓�琛屼袱涓� */
+        #col-0 {
+            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;
+            -webkit-box-orient: vertical;
+            -webkit-box-direction: normal;
+            -webkit-flex-direction: column;
+            flex-direction: column;
+        }
+
+        /* 鎮h�呴」鐩� */
+        .patient-item {
+            font-size: 22px;
+            padding: 8px 5px;
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            -webkit-box-align: center;
+            -webkit-align-items: center;
+            align-items: center;
+            color: #fff;
+            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;
+        }
+
+        .p-name {
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+        }
+
+        .p-name-wrap {
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+        }
+
+        .p-room {
+            color: #4da6ff;
+            font-weight: bold;
+            font-size: 18px;
+            margin-left: 4px;
+        }
+
+        /* 杩囧彿鏍忥紙鍥哄畾鍦� main-content 搴曢儴锛岃嚜鍔ㄦ粴鍔級 */
+        .missed-bar {
+            -webkit-flex-shrink: 0;
+            flex-shrink: 0;
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            -webkit-box-align: center;
+            -webkit-align-items: center;
+            align-items: center;
+            background: rgba(80, 20, 20, 0.7);
+            border: 1px solid #993333;
+            padding: 6px 10px;
+            margin-top: 8px;
+        }
+
+        .missed-bar-empty {
+            display: none;
+        }
+
+        .missed-bar-title {
+            -webkit-flex-shrink: 0;
+            flex-shrink: 0;
+            color: #ff6666;
+            font-size: 18px;
+            font-weight: bold;
+            margin-right: 16px;
+            line-height: 30px;
+        }
+
+        /* 婊氬姩瑁佸壀鍖� */
+        .missed-bar-scroll-area {
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+            overflow: hidden;
+            white-space: nowrap;
+        }
+
+        /* 婊氬姩杞ㄩ亾 */
+        .missed-bar-track {
+            display: inline-block;
+            white-space: nowrap;
+            will-change: transform;
+        }
+
+        .missed-bar-scroll .missed-bar-track {
+            /* 鍔ㄧ敾鏃堕暱鐢� JS 鍔ㄦ�佽缃紝瑙� updateMissedBarSpeed */
+            -webkit-animation-name: missed-scroll;
+            animation-name: missed-scroll;
+            -webkit-animation-timing-function: linear;
+            animation-timing-function: linear;
+            -webkit-animation-iteration-count: infinite;
+            animation-iteration-count: infinite;
+        }
+
+        @-webkit-keyframes missed-scroll {
+            0% { -webkit-transform: translateX(0); transform: translateX(0); }
+            100% { -webkit-transform: translateX(-50%); transform: translateX(-50%); }
+        }
+        @keyframes missed-scroll {
+            0% { transform: translateX(0); }
+            100% { transform: translateX(-50%); }
+        }
+
+        .missed-bar .patient-item {
+            display: -webkit-inline-box;
+            display: -webkit-inline-flex;
+            display: inline-flex;
+            font-size: 17px;
+            padding: 3px 12px;
+            margin-right: 8px;
+            border-right: 1px solid #664444;
+            color: #cc9999;
+        }
+
+        .missed-bar .patient-item:last-child {
+            border-right: none;
+        }
+
+        .missed-bar .p-number {
+            color: #ff9966;
+            font-weight: bold;
+            margin-right: 6px;
+        }
+
+        .missed-bar .p-name {
+            color: #bbaaaa;
+        }
+
+        .missed-bar .p-room {
+            color: #ff6666;
+            font-size: 15px;
+        }
+
+        /* 搴曢儴鏍� */
+        .bottom-footer {
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            -webkit-box-pack: center;
+            -webkit-justify-content: center;
+            justify-content: center;
+            -webkit-box-align: center;
+            -webkit-align-items: center;
+            align-items: center;
+            padding: 10px 30px;
+            background: rgba(0, 30, 60, 0.9);
+            border-top: 1px solid #003366;
+        }
+
+        .footer-tip {
+            font-size: 22px;
+            color: #ffcc00;
+            font-weight: bold;
+            text-align: center;
+        }
+
+        /* 婊氬姩鏉� */
+        .patient-list::-webkit-scrollbar {
+            width: 4px;
+        }
+        .patient-list::-webkit-scrollbar-thumb {
+            background: #444;
+            border-radius: 2px;
+        }
+
+        /* 璋冭瘯闈㈡澘 */
+        .debug-panel {
+            position: fixed;
+            right: 15px;
+            bottom: 70px;
+            width: 350px;
+            height: 200px;
+            background: rgba(0, 0, 0, 0.9);
+            color: #0f0;
+            border-radius: 4px;
+            font-family: monospace;
+            font-size: 12px;
+            z-index: 9999;
+            overflow: hidden;
+        }
+
+        .debug-header {
+            display: -webkit-box;
+            display: -webkit-flex;
+            display: flex;
+            -webkit-box-pack: justify;
+            -webkit-justify-content: space-between;
+            justify-content: space-between;
+            -webkit-box-align: center;
+            -webkit-align-items: center;
+            align-items: center;
+            padding: 5px;
+            background: #333;
+            border-bottom: 1px solid #000;
+        }
+
+        .debug-header span {
+            font-weight: bold;
+            font-size: 13px;
+        }
+
+        .debug-header button {
+            background: #c00;
+            color: #fff;
+            border: none;
+            padding: 2px 6px;
+            font-size: 10px;
+            cursor: pointer;
+        }
+
+        .debug-body {
+            -webkit-box-flex: 1;
+            -webkit-flex: 1;
+            flex: 1;
+            padding: 5px;
+            overflow-y: auto;
+            font-size: 11px;
+        }
+
+        .debug-line {
+            margin-bottom: 2px;
+        }
+
+        .debug-time {
+            color: #888;
+        }
+    </style>
+</head>
+
+<body>
+    <!-- 椤堕儴鏍� -->
+    <div class="top-header">
+        <img src="logo.png" alt="logo" />
+        <span class="title-text">蹇冪數妫�鏌ユ湇鍔¤瘖鍖哄ぇ鍘�</span>
+        <span class="time-info" id="headerTime"></span>
+    </div>
+
+    <!-- 涓讳綋鍐呭 -->
+    <div class="main-content" id="mainContent"></div>
+
+    <!-- 搴曢儴鏍� -->
+    <div class="bottom-footer">
+        <div class="footer-tip">娓╅Θ鎻愮ず锛氳鍚埌鍛煎彨鍚庡墠寰�瀵瑰簲璇婂锛岃繃鍙锋偅鑰呰鍒板璇婂彴澶勭悊锛�</div>
+    </div>
+
+    <!-- 璋冭瘯闈㈡澘 -->
+    <div class="debug-panel" id="debugPanel">
+        <div class="debug-header">
+            <span>[璋冭瘯] 杩愯鏃ュ織</span>
+            <button onclick="document.getElementById('debugBody').innerHTML=''">娓呯┖</button>
+        </div>
+        <div class="debug-body" id="debugBody"></div>
+    </div>
+
+    <script src="./static/jquery.min.js"></script>
+    <script>
+        // ================= 璋冭瘯鏃ュ織 =================
+        function logDebug(msg) {
+            var now = new Date();
+            function pad(num) { return num < 10 ? '0' + num : '' + num; }
+            var timeStr = pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds());
+            var logHtml = '<div class="debug-line"><span class="debug-time">[' + timeStr + ']</span> ' + msg + '</div>';
+            console.log("[" + timeStr + "] " + msg);
+            var body = document.getElementById("debugBody");
+            if (body) {
+                body.insertAdjacentHTML("beforeend", logHtml);
+                body.scrollTop = body.scrollHeight;
+            }
+        }
+
+        // ================= 搴旂敤鐘舵�� =================
+        var appState = {
+            columnTitles: ["甯歌蹇冪數鍥�", "鍔ㄦ�佸績鐢靛浘/琛�鍘�", "蹇冪數鍥捐繍鍔ㄨ瘯楠�", "椋熼亾鐢电敓鐞�", "鍔ㄨ剦纭寲鐩戞祴"],
+            columnSubTitles: ["搴婅竟蹇冪數鍥�(甯歌+棰戣氨) / 蹇冪數鍚戦噺鍥�", "", "", "", ""],
+            patients: [],
+            apiBaseUrl: "http://localhost/admin-api",
+            // apiBaseUrl: "http://192.168.100.110/admin-api",
+            pollTimer: null,
+            callRepeatTimes: 2,
+            spokenPatients: {},
+            ttsQueue: [],
+            isSpeaking: false,
+            // 杩囧彿鎮h�呮粴鍔ㄩ�熷害閰嶇疆锛氭暟鍊间负鍔ㄧ敾鍛ㄦ湡绉掓暟锛岃秺澶ц秺鎱�
+            missedScrollSpeedSlowest: 10,  // 鏈�鎱㈤�熷害锛堟偅鑰呭皯鏃朵娇鐢紝绉掓暟澶�=鎱級
+            missedScrollSpeedFastest: 5   // 鏈�蹇�熷害锛堟偅鑰呭鏃朵笂闄愶紝绉掓暟灏�=蹇級
+        };
+
+        // ================= 璇煶鎾姤 =================
+        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 鎺ュ彛
+            if (typeof wowjoy !== 'undefined' && typeof wowjoy.speek === 'function') {
+                try {
+                    wowjoy.speek(text);
+                    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 {
+                logDebug("[TTS] 娴忚鍣ㄤ笉鏀寔璇煶鍚堟垚");
+                appState.isSpeaking = false;
+                processTtsQueue();
+            }
+        }
+
+        function speak(text) {
+            if (!text) return;
+            appState.ttsQueue.push(text);
+            processTtsQueue();
+        }
+
+        // ================= 娓叉煋锛氭爣棰樻鏋讹紙浠呭垵濮嬪寲涓�娆★級=================
+        function initLayout() {
+            var main = document.getElementById("mainContent");
+            var html = '<div class="columns-row">';
+
+            for (var i = 0; i < appState.columnTitles.length; i++) {
+                // 鏍囬鍜屽壇鏍囬閮芥湁鍥哄畾鍗犱綅锛岄伩鍏嶆湁/鏃犲壇鏍囬鏃堕珮搴﹁烦鍔�
+                var subtitle = appState.columnSubTitles[i] || "&nbsp;";
+                var colClass = (i === 0) ? 'col-wide' : 'col-normal';
+                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" id="col-' + i + '"></div>' +
+                    '</div>';
+            }
+            html += '</div>';
+            html += '<div class="missed-bar missed-bar-empty" id="missedBar">' +
+                '<span class="missed-bar-title">杩囧彿鎮h��</span>' +
+                '<div class="missed-bar-scroll-area"><div class="missed-bar-track" id="missedBarTrack"></div></div>' +
+                '</div>';
+            main.innerHTML = html;
+        }
+
+        // ================= 娓叉煋锛氭偅鑰呭垪琛紙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];
+                // 杩囧彿鎮h�呬笉鏄剧ず鍦ㄥ垪鍐咃紝缁熶竴鍦ㄥ簳閮ㄨ繃鍙锋爮灞曠ず
+                if (isMissedStatus(pat.status)) continue;
+                var roomHtml = pat.roomName ? '<span class="p-room">(' + pat.roomName + ')</span>' : '';
+                h += '<div class="patient-item">' +
+                    '<span class="p-number">' + (pat.seqNum || '') + '</span>' +
+                    '<span class="p-name-wrap"><span class="p-name">' + desensitizeName(pat.patName) + '</span>' + roomHtml + '</span>' +
+                    '</div>';
+            }
+            return h;
+        }
+
+        function buildMissedBarHtml(dataList) {
+            var allMissed = [];
+            for (var i = 0; i < appState.columnTitles.length; i++) {
+                var colData = (dataList && dataList[i]) ? dataList[i] : [];
+                for (var p = 0; p < colData.length; p++) {
+                    var pat = colData[p];
+                    if (isMissedStatus(pat.status)) {
+                        allMissed.push({ patient: pat, colIndex: i });
+                    }
+                }
+            }
+            if (allMissed.length === 0) return "";
+            var h = "";
+            for (var m = 0; m < allMissed.length; m++) {
+                var item = allMissed[m];
+                var pat = item.patient;
+                var colName = appState.columnTitles[item.colIndex];
+                var roomHtml = pat.roomName ? ' <span class="p-room">' + pat.roomName + '</span>' : '';
+                h += '<span class="patient-item">' +
+                    '<span class="p-number">[' + colName + '] ' + (pat.seqNum || '') + '</span>' +
+                    '<span class="p-name">' + desensitizeName(pat.patName) + '</span>' + roomHtml +
+                    '</span>';
+            }
+            // 澶嶅埗涓�浠藉唴瀹瑰疄鐜版棤缂濆惊鐜粴鍔�
+            return h + 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);
+            }
+
+            // 鏇存柊搴曢儴杩囧彿鏍�
+            var missedBar = document.getElementById("missedBar");
+            var missedTrack = document.getElementById("missedBarTrack");
+            if (missedBar && missedTrack) {
+                var missedHtml = buildMissedBarHtml(dataList);
+                if (missedHtml) {
+                    missedTrack.innerHTML = missedHtml;
+                    missedBar.className = "missed-bar missed-bar-scroll";
+                    // 鏍规嵁杩囧彿鎮h�呬汉鏁板姩鎬佽皟鏁存粴鍔ㄩ�熷害
+                    updateMissedBarSpeed(missedTrack, dataList);
+                } else {
+                    missedBar.className = "missed-bar missed-bar-empty";
+                }
+            }
+        }
+
+        // ================= 杩囧彿鏍忔粴鍔ㄩ�熷害 =================
+        // 缁熻杩囧彿鎮h�呮�绘暟锛屽湪 0 鍒� 20 浜轰箣闂寸嚎鎬ф彃鍊煎姩鐢绘椂闀�
+        // 浜哄皯鏃剁敤鏈�鎱㈤�熷害锛堢鏁板ぇ锛夛紝浜哄鏃堕�艰繎鏈�蹇�熷害锛堢鏁板皬锛夛紝鏈�澶� 20 浜鸿揪鍒颁笂闄�
+        function updateMissedBarSpeed(trackEl, dataList) {
+            var count = 0;
+            for (var i = 0; i < appState.columnTitles.length; i++) {
+                var colData = (dataList && dataList[i]) ? dataList[i] : [];
+                for (var p = 0; p < colData.length; p++) {
+                    if (isMissedStatus(colData[p].status)) count++;
+                }
+            }
+            if (count === 0) return;
+
+            var slowest = appState.missedScrollSpeedSlowest;
+            var fastest = appState.missedScrollSpeedFastest;
+            // 浜烘暟闃堝�硷細瓒呰繃姝や汉鏁板嵆浣跨敤鏈�蹇�熷害
+            var maxCount = 20;
+            // 绾挎�ф彃鍊硷細count=1 -> slowest, count>=maxCount -> fastest
+            var ratio = Math.min(count, maxCount) / maxCount;
+            var duration = slowest - (slowest - fastest) * ratio;
+            // 鍙栨暣鍒颁竴浣嶅皬鏁帮紝鍏煎叿绮惧害鍜岀畝娲�
+            duration = Math.round(duration * 10) / 10;
+
+            var animValue = 'missed-scroll ' + duration + 's linear infinite';
+            trackEl.style.webkitAnimation = animValue;
+            trackEl.style.animation = animValue;
+        }
+
+        // ================= 鏁版嵁瀵规瘮涓庢挱鎶� =================
+        function checkAndSpeakNewRooms(oldData, newData) {
+            if (!oldData || oldData.length === 0) return;
+            for (var c = 0; c < newData.length; c++) {
+                var newCol = newData[c];
+                var oldCol = oldData[c];
+                if (Array.isArray(newCol)) {
+                    for (var p = 0; p < newCol.length; p++) {
+                        var newPat = newCol[p];
+                        if (newPat.roomName) {
+                            if (appState.spokenPatients[newPat.patId]) continue;
+                            var oldPat = null;
+                            if (Array.isArray(oldCol)) {
+                                for (var k = 0; k < oldCol.length; k++) {
+                                    if (oldCol[k].patId === newPat.patId) {
+                                        oldPat = oldCol[k];
+                                        break;
+                                    }
+                                }
+                            }
+                            if (!oldPat || !oldPat.roomName) {
+                                var repeatText = "";
+                                for (var r = 0; r < appState.callRepeatTimes; r++) {
+                                    repeatText += "璇� " + newPat.seqNum + " 鍙� " + newPat.patName + " 鍒� " + newPat.roomName + " 灏辫瘖銆�";
+                                }
+                                speak(repeatText);
+                                appState.spokenPatients[newPat.patId] = true;
+                                logDebug("[鎺掗槦] " + newPat.patName + " -> " + newPat.roomName);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // ================= 鏁版嵁鑾峰彇 =================
+        function fetchQueueData() {
+            var url = appState.apiBaseUrl + "/ecg/screen/big-screen-data";
+            $.ajax({
+                url: url,
+                type: "GET",
+                dataType: "json",
+                timeout: 5000,
+                success: function (res) {
+                    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] : [];
+                        }
+                    }
+                    // 鍏� diff 鏇存柊 DOM锛屽啀鎾姤锛屾渶鍚庝繚瀛樻暟鎹敤浜庝笅娆″姣�
+                    updatePatients(dataList);
+                    checkAndSpeakNewRooms(appState.patients, dataList);
+                    appState.patients = dataList;
+
+                    // Android 6 WebView 閫氬父涓嶆敮鎸� performance.memory锛屽畨鍏ㄥ畧鍗�
+                    try {
+                        if (window.performance && window.performance.memory) {
+                            var usedMB = (window.performance.memory.usedJSHeapSize / 1048576).toFixed(2);
+                            logDebug("[鍐呭瓨] " + usedMB + " MB");
+                        }
+                    } catch (e) {}
+                },
+                error: function (err) {
+                    logDebug("[璇锋眰澶辫触] " + (err.statusText || "缃戠粶閿欒"));
+                }
+            });
+        }
+
+        // ================= 鍒濆鍖� =================
+        function onReady() {
+            initLayout();
+            updateHeaderTime();
+            setInterval(updateHeaderTime, 1000);
+            fetchQueueData();
+            appState.pollTimer = setInterval(fetchQueueData, 5000);
+            logDebug("[绯荤粺] 鍚姩瀹屾垚 - Android 6.0.1");
+        }
+
+        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()) + "鏃�";
+            var weekStr = weekDays[now.getDay()];
+            var timeStr = padZero(now.getHours()) + ":" + padZero(now.getMinutes());
+            var el = document.getElementById("headerTime");
+            // 鏄熸湡鍜屾棩鏈熷悇鍗犱竴琛屽湪宸︼紝鏃堕棿澶у瓧鍦ㄥ彸璺ㄤ袱琛�
+            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 鍙兘娌℃湁 $锛�
+        if (typeof $ !== 'undefined') {
+            $(document).ready(onReady);
+        } else if (document.readyState === 'complete' || document.readyState === 'interactive') {
+            setTimeout(onReady, 1);
+        } else {
+            document.addEventListener('DOMContentLoaded', onReady);
+        }
+    </script>
+</body>
+</html>

--
Gitblit v1.9.3