新增功能: - 线圈参数管理页 (/coil-info): 增删改查,日志记录 - 模拟车辆管理页 (/simulate-car): 增删改查,日志记录 - 工装配置页新增线圈/模拟车辆选择区,保存时关联到 tb_fixture_param - 测试信息查询页新增「测试环境」列,显示当前线圈和模拟车辆信息 - edc_server 写入测试数据时自动从 fixture 获取线圈/车辆关联 数据库: - 新增 tb_coil_info、tb_simulate_car 表 - tb_fixture_param 增加 coil_id/simulate_car_id 字段 - tb_state_tst 增加 coil_id/simulate_car_id 字段 后端: - models.py 新增线圈/模拟车辆 CRUD - get_fixture_param 改为 LEFT JOIN 返回线圈/车辆详情 - upsert_fixture_param 支持 coil_id/simulate_car_id - 测试数据查询 LEFT JOIN 线圈/车辆信息
152 lines
5.5 KiB
JavaScript
152 lines
5.5 KiB
JavaScript
// 模拟车辆参数管理
|
||
|
||
let editId = null;
|
||
|
||
function toast(msg, isError = false) {
|
||
const el = document.getElementById("toast");
|
||
el.textContent = msg;
|
||
el.className = "msg-toast " + (isError ? "error" : "") + " show";
|
||
clearTimeout(el._timeout);
|
||
el._timeout = setTimeout(() => { el.className = "msg-toast"; }, 3000);
|
||
}
|
||
|
||
async function loadList() {
|
||
const search = document.getElementById("search-input").value;
|
||
try {
|
||
const resp = await fetch(`/api/simulate-car?search=${encodeURIComponent(search)}`);
|
||
const data = await resp.json();
|
||
renderTable(data);
|
||
} catch (e) {
|
||
console.error("加载失败:", e);
|
||
}
|
||
}
|
||
|
||
function sizeLabel(item) {
|
||
if (item.shape === '圆形') return `半径${item.radius || 0}cm`;
|
||
if (item.shape === '矩形') return `${item.length || 0}×${item.width || 0}cm`;
|
||
return '-';
|
||
}
|
||
|
||
function renderTable(data) {
|
||
const tbody = document.querySelector("#car-table tbody");
|
||
if (!data.length) {
|
||
tbody.innerHTML = '<tr><td colspan="7" style="color:#999;text-align:center;">暂无数据,点右上角「新增」添加</td></tr>';
|
||
return;
|
||
}
|
||
tbody.innerHTML = data.map(t => `
|
||
<tr>
|
||
<td>${esc(t.simulate_num)}</td>
|
||
<td>${esc(t.name)}</td>
|
||
<td>${t.shape || '-'}</td>
|
||
<td>${sizeLabel(t)}</td>
|
||
<td>${esc(t.material || '-')}</td>
|
||
<td>${esc(t.remark || '-')}</td>
|
||
<td>
|
||
<button class="btn-edit" onclick="openModal(${t.id})">编辑</button>
|
||
<button class="btn-del" onclick="deleteRecord(${t.id}, '${esc(t.simulate_num || t.name)}')">删除</button>
|
||
</td>
|
||
</tr>
|
||
`).join("");
|
||
}
|
||
|
||
function openModal(id = null) {
|
||
editId = id;
|
||
document.getElementById("modal-title").textContent = id ? "编辑模拟车辆参数" : "新增模拟车辆参数";
|
||
document.getElementById("edit-modal").style.display = "flex";
|
||
|
||
if (id) {
|
||
fetch(`/api/simulate-car/${id}`)
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
document.getElementById("edit-simulate-num").value = data.simulate_num || "";
|
||
document.getElementById("edit-name").value = data.name || "";
|
||
document.getElementById("edit-shape").value = data.shape || "";
|
||
document.getElementById("edit-length").value = data.length || 0;
|
||
document.getElementById("edit-width").value = data.width || 0;
|
||
document.getElementById("edit-radius").value = data.radius || 0;
|
||
document.getElementById("edit-material").value = data.material || "";
|
||
document.getElementById("edit-remark").value = data.remark || "";
|
||
});
|
||
} else {
|
||
document.getElementById("edit-simulate-num").value = "";
|
||
document.getElementById("edit-name").value = "";
|
||
document.getElementById("edit-shape").value = "";
|
||
document.getElementById("edit-length").value = "0";
|
||
document.getElementById("edit-width").value = "0";
|
||
document.getElementById("edit-radius").value = "0";
|
||
document.getElementById("edit-material").value = "";
|
||
document.getElementById("edit-remark").value = "";
|
||
}
|
||
}
|
||
|
||
function closeModal() {
|
||
document.getElementById("edit-modal").style.display = "none";
|
||
editId = null;
|
||
}
|
||
|
||
async function saveRecord() {
|
||
const data = {
|
||
simulate_num: document.getElementById("edit-simulate-num").value.trim(),
|
||
name: document.getElementById("edit-name").value.trim(),
|
||
shape: document.getElementById("edit-shape").value,
|
||
length: parseFloat(document.getElementById("edit-length").value) || 0,
|
||
width: parseFloat(document.getElementById("edit-width").value) || 0,
|
||
radius: parseFloat(document.getElementById("edit-radius").value) || 0,
|
||
material: document.getElementById("edit-material").value.trim(),
|
||
remark: document.getElementById("edit-remark").value.trim(),
|
||
};
|
||
|
||
if (!data.simulate_num && !data.name) {
|
||
toast("请输入模拟编号或名称", true);
|
||
return;
|
||
}
|
||
|
||
try {
|
||
let resp;
|
||
if (editId) {
|
||
resp = await fetch(`/api/simulate-car/${editId}`, {
|
||
method: "PUT",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(data),
|
||
});
|
||
} else {
|
||
resp = await fetch("/api/simulate-car", {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(data),
|
||
});
|
||
}
|
||
const result = await resp.json();
|
||
if (result.ok || resp.ok) {
|
||
toast(editId ? "更新成功" : "新增成功");
|
||
closeModal();
|
||
loadList();
|
||
} else {
|
||
toast("保存失败: " + (result.error || "未知错误"), true);
|
||
}
|
||
} catch (e) {
|
||
toast("保存失败: " + e.message, true);
|
||
}
|
||
}
|
||
|
||
async function deleteRecord(id, label) {
|
||
if (!confirm(`确定要删除「${label}」吗?`)) return;
|
||
|
||
try {
|
||
const resp = await fetch(`/api/simulate-car/${id}`, { method: "DELETE" });
|
||
const result = await resp.json();
|
||
if (result.ok) {
|
||
toast("删除成功");
|
||
loadList();
|
||
} else {
|
||
toast("删除失败: " + (result.error || "未知错误"), true);
|
||
}
|
||
} catch (e) {
|
||
toast("删除失败: " + e.message, true);
|
||
}
|
||
}
|
||
|
||
function esc(s) { return (s || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); }
|
||
|
||
loadList();
|