Files
lanzhouhailiang_one/lms/nladmin-system/doc/套轴点位日志记录实时看板.html

417 lines
15 KiB
HTML
Raw 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>套轴点位日志记录实时看板</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #183a5c 0%, #274b7a 100%); /* 深科技蓝渐变背景 */
color: #cfd8e3; /* 浅灰蓝文本 */
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
h1 {
color: #ffffff; /* 亮蓝标题40a9ff */
text-align: center;
font-size: 2.5em;
margin-bottom: 30px;
text-shadow: 0 2px 12px #274b7a;
}
.dashboard-container {
display: flex;
justify-content: space-around;
width: 100%;
max-width: 1800px;
margin-bottom: 30px;
}
.device-card {
background: #223a5c; /* 中深蓝卡片背景 */
border: 1px solid #40a9ff; /* 亮蓝边框 */
border-radius: 10px;
padding: 20px;
width: 45%;
min-height: 300px;
height: 350px; /* 新增:固定高度 */
box-shadow: 0 2px 16px rgba(64,169,255,0.12);
transition: transform 0.3s, box-shadow 0.3s;
display: flex;
flex-direction: column;
}
.log-entries {
flex: 1;
overflow-y: auto;
max-height: 250px;
/* 美化滚动条 */
scrollbar-width: thin;
scrollbar-color: #40a9ff #223a5c;
}
.log-entries::-webkit-scrollbar {
width: 8px;
}
.log-entries::-webkit-scrollbar-thumb {
background: linear-gradient(135deg, #40a9ff 0%, #274b7a 100%);
border-radius: 6px;
}
.log-entries::-webkit-scrollbar-track {
background: #223a5c;
border-radius: 6px;
}
/* .device-card:hover {
transform: translateY(-5px) scale(1.02);
box-shadow: 0 0 30px #40a9ff;
} */
.device-card h2 {
color: #ffffff;
border-bottom: 1px solid #274b7a;
padding-bottom: 10px;
margin-top: 0;
font-size: 1.5em;
}
.log-entry {
background: #274b7a;
color: #cfd8e3;
padding: 8px;
margin-bottom: 8px;
border-radius: 4px;
border-left: 3px solid #40a9ff;
font-size: 0.95em;
word-wrap: break-word;
}
.table-container {
width: 95%;
max-width: 1800px;
background: #223a5c;
border: 1px solid #40a9ff;
border-radius: 10px;
padding: 0 20px 20px 20px;
margin-top: 20px;
box-shadow: 0 2px 16px rgba(64,169,255,0.12);
}
.table-container h2 {
color: #ffffff;
text-align: center;
font-size: 1.8em;
margin-bottom: 20px;
}
table {
width: 100%;
border-collapse: collapse;
color: #cfd8e3;
background: #274b7a;
}
th, td {
border: 1px solid #3b6ea5;
padding: 10px;
text-align: left;
font-size: 0.95em;
}
th {
background: linear-gradient(90deg, #274b7a 0%, #3b6ea5 100%);
color: #40a9ff;
}
tbody tr:nth-child(odd) {
background: #223a5c;
}
tbody tr:hover {
background: #3b6ea5;
}
.timeout-row-warning {
background: #5c1a1a !important;
color: #f8d7da;
}
.timeout-row-warning td {
color: #f8d7da !important;
}
</style>
</head>
<body>
<h1>套轴点位日志记录实时看板</h1>
<div class="dashboard-container">
<div class="device-card" id="device-B_CBJ01">
<h2>B_CBJ01<span id="tip-B_CBJ01" style="font-size:0.7em;color:#ffec3d;margin-left:12px;"></span></h2>
<!-- 添加tip2显示区域 -->
<div id="tip2-B_CBJ01" style="color:#ffec3d;font-size:0.9em;margin-bottom:10px;background:rgba(64,169,255,0.1);padding:5px;border-radius:4px;"></div>
<div class="log-entries">
<!-- 日志条目将在这里动态添加 -->
</div>
</div>
<div class="device-card" id="device-B_CBJ02">
<h2>B_CBJ02<span id="tip-B_CBJ02" style="font-size:0.7em;color:#ffec3d;margin-left:12px;"></span></h2>
<!-- 添加tip2显示区域 -->
<div id="tip2-B_CBJ02" style="color:#ffec3d;font-size:0.9em;margin-bottom:10px;background:rgba(64,169,255,0.1);padding:5px;border-radius:4px;"></div>
<div class="log-entries">
<!-- 日志条目将在这里动态添加 -->
</div>
</div>
</div>
<!-- 新增的表格容器 -->
<div class="table-container">
<h2>套轴监控系统实时数据</h2>
<table id="slitter-table">
<thead>
<tr>
<th>设备</th>
<th>子卷号</th>
<th>轴位置</th>
<th>气胀轴尺寸</th>
<th>气胀轴代数</th>
<th>气胀轴状态</th>
<th>呼叫时间</th>
<th>管芯规格</th>
<th>套轴标记</th>
</tr>
</thead>
<tbody id="slitter-table-body">
<!-- 表格数据将在这里动态添加 -->
</tbody>
</table>
</div>
<script>
const logApiUrl = 'http://10.1.3.91:8013/api/wms/apply/v2/tzInfo';
const devices = ['B_CBJ01', 'B_CBJ02'];
const refreshInterval = 10000; // 刷新间隔统一为10秒
async function fetchLogData(deviceCode) {
try {
const response = await fetch(logApiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ device_code: deviceCode }),
});
if (!response.ok) {
const errorText = await response.text();
console.error(`HTTP error response for ${deviceCode} (log):`, errorText);
throw new Error(`HTTP error! status: ${response.status} for ${deviceCode} (log). Response: ${errorText}`);
}
const responseText = await response.text();
if (!responseText) {
console.warn(`Empty response received for ${deviceCode} (log)`);
return [];
}
try {
const data = JSON.parse(responseText);
return data;
} catch (e) {
console.error(`Error parsing JSON for ${deviceCode} (log):`, e);
console.error(`Raw response text for ${deviceCode} (log):`, responseText);
throw new Error(`Failed to parse JSON response for ${deviceCode} (log). Raw text: ${responseText.substring(0, 100)}...`);
}
} catch (error) {
console.error(`Error fetching log data for ${deviceCode}:`, error);
return [`获取 ${deviceCode} 日志数据失败: ${error.message}`];
}
}
function displayLogData(deviceCode, data) {
const deviceElement = document.getElementById(`device-${deviceCode}`);
if (!deviceElement) {
console.error(`Element with ID 'device-${deviceCode}' not found.`);
return;
}
const logEntriesContainer = deviceElement.querySelector('.log-entries');
logEntriesContainer.innerHTML = '';
if (Array.isArray(data) && data.length > 0) {
data.forEach(entry => {
const logEntryDiv = document.createElement('div');
logEntryDiv.classList.add('log-entry');
logEntryDiv.textContent = entry;
logEntriesContainer.appendChild(logEntryDiv);
});
} else {
const noDataEntry = document.createElement('div');
noDataEntry.classList.add('log-entry');
noDataEntry.textContent = '暂无日志信息。';
logEntriesContainer.appendChild(noDataEntry);
}
}
async function updateLogDashboard() {
for (const device of devices) {
const data = await fetchLogData(device);
displayLogData(device, data);
}
}
// 新增表格数据相关逻辑
const tableApiUrl = 'http://10.1.3.91:8013/api/pda/slitter/showManualView';
async function fetchTableData() {
try {
const response = await fetch(tableApiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
project: "套轴监控系统",
timestamp: Date.now() // 使用当前时间戳
}),
});
if (!response.ok) {
const errorText = await response.text();
console.error('HTTP error response for table data:', errorText);
throw new Error(`HTTP error! status: ${response.status} for table data. Response: ${errorText}`);
}
const responseText = await response.text();
if (!responseText) {
console.warn('Empty response received for table data');
return [];
}
try {
const data = JSON.parse(responseText);
return data;
} catch (e) {
console.error('Error parsing JSON for table data:', e);
console.error('Raw response text for table data:', responseText);
throw new Error(`Failed to parse JSON response for table data. Raw text: ${responseText.substring(0, 100)}...`);
}
} catch (error) {
console.error('Error fetching table data:', error);
// 可以选择在表格中显示错误信息
const tableBody = document.getElementById('slitter-table-body');
if (tableBody) {
tableBody.innerHTML = `<tr><td colspan="7">获取表格数据失败: ${error.message}</td></tr>`;
}
return []; // 返回空数组以避免后续处理错误
}
}
function displayTableData(data) {
const tableBody = document.getElementById('slitter-table-body');
if (!tableBody) {
console.error("Element with ID 'slitter-table-body' not found.");
return;
}
tableBody.innerHTML = ''; // 清空旧数据
if (Array.isArray(data) && data.length > 0) {
data.forEach(item => {
const row = tableBody.insertRow();
row.insertCell().textContent = item.resource_name || 'N/A';
row.insertCell().textContent = item.container_name || 'N/A';
row.insertCell().textContent = item.up_or_down === '1' ? '上' : (item.up_or_down === '2' ? '下' : item.up_or_down || 'N/A');
row.insertCell().textContent = item.qzz_size || 'N/A';
row.insertCell().textContent = item.qzz_generation || 'N/A';
let statusText = '已完成';
if (item.status === '01') {
statusText = '准备套轴';
} else if (item.status === '02') {
statusText = '正在配送';
} else if (item.status === '03') {
statusText = '配送完成';
} else if (item.status) {
statusText = '已完成';
}
row.insertCell().textContent = statusText;
const startTimeCell = row.insertCell();
startTimeCell.textContent = item.start_time || 'N/A';
row.insertCell().textContent = item.tube || 'N/A';
let tzText = '未套轴';
if (item.is_paper_ok === '2') {
tzText = '已套轴';
}
row.insertCell().textContent = tzText || 'N/A';
// 检查start_time是否超过2小时并设置行样式
if (item.start_time) {
const startTime = new Date(item.start_time.replace(/-/g, '/'));
const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000);
if (startTime < twoHoursAgo) {
row.classList.add('timeout-row-warning'); // 应用于整行
}
}
});
} else {
const row = tableBody.insertRow();
const cell = row.insertCell();
cell.colSpan = 7;
cell.textContent = '暂无数据。';
cell.style.textAlign = 'center';
}
}
async function updateTableDashboard() {
const data = await fetchTableData();
displayTableData(data);
}
// 新增获取tip并显示在标题后
const tipApiUrl = 'http://10.1.3.91:8013/api/wms/apply/v2/tzTaskINfo';
async function fetchAndDisplayTip(deviceCode) {
try {
const response = await fetch(tipApiUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ device_code: deviceCode })
});
let tip = '';
let tip2 = '';
if (response.ok) {
const data = await response.json();
tip = data.tip || '';
tip2 = data.tip2 || '';
// 显示tip2在对应设备标题下方
document.getElementById('tip2-' + deviceCode).textContent = tip2;
}
document.getElementById('tip-' + deviceCode).textContent = tip;
} catch (e) {
document.getElementById('tip-' + deviceCode).textContent = '';
document.getElementById('tip2-' + deviceCode).textContent = '';
}
}
function updateAllTips() {
devices.forEach(device => fetchAndDisplayTip(device));
}
// 初始加载tip
updateAllTips();
// 定时刷新tip
setInterval(updateAllTips, refreshInterval);
// 初始加载数据
updateLogDashboard();
updateTableDashboard();
// 定时刷新数据
setInterval(updateLogDashboard, refreshInterval);
setInterval(updateTableDashboard, refreshInterval); // 表格也使用相同的刷新间隔
</script>
</body>
</html>