From 796047fbe84d51816f44be535501415d3c66dd9d Mon Sep 17 00:00:00 2001
From: yxh <172933527@qq.com>
Date: 星期日, 21 六月 2026 23:24:37 +0800
Subject: [PATCH] yxh
---
big1.html | 680 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 680 insertions(+), 0 deletions(-)
diff --git a/big1.html b/big1.html
new file mode 100644
index 0000000..848b08d
--- /dev/null
+++ b/big1.html
@@ -0,0 +1,680 @@
+锘�<!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;
+ }
+
+ /* 杩囧彿鎮h�咃細鎺掑湪鍒楀唴锛岃瑙夊急鍖� */
+ .patient-item.missed {
+ color: #aa8888;
+ }
+
+ .patient-item.missed .p-number {
+ color: #cc9966;
+ }
+
+ .patient-item.missed .p-missed-tag {
+ color: #ff6666;
+ font-size: 16px;
+ margin-left: 4px;
+ -webkit-flex-shrink: 0;
+ flex-shrink: 0;
+ }
+
+ /* 搴曢儴鏍� */
+ .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 {
+ display: none; /* 闇�瑕佽皟璇曟椂鍒犳帀姝よ鍗冲彲鏄剧ず */
+ 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: visible;
+ }
+
+ .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;
+ }
+ }
+
+ // ================= 搴旂敤鐘舵�� =================
+ // 鍛煎彨鍙彿娆℃暟鍙傛暟锛氬懠鍙偅鑰呭氨璇婃椂閲嶅鎾姤鐨勬鏁帮紝榛樿 2 娆�
+ var CALL_REPEAT_TIMES = 2;
+ var appState = {
+ columnTitles: ["甯歌蹇冪數鍥�", "鍔ㄦ�佸績鐢靛浘/琛�鍘�", "蹇冪數鍥捐繍鍔ㄨ瘯楠�", "椋熼亾鐢电敓鐞�", "鍔ㄨ剦纭寲鐩戞祴"],
+ columnSubTitles: ["搴婅竟蹇冪數鍥�(甯歌+棰戣氨) / 蹇冪數鍚戦噺鍥�", "", "", "", ""],
+ patients: [],
+ apiBaseUrl: "http://localhost/admin-api",
+ // apiBaseUrl: "http://10.0.2.193/admin-api",
+ pollTimer: null,
+ spokenPatients: {},
+ ttsQueue: [],
+ isSpeaking: false,
+ };
+
+ var patStatus = {
+ 3: "宸茶繃鍙�-鎺掗槦", 5: "宸茶繃鍙�", 7: "宸茶繃鍙�-瀹夎", 10: "鎺掗槦涓�", 12: "浜插拰",
+ 13: "浜插拰-瀹夎", 15: "宸插彫鍥�", 20: "鍊欒瘖涓�", 30: "灏辫瘖涓�", 33: "宸查鐢�",
+ 34: "宸插彫鍥�-瀹夎", 36: "瀹夎涓�", 40: "宸插氨璇�"
+ };
+
+ // ================= 璇煶鎾姤 =================
+ 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] || " ";
+ 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>';
+ 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];
+ 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);
+ }
+ }
+
+ // ================= 鏁版嵁瀵规瘮涓庢挱鎶� =================
+ 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 = "";
+ repeatText += "璇� " + newPat.seqNum + " 鍙� " + newPat.patName + " 鍒� " + newPat.roomName + " 灏辫瘖銆�";
+ for (var r = 0; r < CALL_REPEAT_TIMES; r++) {
+ 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>
\ No newline at end of file
--
Gitblit v1.9.3