TVscreen/TAT/index-1.html
2026-09-18 15:38:25 +08:00

388 lines
14 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAT监控大屏</title>
<script src="./js/vue.global.prod.js"></script>
<link rel="stylesheet" href="./css/element-plus.css">
<script src="./js/element-plus.js"></script>
<script src="./js/axios.min.js"></script>
<script src="./js/dayjs.min.js"></script>
<!-- 自定义样式 -->
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div id="app">
<div class="screen-container">
<!-- 顶部标题 + 右侧动态时间 -->
<div class="screen-header">
<div class="screen-title">TAT监控大屏</div>
<div class="screen-time">{{ nowTime }}</div>
</div>
<div class="grid-wrapper">
<div class="card">
<div class="card-header">
<span>已采集待收标本</span>
<span class="red-text">
共 {{list1.length}}个标本
</span>
</div>
<div class="table-box">
<el-table :data="list1" border stripe class="table" height="35vh" ref="table1Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="ksdh" label="科室"></el-table-column>
<el-table-column label="姓名/条码">
<template #default="{ row }">
<span>{{ row.brxm }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目">
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="cysj" label="采样时间"></el-table-column>
<el-table-column label="等待时间">
<template #default="{ row }">
<span class="red-text">{{ row.holdtime }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<div class="card">
<div class="card-header">
<span>已核收还未上机标本</span>
<span class="red-text">
共 {{list2.length}}个标本
</span>
</div>
<div class="table-box">
<el-table :data="list2" border stripe class="table" height="35vh" ref="table2Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="ksdh" label="科室"></el-table-column>
<el-table-column label="姓名/条码">
<template #default="{ row }">
<span>{{ row.brxm }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目">
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="jssj" label="签收时间"></el-table-column>
<el-table-column label="等待时间">
<template #default="{ row }">
<span class="red-text">{{ row.holdtime }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<div class="card">
<div class="card-header">
<span>标本完成效率TAT</span>
</div>
<div class="table-box">
<el-table :data="list3" border stripe class="table" height="35vh" ref="table3Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="yq" label="仪器"></el-table-column>
<el-table-column label="样本号/条码号">
<template #default="{ row }">
<span>{{ row.ybh }} / {{ row.sqh }}</span>
</template>
</el-table-column>
<el-table-column label="标本/项目">
<template #default="{ row }">
<span>{{ row.yblx }} / {{ row.jymd }}</span>
</template>
</el-table-column>
<el-table-column prop="sjsj" label="上机时间"></el-table-column>
<el-table-column label="等待时间">
<template #default="{ row }">
<span class="red-text">{{ row.holdtime }} 分钟</span>
</template>
</el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
<div class="card">
<div class="card-header red-title">危急值结果:(请工作人员及时处理!)</div>
<div class="table-box">
<el-table :data="list4" border stripe class="table" height="35vh" ref="table4Ref"
:header-cell-style="tableHeaderStyle" :cell-style="tableCellStyle" :row-style="tableRowStyle">
<el-table-column prop="yq" label="仪器"></el-table-column>
<el-table-column prop="ybh" label="样本号"></el-table-column>
<el-table-column prop="xmmc" label="项目"></el-table-column>
<el-table-column prop="csjg" label="结果"></el-table-column>
<el-table-column prop="confirm" label="确认超时"></el-table-column>
</el-table>
</div>
<span class="border_bg_leftTop"></span>
<span class="border_bg_rightTop"></span>
<span class="border_bg_leftBottom"></span>
<span class="border_bg_rightBottom"></span>
</div>
</div>
</div>
</div>
<script>
const { createApp, ref, onMounted, onUnmounted, nextTick } = Vue;
const app = createApp({
components: {
...ElementPlus.components
},
setup() {
// 创建axios实例
const request = axios.create({
baseURL: '',
timeout: 5000 // 请求超时时间
})
// 表格数据
const list1 = ref([]);
const list2 = ref([]);
const list3 = ref([]);
const list4 = ref([]);
// 表格样式配置
const tableHeaderStyle = {
background: 'rgba(30, 104, 195, 1)',
color: '#ffffff',
fontSize: '16px',
fontWeight: 'bold',
borderColor: '#0099ff',
padding: '4px 0px'
}
const tableCellStyle = {
background: 'transparent',
color: '#ffffff',
fontSize: '15px',
borderColor: '#0099ff',
padding: '2px 0px'
}
const tableRowStyle = ({ rowIndex }) => {
return {
background: rowIndex % 2 === 0 ? 'transparent' : 'rgba(0, 153, 255, 0.1)',
hover: 'rgba(0, 153, 255, 0.2)'
}
}
// 表格引用
const table1Ref = ref()
const table2Ref = ref()
const table3Ref = ref()
const table4Ref = ref()
// 定义各表格对应的接口地址
const tableApiMap = {
list1: '/api/list1',
list2: '/api/list2',
list3: '/api/list3',
list4: '/api/list4'
};
// 配置
const SCROLL_INTERVAL = 100; // 滚动速度
const SCROLL_PAUSE = 5000; // 到底停顿时间
const NO_SCROLL_REFRESH = 5000; // 无滚动自动刷新
const TOP_PAUSE = 3000; // 回到顶部后停顿时间
// 锁:防止重复触发
const locked = ref({
list1: false,
list2: false,
list3: false,
list4: false
});
const getScrollWrapper = (tableRef) => {
if (!tableRef.value) return null;
const bodyWrapper = tableRef.value.layout.table.refs.bodyWrapper;
return bodyWrapper?.firstElementChild?.firstElementChild || null;
};
// 获取单个表格数据
const fetchTableData = async (listKey) => {
try {
const response = await request.get(tableApiMap[listKey]);
// 根据列表key更新对应数据
if (listKey === 'list1') {
list1.value = response.data.data || [];
} else if (listKey === 'list2') {
list2.value = response.data.data || [];
} else if (listKey === 'list3') {
list3.value = response.data.data || [];
} else if (listKey === 'list4') {
list4.value = response.data.data || [];
}
console.log(`成功获取${listKey}数据`, response.data);
} catch (error) {
console.error(`获取${listKey}数据失败`, error);
}
};
// 封装滚动函数,接收表格ref、数据列表key、数据列表
const createTableScroll = (tableRef, listKey) => {
let scrollTimer = null;
let refreshTimer = null;
const clear = () => {
clearInterval(scrollTimer);
clearInterval(refreshTimer);
scrollTimer = null;
refreshTimer = null;
};
const start = () => {
clear();
// 定时检查:是否需要滚动
const checkAndScroll = () => {
const wrapper = getScrollWrapper(tableRef);
if (!wrapper) return;
// 内容没有溢出 → 只刷新,不滚动
if (wrapper.scrollHeight <= wrapper.clientHeight) {
return;
}
// 锁定中 → 不滚动
if (locked.value[listKey]) return;
// 正常滚动
wrapper.scrollTop += 1;
// 判断到底
const isBottom = wrapper.scrollTop + wrapper.clientHeight >= wrapper.scrollHeight - 2;
if (isBottom) {
locked.value[listKey] = true;
clearInterval(scrollTimer);
// 停顿后刷新 + 重置
setTimeout(async () => {
await fetchTableData(listKey);
await nextTick(); // 等待DOM更新
const newWrapper = getScrollWrapper(tableRef);
if (newWrapper) newWrapper.scrollTop = 0;
// 新增:回到顶部后停顿3秒再解锁并重启滚动
setTimeout(() => {
locked.value[listKey] = false;
start(); // 重新启动滚动
}, TOP_PAUSE);
}, SCROLL_PAUSE);
}
};
// 启动滚动定时器
scrollTimer = setInterval(checkAndScroll, SCROLL_INTERVAL);
// 无滚动时定时刷新
refreshTimer = setInterval(async () => {
const wrapper = getScrollWrapper(tableRef);
if (wrapper && wrapper.scrollHeight <= wrapper.clientHeight) {
await fetchTableData(listKey);
}
}, NO_SCROLL_REFRESH);
};
return { start, clear };
};
// 初始化所有表格数据
const initAllTableData = async () => {
await Promise.all([
fetchTableData('list1'),
fetchTableData('list2'),
fetchTableData('list3'),
fetchTableData('list4')
]);
};
// 每个表格独立实例化滚动
const table1Scroll = createTableScroll(table1Ref, 'list1');
const table2Scroll = createTableScroll(table2Ref, 'list2');
const table3Scroll = createTableScroll(table3Ref, 'list3');
const table4Scroll = createTableScroll(table4Ref, 'list4');
// 动态时间
const nowTime = ref('');
const updateTime = () => {
nowTime.value = dayjs().format('YYYY年MM月DD日 HH:mm:ss');
};
let timeTimer = null;
onMounted(async () => {
// 更新时间
updateTime();
timeTimer = setInterval(updateTime, 1000);
// 初始化加载所有表格数据
await initAllTableData();
// 等待DOM渲染完成后启动表格滚动/刷新
await nextTick();
table1Scroll.start();
table2Scroll.start();
table3Scroll.start();
table4Scroll.start();
});
onUnmounted(() => {
// 清理所有定时器
clearInterval(timeTimer);
table1Scroll.clear();
table2Scroll.clear();
table3Scroll.clear();
table4Scroll.clear();
});
return {
list1,
list2,
list3,
list4,
table1Ref,
table2Ref,
table3Ref,
table4Ref,
nowTime,
tableHeaderStyle,
tableCellStyle,
tableRowStyle
};
}
});
// 注册Element Plus
app.use(ElementPlus);
app.mount('#app');
</script>
</body>
</html>