From ebee36ca9a39b59d98da3613804791faa8dd2da6 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期六, 22 十一月 2025 16:20:52 +0800
Subject: [PATCH] 打印完善
---
src/views/ecg/callingscreen/roomscreen.vue | 985 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 755 insertions(+), 230 deletions(-)
diff --git a/src/views/ecg/callingscreen/roomscreen.vue b/src/views/ecg/callingscreen/roomscreen.vue
index 8437e08..be74bd6 100644
--- a/src/views/ecg/callingscreen/roomscreen.vue
+++ b/src/views/ecg/callingscreen/roomscreen.vue
@@ -1,246 +1,771 @@
-<script setup lang="ts">
-
-import {RoomProfileVO} from "@/api/ecg/doctor";
-import {RoomApi} from "@/api/ecg/room";
-import {ScreenQueueVO, ScreenApi} from "@/api/ecg/screen";
-import {CallApi, CallVO} from "@/api/ecg/call";
-import {queueStatusConvert} from "../../../utils/statusFormatter";
-import {getCheckTypeName, getCheckTypeSeqPrefix} from "../../../utils/checkTypeFormatter";
-
-defineOptions({ name: 'roomscreen' })
-let roomId = ref<number>(0)
-
-const checkRelatedPatientList = ref<ScreenQueueVO[]>([])
-const installRelatedPatientList = ref<ScreenQueueVO[]>([])
-
-let curSpeakPat : CallVO | null = null;
-
-const roomProfile = ref<RoomProfileVO>()
-
-const getList = async () => {
- const data = await ScreenApi.getRoomScreenData(roomId.value)
- checkRelatedPatientList.value = data[1]
- installRelatedPatientList.value = data[2]
-}
-
-const getRoomByIp = async () => {
- const data = await RoomApi.getRoomByIP(roomId.value)
- roomProfile.value = data
-}
-
-const startScrolling = () => {
- setInterval(() => {
- getList()
- if ( curSpeakPat === null ) {
- initiateSpeak()
- }
- }, 3000); // 姣忎袱绉掓粴鍔ㄤ竴娆�
-}
-
-const nameDesensitize = (patName) => {
- if (patName.length == 2) {
- //鎴彇name 瀛楃涓叉埅鍙栫涓�涓瓧绗︼紝
- return patName.substring(0, 1) + '*';
- } else if (patName.length == 3) {
- //鎴彇绗竴涓拰绗笁涓瓧绗�
- return patName.substring(0, 1) + '*' + patName.substring(2, 3);
- } else if (patName.length > 3) {
- //鎴彇绗竴涓拰澶т簬绗�4涓瓧绗�
- return (
- patName.substring(0, 1) + '*' + '*' + patName.substring(3, patName.length)
- );
- }
-}
-
-const tableRowClassName = ({row, rowIndex}: {
- row: ScreenQueueVO
- rowIndex: number
-}) => {
- if (row.status === 5) {
- return 'warning-row'
- } else if (row.status === 7) {
- return 'warning-row' //return 'success-row'
- }
- return ''
-}
-
-const onSpeachEndEvent = async (event) => {
- console.log("Speech ended... " + event.currentTarget.text);
- curSpeakPat!.called = 1
- await CallApi.updateCall(curSpeakPat!)
- initiateSpeak()
-}
-
-const initiateSpeak = async () => {
- //TODO: 娴嬭瘯鐢紝鏆傛椂涓嶆挱闊�
- return;
-
- curSpeakPat = await CallApi.getNextInstallCall()
- if (curSpeakPat == null)
- return;
-
- speak("璇枫��" + curSpeakPat.patName + "鍒�" + curSpeakPat.roomName + "瑁呮満");
-}
-
-const speak = (msg) => {
- console.info("speak " + msg);
- var speech = new SpeechSynthesisUtterance()
- speech.text = msg + "銆傘�傘��" + msg + "銆傘�傘��" + msg + "銆傘�傘��"
- speech.pitch = 1 // 鑾峰彇骞惰缃瘽璇殑闊宠皟(0-2 榛樿1锛屽�艰秺澶ц秺灏栭攼,瓒婁綆瓒婁綆娌�)
- speech.rate = 0.9 // 鑾峰彇骞惰缃璇濈殑閫熷害(0.1-10 榛樿1锛屽�艰秺澶ц閫熻秺蹇�,瓒婂皬璇�熻秺鎱�)
- speech.volume = 100 // 鑾峰彇骞惰缃璇濈殑闊抽噺
- speech.lang = 'zh-CN' // 璁剧疆鎾斁璇█
-
- speech.onend = onSpeachEndEvent
- speechSynthesis.speak(speech)
-}
-
-onMounted( () => {
- getRoomByIp()
- startScrolling()
-})
-
-</script>
-
<template>
- <el-container style="height: 100%;">
- <el-header style="font-size: 25px">
- {{ roomProfile?.roomName||'-' }}
- <el-input-number v-model="roomId" @change="getRoomByIp" />
- </el-header>
- <el-main>
- <div class="layout-content">
- <div class="left" v-if="roomProfile?.callingScreenType === 10 || roomProfile?.callingScreenType === 20 || roomProfile?.callingScreenType === 40 || roomProfile?.callingScreenType === 50">
- <el-table
- :data="checkRelatedPatientList"
- :show-header="false"
- style="width: 100%; height: 100%; border: solid var(--el-color-primary-light-7); font-size: 18px;"
- :row-class-name="tableRowClassName"
- >
- <el-table-column
- prop="patName"
- label="棰勭害搴忓彿"
- width="60px">
- <template #default="scope">
- <span style="display:inline-block; width:60px;">{{getCheckTypeSeqPrefix(scope.row.bookCheckType)}}{{scope.row.bookSeqNum}} </span>
- </template>
- </el-table-column>
- <el-table-column
- prop="patName"
- label="鎮h�呭鍚�"
- width="80px">
- <template #default="scope">
- <span style="display:inline-block; width:80px;">{{ nameDesensitize(scope.row.patName) }} </span>
- </template>
- </el-table-column>
- <el-table-column
- prop="patName"
- label="妫�鏌ラ」鐩�"
- width="80px">
- <template #default="scope">
- <span style="display:inline-block; width:80px;">{{scope.row.bookCheckType && getCheckTypeName(scope.row.bookCheckType)}} </span>
- </template>
- </el-table-column>
- <el-table-column label="鐘舵��" align="center" width="200px">
- <template #default="scope">
- <!-- <dict-tag :type="DICT_TYPE.ECG_QUEUE_STATUS" :value="scope.row.status" />-->
- {{queueStatusConvert(scope.row.status)}} {{scope.row.bedNo}}
- </template>
- </el-table-column>
- </el-table>
+ <div class="room-screen-container">
+ <div class="search-bar">
+ <input
+ class="search-input"
+ type="text"
+ placeholder="璇疯緭鍏ユ埧闂村彿鏌ヨ"
+ v-model="searchRoomInput"
+ @keyup.enter="searchRoom"
+ />
+ <button class="search-btn" @click="searchRoom"> 鏌ヨ </button>
+ </div>
+
+ <div class="header">
+ <div class="clinic-title">蹇冪數鍥捐瘖闂村彨鍙风郴缁�</div>
+ <div class="clinic-info">
+ <div class="room-name">
+ {{ roomProfile.roomName || '璇婇棿鍔犺浇涓�...' }}
</div>
- <div class="right" v-if="roomProfile?.callingScreenType === 30 || roomProfile?.callingScreenType === 40 || roomProfile?.callingScreenType === 50">
- <el-table
- :data="installRelatedPatientList"
- :show-header="false"
- style="width: 100%; height: 100%; border: solid var(--el-color-primary-light-7); font-size: 18px;"
- :row-class-name="tableRowClassName"
+ <div class="screen-type"> 妯″紡锛歿{ screenTypeText }} </div>
+ </div>
+ </div>
+
+ <div class="main-content">
+ <div class="panel" v-if="showCheckPanel">
+ <div class="panel-header">妫�鏌ラ槦鍒�</div>
+ <div class="patient-list">
+ <div v-if="checkRelatedPatientList.length === 0" class="empty-state">
+ 鏆傛棤绛夊緟妫�鏌ョ殑鎮h��
+ </div>
+ <div
+ v-for="(patient, index) in checkRelatedPatientList"
+ :key="'check-' + index"
+ class="patient-item"
+ :class="getStatusClass(patient.status)"
>
- <el-table-column
- prop="patName"
- label="棰勭害搴忓彿"
- width="60px">
- <template #default="scope">
- <span style="display:inline-block; width:60px;">{{getCheckTypeSeqPrefix(scope.row.bookCheckType)}}{{scope.row.bookSeqNum}} </span>
- </template>
- </el-table-column>
- <el-table-column
- prop="patName"
- label="鎮h�呭鍚�"
- width="80px">
- <template #default="scope">
- <span style="display:inline-block; width:80px;">{{ nameDesensitize(scope.row.patName) }} </span>
- </template>
- </el-table-column>
- <el-table-column
- prop="patName"
- label="妫�鏌ラ」鐩�"
- width="80px">
- <template #default="scope">
- <span style="display:inline-block; width:80px;">{{scope.row.bookCheckType && getCheckTypeName(scope.row.bookCheckType)}} </span>
- </template>
- </el-table-column>
- <el-table-column label="鐘舵��" align="center" width="200px">
- <template #default="scope">
- <!-- <dict-tag :type="DICT_TYPE.ECG_QUEUE_STATUS" :value="scope.row.status" />-->
- {{queueStatusConvert(scope.row.status)}} {{scope.row.bedNo}}
- </template>
- </el-table-column>
- </el-table>
+ <div class="patient-info">
+ <div class="patient-number"> {{ getSeqPrefix(patient) }}{{ patient.bedNo }} </div>
+ <div class="patient-name">
+ {{ nameDesensitize(patient.patName) }}
+ </div>
+ <div class="patient-check-type">
+ {{ getCheckTypeName(patient.bookCheckType) }}
+ </div>
+ <div class="patient-status" :class="'status-' + getStatusClass(patient.status)">
+ {{ queueStatusConvert(patient.status) }}
+ </div>
+ </div>
+ </div>
</div>
</div>
- </el-main>
- <el-button @click="speak('娆㈣繋浣跨敤')" >娆㈣繋浣跨敤</el-button>
-<!--
- <el-footer height="100px" style="padding: 0 0">
- <el-header height="30px" style="background-color: #98b8e5; line-height: 30px;">杩囧彿鍖�</el-header>
- <span v-for="(passedItem, index) in installRelatedPatientList" :key="index">
- {{nameDesensitize(passedItem.patName) + " "}}
- </span>
- </el-footer>
--->
- </el-container>
+
+ <div class="panel" v-if="showInstallPanel">
+ <div class="panel-header">瑁呮満闃熷垪</div>
+ <div class="patient-list">
+ <div v-if="installRelatedPatientList.length === 0" class="empty-state">
+ 鏆傛棤绛夊緟瑁呮満鐨勬偅鑰�
+ </div>
+ <div
+ v-for="(patient, index) in installRelatedPatientList"
+ :key="'install-' + index"
+ class="patient-item"
+ :class="getStatusClass(patient.status)"
+ >
+ <div class="patient-info">
+ <div class="patient-number">
+ {{ patient.bookSeqNum }}
+ </div>
+ <div class="patient-name">
+ {{ nameDesensitize(patient.patName) }}
+ </div>
+ <div class="patient-check-type">
+ {{ getCheckTypeName(patient.bookCheckType) }}
+ </div>
+ <div class="patient-status" :class="'status-' + getStatusClass(patient.status)">
+ {{ queueStatusConvert(patient.status) }}
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="footer">
+ <div class="announcement">
+ {{ announcementText }}
+ </div>
+ <div class="controls">
+ <button class="control-btn pulse" @click="initiateSpeak">
+ <i>馃摙</i>
+ <span>鍙彿</span>
+ </button>
+ <button class="flex-1 control-btn" @click="speak('娆㈣繋浣跨敤璇婇棿鍙彿绯荤粺')">
+ <i>馃攰</i>
+ <span>娴嬭瘯鎾煶</span>
+ </button>
+ <button class="flex-1 control-btn" @click="changeRoom">
+ <i>馃攧</i>
+ <span>鍒囨崲璇婇棿</span>
+ </button>
+ </div>
+ </div>
+ </div>
</template>
-<style scoped lang="scss">
-.el-header, .el-footer {
- background-color: var(--el-color-primary-light-7);
- color: #333;
- text-align: center;
- line-height: 60px;
-}
+<script>
+import { ref, computed, onBeforeUnmount } from 'vue'
+import { ScreenApi } from '@/api/ecg/screen'
+import { RoomApi } from '@/api/ecg/room'
-.el-aside {
- background-color: var(--el-color-primary-light-7);
- color: #333;
- text-align: center;
- line-height: 200px;
-}
+import axios from 'axios'
-.el-main {
- background-color: var(--el-color-primary-light-7);
- color: #333;
- padding: 0 0;
- text-align: center;
- line-height: 160px;
-}
+export default {
+ name: 'RoomScreen',
+ setup() {
+ // 鍝嶅簲寮忔暟鎹�
+ const roomProfile = ref({
+ roomName: '蹇冪數鍥捐瘖瀹� 01',
+ callingScreenType: 40
+ })
-.el-table ::v-deep .warning-row {
- --el-table-tr-bg-color: var(--el-color-warning-light-9);
-}
-.el-table ::v-deep .success-row {
- --el-table-tr-bg-color: var(--el-color-success-light-9);
-}
+ const checkRelatedPatientList = ref([])
+ const installRelatedPatientList = ref([])
+ const curSpeakPat = ref(null)
+ const announcementText = ref('绯荤粺杩愯涓�...')
+ const roomId = ref(1)
+ const timer = ref(null)
+ const speechSynthesis = ref(window.speechSynthesis || null)
+ const searchRoomInput = ref('')
-.layout-content {
+ // 璁$畻灞炴��
+ const screenTypeText = computed(() => {
+ const types = {
+ 10: '浠呮鏌ラ槦鍒�',
+ 20: '浠呮鏌ラ槦鍒�',
+ 30: '浠呰鏈洪槦鍒�',
+ 40: '鍙岄槦鍒楁ā寮�',
+ 50: '鍙岄槦鍒楁ā寮�'
+ }
+ return types[roomProfile.value.callingScreenType] || '鏈煡妯″紡'
+ })
+
+ const showCheckPanel = computed(() => {
+ return [10, 20, 40, 50].includes(roomProfile.value.callingScreenType)
+ })
+
+ const showInstallPanel = computed(() => {
+ return [30, 40, 50].includes(roomProfile.value.callingScreenType)
+ })
+
+ // 鏂规硶
+ const searchRoom = () => {
+ if (!searchRoomInput.value.trim()) {
+ announcementText.value = '璇疯緭鍏ユ湁鏁堢殑鎴块棿鍙�'
+ return
+ }
+ RoomApi.getRoomByIP(roomId.value).then((response) => {
+ roomProfile.value = response
+ console.log(roomProfile.value.callingScreenType,'绫诲瀷');
+
+ })
+
+ announcementText.value = `姝e湪鏌ヨ ${searchRoomInput.value} 鎴块棿淇℃伅...`
+
+ setTimeout(() => {
+ const roomNum = parseInt(searchRoomInput.value) || 0
+ // roomId.value = roomNum % 3
+ getRoomByIp()
+ announcementText.value = `宸插姞杞� ${roomProfile.value.roomName} 淇℃伅`
+ }, 500)
+ }
+
+ const getRoomByIp = () => {
+ setTimeout(() => {
+ ScreenApi.getRoomScreenData(searchRoomInput.value)
+ .then((response) => {
+ console.log(response, '991')
+ checkRelatedPatientList.value = response[1]
+ })
+ .catch((error) => {
+ console.error('鑾峰彇鎮h�呭け璐�:', error)
+ })
+ // axios
+ // .get(`http://localhost:48080/admin-api/ecg/screen/room-screen-data`, {
+ // params: {
+ // roomId: searchRoomInput.value
+ // }
+ // })
+ // .then((response) => {
+ // const patient = response.data
+ // console.log(response.data, '55')
+
+ // if (patient && patient.called === 0) {
+ // curSpeakPat.value = patient
+ // speak(`璇�${patient.patName}鍒�${roomProfile.value.roomName}瑁呮満`)
+ // }
+ // })
+ // .catch((error) => {
+ // console.error('鑾峰彇涓嬩竴浣嶆偅鑰呭け璐�:', error)
+ // })
+
+ const rooms = [
+ { roomName: '蹇冪數鍥捐瘖瀹� 01', callingScreenType: 40 },
+ { roomName: '鍔ㄦ�佸績鐢靛浘瀹�', callingScreenType: 10 },
+ { roomName: '杩愬姩璇曢獙瀹�', callingScreenType: 30 }
+ ]
+ roomProfile.value = rooms[roomId.value % 3]
+ announcementText.value = `宸插姞杞� ${roomProfile.value.roomName} 淇℃伅`
+ }, 300)
+ }
+
+ const getList = () => {
+ setTimeout(() => {
+ ScreenApi.getRoomScreenData(searchRoomInput.value)
+ .then((response) => {
+ console.log(response, '199')
+ checkRelatedPatientList.value = response[1]
+ })
+ .catch((error) => {
+ console.error('鑾峰彇鎮h�呭け璐�:', error)
+ })
+ // axios
+ // .get(`http://localhost:48080/admin-api/ecg/screen/room-screen-data`, {
+ // params: {
+ // roomId: searchRoomInput.value
+ // }
+ // })
+ // .then((response) => {
+ // checkRelatedPatientList.value = response.data.data[1]
+ // console.log(response.data.data[1], '66')
+ // })
+ // .catch((error) => {
+ // console.error('鑾峰彇涓嬩竴浣嶆偅鑰呭け璐�:', error)
+ // })
+
+ if (!curSpeakPat.value && Math.random() > 0.7) {
+ initiateSpeak()
+ }
+ }, 500)
+ }
+
+ const startScrolling = () => {
+ getList()
+ timer.value = setInterval(() => {
+ getList()
+ }, 5000)
+ }
+
+ const nameDesensitize = (patName) => {
+ if (!patName) return ''
+ if (patName.length === 2) {
+ return patName.substring(0, 1) + '*'
+ } else if (patName.length === 3) {
+ return patName.substring(0, 1) + '*' + patName.substring(2, 3)
+ } else if (patName.length > 3) {
+ return patName.substring(0, 1) + '*' + '*' + patName.substring(3, patName.length)
+ }
+ return patName
+ }
+
+ const getStatusClass = (status) => {
+ if (status === 10 || status === 40 || status === 33 || status === 20 || status === 10)
+ return 'waiting'
+ if (status === 30) return 'in-progress'
+ if (status === 7 || status === 3 || status === 5) return 'completed'
+ return ''
+ }
+
+ const queueStatusConvert = (status) => {
+ const statusMap = {
+ 3: '宸茶繃鍙�-鎺掗槦',
+ 5: '宸茶繃鍙�',
+ 7: '宸茶繃鍙�-瀹夎',
+ 10: '鎺掗槦涓�',
+ 12: '浜插拰',
+ 13: '浜插拰-瀹夎',
+ 15: '宸插彫鍥�',
+ 20: '鍊欒瘖涓�',
+ 30: '灏辫瘖涓�',
+ 33: '宸查鐢�',
+ 34: '宸插彫鍥�-瀹夎',
+ 36: '瀹夎涓�',
+ 40: '宸插氨璇�'
+ }
+ return statusMap[status] || '鏈煡鐘舵��'
+ }
+
+ const getCheckTypeName = (type) => {
+ const types = {
+ 1: '甯歌蹇冪數鍥�',
+ 2: '鍔ㄦ�佸績鐢靛浘',
+ 3: '杩愬姩璇曢獙',
+ 4: '蹇冪數鐩戞姢'
+ }
+ return types[type] || '鏈煡妫�鏌�'
+ }
+
+ const getSeqPrefix = (patient) => {
+ const types = {
+ 1: 'A001',
+ 2: 'A002',
+ 3: 'A003',
+ 4: 'A004'
+ }
+ return types[patient.bookCheckType] || ''
+ }
+
+ const initiateSpeak = () => {
+ const waitingPatients = installRelatedPatientList.value.filter((p) => p.status === 5)
+ if (waitingPatients.length === 0) {
+ announcementText.value = '褰撳墠娌℃湁绛夊緟瑁呮満鐨勬偅鑰�'
+ return
+ }
+
+ const patient = waitingPatients[0]
+ curSpeakPat.value = {
+ patName: patient.patName,
+ roomName: roomProfile.value.roomName
+ }
+
+ speak('璇�' + patient.patName + '鍒�' + roomProfile.value.roomName + '瑁呮満')
+ }
+
+ const speak = (msg) => {
+ announcementText.value = '姝e湪鍛煎彨: ' + msg
+
+ if (!speechSynthesis.value) {
+ console.warn('褰撳墠娴忚鍣ㄤ笉鏀寔璇煶鍚堟垚')
+ return
+ }
+
+ speechSynthesis.value.cancel()
+
+ const speech = new SpeechSynthesisUtterance()
+ speech.text = msg + '銆傘�傘��' + msg + '銆傘�傘��' + msg
+ speech.pitch = 1
+ speech.rate = 0.9
+ speech.volume = 1
+ speech.lang = 'zh-CN'
+
+ speechSynthesis.value.speak(speech)
+ }
+
+ const onSpeachEndEvent = (event) => {
+ curSpeakPat.value = null
+ announcementText.value = '绯荤粺杩愯涓�...'
+ }
+
+ const changeRoom = () => {
+ roomId.value = (roomId.value + 1) % 3
+ getRoomByIp()
+ announcementText.value = '姝e湪鍒囨崲璇婇棿...'
+ }
+
+ // 鐢熷懡鍛ㄦ湡閽╁瓙
+ onBeforeUnmount(() => {
+ if (timer.value) {
+ clearInterval(timer.value)
+ }
+ })
+
+ // 鍒濆鍖�
+ getRoomByIp()
+ startScrolling()
+
+ // 鍒濆鍖栬闊冲悎鎴�
+ if (speechSynthesis.value) {
+ speechSynthesis.value.onend = onSpeachEndEvent
+ }
+
+ return {
+ roomProfile,
+ checkRelatedPatientList,
+ installRelatedPatientList,
+ curSpeakPat,
+ announcementText,
+ roomId,
+ timer,
+ speechSynthesis,
+ searchRoomInput,
+ screenTypeText,
+ showCheckPanel,
+ showInstallPanel,
+ searchRoom,
+ getRoomByIp,
+ getList,
+ startScrolling,
+ nameDesensitize,
+ getStatusClass,
+ queueStatusConvert,
+ getCheckTypeName,
+ getSeqPrefix,
+ initiateSpeak,
+ speak,
+ onSpeachEndEvent,
+ changeRoom
+ }
+ }
+}
+</script>
+
+<style scoped>
+.room-screen-container {
+ height: 100vh;
display: flex;
- height: 100%;
-}
-
-.left, .right {
- flex: 1;
- border: 1px solid #ccc;
+ flex-direction: column;
+ background: linear-gradient(135deg, #e6f0f8, #d9e4f0);
+ color: #333;
+ line-height: 1.5;
+ overflow: hidden;
padding: 10px;
}
+.search-bar {
+ background: rgba(255, 255, 255, 0.8);
+ border-radius: 16px;
+ padding: 12px 15px;
+ margin-bottom: 10px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ display: flex;
+ align-items: center;
+}
+
+.search-input {
+ flex: 1;
+ border: none;
+ background: rgba(240, 244, 249, 0.7);
+ border-radius: 12px;
+ padding: 8px 12px;
+ font-size: 0.9rem;
+ outline: none;
+ color: #4a5568;
+}
+
+.search-btn {
+ margin-left: 8px;
+ background: #5b8cff;
+ color: white;
+ border: none;
+ border-radius: 12px;
+ padding: 8px 15px;
+ font-size: 0.9rem;
+ cursor: pointer;
+ transition: all 0.3s;
+}
+
+.search-btn:hover {
+ background: #3a7bff;
+}
+
+.header {
+ background: rgba(255, 255, 255, 0.8);
+ border-radius: 16px;
+ padding: 12px 15px;
+ margin-bottom: 10px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.clinic-title {
+ font-size: 1.4rem;
+ font-weight: bold;
+ text-align: center;
+ margin-bottom: 5px;
+ color: #4a7dff;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.clinic-info {
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ font-size: 0.9rem;
+ color: #555;
+}
+
+.room-name {
+ background: rgba(91, 140, 255, 0.1);
+ padding: 4px 10px;
+ border-radius: 20px;
+ min-width: 120px;
+ text-align: center;
+ color: #4a7dff;
+}
+
+.screen-type {
+ background: rgba(91, 140, 255, 0.1);
+ padding: 4px 10px;
+ border-radius: 20px;
+ color: #4a7dff;
+}
+
+.main-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ overflow: hidden;
+}
+
+.panel {
+ background: rgba(255, 255, 255, 0.95);
+ border-radius: 14px;
+ padding: 12px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ flex: 1;
+ border: 1px solid rgba(0, 0, 0, 0.05);
+}
+
+.panel-header {
+ background: linear-gradient(90deg, #a8c4ff, #c0d3ff);
+ color: #2c3e50;
+ padding: 8px 12px;
+ border-radius: 8px;
+ margin-bottom: 10px;
+ font-size: 1rem;
+ font-weight: bold;
+ text-align: center;
+}
+
+.patient-list {
+ flex: 1;
+ overflow-y: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+.patient-item {
+ display: flex;
+ align-items: center;
+ padding: 10px 8px;
+ border-bottom: 1px solid #eee;
+ transition: all 0.3s;
+}
+
+.patient-item:last-child {
+ border-bottom: none;
+}
+
+.patient-item.warning {
+ background-color: #fdf6ec;
+}
+
+.patient-item.in-progress {
+ background-color: #f0f9eb;
+}
+
+.patient-item.completed {
+ background-color: #f4f4f5;
+}
+
+.patient-info {
+ display: flex;
+ flex: 1;
+ min-width: 0;
+}
+
+.patient-number {
+ width: 80px;
+ font-weight: bold;
+ color: #5b8cff;
+ font-size: 0.95rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.patient-name {
+ width: 100px;
+ font-size: 0.95rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.patient-check-type {
+ flex: 1;
+ font-size: 0.95rem;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.patient-status {
+ width: 70px;
+ font-size: 0.8rem;
+ font-weight: bold;
+ text-align: center;
+ padding: 3px 8px;
+ border-radius: 10px;
+}
+
+.status-waiting {
+ background-color: #fdf6ec;
+ color: #e6a23c;
+}
+
+.status-in-progress {
+ background-color: #f0f9eb;
+ color: #67c23a;
+}
+
+.status-completed {
+ background-color: #f4f4f5;
+ color: #909399;
+}
+
+.patient-bed {
+ width: 60px;
+ font-size: 0.85rem;
+ text-align: right;
+ color: #666;
+}
+
+.footer {
+ background: rgba(255, 255, 255, 0.8);
+ border-radius: 16px;
+ padding: 12px 15px;
+ margin-top: 10px;
+ box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
+ border: 1px solid rgba(0, 0, 0, 0.05);
+}
+
+.announcement {
+ background: rgba(91, 140, 255, 0.1);
+ padding: 8px 15px;
+ border-radius: 20px;
+ font-size: 0.9rem;
+ text-align: center;
+ margin-bottom: 12px;
+ min-height: 20px;
+ color: #4a7dff;
+}
+
+.controls {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 8px;
+}
+
+.control-btn {
+ padding: 8px 5px;
+ background: rgba(91, 140, 255, 0.1);
+ border: none;
+ border-radius: 12px;
+ color: #4a7dff;
+ font-size: 0.85rem;
+ cursor: pointer;
+ transition: all 0.3s;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+.control-btn i {
+ font-size: 1.2rem;
+ margin-bottom: 3px;
+}
+
+.control-btn:hover {
+ background: rgba(91, 140, 255, 0.2);
+}
+
+.control-btn:active {
+ transform: scale(0.95);
+}
+
+.empty-state {
+ text-align: center;
+ color: #999;
+ padding: 20px;
+ font-size: 0.9rem;
+}
+
+/* 婊氬姩鏉℃牱寮� */
+.patient-list::-webkit-scrollbar {
+ width: 5px;
+}
+
+.patient-list::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 4px;
+}
+
+.patient-list::-webkit-scrollbar-thumb {
+ background: #c0c4cc;
+ border-radius: 4px;
+}
+
+.patient-list::-webkit-scrollbar-thumb:hover {
+ background: #909399;
+}
+
+/* 鍔ㄧ敾鏁堟灉 */
+@keyframes pulse {
+ 0% {
+ transform: scale(1);
+ }
+
+ 50% {
+ transform: scale(1.05);
+ }
+
+ 100% {
+ transform: scale(1);
+ }
+}
+
+.pulse {
+ animation: pulse 2s infinite;
+}
+
+/* 鍝嶅簲寮忚皟鏁� */
+@media (max-width: 480px) {
+ .header {
+ padding: 10px 12px;
+ }
+
+ .clinic-title {
+ font-size: 1.2rem;
+ }
+
+ .clinic-info {
+ font-size: 0.8rem;
+ }
+
+ .panel {
+ padding: 10px;
+ }
+
+ .panel-header {
+ font-size: 0.9rem;
+ padding: 6px 10px;
+ }
+
+ .patient-item {
+ padding: 8px 6px;
+ }
+
+ .patient-number,
+ .patient-name {
+ width: 60px;
+ font-size: 0.9rem;
+ }
+
+ .patient-status {
+ width: 60px;
+ font-size: 0.7rem;
+ }
+
+ .patient-bed {
+ width: 50px;
+ }
+}
+
+@media (max-height: 600px) {
+ .header {
+ padding: 8px 10px;
+ }
+
+ .panel {
+ padding: 8px;
+ }
+
+ .patient-item {
+ padding: 6px 4px;
+ }
+}
</style>
--
Gitblit v1.9.3