Files
zimoyin 13fd9c5f0a init
2026-04-06 20:48:32 +08:00

333 lines
17 KiB
HTML

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>设备情况管理</title>
<link rel="stylesheet" href="/app/admin/component/pear/css/pear.css" />
<link rel="stylesheet" href="/app/admin/admin/css/reset.css" />
<style>
/* 设备按钮组 */
.device-btn-group { padding: 12px 15px; display: flex; flex-wrap: wrap; gap: 8px; }
.dev-btn {
display: inline-block; padding: 6px 18px; border-radius: 4px; cursor: pointer;
font-size: 13px; color: #fff; background: #1E9FFF; border: none; transition: all .2s;
}
.dev-btn:hover { background: #0d8de6; }
.dev-btn.active { background: #FF5722; box-shadow: 0 2px 8px rgba(255,87,34,.3); }
/* 信息卡片 */
.info-card { border-radius: 6px; overflow: hidden; margin-bottom: 15px; box-shadow: 0 1px 6px rgba(0,0,0,.08); border: none; }
.info-card .card-header {
background: linear-gradient(135deg, #1E9FFF 0%, #4db8ff 100%);
padding: 12px 16px; color: #fff;
}
.info-card .card-header h3 { margin: 0; font-size: 15px; font-weight: 600; color: #fff; }
.info-card .card-header .desc { font-size: 12px; color: rgba(255,255,255,.8); margin-bottom: 4px; }
.info-card .card-body { padding: 18px 16px; background: #fff; }
/* 消毒情况卡 - 绿色 */
.info-card.card-green .card-header { background: linear-gradient(135deg, #4CAF50 0%, #66BB6A 100%); }
/* 报警情况卡 - 橙色 */
.info-card.card-orange .card-header { background: linear-gradient(135deg, #FF9800 0%, #FFB74D 100%); }
/* 统计数字 */
.stat-item { text-align: center; display: inline-block; min-width: 80px; }
.stat-item .stat-num { font-size: 30px; font-weight: 700; margin: 4px 0; }
.stat-item .stat-num.blue { color: #1E9FFF; }
.stat-item .stat-num.green { color: #4CAF50; }
.stat-item .stat-num.red { color: #FF5722; }
.stat-item .stat-num.orange { color: #FF9800; }
.stat-item .stat-label { font-size: 12px; color: #888; }
.warn-stats { display: flex; justify-content: space-around; }
/* 图表 & 表格区域 */
.chart-area { min-height: 400px; }
.run-table-area { max-height: 400px; overflow-y: auto; }
.run-table-area table { width: 100%; border-collapse: collapse; }
.run-table-area th, .run-table-area td { padding: 6px 8px; text-align: center; font-size: 13px; border: 1px solid #eee; }
.run-table-area thead { background: #f8f8f8; position: sticky; top: 0; z-index: 1; }
.run-table-area thead th { font-weight: 600; color: #333; }
/* 操作记录区域 */
.record-header { display: flex; align-items: center; justify-content: space-between; }
.record-header .title { font-size: 16px; font-weight: 600; }
</style>
</head>
<body class="pear-container">
<!-- 设备按钮列表 -->
<div class="layui-card">
<div class="layui-card-body device-btn-group" id="deviceBtnGroup">
<span style="color:#999;">加载中...</span>
</div>
</div>
<!-- 三张信息卡片 -->
<div class="layui-row layui-col-space15">
<!-- 设备基本信息 -->
<div class="layui-col-md4">
<div class="info-card">
<div class="card-header">
<div class="desc" id="deviceDesc"></div>
<h3 id="deviceName">-</h3>
</div>
<div class="card-body">
<div style="margin-bottom:8px;">品牌:<strong id="deviceManufacturer">-</strong></div>
<div style="margin-bottom:8px;">医院:<strong id="deviceHospital">-</strong></div>
<div>科室:<strong id="deviceDepartment">-</strong></div>
</div>
</div>
</div>
<!-- 消毒情况 -->
<div class="layui-col-md4">
<div class="info-card card-green">
<div class="card-header"><h3>消毒情况</h3></div>
<div class="card-body" style="display:flex; justify-content:space-around;">
<div class="stat-item">
<div class="stat-num blue" id="totalCount">0</div>
<div class="stat-label">共计消毒次数</div>
</div>
<div class="stat-item">
<div class="stat-num green" id="complianceCount">0</div>
<div class="stat-label">合规次数</div>
</div>
</div>
</div>
</div>
<!-- 报警情况 -->
<div class="layui-col-md4">
<div class="info-card card-orange">
<div class="card-header"><h3>报警情况</h3></div>
<div class="card-body warn-stats">
<div class="stat-item">
<div class="stat-num red" id="totalWarnCount">0</div>
<div class="stat-label">共计次数</div>
</div>
<div class="stat-item">
<div class="stat-num orange" id="tempWarnCount">0</div>
<div class="stat-label">温度报警</div>
</div>
<div class="stat-item">
<div class="stat-num orange" id="pressureWarnCount">0</div>
<div class="stat-label">压力报警</div>
</div>
<div class="stat-item">
<div class="stat-num orange" id="timeWarnCount">0</div>
<div class="stat-label">时间报警</div>
</div>
</div>
</div>
</div>
</div>
<!-- 实时监测图表 + 运行数据表 -->
<div class="layui-row layui-col-space15">
<div class="layui-col-md8">
<div class="layui-card">
<div class="layui-card-header">实时监测</div>
<div class="layui-card-body">
<div id="chartContainer" class="chart-area"></div>
</div>
</div>
</div>
<div class="layui-col-md4">
<div class="layui-card">
<div class="layui-card-header">周期运行数据</div>
<div class="layui-card-body run-table-area">
<table>
<thead><tr><th>时间</th><th>温度</th><th>压力</th></tr></thead>
<tbody id="runTableBody"><tr><td colspan="3">暂无数据</td></tr></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 操作记录 -->
<div class="layui-card">
<div class="layui-card-header">
<div class="record-header">
<span class="title">操作记录</span>
</div>
</div>
<div class="layui-card-body">
<table id="cycleTable" lay-filter="cycleTable"></table>
</div>
</div>
<script src="/app/admin/component/layui/layui.js?v=2.8.12"></script>
<script src="/app/admin/component/pear/pear.js"></script>
<script src="/app/admin/admin/js/permission.js"></script>
<script src="/app/admin/admin/js/common.js"></script>
<script>
const BASE_URL = "/app/admin/device-status";
layui.use(["table", "echarts"], function() {
let table = layui.table, $ = layui.$, echarts = layui.echarts;
let currentDeviceId = '';
let myChart = echarts.init(document.getElementById('chartContainer'));
// 加载设备按钮列表
function loadDeviceButtons() {
$.getJSON(BASE_URL + "/get-device-name-list", function(res) {
if (res.code !== 0 || !res.data || res.data.length === 0) {
$("#deviceBtnGroup").html('<span style="color:#999;">暂无设备</span>');
return;
}
let html = '';
res.data.forEach(function(item, idx) {
let cls = idx === 0 ? 'dev-btn active' : 'dev-btn';
html += '<button class="' + cls + '" data-device-id="' + item.id + '">' + item.name + '</button>';
});
$("#deviceBtnGroup").html(html);
// 默认加载第一个设备数据
currentDeviceId = res.data[0].id;
loadAllData(currentDeviceId);
});
}
// 按钮点击事件(事件委托,确保动态按钮可靠绑定)
$("#deviceBtnGroup").on("click", ".dev-btn", function() {
let id = $(this).attr("data-device-id");
if (id == currentDeviceId) return; // 同一设备不重复请求
currentDeviceId = id;
$("#deviceBtnGroup .dev-btn").removeClass("active");
$(this).addClass("active");
loadAllData(id);
});
// 加载全部数据
function loadAllData(deviceId) {
loadBasicInfo(deviceId);
loadRunInfo(deviceId);
loadWarnInfo(deviceId);
loadCycleRunLine(deviceId);
loadCycleRunList(deviceId);
loadCycleInfo(deviceId);
}
// 设备基本信息
function loadBasicInfo(deviceId) {
$.getJSON(BASE_URL + "/get-device-basic-info", {id: deviceId}, function(res) {
if (res.code === 0 && res.data) {
let d = res.data;
$("#deviceName").text(d.name || '-');
$("#deviceDesc").text(d.description || '');
$("#deviceManufacturer").text(d.manufacturer || '-');
$("#deviceHospital").text(d.hospital || '-');
$("#deviceDepartment").text(d.department || '-');
}
});
}
// 消毒情况
function loadRunInfo(deviceId) {
$.getJSON(BASE_URL + "/get-device-run-info", {id: deviceId}, function(res) {
if (res.code === 0 && res.data) {
$("#totalCount").text(res.data.totalCount || 0);
$("#complianceCount").text(res.data.ComplianceCount || 0);
}
});
}
// 报警情况
function loadWarnInfo(deviceId) {
$.getJSON(BASE_URL + "/get-device-warn-info", {id: deviceId}, function(res) {
if (res.code === 0 && res.data) {
$("#totalWarnCount").text(res.data.totalWarnCount || 0);
$("#tempWarnCount").text(res.data.totalTemperatureWarnCount || 0);
$("#pressureWarnCount").text(res.data.totalPressureWarnCount || 0);
$("#timeWarnCount").text(res.data.totalTimeWarnCount || 0);
}
});
}
// 实时监测折线图
function loadCycleRunLine(deviceId) {
$.getJSON(BASE_URL + "/get-device-cycle-run-line", {id: deviceId}, function(res) {
if (res.code === 0 && res.data && res.data.time && res.data.time.length > 0) {
let option = {
tooltip: { trigger: 'axis' },
legend: { data: ['温度(℃)', '压力(kpa)'] },
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: { type: 'category', data: res.data.time, axisLabel: { rotate: 30, fontSize: 10 } },
yAxis: [
{ type: 'value', name: '温度(℃)' },
{ type: 'value', name: '压力(kpa)' }
],
series: [
{ name: '温度(℃)', type: 'line', smooth: true, data: res.data.temperature, itemStyle: { color: '#FF5722' } },
{ name: '压力(kpa)', type: 'bar', yAxisIndex: 1, data: res.data.pressure, itemStyle: { color: '#1E9FFF' }, barWidth: '30%', opacity: 0.6 }
]
};
myChart.setOption(option, true);
} else {
myChart.clear();
myChart.setOption({
title: { text: '暂无数据', left: 'center', top: 'center', textStyle: { color: '#999', fontSize: 16 } }
});
}
});
}
// 周期运行列表(右侧小表格)
function loadCycleRunList(deviceId) {
$.getJSON(BASE_URL + "/get-device-cycle-run-list", {id: deviceId}, function(res) {
if (res.code === 0 && res.data && res.data.length > 0) {
let html = '';
res.data.forEach(function(item) {
html += '<tr><td>' + item.sensor_time + '</td><td>' + item.temperature + '℃</td><td>' + item.pressure + 'kpa</td></tr>';
});
$("#runTableBody").html(html);
} else {
$("#runTableBody").html('<tr><td colspan="3">暂无数据</td></tr>');
}
});
}
// 操作记录表格
function loadCycleInfo(deviceId) {
$.getJSON(BASE_URL + "/get-device-all-cycle-info", {id: deviceId}, function(res) {
if (res.code === 0 && res.data) {
table.render({
elem: "#cycleTable",
data: res.data,
page: true,
limit: 10,
cols: [[
{ title: "序号", type: "numbers", align: "center", width: 60 },
{ title: "操作人员", field: "operation", align: "center", minWidth: 100 },
{ title: "消毒灭菌器名称", field: "name", align: "center", minWidth: 150 },
{ title: "操作日期", field: "created_at", align: "center", width: 170 },
{ title: "灭菌开始时间", field: "start_time", align: "center", width: 170 },
{ title: "灭菌批次", field: "pack", align: "center", width: 120 },
{
title: "状态", field: "is_warn", align: "center", width: 90,
templet: function(d) {
if (d.is_warn === '正常') return '<span class="layui-badge" style="background:#4CAF50;padding:3px 10px;">正常</span>';
return '<span class="layui-badge" style="background:#FF5722;padding:3px 10px;">预警</span>';
}
}
]],
skin: "line",
size: "lg"
});
}
});
}
// 窗口resize时重绘图表
$(window).on("resize", function() {
if (myChart) myChart.resize();
});
// 初始化
loadDeviceButtons();
});
</script>
</body>
</html>