- 🐍 添加所有 Python 源码文件(*.py) - 📄 添加所有 HTML 模板文件(templates/) - 🗂️ 添加控制器、模型、测试等目录结构 - 📋 添加文档文件(*.md)和配置文件 - ⚙️ 更新 .gitignore 配置,只忽略日志和 SQL 文件 - 🚀 确保所有重要代码都被 Git 跟踪和版本控制 根据要求:ljwx-bigscreen/bigscreen/bigScreen 里面除了 log 和 sql 都需要提交
1527 lines
64 KiB
HTML
1527 lines
64 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head lang="en">
|
|
<meta charset="utf-8">
|
|
|
|
<title>智能穿戴管理演示大屏</title>
|
|
|
|
|
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/personal-index.css') }}">
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/profile-button.css') }}">
|
|
<style type="text/css">
|
|
.profile-button a {
|
|
color: #28a745; /* 链接文字为绿色 */
|
|
text-decoration: none;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.profile-button a:hover {
|
|
color: #1e7e34; /* 鼠标悬停时,文字变深绿 */
|
|
}
|
|
|
|
/*resize*/
|
|
.breathe-zct{ position:relative; width:20px; height:20px; top:2px;float:left; border:1px solid #008000; border-radius:20px; color:#fff; font-size:10px; cursor:pointer; box-shadow:0 1px 2px rgba(0,0,0,.3); overflow:hidden;
|
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#00FF00), to(#00FF00));
|
|
background-image: -moz-linear-gradient(#00FF00,#00FF00);
|
|
}
|
|
|
|
.breathe-yct{ position:relative; width:20px; height:20px; top:2px;float:left; border:1px solid #008000; border-radius:20px; color:#fff; font-size:20px; cursor:pointer; box-shadow:0 1px 2px rgba(0,0,0,.3); overflow:hidden;
|
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#FF0000), to(#FF0000));
|
|
background-image: -moz-linear-gradient(#FF0000,#FF0000);
|
|
}
|
|
|
|
.breathe-zc{ position:relative; width:20px; height:20px; margin:10px auto; line-height:40px; border:1px solid #008000; border-radius:10px; color:#fff; font-size:20px; text-align:center; cursor:pointer; box-shadow:0 1px 2px rgba(0,0,0,.3); overflow:hidden;
|
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#00FF00), to(#00FF00));
|
|
background-image: -moz-linear-gradient(#00FF00,#00FF00);
|
|
-webkit-animation-timing-function: ease-in-out;
|
|
-webkit-animation-name: breathe;
|
|
-webkit-animation-duration: 500ms;
|
|
-webkit-animation-iteration-count: infinite;
|
|
-webkit-animation-direction: alternate;
|
|
animation:ease-in-out breathe 500ms infinite alternate;
|
|
}
|
|
@keyframes breathe{
|
|
0% { opacity: .2; box-shadow:0 1px 2px rgba(255,255,255,0.1);}
|
|
100% { opacity: 1; border:1px solid rgba(59,235,235,1); box-shadow:0 1px 30px rgba(59,255,255,1);}
|
|
}
|
|
@-webkit-keyframes breathe {
|
|
0% { opacity: .2; box-shadow:0 1px 2px rgba(255,255,255,0.1);}
|
|
100% { opacity: 1; border:1px solid rgba(59,235,235,1); box-shadow:0 1px 30px rgba(59,255,255,1);}
|
|
}
|
|
|
|
.breathe-yc{ position:relative; width:20px; height:20px; margin:10px auto; line-height:40px; border:1px solid #008000; border-radius:10px; color:#fff; font-size:20px; text-align:center; cursor:pointer; box-shadow:0 1px 2px rgba(0,0,0,.3); overflow:hidden;
|
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#FF0000), to(#FF0000));
|
|
background-image: -moz-linear-gradient(#FF0000,#FF0000);
|
|
-webkit-animation-timing-function: ease-in-out;
|
|
-webkit-animation-name: breathe;
|
|
-webkit-animation-duration: 1000ms;
|
|
-webkit-animation-iteration-count: infinite;
|
|
-webkit-animation-direction: alternate;
|
|
animation:ease-in-out breathe 500ms infinite alternate;
|
|
}
|
|
@keyframes breathe{
|
|
0% { opacity: .2; box-shadow:0 1px 2px rgba(255,255,255,0.1);}
|
|
100% { opacity: 1; border:1px solid rgba(59,235,235,1); box-shadow:0 1px 30px rgba(59,255,255,1);}
|
|
}
|
|
@-webkit-keyframes breathe {
|
|
0% { opacity: .2; box-shadow:0 1px 2px rgba(255,255,255,0.1);}
|
|
100% { opacity: 1; border:1px solid rgba(59,235,235,1); box-shadow:0 1px 30px rgba(59,255,255,1);}
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
<div class="content">
|
|
<div class="left">
|
|
<!--气压-->
|
|
<div class="air">
|
|
<div class="air-title title numfont">指标指数</div>
|
|
|
|
<div class="air-relative">
|
|
<div class="air-val">
|
|
<span class="air-icon"></span>
|
|
<div class="numfont">
|
|
<p class="hpa-rel"></p>
|
|
<p class="hpa-nam">健康指数</p>
|
|
</div>
|
|
</div>
|
|
<div class="gray">
|
|
|
|
</div>
|
|
<div class="light">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
<div class="air-absolutely">
|
|
<div class="air-val">
|
|
<span class="air-icon"></span>
|
|
<div class="numfont">
|
|
<p class="hpa-abs"></p>
|
|
<p class="hpa-nam">告警指数</p>
|
|
</div>
|
|
</div>
|
|
<div class="gray">
|
|
|
|
</div>
|
|
<div class="light">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
<!--气压 end-->
|
|
<!--温度和湿度-->
|
|
<div class="tem-hum">
|
|
<div class="air-title title numfont">实时体征数据</div>
|
|
<div class="temperature">
|
|
<div class="tem-hum-title numfont">实时心率</div>
|
|
<div class="tem-hum-chart" id="heartRateChart">
|
|
|
|
</div>
|
|
|
|
<div class="heartRate-val">
|
|
<button class="profile-button">87</button>
|
|
</div>
|
|
</div>
|
|
<div class="humidity">
|
|
<div class="tem-hum-title numfont">实时血氧</div>
|
|
<div class="tem-hum-chart" id="bloodOxygenChart">
|
|
|
|
</div>
|
|
<div class="bloodOxygen-val">
|
|
<button class="profile-button">87</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tem-hum">
|
|
<div class="temperature">
|
|
<div class="tem-hum-title numfont">实时血压</div>
|
|
<div class="tem-hum-chart" id="pressureChart">
|
|
|
|
</div>
|
|
<div class="pressure-val">
|
|
<button class="profile-button">101/101</button>
|
|
</div>
|
|
</div>
|
|
<div class="humidity">
|
|
<div class="tem-hum-title numfont">实时体温</div>
|
|
<div class="tem-hum-chart" id="temperatureChart">
|
|
|
|
</div>
|
|
<div class="temperature-val">
|
|
<button class="profile-button">33</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--温度和湿度 end-->
|
|
<!--温度一周k线图-->
|
|
|
|
|
|
</div>
|
|
|
|
<div class="middle">
|
|
<div class="headTitle">灵境万象智能穿戴个人大屏</div>
|
|
<!--地图-->
|
|
<div class="chinaMap" style="color: white;">
|
|
<div class="circle0"></div>
|
|
|
|
<div id="btn" style="display: none;">
|
|
<div style="position: relative;">
|
|
<div class="btn0"></div>
|
|
<div class="btn1"></div>
|
|
<div class="btn2"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mapBox">
|
|
<div id="map">
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<!--地图 end-->
|
|
<!--动画-->
|
|
<div class="lineRun">
|
|
|
|
</div>
|
|
<!--动画 end-->
|
|
</div>
|
|
|
|
<div class="right">
|
|
<div class="rainfall">
|
|
<div class="air-title title numfont">设备状态</div>
|
|
<div class="hp_con_right_u">
|
|
<table class="table3" style="border:0px; width:96%">
|
|
|
|
<tbody style="border:0px;">
|
|
<!--<tr><td colspan="4"><p style="width:9.6rem;">暂无数据</p></td></tr>-->
|
|
|
|
<tr style="border:0px;">
|
|
<td style="border:0px;"><div id="wearStatus" class="breathe-zc"></div></td>
|
|
<td style="border:0px;"><div id="chargeStatus" class="breathe-zc"></div></td>
|
|
<td style="border:0px;"><div id="onlineStatus" class="breathe-zc"></div></td>
|
|
<td style="border:0px;"><div id="alertStatus" class="breathe-zc"></div></td>
|
|
</tr>
|
|
<tr style="border:0px;">
|
|
<td style="border:0px;">佩戴状态</td>
|
|
<td style="border:0px;">充电状态</td>
|
|
<td style="border:0px;">在线状态</td>
|
|
<td style="border:0px;">告警状态</td>
|
|
</tr>
|
|
|
|
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="message-table">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>消息内容</th>
|
|
<th>消息类型</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="message-table-body">
|
|
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!--风-->
|
|
<div class="wind">
|
|
<div class="air-title title numfont">健康画像</div>
|
|
<div id="windChart">
|
|
|
|
</div>
|
|
<div class="windData">
|
|
<div class="windSpeed">
|
|
<div class="windTitle numfont">健康指数</div>
|
|
<div class="windBox">
|
|
<div style="width: 20%;margin-left: 4%;">
|
|
|
|
<p><span class="currentSpeed" id="nowWind">64</span></p>
|
|
|
|
</div>
|
|
<div style="width: 30%;margin-left: 4%;">
|
|
<p><span>心率:2.8</span></p>
|
|
<p><span>血氧:5.3</span></p>
|
|
<p><span>体温:7.1</span></p>
|
|
</div>
|
|
<div style="width: 30%;margin-left: 4%;">
|
|
<p><span>压力:5.4</span></p>
|
|
<p><span>睡眠:10.6</span></p>
|
|
<p><span>步数:8.5</span></p>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="gust">
|
|
<div class="windTitle numfont">健康基线</div>
|
|
<div class="windBox">
|
|
<div style="width: 30%;margin-left: 4%;">
|
|
<p><span class="healthIndex">心率</span></p>
|
|
<p><span id="heartRate">86-118</span></p>
|
|
</div>
|
|
<div style="width: 30%;margin-left: 4%;">
|
|
<p><span class="healthIndex">血氧</span></p>
|
|
<p><span id="bloodOxygen">90-100</span></p>
|
|
</div>
|
|
<div style="width: 30%;">
|
|
<p><span class="healthIndex">血压</span></p>
|
|
<p><span id="bloodPressure">120-130</span></p>
|
|
</div>
|
|
<div style="width: 30%;margin-left: 4%;">
|
|
<p><span class="healthIndex">心率</span></p>
|
|
<p><span id="heartRate">86-118</span></p>
|
|
</div>
|
|
<div style="width: 30%;margin-left: 4%;">
|
|
<p><span class="healthIndex">血氧</span></p>
|
|
<p><span id="bloodOxygen">90-100</span></p>
|
|
</div>
|
|
<div style="width: 30%;">
|
|
<p><span class="healthIndex">血压</span></p>
|
|
<p><span id="bloodPressure">120-130</span></p>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!--风 end-->
|
|
<!--降雨量-->
|
|
<div class="rainfall">
|
|
|
|
<div class="alert-table">
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
|
|
<th>告警类型</th>
|
|
<th>告警级别</th>
|
|
<th>告警时间</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="alert-table-body">
|
|
<!-- Existing static rows can be removed if you want to fully rely on dynamic data -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<!--降雨量 end-->
|
|
</div>
|
|
</div>
|
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='personal-js/jquery-3.2.1.min.js') }}">
|
|
|
|
<script src="{{ url_for('static', filename='personal-js/echarts.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='personal-js/china.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='personal-js/render.js') }}"></script>
|
|
|
|
|
|
<script>
|
|
function initialize() {
|
|
for (var i = 0; i < 50; i++) {
|
|
$('.air-relative').find('.gray').append('<span></span>');
|
|
$('.air-absolutely').find('.gray').append('<span></span>')
|
|
}
|
|
var pressureValRel = 0; //初始气压(相对)
|
|
var pressureValNowRel = 43; //当前气压(相对)
|
|
function airPreRel(now, old, par) {
|
|
if (now > old) {
|
|
par.find('.light').append('<span></span>');
|
|
pressureValRel++;
|
|
} else if (now < old) {
|
|
par.find('.light').children('span:last-child').remove();
|
|
pressureValRel--;
|
|
} else {
|
|
clearInterval(pressureRunRel);
|
|
return
|
|
}
|
|
$('.hpa-rel').text(pressureValRel * 2);
|
|
}
|
|
var pressureRunRel = setInterval(function() {
|
|
airPreRel(pressureValNowRel, pressureValRel, $('.air-relative'));
|
|
}, 50);
|
|
|
|
var pressureValAbs = 0; //初始气压(绝对)
|
|
var pressureValNowAbs = 33; //当前气压(绝对)
|
|
function airPreAbs(now, old, par) {
|
|
if (now > old) {
|
|
par.find('.light').append('<span></span>');
|
|
pressureValAbs++;
|
|
} else if (now < old) {
|
|
par.find('.light').children('span:last-child').remove();
|
|
pressureValAbs--;
|
|
} else {
|
|
clearInterval(pressureRunAbs);
|
|
return
|
|
}
|
|
$('.hpa-abs').text(pressureValAbs * 2);
|
|
}
|
|
var pressureRunAbs = setInterval(function() {
|
|
airPreAbs(pressureValNowAbs, pressureValAbs, $('.air-absolutely'));
|
|
}, 50);
|
|
|
|
//温度和湿度
|
|
var heartRateChart = echarts.init(document.getElementById('heartRateChart'));
|
|
var bloodOxygenChart = echarts.init(document.getElementById('bloodOxygenChart'));
|
|
var pressureChart = echarts.init(document.getElementById('pressureChart'));
|
|
var temperatureChart = echarts.init(document.getElementById('temperatureChart'));
|
|
var heartRateOption = {
|
|
tooltip: {
|
|
formatter: '{a}<br/>当前:{c}次/分'
|
|
},
|
|
series: [
|
|
//内圈
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '30%',
|
|
min: 0,
|
|
max: 10,
|
|
startAngle: 270,
|
|
endAngle: -89.99999,
|
|
splitNumber: 10,
|
|
axisLine: { // 仪表盘轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#ff4500']
|
|
],
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度标签
|
|
show: false
|
|
},
|
|
axisTick: { // 刻度
|
|
length: 4, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'rgba(176,204,53,.5)'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
show: false
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//中圈
|
|
{
|
|
name: '转速',
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '60%',
|
|
min: 0,
|
|
max: 10,
|
|
splitNumber: 10,
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#6E6560']
|
|
],
|
|
width: 8,
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: '',
|
|
color: 'rgba(30,144,255,0)',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisTick: { // 坐标轴小标记
|
|
length: 2, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'auto'
|
|
/*shadowColor : '#fff', //默认透明
|
|
shadowBlur: 10*/
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 0, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 0,
|
|
color: '#fff',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//外圈室内
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '100%',
|
|
min: 60, // Updated minimum value
|
|
max: 150, // Updated maximum value
|
|
name: '心率',
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: {
|
|
color: [
|
|
[0.33, '#FF0000'], // Red for 60-100
|
|
[0.67, '#00FF00'], // Green for 100-130
|
|
[1, '#FF0000'] // Red for 130-150
|
|
], // Adjusted color segments
|
|
width: 1
|
|
}
|
|
},
|
|
itemStyle: {
|
|
normal: {
|
|
color: '#FF0000'
|
|
}
|
|
},
|
|
axisTick: {
|
|
length: 3
|
|
},
|
|
axisLabel: { // 坐标轴小标记
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: 'bolder',
|
|
fontSize: 10,
|
|
fontFamily: 'numfont'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 5, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 3,
|
|
length: '90%'
|
|
},
|
|
detail: {
|
|
show: false
|
|
},
|
|
data: [{
|
|
value: 87
|
|
}]
|
|
}
|
|
]
|
|
};
|
|
var bloodOxygenOption = {
|
|
tooltip: {
|
|
formatter: '{a}<br/>当前:{c}'
|
|
},
|
|
series: [
|
|
//内圈
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '30%',
|
|
min: 0,
|
|
max: 10,
|
|
startAngle: 270,
|
|
endAngle: -89.99999,
|
|
splitNumber: 10,
|
|
axisLine: { // 仪表盘轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#ff4500']
|
|
],
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度标签
|
|
show: false
|
|
},
|
|
axisTick: { // 刻度
|
|
length: 4, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'rgba(176,204,53,.5)'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
show: false
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//中圈
|
|
{
|
|
name: '转速',
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '60%',
|
|
min: 0,
|
|
max: 10,
|
|
splitNumber: 10,
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#6E6560']
|
|
],
|
|
width: 8,
|
|
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: '',
|
|
color: 'rgba(30,144,255,0)',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisTick: { // 坐标轴小标记
|
|
length: 2, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'auto'
|
|
/*shadowColor : '#fff', //默认透明
|
|
shadowBlur: 10*/
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 0, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 0,
|
|
color: '#fff',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//外圈室内
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '100%',
|
|
min: 80, // Updated minimum value
|
|
max: 100, // Updated maximum value
|
|
name: '血氧',
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: {
|
|
color: [
|
|
[0.5, '#FF0000'], // Red for 80-90
|
|
[1, '#00FF00'] // Green for 90-100
|
|
], // 属性lineStyle控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
itemStyle: {
|
|
normal: {
|
|
color: '#FF0000'
|
|
}
|
|
},
|
|
axisTick: {
|
|
length: 3
|
|
},
|
|
axisLabel: { // 坐标轴标记
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: 'bolder',
|
|
fontSize: 10,
|
|
fontFamily: 'numfont'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 5, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 3,
|
|
length: '90%'
|
|
},
|
|
detail: {
|
|
show: false
|
|
},
|
|
data: [{
|
|
value: 87
|
|
}]
|
|
},
|
|
//外圈室外
|
|
|
|
|
|
]
|
|
};
|
|
var pressureOption = {
|
|
tooltip: {
|
|
formatter: '{a}<br/>当前:{c}mmHg'
|
|
},
|
|
series: [
|
|
//内圈
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '30%',
|
|
min: 0,
|
|
max: 10,
|
|
startAngle: 270,
|
|
endAngle: -89.99999,
|
|
splitNumber: 10,
|
|
axisLine: { // 仪表盘轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#ff4500']
|
|
],
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度标签
|
|
show: false
|
|
},
|
|
axisTick: { // 度
|
|
length: 4, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'rgba(176,204,53,.5)'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
show: false
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//中圈
|
|
{
|
|
name: '转速',
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '60%',
|
|
min: 0,
|
|
max: 10,
|
|
splitNumber: 10,
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#6E6560']
|
|
],
|
|
width: 8,
|
|
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: '',
|
|
color: 'rgba(30,144,255,0)',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisTick: { // 坐标轴小标记
|
|
length: 2, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'auto'
|
|
/*shadowColor : '#fff', //默认透明
|
|
shadowBlur: 10*/
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 0, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 0,
|
|
color: '#fff',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//外圈室内
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '100%',
|
|
min: 0,
|
|
max: 150,
|
|
name: '高压',
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: {
|
|
color: [
|
|
[1, '#C7C5C3']
|
|
], // 属性lineStyle控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
itemStyle: {
|
|
normal: {
|
|
color: '#FF0000'
|
|
}
|
|
},
|
|
axisTick: {
|
|
length: 3
|
|
},
|
|
axisLabel: { // 坐标轴小标记
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: 'bolder',
|
|
fontSize: 10,
|
|
fontFamily: 'numfont'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 5, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 3,
|
|
length: '90%'
|
|
},
|
|
detail: {
|
|
show: false
|
|
},
|
|
data: [{
|
|
value: 101
|
|
}]
|
|
},
|
|
//外圈室外
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '100%',
|
|
min: 0,
|
|
max: 150,
|
|
name: '低压',
|
|
axisTick: {
|
|
length: 3
|
|
},
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: {
|
|
color: [
|
|
[1, '#C7C5C3']
|
|
], // 属性lineStyle控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 3,
|
|
length: '90%'
|
|
},
|
|
itemStyle: {
|
|
normal: {
|
|
color: '#B0CC35'
|
|
}
|
|
|
|
},
|
|
axisLabel: {
|
|
textStyle: {
|
|
fontWeight: 'bolder',
|
|
fontSize: 16,
|
|
color: 'rgba(30,144,255,0)'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 5, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
detail: {
|
|
show: false
|
|
},
|
|
data: [{
|
|
value: 88
|
|
}],
|
|
title: {
|
|
show: false
|
|
}
|
|
}
|
|
|
|
]
|
|
};
|
|
|
|
var temperatureOption = {
|
|
tooltip: {
|
|
formatter: '{a}<br/>当前:{c}℃'
|
|
},
|
|
series: [
|
|
//内圈
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '30%',
|
|
min: 0,
|
|
max: 10,
|
|
startAngle: 270,
|
|
endAngle: -89.99999,
|
|
splitNumber: 10,
|
|
axisLine: { // 仪表盘轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#ff4500']
|
|
],
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度标签
|
|
show: false
|
|
},
|
|
axisTick: { // 刻度
|
|
length: 4, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'rgba(176,204,53,.5)'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
show: false
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//中圈
|
|
{
|
|
name: '转速',
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '60%',
|
|
min: 0,
|
|
max: 10,
|
|
splitNumber: 10,
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: [
|
|
[1, '#6E6560']
|
|
],
|
|
width: 8,
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisLabel: { // 刻度
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: '',
|
|
color: 'rgba(30,144,255,0)',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
axisTick: { // 坐标轴小标记
|
|
length: 2, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle控制线条样式
|
|
color: 'auto'
|
|
/*shadowColor : '#fff', //默认透明
|
|
shadowBlur: 10*/
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 0, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 0,
|
|
color: '#fff',
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 10
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 0,
|
|
shadowColor: '#fff', //默认透明
|
|
shadowBlur: 5
|
|
},
|
|
detail: {
|
|
show: false
|
|
}
|
|
},
|
|
//外圈室内
|
|
{
|
|
type: 'gauge',
|
|
center: ['50%', '60%'], // 默认全局居中
|
|
radius: '100%',
|
|
min: 34, // Updated minimum value
|
|
max: 41, // Updated maximum value
|
|
name: '体温',
|
|
axisLine: { // 坐标轴线
|
|
lineStyle: {
|
|
color: [
|
|
[0.1429, '#FF0000'], // Red for 34-35
|
|
[0.5, '#00FF00'], // Green for 35-37.5
|
|
[1, '#FF0000'] // Red for 37.5-41
|
|
], // 属性lineStyle控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
itemStyle: {
|
|
normal: {
|
|
color: '#FF0000'
|
|
}
|
|
},
|
|
axisTick: {
|
|
length: 3
|
|
},
|
|
axisLabel: { // 坐标轴小标记
|
|
textStyle: { // 属性lineStyle控制线条样式
|
|
fontWeight: 'bolder',
|
|
fontSize: 10,
|
|
fontFamily: 'numfont'
|
|
}
|
|
},
|
|
splitLine: { // 分隔线
|
|
length: 5, // 属性length控制线长
|
|
lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式
|
|
width: 1
|
|
}
|
|
},
|
|
pointer: {
|
|
width: 3,
|
|
length: '90%'
|
|
},
|
|
detail: {
|
|
show: false
|
|
},
|
|
data: [{
|
|
value: 36.5
|
|
}]
|
|
}
|
|
]
|
|
};
|
|
heartRateChart.setOption(heartRateOption);
|
|
bloodOxygenChart.setOption(bloodOxygenOption);
|
|
pressureChart.setOption(pressureOption);
|
|
temperatureChart.setOption(temperatureOption);
|
|
|
|
|
|
|
|
// Define the function globally
|
|
window.temHum = function(heartRateVal, bloodOxygenVal, pressureHighVal, pressureLowVal, temperatureVal) {
|
|
heartRateOption.series[2].data[0].value = heartRateVal;
|
|
heartRateChart.setOption(heartRateOption);
|
|
|
|
$('.heartRate-val').find('.profile-button').text(heartRateVal);
|
|
bloodOxygenOption.series[2].data[0].value = bloodOxygenVal;
|
|
bloodOxygenChart.setOption(bloodOxygenOption);
|
|
$('.bloodOxygen-val').find('.profile-button').text(bloodOxygenVal);
|
|
|
|
pressureOption.series[2].data[0].value = pressureHighVal;
|
|
pressureOption.series[3].data[0].value = pressureLowVal;
|
|
pressureChart.setOption(pressureOption);
|
|
console.log("temHum::pressureHighVal:", pressureHighVal);
|
|
$('.pressure-val').find('.profile-button').text(`${pressureHighVal}/${pressureLowVal}`);
|
|
temperatureOption.series[2].data[0].value = temperatureVal;
|
|
|
|
temperatureChart.setOption(temperatureOption);
|
|
$('.temperature-val').find('.profile-button').text(temperatureVal+ '℃');
|
|
};
|
|
|
|
|
|
|
|
//风向图
|
|
var windOption = {
|
|
tooltip: {},
|
|
radar: {
|
|
indicator: [{
|
|
name: '心率',
|
|
max: 12
|
|
},
|
|
{
|
|
name: '血氧',
|
|
max: 12
|
|
},
|
|
{
|
|
name: '体温',
|
|
max: 12
|
|
},
|
|
{
|
|
name: '压力',
|
|
max: 12
|
|
},
|
|
{
|
|
name: '睡眠',
|
|
max: 12
|
|
},
|
|
{
|
|
name: '步数',
|
|
max: 12
|
|
},
|
|
{
|
|
name: '血压',
|
|
max: 12
|
|
}
|
|
],
|
|
name: {
|
|
textStyle: {
|
|
color: 'rgba(176,204,53,1)'
|
|
}
|
|
},
|
|
axisLine: {
|
|
lineStyle: {
|
|
color: 'rgba(255, 255, 255, 0.4)'
|
|
}
|
|
},
|
|
splitLine: {
|
|
lineStyle: {
|
|
color: 'rgba(255, 255, 255, 0.4)'
|
|
}
|
|
},
|
|
splitArea: {
|
|
areaStyle: {
|
|
color: 'rgba(255,255,255,0)'
|
|
}
|
|
}
|
|
},
|
|
series: [{
|
|
type: 'radar',
|
|
data: [{
|
|
value: [2.8, 5.3, 7.1, 5.4, 10.6, 8.5, 10.0],
|
|
name: '2024'
|
|
}],
|
|
areaStyle: {
|
|
normal: {
|
|
color: 'rgba(176,204,53,.5)'
|
|
}
|
|
},
|
|
lineStyle: {
|
|
normal: {
|
|
color: 'rgba(176,204,53,.7)'
|
|
|
|
}
|
|
},
|
|
symbol: 'circle',
|
|
symbolSize: 6,
|
|
itemStyle: {
|
|
normal: {
|
|
color: '#A9C33B'
|
|
}
|
|
}
|
|
}]
|
|
};
|
|
var windChart = echarts.init(document.getElementById('windChart'));
|
|
windChart.setOption(windOption);
|
|
|
|
|
|
//风速与阵风数据
|
|
var speed = {
|
|
wind: [86, 42],
|
|
gust: [2.8, 4.3]
|
|
};
|
|
|
|
function getData() {
|
|
$('#nowWind').text(speed.wind[0]);
|
|
$('#highWind').text(speed.wind[1]);
|
|
var windSpeed = (50 - speed.wind[0]) * 10;
|
|
$('.windSpeed .windFan').css('animation-duration', windSpeed + 'ms');
|
|
$('#nowGust').text(speed.gust[0]);
|
|
$('#highGust').text(speed.gust[1]);
|
|
var gustSpeed = (50 - speed.gust[0]) * 10;
|
|
$('.gust .windFan').css('animation-duration', gustSpeed + 'ms');
|
|
}
|
|
getData();
|
|
|
|
|
|
|
|
};
|
|
initialize();
|
|
</script>
|
|
|
|
<style>
|
|
.device-status {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
padding: 20px;
|
|
background-color: #333;
|
|
color: #fff;
|
|
}
|
|
|
|
.status-item {
|
|
text-align: center;
|
|
transition: transform 0.3s;
|
|
}
|
|
|
|
.status-item:hover {
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
.status-title {
|
|
margin-bottom: 10px;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.status-icon {
|
|
font-size: 24px;
|
|
transition: color 0.3s, transform 0.3s;
|
|
}
|
|
|
|
.icon {
|
|
transition: color 0.3s, transform 0.3s;
|
|
}
|
|
|
|
.icon.active {
|
|
color: green;
|
|
animation: pulse 1s infinite;
|
|
}
|
|
|
|
.icon.inactive {
|
|
color: red;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% {
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
transform: scale(1.2);
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script type="text/javascript">
|
|
|
|
|
|
//设置渠道状态
|
|
function qdzt(){
|
|
//breathe-zc 绿灯;breathe-yc 红灯
|
|
$("#dx").removeClass("breathe-yc");
|
|
$("#dx").addClass("breathe-zc");
|
|
|
|
$("#cz").removeClass("breathe-zc");
|
|
$("#cz").addClass("breathe-yc");
|
|
|
|
$("#gt").removeClass("breathe-yc");
|
|
$("#gt").addClass("breathe-zc");
|
|
|
|
$("#dlbxsp").removeClass("breathe-yc");
|
|
$("#dlbxsp").addClass("breathe-zc");
|
|
}
|
|
</script>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
async function fetchData() {
|
|
try {
|
|
// Fetch data from the API
|
|
const response = await fetch(`./get_personal_info?deviceSn={{deviceSn}}`);
|
|
|
|
//console.log("get_personal_info response:", response);
|
|
|
|
// Check content type
|
|
const contentType = response.headers.get("content-type");
|
|
if (contentType && contentType.includes("application/json")) {
|
|
const personalData = await response.json();
|
|
console.log("get_personal_info response:", personalData);
|
|
|
|
// Ensure data structure is valid
|
|
if (personalData && personalData.success) {
|
|
const healthData = personalData.data.health_data.healthData[0];
|
|
console.log("DOMContentLoaded::healthData:", healthData);
|
|
if (healthData) {
|
|
const heartRate = healthData.heartRate;
|
|
const bloodOxygen = healthData.bloodOxygen;
|
|
const pressureHigh = healthData.pressureHigh;
|
|
const pressureLow = healthData.pressureLow;
|
|
const temperature = healthData.temperature;
|
|
// Initialize page components with the fetched data
|
|
temHum(heartRate, bloodOxygen, pressureHigh, pressureLow, temperature);
|
|
//console.log("DOMContentLoaded::data:", personalData.data);
|
|
} else {
|
|
console.error('Health data is undefined:', personalData.data);
|
|
}
|
|
|
|
const deviceInfo = personalData.data.device_info.devices[0];
|
|
console.log("DOMContentLoaded1::device_info:", deviceInfo);
|
|
// Device info handling
|
|
if (deviceInfo) {
|
|
const chargingStatus = deviceInfo.charging_status || 'UNKNOWN';
|
|
const wearableStatus = deviceInfo.wearable_status || 'UNKNOWN';
|
|
const onlineStatus = deviceInfo.status || 'UNKNOWN';
|
|
|
|
// Update charging status
|
|
if (chargingStatus === 'NOT_CHARGING') {
|
|
$("#chargeStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#chargeStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
|
|
// Update wearable status
|
|
if (wearableStatus === 'NOT_WORN') {
|
|
$("#wearStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#wearStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
|
|
// Update online status
|
|
if (onlineStatus === 'INACTIVE') {
|
|
$("#onlineStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#onlineStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
}
|
|
|
|
const alerts = personalData.data.alert_info.alerts;
|
|
console.log("DOMContentLoaded::alertInfo:", alerts);
|
|
// Handle alert_info
|
|
if (alerts.length > 0) {
|
|
const alertTableBody = document.getElementById('alert-table-body');
|
|
alertTableBody.innerHTML = '';
|
|
//const alerts = alertInfo.alerts;
|
|
//console.log("DOMContentLoaded::alerts:", alerts);
|
|
|
|
alerts.slice(0, 3).forEach(alert => {
|
|
const row = document.createElement('tr');
|
|
row.innerHTML = `
|
|
<td>${alert.alert_type || '未知'}</td>
|
|
<td>
|
|
<span class="level ${alert.severity_level || 'unknown'}">
|
|
${mapSeverityLevel(alert.severity_level) || '未知'}
|
|
</span>
|
|
</td>
|
|
<td>${alert.alert_timestamp || '未知时间'}</td>
|
|
<td>
|
|
<button class="profile-button"><a href="./dealAlert?alertId=${alert.id}">一键处理</a></button>
|
|
</td>
|
|
`;
|
|
alertTableBody.appendChild(row);
|
|
});
|
|
|
|
// Update alert status indicator
|
|
if (alerts.length > 0) {
|
|
$("#alertStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#alertStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
}
|
|
|
|
const messageInfo = personalData.data.message_info;
|
|
|
|
const messages = messageInfo.messages;
|
|
// Handle message_info
|
|
console.log("DOMContentLoaded::messageInfo:", messages);
|
|
const messageTableBody = document.getElementById('message-table-body');
|
|
messageTableBody.innerHTML = '';
|
|
messages.slice(0, 3).forEach(message => {
|
|
const row = document.createElement('tr');
|
|
row.innerHTML = `
|
|
<td>${message.message || '未知消息'}</td>
|
|
<td><span class="status ${message.message_type || 'unknown'}">${mapMessageType(message.message_type) || '未知类型'}</span></td>
|
|
<td class="${message.message_status === 'responded' ? 'responded' : 'pending'}">${mapMessageStatus(message.message_status) || '未处理'}</td>
|
|
`;
|
|
messageTableBody.appendChild(row);
|
|
});
|
|
|
|
} else {
|
|
console.error('Failed to fetch personal info:', data.error || 'Unknown error');
|
|
}
|
|
} else {
|
|
console.error('Response is not JSON:', await response.text());
|
|
}
|
|
} catch (error) {
|
|
console.error('Error fetching personal info:', error.message || error);
|
|
//alert('无法加载个人信息,请稍后重试。');
|
|
}
|
|
}
|
|
|
|
// Fetch data initially and then every 5 seconds
|
|
fetchData();
|
|
setInterval(fetchData, 5000);
|
|
|
|
});
|
|
</script>
|
|
<script>
|
|
const socket = io.connect(); // Adjust the URL as needed
|
|
console.log("socket", socket);
|
|
|
|
// Log when the connection is established
|
|
socket.on('connect', function() {
|
|
console.log('Connected to socket server');
|
|
});
|
|
|
|
// Log any connection errors
|
|
socket.on('connect_error', function(error) {
|
|
console.error('Connection error:', error);
|
|
});
|
|
|
|
// Listen for the personal_info_update event
|
|
socket.on('personal_info_update', function(data) {
|
|
console.log("personal_info_update:", data.data.health_data.heartRate);
|
|
temHum(data.data.health_data.heartRate, data.data.health_data.bloodOxygen, data.data.health_data.pressureHigh, data.data.health_data.pressureLow, data.data.health_data.temperature);
|
|
//console.log(data.data.device_info);
|
|
// Update charging status
|
|
if (data.data.device_info.charging_status === 'NOT_CHARGING') {
|
|
$("#chargeStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#chargeStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
|
|
// Update wearable status
|
|
if (data.data.device_info.wearable_status === 'NOT_WORN') {
|
|
$("#wearStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#wearStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
|
|
// Update online status
|
|
if (data.data.device_info.status === 'INACTIVE') {
|
|
$("#onlineStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#onlineStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
|
|
// Update alert status
|
|
if (Object.keys(data.data.alert_info).length > 0) {
|
|
$("#alertStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#alertStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
// Handle alert_info
|
|
if (data.data.alert_info && typeof data.data.alert_info === 'object') {
|
|
const alertTableBody = document.getElementById('alert-table-body');
|
|
alertTableBody.innerHTML = '';
|
|
|
|
// 将对象的值转换为数组并解析 JSON 字符串
|
|
const alerts = Object.values(data.data.alert_info).map(alertStr => JSON.parse(alertStr));
|
|
|
|
alerts.slice(0, 3).forEach(alert => {
|
|
//console.log("alert:", alert.severityLevel);
|
|
|
|
const row = document.createElement('tr');
|
|
row.innerHTML = `
|
|
<td>${alert.alertType || '未知'}</td>
|
|
<td>
|
|
<span class="level ${alert.severityLevel || 'unknown'}">
|
|
${mapSeverityLevel(alert.severityLevel) || '未知'}
|
|
</span>
|
|
</td>
|
|
<td>${alert.timestamp || '未知时间'}</td>
|
|
<td>
|
|
<button class="profile-button"><a href="./dealAlert?alertId=${alert.id}">一键处理</a></button>
|
|
</td>
|
|
`;
|
|
alertTableBody.appendChild(row);
|
|
});
|
|
|
|
// Update alert status indicator
|
|
if (alerts.length > 0) {
|
|
$("#alertStatus").removeClass("breathe-zc").addClass("breathe-yc");
|
|
} else {
|
|
$("#alertStatus").removeClass("breathe-yc").addClass("breathe-zc");
|
|
}
|
|
}
|
|
|
|
//console.log("data.message_info:", data.data.message_info);
|
|
if (data.data.message_info && typeof data.data.message_info === 'object') {
|
|
const messages = Object.values(data.data.message_info).map(messageStr => JSON.parse(messageStr));
|
|
// Handle message_info
|
|
const messageTableBody = document.getElementById('message-table-body');
|
|
messageTableBody.innerHTML = '';
|
|
|
|
// Iterate over each message in message_info
|
|
messages.slice(0, 3).forEach(message => {
|
|
console.log("message:", message.message_type);
|
|
const row = document.createElement('tr');
|
|
row.innerHTML = `
|
|
<td>${message.message || '未知消息'}</td>
|
|
<td><span class="status ${message.message_type || 'unknown'}">${mapMessageType(message.message_type) || '未知类型'}</span></td>
|
|
|
|
<td class="${message.message_status === '1' ? 'pending' : 'responded'}">${mapMessageStatus(message.message_status)}</td>
|
|
`;
|
|
messageTableBody.appendChild(row);
|
|
});
|
|
}
|
|
|
|
// Update the DOM with the new data
|
|
//const personalInfoDiv = document.getElementById('personal-info');
|
|
//personalInfoDiv.innerHTML = JSON.stringify(data.data, null, 2); // Example: display JSON data
|
|
});
|
|
</script>
|
|
<script>
|
|
function mapSeverityLevel(severityLevel) {
|
|
switch (severityLevel) {
|
|
case 'critical':
|
|
return '一级';
|
|
case 'high':
|
|
return '二级';
|
|
case 'medium':
|
|
return '三级';
|
|
default:
|
|
return '其他';
|
|
}
|
|
}
|
|
|
|
function mapMessageType(messageType) {
|
|
switch (messageType) {
|
|
case 'announcement':
|
|
return '公告';
|
|
case 'warning':
|
|
return '警告';
|
|
case 'notification':
|
|
return '通知';
|
|
case 'task':
|
|
return '任务管理';
|
|
case 'job':
|
|
return '作业指引';
|
|
default:
|
|
return '未知';
|
|
}
|
|
}
|
|
function mapMessageStatus(status) {
|
|
const statusMap = {
|
|
'1': '未响应',
|
|
'0': '已响应',
|
|
};
|
|
return statusMap[status] || '未响应';
|
|
}
|
|
</script>
|
|
|
|
|
|
</body>
|
|
|
|
</html> |