395 lines
15 KiB
HTML
395 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-cn">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>数据概览 | 消毒灭菌在线监测系统</title>
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<link rel="stylesheet" href="/app/admin/component/pear/css/pear.css" />
|
||
<link rel="stylesheet" href="/app/admin/admin/css/reset.css" />
|
||
<style>
|
||
html, body { margin: 0; padding: 0; background: #f2f2f2; }
|
||
.overview-container { padding: 15px; }
|
||
|
||
/* 统计卡片 */
|
||
.stat-card {
|
||
text-align: center;
|
||
padding: 15px 10px;
|
||
background: #fff;
|
||
border-radius: 6px;
|
||
}
|
||
.stat-card .num {
|
||
font-size: 28px;
|
||
font-weight: 700;
|
||
color: #333;
|
||
margin-bottom: 5px;
|
||
}
|
||
.stat-card .label {
|
||
font-size: 13px;
|
||
color: #999;
|
||
}
|
||
|
||
/* 设备状态条 */
|
||
.device-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 10px 12px;
|
||
border: 1px solid #eee;
|
||
border-radius: 8px;
|
||
margin-bottom: 8px;
|
||
}
|
||
.device-item .info p { margin: 2px 0; font-size: 13px; }
|
||
.device-item .status-tag {
|
||
display: inline-block;
|
||
padding: 4px 14px;
|
||
border-radius: 15px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
border: 2px solid #5663D2;
|
||
color: #5663D2;
|
||
}
|
||
|
||
/* 预警设备列表 */
|
||
.warn-device-item {
|
||
padding: 8px 10px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
.warn-device-item p { margin: 2px 0; font-size: 13px; }
|
||
|
||
/* 事件块 */
|
||
.event-block {
|
||
text-align: center;
|
||
background: #f7f7f7;
|
||
border-radius: 8px;
|
||
padding: 15px 0;
|
||
}
|
||
.event-block .num { font-size: 32px; font-weight: 700; }
|
||
.event-block .label { font-size: 13px; color: #999; margin-top: 5px; }
|
||
|
||
/* 时间切换 */
|
||
.time-switch a {
|
||
cursor: pointer;
|
||
padding: 2px 10px;
|
||
font-size: 13px;
|
||
color: #666;
|
||
}
|
||
.time-switch a.active { color: #5663D2; font-weight: 700; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="overview-container">
|
||
<div class="layui-row layui-col-space15">
|
||
|
||
<!-- ========== 左侧列 ========== -->
|
||
<div class="layui-col-md3">
|
||
<!-- 消毒灭菌概况 -->
|
||
<div class="layui-card">
|
||
<div class="layui-card-header">消毒灭菌概况</div>
|
||
<div class="layui-card-body">
|
||
<div class="layui-row layui-col-space10">
|
||
<div class="layui-col-xs6">
|
||
<div class="stat-card">
|
||
<div class="num" id="todayCount">-</div>
|
||
<div class="label">今日次数</div>
|
||
</div>
|
||
</div>
|
||
<div class="layui-col-xs6">
|
||
<div class="stat-card">
|
||
<div class="num" id="weekCount">-</div>
|
||
<div class="label">本周次数</div>
|
||
</div>
|
||
</div>
|
||
<div class="layui-col-xs6">
|
||
<div class="stat-card">
|
||
<div class="num" id="monthCount">-</div>
|
||
<div class="label">本月次数</div>
|
||
</div>
|
||
</div>
|
||
<div class="layui-col-xs6">
|
||
<div class="stat-card">
|
||
<div class="num" id="yearCount">-</div>
|
||
<div class="label">本年次数</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 消毒灭菌锅概况 -->
|
||
<div class="layui-card">
|
||
<div class="layui-card-header">消毒灭菌锅概况</div>
|
||
<div class="layui-card-body" id="deviceList">
|
||
<div style="color:#999;text-align:center;padding:20px;">加载中...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ========== 中间列 ========== -->
|
||
<div class="layui-col-md6">
|
||
<!-- 消毒灭菌统计 -->
|
||
<div class="layui-card">
|
||
<div class="layui-card-header">
|
||
消毒灭菌统计
|
||
<span class="time-switch" style="float:right;">
|
||
<a class="active" data-time="week">7日</a>
|
||
<a data-time="month">30日</a>
|
||
<a data-time="year">本年</a>
|
||
</span>
|
||
</div>
|
||
<div class="layui-card-body">
|
||
<div id="lineChart" style="height:350px;"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 事件数据 -->
|
||
<div class="layui-card">
|
||
<div class="layui-card-header">事件数据</div>
|
||
<div class="layui-card-body">
|
||
<div class="layui-row layui-col-space15">
|
||
<div class="layui-col-xs6">
|
||
<div class="event-block">
|
||
<div class="num" id="noStandard">0</div>
|
||
<div class="label">灭菌不达标</div>
|
||
</div>
|
||
</div>
|
||
<div class="layui-col-xs6">
|
||
<div class="event-block">
|
||
<div class="num" id="LowFrequency">0</div>
|
||
<div class="label">灭菌频率低</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ========== 右侧列 ========== -->
|
||
<div class="layui-col-md3">
|
||
<!-- 预警概览 -->
|
||
<div class="layui-card">
|
||
<div class="layui-card-header">预警概览</div>
|
||
<div class="layui-card-body">
|
||
<div class="layui-row layui-col-space10">
|
||
<div class="layui-col-xs6">
|
||
<div class="stat-card">
|
||
<div class="num" id="warnCount">-</div>
|
||
<div class="label">预警次数</div>
|
||
</div>
|
||
</div>
|
||
<div class="layui-col-xs6">
|
||
<div class="stat-card">
|
||
<div class="num" id="warnDealCount">-</div>
|
||
<div class="label">处理次数</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 预警分布 -->
|
||
<div class="layui-card">
|
||
<div class="layui-card-header">预警分布</div>
|
||
<div class="layui-card-body">
|
||
<div id="donutChart" style="height:230px;"></div>
|
||
<div class="layui-row" style="text-align:center;margin-top:10px;">
|
||
<div class="layui-col-xs4">
|
||
<div style="color:#5664d2;">● 温度预警</div>
|
||
<div id="tempPercent">0 %</div>
|
||
</div>
|
||
<div class="layui-col-xs4">
|
||
<div style="color:#1cbb8c;">● 压力预警</div>
|
||
<div id="pressurePercent">0 %</div>
|
||
</div>
|
||
<div class="layui-col-xs4">
|
||
<div style="color:#eeb902;">● 时间预警</div>
|
||
<div id="timePercent">0 %</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 预警设备 -->
|
||
<div class="layui-card">
|
||
<div class="layui-card-header">预警设备</div>
|
||
<div class="layui-card-body" id="warnDeviceList">
|
||
<div style="color:#999;text-align:center;padding:20px;">加载中...</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 依赖脚本 -->
|
||
<script src="/app/admin/component/layui/layui.js"></script>
|
||
<script src="/app/admin/component/pear/pear.js"></script>
|
||
<!-- ApexCharts -->
|
||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||
|
||
<script>
|
||
layui.use(['jquery'], function(){
|
||
var $ = layui.jquery;
|
||
|
||
var API_BASE = '/app/admin/data-overview';
|
||
var lineChartInstance = null;
|
||
var donutChartInstance = null;
|
||
|
||
// ========== 加载所有数据 ==========
|
||
function loadAll() {
|
||
loadIndexCount();
|
||
loadIndexRunStatus();
|
||
loadIndexLine('week');
|
||
loadIndexWarnCount();
|
||
loadIndexWarnTypePie();
|
||
loadIndexWarnTypePieInfo();
|
||
loadIndexWarnDeviceList();
|
||
loadIndexEvent();
|
||
}
|
||
|
||
// ========== 消毒灭菌概况 ==========
|
||
function loadIndexCount() {
|
||
$.get(API_BASE + '/getIndexCount', function(res){
|
||
if (res.code === 0) {
|
||
$('#todayCount').text(res.data.todayCount);
|
||
$('#weekCount').text(res.data.weekCount);
|
||
$('#monthCount').text(res.data.monthCount);
|
||
$('#yearCount').text(res.data.yearCount);
|
||
}
|
||
});
|
||
}
|
||
|
||
// ========== 设备运行状态 ==========
|
||
function loadIndexRunStatus() {
|
||
$.get(API_BASE + '/getIndexRunStatus', function(res){
|
||
if (res.code === 0 && res.data.length) {
|
||
var html = '';
|
||
$.each(res.data, function(i, item){
|
||
html += '<div class="device-item">' +
|
||
'<div class="info"><p style="color:#999;">' + (item.description || '') + '</p>' +
|
||
'<p style="font-weight:600;">' + item.name + '</p></div>' +
|
||
'<span class="status-tag">' + item.status + '</span></div>';
|
||
});
|
||
$('#deviceList').html(html);
|
||
} else {
|
||
$('#deviceList').html('<div style="color:#999;text-align:center;padding:20px;">暂无设备</div>');
|
||
}
|
||
});
|
||
}
|
||
|
||
// ========== 消毒灭菌统计图表 ==========
|
||
function loadIndexLine(parameterTime) {
|
||
$.get(API_BASE + '/getIndexLine', { parameter_time: parameterTime }, function(res){
|
||
if (res.code !== 0) return;
|
||
|
||
var options = {
|
||
chart: { height: 350, type: 'bar', toolbar: { show: false } },
|
||
plotOptions: { bar: { horizontal: false, columnWidth: '45%', endingShape: 'rounded' } },
|
||
dataLabels: { enabled: false },
|
||
stroke: { show: true, width: 2, colors: ['transparent'] },
|
||
series: [
|
||
{ name: '灭菌次数', data: res.data.count },
|
||
{ name: '合格灭菌次数', data: res.data.qualifiedCount }
|
||
],
|
||
colors: ['#5664d2', '#1cbb8c'],
|
||
xaxis: { categories: res.data.time },
|
||
grid: { borderColor: '#f1f1f1', padding: { bottom: 10 } },
|
||
fill: { opacity: 1 },
|
||
tooltip: { y: { formatter: function(e) { return e; } } },
|
||
legend: { offsetY: 7 }
|
||
};
|
||
|
||
if (lineChartInstance) {
|
||
lineChartInstance.destroy();
|
||
}
|
||
lineChartInstance = new ApexCharts(document.querySelector('#lineChart'), options);
|
||
lineChartInstance.render();
|
||
});
|
||
}
|
||
|
||
// ========== 预警概览 ==========
|
||
function loadIndexWarnCount() {
|
||
$.get(API_BASE + '/getIndexWarnCount', function(res){
|
||
if (res.code === 0) {
|
||
$('#warnCount').text(res.data.warnCount);
|
||
$('#warnDealCount').text(res.data.warnDealCount);
|
||
}
|
||
});
|
||
}
|
||
|
||
// ========== 预警分布饼图 ==========
|
||
function loadIndexWarnTypePie() {
|
||
$.get(API_BASE + '/getIndexWarnTypePie', function(res){
|
||
if (res.code !== 0) return;
|
||
|
||
var options = {
|
||
series: res.data,
|
||
chart: { height: 230, type: 'donut' },
|
||
labels: ['温度预警', '压力预警', '时间预警'],
|
||
plotOptions: { pie: { donut: { size: '75%' } } },
|
||
legend: { show: false },
|
||
colors: ['#5664d2', '#1cbb8c', '#eeb902']
|
||
};
|
||
|
||
if (donutChartInstance) {
|
||
donutChartInstance.destroy();
|
||
}
|
||
donutChartInstance = new ApexCharts(document.querySelector('#donutChart'), options);
|
||
donutChartInstance.render();
|
||
});
|
||
}
|
||
|
||
// ========== 预警百分比 ==========
|
||
function loadIndexWarnTypePieInfo() {
|
||
$.get(API_BASE + '/getIndexWarnTypePieInfo', function(res){
|
||
if (res.code === 0) {
|
||
$('#tempPercent').text(res.data.temperature + ' %');
|
||
$('#pressurePercent').text(res.data.pressure + ' %');
|
||
$('#timePercent').text(res.data.time + ' %');
|
||
}
|
||
});
|
||
}
|
||
|
||
// ========== 预警设备列表 ==========
|
||
function loadIndexWarnDeviceList() {
|
||
$.get(API_BASE + '/getIndexWarnDeviceList', function(res){
|
||
if (res.code === 0 && res.data && res.data !== false) {
|
||
var html = '';
|
||
$.each(res.data, function(i, item){
|
||
html += '<div class="warn-device-item">' +
|
||
'<p style="font-weight:600;">' + item.hospital + ' ' + item.name + '</p>' +
|
||
'<p style="color:#999;">' + item.type + '(' + item.level + ') ' + item.notification_time + '</p>' +
|
||
'</div>';
|
||
});
|
||
$('#warnDeviceList').html(html);
|
||
} else {
|
||
$('#warnDeviceList').html('<div style="color:red;text-align:center;padding:20px;">暂无预警数据</div>');
|
||
}
|
||
});
|
||
}
|
||
|
||
// ========== 事件数据 ==========
|
||
function loadIndexEvent() {
|
||
$.get(API_BASE + '/getIndexEvent', function(res){
|
||
if (res.code === 0) {
|
||
$('#noStandard').text(res.data.noStandard);
|
||
$('#LowFrequency').text(res.data.LowFrequency);
|
||
}
|
||
});
|
||
}
|
||
|
||
// ========== 时间切换事件 ==========
|
||
$(document).on('click', '.time-switch a', function(){
|
||
$('.time-switch a').removeClass('active');
|
||
$(this).addClass('active');
|
||
loadIndexLine($(this).data('time'));
|
||
});
|
||
|
||
// ========== 启动 ==========
|
||
loadAll();
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|