life_handle_tool/static/main.js

630 lines
22 KiB
JavaScript
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.

console.log('main.js 文件开始执行');
let lightHistory = {
common: false,
alarm: false,
up: false,
down: false,
emergency_stop: false
};
let allTestsPassed = false;
let currentDeviceType = '5'; // 默认为五孔设备
function updateLights() {
if (!currentDeviceType) return; // 如果没有选择设备类型,不更新灯光状态
fetch('/get_lights_status')
.then(response => response.json())
.then(data => {
console.log('获取到的灯光状态:', data); // 调试输出
for (let light in data) {
let element5 = document.getElementById(light + '-5');
let element4 = document.getElementById(light + '-4');
// 根据当前设备类型更新相应的灯光
if (currentDeviceType === '5' && element5) {
updateLightStatus(element5, data[light]);
} else if (currentDeviceType === '4' && element4) {
updateLightStatus(element4, data[light]);
}
// 更新灯光历史和检查列表
if (data[light] && !lightHistory[light]) {
lightHistory[light] = true;
updateCheckList(light);
}
}
checkAllTestsPassed();
})
.catch(error => {
console.error('获取灯光状态失败:', error);
});
}
function updateLightStatus(element, isOn) {
if (isOn) {
element.classList.add('on');
element.classList.remove('off');
} else {
element.classList.add('off');
element.classList.remove('on');
}
}
function updateCheckList(light) {
const listItem = document.querySelector(`#statusCheckList${currentDeviceType} li[data-light="${light}"]`);
if (listItem) {
const checkMark = listItem.querySelector('.badge');
checkMark.style.display = 'inline-block';
}
}
function checkAllTestsPassed() {
// 检查所有测试项是否都通过
allTestsPassed = Array.from(document.querySelectorAll(`#statusCheckList${currentDeviceType} .badge`))
.every(badge => badge.style.display === 'inline-block');
console.log('所有测试是否通过:', allTestsPassed); // 调试输出
// 如果所有测试都通过,更新测试结果
if (allTestsPassed) {
const rows = document.querySelectorAll('#resultTable tbody tr');
const lastRow = rows[rows.length - 1];
if (lastRow) {
const checkbox = lastRow.querySelector('.form-check-input');
const label = lastRow.querySelector('.form-check-label');
const pendingSpan = label.querySelector('.pending');
const passSpan = label.querySelector('.pass');
const failSpan = label.querySelector('.fail');
const passTimeSpan = lastRow.querySelector('.pass-time');
// 更新复选框状态
checkbox.disabled = false;
checkbox.checked = true;
// 更新显示状态
pendingSpan.style.display = 'none';
passSpan.style.display = 'inline';
failSpan.style.display = 'none';
// 更新行样式
lastRow.classList.remove('pending-row', 'fail-row');
lastRow.classList.add('pass-row');
// 记录通过时间
const now = new Date();
const timeString = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
passTimeSpan.textContent = timeString;
console.log('测试通过,更新完成'); // 调试输出
}
}
}
function resetCheckList() {
lightHistory = {
common: false,
alarm: false,
up: false,
down: false,
emergency_stop: false
};
allTestsPassed = false;
const deviceType = document.getElementById('deviceType').value;
const checkList = document.getElementById(`statusCheckList${currentDeviceType}`);
if (checkList) {
const badges = checkList.querySelectorAll('.badge');
badges.forEach(badge => {
badge.style.display = 'none';
});
}
// 强制更新最后一行的状态为待测试
const rows = document.querySelectorAll('#resultTable tbody tr');
const lastRow = rows[rows.length - 1];
if (lastRow) {
const checkbox = lastRow.querySelector('.form-check-input');
const label = lastRow.querySelector('.form-check-label');
const pendingSpan = label.querySelector('.pending');
const passSpan = label.querySelector('.pass');
const failSpan = label.querySelector('.fail');
checkbox.disabled = true;
checkbox.checked = false;
pendingSpan.style.display = 'inline';
passSpan.style.display = 'none';
failSpan.style.display = 'none';
lastRow.classList.add('pending-row');
lastRow.classList.remove('pass-row', 'fail-row');
}
}
function updateTestResult() {
const rows = document.querySelectorAll('#resultTable tbody tr');
const lastRow = rows[rows.length - 1];
if (!lastRow) return;
const checkbox = lastRow.querySelector('.form-check-input');
const label = lastRow.querySelector('.form-check-label');
const pendingSpan = label.querySelector('.pending');
const passSpan = label.querySelector('.pass');
const failSpan = label.querySelector('.fail');
const passTimeSpan = lastRow.querySelector('.pass-time');
if (allTestsPassed) {
// 如果所有测试通过,设置为合格状态
checkbox.disabled = false;
checkbox.checked = true;
pendingSpan.style.display = 'none';
passSpan.style.display = 'inline';
failSpan.style.display = 'none';
lastRow.classList.remove('pending-row', 'fail-row');
lastRow.classList.add('pass-row');
// 如果还没有记录时间,则记录当前时间
if (!passTimeSpan.textContent) {
const now = new Date();
const timeString = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
passTimeSpan.textContent = timeString;
}
} else {
// 如果测试未完成,设置为待测试状态
checkbox.disabled = true;
checkbox.checked = false;
pendingSpan.style.display = 'inline';
passSpan.style.display = 'none';
failSpan.style.display = 'none';
lastRow.classList.add('pending-row');
lastRow.classList.remove('pass-row', 'fail-row');
passTimeSpan.textContent = '';
}
}
function addNewRow(button) {
const table = document.getElementById('resultTable').getElementsByTagName('tbody')[0];
const currentRow = button.closest('tr');
const serialNumberInput = currentRow.querySelector('.serial-number');
if (serialNumberInput.value.trim() === '') {
alert('请输入设备序列号');
return;
}
// 固定当前行状态
finalizeRowStatus(currentRow);
// 创建新行
const newRow = table.insertRow();
const rowIndex = table.rows.length - 1;
// 重置所有状态(在创建新行之前)
allTestsPassed = false;
lightHistory = {
common: false,
alarm: false,
up: false,
down: false,
emergency_stop: false
};
// 创建新行的HTML
const cell1 = newRow.insertCell(0);
const cell2 = newRow.insertCell(1);
const cell3 = newRow.insertCell(2);
const cell4 = newRow.insertCell(3);
// 设置新行的初始状态
cell1.innerHTML = '<input type="text" class="form-control serial-number" placeholder="输入设备序列号">';
cell2.innerHTML = `
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="result-${rowIndex}" disabled>
<label class="form-check-label" for="result-${rowIndex}">
<span class="pending" style="display: inline;">待测试</span>
<span class="pass" style="display: none;">合格</span>
<span class="fail" style="display: none;">不合格</span>
</label>
</div>`;
cell3.innerHTML = '<span class="pass-time"></span>';
cell4.innerHTML = '<button class="btn btn-primary add-row-btn" onclick="addNewRow(this)">增加下一条</button>';
// 直接设置新行的状态不依赖updateTestResult函数
const newCheckbox = newRow.querySelector('.form-check-input');
const newLabel = newRow.querySelector('.form-check-label');
const newPendingSpan = newLabel.querySelector('.pending');
const newPassSpan = newLabel.querySelector('.pass');
const newFailSpan = newLabel.querySelector('.fail');
newCheckbox.disabled = true;
newCheckbox.checked = false;
newPendingSpan.style.display = 'inline';
newPassSpan.style.display = 'none';
newFailSpan.style.display = 'none';
newRow.classList.add('pending-row');
newRow.classList.remove('pass-row', 'fail-row');
// 重置其他状态
resetLightStatus();
clearSignalData();
resetDetectionStatus();
resetCheckList();
// 聚焦到新的设备序列号输入框
const newSerialInput = newRow.querySelector('.serial-number');
newSerialInput.focus();
}
function finalizeRowStatus(row) {
const serialNumberInput = row.querySelector('.serial-number');
const addButton = row.querySelector('.add-row-btn');
const checkbox = row.querySelector('.form-check-input');
serialNumberInput.disabled = true;
addButton.style.display = 'none';
checkbox.disabled = true;
}
//重置测试结果
function resetTestResult() {
allTestsPassed = false;
updateTestResult();
}
//重置检测状态记录
function resetDetectionStatus() {
lightHistory = {
common: false,
alarm: false,
up: false,
down: false,
emergency_stop: false
};
const deviceType = document.getElementById('deviceType').value;
const checkList = document.getElementById(`statusCheckList${deviceType}`);
if (checkList) {
const badges = checkList.querySelectorAll('.badge');
badges.forEach(badge => {
badge.style.display = 'none';
});
}
}
//重置灯光状态
function resetLightStatus() {
const lights = document.querySelectorAll('.light');
lights.forEach(light => {
light.classList.remove('on');
light.classList.add('off');
});
}
function resetForm() {
// 重置测试结果为待测试状态
resetTestResult();
// 重置灯光状态
resetLightStatus();
// 重置检测状态记录
resetCheckList();
// 重置检测状态记录
resetDetectionStatus();
// 清空信号数据
clearSignalData();
// 重新初始化灯光显示
updateDeviceTypeDisplay();
// 确保 allTestsPassed 被重置
allTestsPassed = false;
}
function clearSignalData() {
// 发送请求到后端清空信号数据
fetch('/clear_signal_data', { method: 'POST' })
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('信号数据已清空');
} else {
console.error('清空信号数据失败');
}
})
.catch(error => {
console.error('清空信号数据时发生错误:', error);
});
}
function exportToExcel() {
const table = document.getElementById('resultTable');
const deviceType = document.getElementById('deviceType').value;
const deviceModel = document.getElementById('deviceModel').value;
const tester = document.getElementById('tester').value;
const orderNumber = document.getElementById('orderNumber').value;
const testDate = document.getElementById('testDate').value;
const data = [];
// 添加测试信息
data.push(['设备类型', deviceType]);
data.push(['设备型号', deviceModel]);
data.push(['检测人员', tester]);
data.push(['订单编号', orderNumber]);
data.push(['测试日期', testDate]);
data.push([]); // 空行
const headers = ['设备序列号', '测试结果', '合格时间'];
data.push(headers);
for (let i = 1; i < table.rows.length; i++) {
const row = table.rows[i];
const serialNumber = row.cells[0].querySelector('input').value;
const testResult = row.cells[1].querySelector('input').checked ? '合格' : '不合格';
const passTime = row.cells[2].querySelector('.pass-time').textContent;
data.push([serialNumber, testResult, passTime]);
}
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
const colWidth = [{ wch: 20 }, { wch: 10 }, { wch: 20 }];
ws['!cols'] = colWidth;
XLSX.utils.book_append_sheet(wb, ws, "测试结果");
XLSX.writeFile(wb, `测试结果_${orderNumber}_${testDate}.xlsx`);
}
function startTest() {
disableInfoInputs();
const deviceTypeSelect = document.getElementById('deviceType');
if (deviceTypeSelect) {
deviceTypeSelect.disabled = false;
}
const firstSerialInput = document.getElementById('firstSerialNumber');
if (firstSerialInput) {
firstSerialInput.focus();
firstSerialInput.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}
function disableInfoInputs() {
const infoInputs = document.querySelectorAll('.info-input:not(#deviceType)');
infoInputs.forEach(input => {
input.disabled = true;
});
const startTestBtn = document.getElementById('startTestBtn');
if (startTestBtn) {
startTestBtn.disabled = true;
}
}
function setupDeviceTypeListener() {
const deviceTypeSelect = document.getElementById('deviceType');
const deviceModelSelect = document.getElementById('deviceModel');
if (deviceTypeSelect) {
deviceTypeSelect.addEventListener('change', function() {
const selectedType = this.value;
// 根据设备类型更新 currentDeviceType
if (selectedType === 'A类-4孔') {
currentDeviceType = '4'; // 对应四孔
} else if (selectedType === 'B类-5孔') {
currentDeviceType = '5'; // 对应五孔
} else {
currentDeviceType = '';
}
// 更新显示
updateDeviceTypeDisplay();
// 重置检测状态
resetForm();
// 重新开始监控灯光状态
updateLights();
});
}
}
function updateDeviceTypeDisplay() {
const fiveHoleLights = document.getElementById('fiveHoleLights');
const fourHoleLights = document.getElementById('fourHoleLights');
const statusCheckList5 = document.getElementById('statusCheckList5');
const statusCheckList4 = document.getElementById('statusCheckList4');
// 首先隐藏所有元素
if (fiveHoleLights) fiveHoleLights.style.display = 'none';
if (fourHoleLights) fourHoleLights.style.display = 'none';
if (statusCheckList5) statusCheckList5.style.display = 'none';
if (statusCheckList4) statusCheckList4.style.display = 'none';
// 根据当前设备类型显示相应元素
if (currentDeviceType === '5') { // B类-5孔
if (fiveHoleLights) {
fiveHoleLights.style.display = 'flex';
// 确保所有灯初始状态为关闭
const lights = fiveHoleLights.querySelectorAll('.light');
lights.forEach(light => {
light.classList.remove('on');
light.classList.add('off');
});
}
if (statusCheckList5) statusCheckList5.style.display = 'block';
} else if (currentDeviceType === '4') { // A类-4孔
if (fourHoleLights) {
fourHoleLights.style.display = 'flex';
// 确保所有灯初始状态为关闭
const lights = fourHoleLights.querySelectorAll('.light');
lights.forEach(light => {
light.classList.remove('on');
light.classList.add('off');
});
}
if (statusCheckList4) statusCheckList4.style.display = 'block';
}
// 重置检查列表状态
resetCheckList();
}
function setupPortSelection() {
const selectPortBtn = document.getElementById('selectPortBtn');
const confirmPortBtn = document.getElementById('confirmPortBtn');
const portSelect = document.getElementById('portSelect');
selectPortBtn.addEventListener('click', async () => {
try {
const response = await fetch('/get_ports');
const ports = await response.json();
portSelect.innerHTML = '';
if (ports.length === 0) {
const option = document.createElement('option');
option.textContent = '没有找到可用的串口';
portSelect.appendChild(option);
confirmPortBtn.disabled = true;
} else {
ports.forEach(port => {
const option = document.createElement('option');
option.value = port.device;
option.textContent = `${port.device} - ${port.description}`;
portSelect.appendChild(option);
});
confirmPortBtn.disabled = false;
}
const portModal = new bootstrap.Modal(document.getElementById('portModal'));
portModal.show();
} catch (error) {
console.error('获取串口列表失败:', error);
alert('获取串口列表失败,请重试。');
}
});
confirmPortBtn.addEventListener('click', async () => {
const selectedPort = portSelect.value;
if (selectedPort) {
try {
const response = await fetch('/set_port', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ port: selectedPort }),
});
const result = await response.json();
if (result.success) {
alert('串口设置成功');
bootstrap.Modal.getInstance(document.getElementById('portModal')).hide();
} else {
alert('串口设置失败: ' + result.message);
}
} catch (error) {
console.error('设置串口失败:', error);
alert('设置串口失败,请重试。');
}
} else {
alert('请选择一个串口');
}
});
}
async function loadDeviceData() {
try {
const response = await fetch('../static/config/model.json');
const data = await response.json();
// 获取所有不重复的设备型
const deviceTypes = [...new Set(data.map(item => item.Type))];
// 填充设备类型下拉框
const deviceTypeSelect = document.getElementById('deviceType');
deviceTypeSelect.innerHTML = '<option selected>请选择...</option>';
deviceTypes.forEach(type => {
const option = document.createElement('option');
option.value = type;
option.textContent = type;
deviceTypeSelect.appendChild(option);
});
// 设置设备类型变化时的监听器
deviceTypeSelect.addEventListener('change', function() {
const selectedType = this.value;
const deviceModelSelect = document.getElementById('deviceModel');
if (selectedType === '请选择...') {
deviceModelSelect.innerHTML = '<option selected>请先选择设备类型...</option>';
deviceModelSelect.disabled = true;
return;
}
// 获取选中类型对应的型号
const models = data.filter(item => item.Type === selectedType);
// 填充设备型号下拉框
deviceModelSelect.innerHTML = '<option selected>请选择型号...</option>';
models.forEach(model => {
const option = document.createElement('option');
option.value = model.Model;
option.textContent = model.Model;
deviceModelSelect.appendChild(option);
});
deviceModelSelect.disabled = false;
});
} catch (error) {
console.error('加载设备数据失败:', error);
}
}
document.addEventListener('DOMContentLoaded', function() {
loadDeviceData();
setupDeviceTypeListener();
setupPortSelection();
const startTestBtn = document.getElementById('startTestBtn');
if (startTestBtn) {
startTestBtn.addEventListener('click', function(event) {
event.preventDefault();
startTest();
});
}
// 初始化设备类型显示
updateDeviceTypeDisplay();
// 每300毫秒更新一次灯光状态
if (!window.lightUpdateInterval) {
window.lightUpdateInterval = setInterval(updateLights, 300);
}
});