feat: 波动测试模式前端适配 — tb_state_tst扩展+0xB4存库+页面更新
- edc_server/models.py: tb_state_tst DDL增加test_mode/data_source + B4字段 + ALTER TABLE自动迁移 + insert_test_result扩展 + insert_wave_data - edc_server/handlers.py: 0xB2处理传test_mode、0xB4处理调用insert_wave_data存库 - edc-web/models.py: 新增get_latest_wave_data/get_wave_records + test_mode筛选 - edc-web/routes: test_op返回wave数据、test_data支持test_mode筛选 - 前端: test_op页面增加波动数据显示区+测试模式列 test_data页面增加test_mode下拉筛选+B4字段列+CSV导出适配
This commit is contained in:
248
docs/plans/2026-05-31-wave-test-frontend.md
Normal file
248
docs/plans/2026-05-31-wave-test-frontend.md
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
# 波动测试模式前端适配 实施计划
|
||||||
|
|
||||||
|
> **For Hermes:** 直接执行各 Task。
|
||||||
|
|
||||||
|
**Goal:** 将波动测试模式(0xB2 的 test_mode + 0xB4 上报数据)接入测试操作页面、查询导出页面,扩展 `tb_state_tst` 表字段。
|
||||||
|
|
||||||
|
**Architecture:** 单表方案 — `tb_state_tst` 增加 `test_mode`、`data_source` 和 B4 专属字段,B2 和 B4 记录共存同表,通过 `data_source` 区分。后端 edc_server 存储、edc-web 查询/导出均扩展。
|
||||||
|
|
||||||
|
**Tech Stack:** Python/aiomysql (edc_server) + Flask/pymysql (edc-web) + vanilla JS 前端
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 涉及文件
|
||||||
|
|
||||||
|
| 层 | 文件 | 变更 |
|
||||||
|
|---|---|---|
|
||||||
|
| 数据库 | `edc_server/src/models.py` | DDL + ALTER 迁移 + `insert_test_result` 扩展 + 新增 `insert_wave_data` |
|
||||||
|
| 解析 | `edc_server/src/handlers.py` | 0xB2 传 test_mode、0xB4 调 insert_wave_data |
|
||||||
|
| 查询 | `edc-web/app/models.py` | 新增查询函数、导出扩展 |
|
||||||
|
| API | `edc-web/app/routes/test_op.py` | progress 端点返回波动数据 |
|
||||||
|
| API | `edc-web/app/routes/test_data.py` | 查询/导出增加新字段 |
|
||||||
|
| 前端 | `edc-web/app/templates/test_op.html` | 增加波动数据显示区 |
|
||||||
|
| 前端 | `edc-web/app/static/js/test_op.js` | renderLatest/renderRecords 扩展 + B4 轮询 |
|
||||||
|
| 前端 | `edc-web/app/templates/test_data.html` | 表头增加列 + test_mode 筛选 |
|
||||||
|
| 前端 | `edc-web/app/static/js/test_data.js` | renderTable 扩展 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: 扩展 tb_state_tst DDL + 迁移 (edc_server)
|
||||||
|
|
||||||
|
**文件:** `edc_server/src/models.py`
|
||||||
|
|
||||||
|
**Step 1:** 修改 CREATE TABLE 增加 9 列
|
||||||
|
|
||||||
|
在现有 `tb_state_tst` DDL 中增加:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
`test_mode` TINYINT DEFAULT 0 COMMENT '0 灵敏度测试, 1 波动测试',
|
||||||
|
`data_source` CHAR(2) DEFAULT 'B2' COMMENT '数据来源 B2/B4',
|
||||||
|
`remain_count` INT DEFAULT 0 COMMENT '剩余波动次数 (B4)',
|
||||||
|
`work_freq` FLOAT DEFAULT 0 COMMENT '工作频率 Hz (B4)',
|
||||||
|
`curr_dist` INT DEFAULT 0 COMMENT '当前距离 mm (B4)',
|
||||||
|
`speed` INT DEFAULT 0 COMMENT '当前速度 dm/s (B4)',
|
||||||
|
`near_dist` INT DEFAULT 0 COMMENT '波动最近距离 mm (B4)',
|
||||||
|
`far_dist` INT DEFAULT 0 COMMENT '波动最远距离 mm (B4)',
|
||||||
|
`b4_enter_dist` INT DEFAULT 0 COMMENT 'B4 进入高度 mm',
|
||||||
|
`b4_leave_dist` INT DEFAULT 0 COMMENT 'B4 离开高度 mm'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2:** 在 `_create_tables` 末尾增加 ALTER TABLE 迁移逻辑(参照已有的 `tb_fixture_param` 迁移模式)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# V2.0.4 迁移:tb_state_tst 增加波动测试字段
|
||||||
|
for col, col_def in [
|
||||||
|
("test_mode", "TINYINT DEFAULT 0 COMMENT '0 灵敏度, 1 波动测试'"),
|
||||||
|
("data_source", "CHAR(2) DEFAULT 'B2' COMMENT 'B2/B4'"),
|
||||||
|
("remain_count", "INT DEFAULT 0 COMMENT '剩余波动次数'"),
|
||||||
|
("work_freq", "FLOAT DEFAULT 0 COMMENT '工作频率 Hz'"),
|
||||||
|
("curr_dist", "INT DEFAULT 0 COMMENT '当前距离 mm'"),
|
||||||
|
("speed", "INT DEFAULT 0 COMMENT '当前速度 dm/s'"),
|
||||||
|
("near_dist", "INT DEFAULT 0 COMMENT '波动最近距离 mm'"),
|
||||||
|
("far_dist", "INT DEFAULT 0 COMMENT '波动最远距离 mm'"),
|
||||||
|
("b4_enter_dist", "INT DEFAULT 0 COMMENT 'B4 进入高度 mm'"),
|
||||||
|
("b4_leave_dist", "INT DEFAULT 0 COMMENT 'B4 离开高度 mm'"),
|
||||||
|
]:
|
||||||
|
try:
|
||||||
|
await cur.execute(f"ALTER TABLE `tb_state_tst` ADD COLUMN `{col}` {col_def}")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3:** 修改 `insert_test_result` 函数签名,增加 `test_mode`、`data_source` 参数
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def insert_test_result(dnt_id, dpg430_addr, pcnum, serialnum,
|
||||||
|
sub_type, str_type, iffinish, fault_info,
|
||||||
|
relay_out, ppvalue, idle_freq, enter_freq,
|
||||||
|
exit_freq, enter_dist, exit_dist,
|
||||||
|
enter_speed, exit_speed,
|
||||||
|
test_mode=0, data_source='B2'):
|
||||||
|
```
|
||||||
|
|
||||||
|
INSERT 语句增加 `test_mode`, `data_source` 列。
|
||||||
|
|
||||||
|
**Step 4:** 新增 `insert_wave_data` 函数
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def insert_wave_data(dnt_id, dpg430_addr, remain_count, relay_out,
|
||||||
|
work_freq, curr_dist, speed, near_dist, far_dist,
|
||||||
|
enter_dist, leave_dist):
|
||||||
|
"""插入 0xB4 波动测试上报数据到 tb_state_tst"""
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 2: handlers.py 适配
|
||||||
|
|
||||||
|
**文件:** `edc_server/src/handlers.py`
|
||||||
|
|
||||||
|
**Step 1:** 0xB2 处理 — `insert_test_result` 调用增加 `test_mode=status.test_mode`
|
||||||
|
|
||||||
|
```python
|
||||||
|
await insert_test_result(
|
||||||
|
...
|
||||||
|
test_mode=status.test_mode,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2:** 0xB4 处理 — 调用 `insert_wave_data` 存库
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src.models import insert_wave_data # 增加导入
|
||||||
|
|
||||||
|
# 在 0xB4 分支末尾
|
||||||
|
await insert_wave_data(
|
||||||
|
dnt_id=dnt_id,
|
||||||
|
dpg430_addr=wave.addr,
|
||||||
|
remain_count=wave.remain_count,
|
||||||
|
relay_out=wave.relay_out,
|
||||||
|
work_freq=wave.work_freq,
|
||||||
|
curr_dist=wave.curr_dist,
|
||||||
|
speed=wave.speed,
|
||||||
|
near_dist=wave.near_dist,
|
||||||
|
far_dist=wave.far_dist,
|
||||||
|
enter_dist=wave.enter_dist,
|
||||||
|
leave_dist=wave.leave_dist,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 3: edc-web models.py 查询扩展
|
||||||
|
|
||||||
|
**文件:** `edc-web/app/models.py`
|
||||||
|
|
||||||
|
**Step 1:** 新增 `get_latest_wave_data(dnt_id)` — 获取最新一条 B4 数据
|
||||||
|
|
||||||
|
**Step 2:** 新增 `get_wave_records(dnt_id, since)` — 获取本轮 B4 明细
|
||||||
|
|
||||||
|
查询条件: `data_source='B4' AND create_time >= since`
|
||||||
|
|
||||||
|
**Step 3:** 修改 `get_automation_averages` — 不涉及波动字段,保持不变
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 4: edc-web test_op.py 路由扩展
|
||||||
|
|
||||||
|
**文件:** `edc-web/app/routes/test_op.py`
|
||||||
|
|
||||||
|
在 `api_automation_progress` 中增加返回 B4 数据:
|
||||||
|
|
||||||
|
```python
|
||||||
|
latest_wave = get_latest_wave_data(dnt_id)
|
||||||
|
wave_records = get_wave_records(dnt_id, since) if since else []
|
||||||
|
return jsonify({
|
||||||
|
...
|
||||||
|
"latest_wave": latest_wave,
|
||||||
|
"wave_records": wave_records,
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
导入新增的 `get_latest_wave_data`, `get_wave_records`。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 5: edc-web test_data.py 路由扩展
|
||||||
|
|
||||||
|
**文件:** `edc-web/app/routes/test_data.py`
|
||||||
|
|
||||||
|
**Step 1:** `api_test_data` — 增加 `test_mode` 筛选参数
|
||||||
|
|
||||||
|
```python
|
||||||
|
test_mode = request.args.get("test_mode", "", type=str) # '' = 全部, '0' = 灵敏度, '1' = 波动
|
||||||
|
```
|
||||||
|
|
||||||
|
传给 `get_test_data`,在 SQL WHERE 中增加 `AND t.test_mode = %s` 条件。
|
||||||
|
|
||||||
|
**Step 2:** 修改 `get_test_data` 函数签名和 SQL(在 models.py 中)
|
||||||
|
|
||||||
|
**Step 3:** CSV 导出同样支持 `test_mode` 筛选
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 6: 前端 test_op.html + test_op.js
|
||||||
|
|
||||||
|
**文件:** `edc-web/app/templates/test_op.html` + `static/js/test_op.js`
|
||||||
|
|
||||||
|
**Step 1:** HTML — 在 `latest-result` 区域增加波动数据显示 div
|
||||||
|
|
||||||
|
```html
|
||||||
|
<h3>波动测试数据</h3>
|
||||||
|
<div id="latest-wave">
|
||||||
|
<p class="placeholder">暂无波动数据...</p>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2:** JS — `renderLatest` 增加 test_mode 显示
|
||||||
|
|
||||||
|
在现有显示中增加:
|
||||||
|
```js
|
||||||
|
<p>测试模式:<strong>${data.test_mode === 1 ? '波动测试' : '灵敏度测试'}</strong></p>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3:** JS — 新增 `renderLatestWave(data)` 函数
|
||||||
|
|
||||||
|
显示 B4 上报数据:剩余次数、当前距离、速度、最近/最远距离、进入/离开高度。
|
||||||
|
|
||||||
|
**Step 4:** JS — `pollProgress` 中调用 `renderLatestWave(data.latest_wave)`
|
||||||
|
|
||||||
|
**Step 5:** JS — 明细表 `renderRecords` 增加测试模式列
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 7: 前端 test_data.html + test_data.js
|
||||||
|
|
||||||
|
**文件:** `edc-web/app/templates/test_data.html` + `static/js/test_data.js`
|
||||||
|
|
||||||
|
**Step 1:** HTML — 搜索栏增加测试模式下拉筛选
|
||||||
|
|
||||||
|
```html
|
||||||
|
<label>
|
||||||
|
测试模式:
|
||||||
|
<select id="search-test-mode">
|
||||||
|
<option value="">全部</option>
|
||||||
|
<option value="0">灵敏度测试</option>
|
||||||
|
<option value="1">波动测试</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2:** HTML — 表头增加列:测试模式、数据来源、剩余次数、工作频率、当前距离、速度、最近距离、最远距离
|
||||||
|
|
||||||
|
**Step 3:** JS — `searchData` 传 `test_mode` 参数
|
||||||
|
|
||||||
|
**Step 4:** JS — `renderTable` 增加新列渲染
|
||||||
|
|
||||||
|
**Step 5:** JS — `exportCSV` 传 `test_mode` 参数
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 8: 提交推送
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/wfq/projects/vd_test_fixture
|
||||||
|
git add -A
|
||||||
|
git commit -m "feat: 波动测试模式前端适配 — tb_state_tst扩展+0xB4存库+页面更新"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
@@ -151,8 +151,11 @@ def get_latest_test_state(dnt_id: int) -> dict | None:
|
|||||||
|
|
||||||
def get_test_data(page: int = 1, per_page: int = 20,
|
def get_test_data(page: int = 1, per_page: int = 20,
|
||||||
serial: str = "", date_from: str = "",
|
serial: str = "", date_from: str = "",
|
||||||
date_to: str = "") -> tuple[list[dict], int]:
|
date_to: str = "", test_mode: str = "") -> tuple[list[dict], int]:
|
||||||
"""分页查询测试数据(JOIN dnt_info),返回 (records, total)"""
|
"""分页查询测试数据(JOIN dnt_info),返回 (records, total)
|
||||||
|
|
||||||
|
test_mode: ''=全部, '0'=灵敏度, '1'=波动
|
||||||
|
"""
|
||||||
conn = get_conn()
|
conn = get_conn()
|
||||||
try:
|
try:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
@@ -167,6 +170,9 @@ def get_test_data(page: int = 1, per_page: int = 20,
|
|||||||
if date_to:
|
if date_to:
|
||||||
where.append("t.create_time <= %s")
|
where.append("t.create_time <= %s")
|
||||||
params.append(date_to + " 23:59:59")
|
params.append(date_to + " 23:59:59")
|
||||||
|
if test_mode:
|
||||||
|
where.append("t.test_mode = %s")
|
||||||
|
params.append(int(test_mode))
|
||||||
|
|
||||||
where_clause = " AND ".join(where) if where else "1=1"
|
where_clause = " AND ".join(where) if where else "1=1"
|
||||||
|
|
||||||
@@ -195,8 +201,11 @@ def get_test_data(page: int = 1, per_page: int = 20,
|
|||||||
|
|
||||||
|
|
||||||
def get_all_test_data_for_export(serial: str = "", date_from: str = "",
|
def get_all_test_data_for_export(serial: str = "", date_from: str = "",
|
||||||
date_to: str = "") -> list[dict]:
|
date_to: str = "", test_mode: str = "") -> list[dict]:
|
||||||
"""导出全部数据"""
|
"""导出全部数据
|
||||||
|
|
||||||
|
test_mode: ''=全部, '0'=灵敏度, '1'=波动
|
||||||
|
"""
|
||||||
conn = get_conn()
|
conn = get_conn()
|
||||||
try:
|
try:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
@@ -211,6 +220,9 @@ def get_all_test_data_for_export(serial: str = "", date_from: str = "",
|
|||||||
if date_to:
|
if date_to:
|
||||||
where.append("t.create_time <= %s")
|
where.append("t.create_time <= %s")
|
||||||
params.append(date_to + " 23:59:59")
|
params.append(date_to + " 23:59:59")
|
||||||
|
if test_mode:
|
||||||
|
where.append("t.test_mode = %s")
|
||||||
|
params.append(int(test_mode))
|
||||||
|
|
||||||
where_clause = " AND ".join(where) if where else "1=1"
|
where_clause = " AND ".join(where) if where else "1=1"
|
||||||
cur.execute(
|
cur.execute(
|
||||||
@@ -285,6 +297,37 @@ def get_automation_records(dnt_id: int, since: str) -> list[dict]:
|
|||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
def get_latest_wave_data(dnt_id: int) -> dict | None:
|
||||||
|
"""获取设备最新一条 B4 波动测试数据"""
|
||||||
|
conn = get_conn()
|
||||||
|
try:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(
|
||||||
|
"SELECT * FROM tb_state_tst WHERE dnt_id=%s AND data_source='B4' "
|
||||||
|
"ORDER BY id DESC LIMIT 1",
|
||||||
|
(dnt_id,),
|
||||||
|
)
|
||||||
|
return cur.fetchone()
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
def get_wave_records(dnt_id: int, since: str) -> list[dict]:
|
||||||
|
"""获取本轮 B4 波动测试明细"""
|
||||||
|
conn = get_conn()
|
||||||
|
try:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(
|
||||||
|
"SELECT * FROM tb_state_tst "
|
||||||
|
"WHERE dnt_id=%s AND data_source='B4' AND create_time >= %s "
|
||||||
|
"ORDER BY id ASC",
|
||||||
|
(dnt_id, since),
|
||||||
|
)
|
||||||
|
return cur.fetchall()
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
# ─── 用户管理 ──────────────────────────────────────────────────────
|
# ─── 用户管理 ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
def get_user_by_username(username: str) -> dict | None:
|
def get_user_by_username(username: str) -> dict | None:
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ def api_test_data():
|
|||||||
serial = request.args.get("serial", "", type=str)
|
serial = request.args.get("serial", "", type=str)
|
||||||
date_from = request.args.get("date_from", "", type=str)
|
date_from = request.args.get("date_from", "", type=str)
|
||||||
date_to = request.args.get("date_to", "", type=str)
|
date_to = request.args.get("date_to", "", type=str)
|
||||||
|
test_mode = request.args.get("test_mode", "", type=str)
|
||||||
|
|
||||||
records, total = get_test_data(page, per_page, serial, date_from, date_to)
|
records, total = get_test_data(page, per_page, serial, date_from, date_to, test_mode)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"records": records,
|
"records": records,
|
||||||
"total": total,
|
"total": total,
|
||||||
@@ -40,8 +41,9 @@ def api_export():
|
|||||||
serial = request.args.get("serial", "", type=str)
|
serial = request.args.get("serial", "", type=str)
|
||||||
date_from = request.args.get("date_from", "", type=str)
|
date_from = request.args.get("date_from", "", type=str)
|
||||||
date_to = request.args.get("date_to", "", type=str)
|
date_to = request.args.get("date_to", "", type=str)
|
||||||
|
test_mode = request.args.get("test_mode", "", type=str)
|
||||||
|
|
||||||
records = get_all_test_data_for_export(serial, date_from, date_to)
|
records = get_all_test_data_for_export(serial, date_from, date_to, test_mode)
|
||||||
|
|
||||||
output = io.StringIO()
|
output = io.StringIO()
|
||||||
writer = csv.writer(output)
|
writer = csv.writer(output)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ from app.models import (
|
|||||||
get_latest_test_state,
|
get_latest_test_state,
|
||||||
get_automation_averages,
|
get_automation_averages,
|
||||||
get_automation_records,
|
get_automation_records,
|
||||||
|
get_latest_wave_data,
|
||||||
|
get_wave_records,
|
||||||
clear_serialnet_records,
|
clear_serialnet_records,
|
||||||
insert_log,
|
insert_log,
|
||||||
)
|
)
|
||||||
@@ -118,9 +120,13 @@ def api_automation_progress(dnt_id):
|
|||||||
latest = get_latest_test_state(dnt_id)
|
latest = get_latest_test_state(dnt_id)
|
||||||
averages = get_automation_averages(dnt_id, since if since else None)
|
averages = get_automation_averages(dnt_id, since if since else None)
|
||||||
records = get_automation_records(dnt_id, since) if since else []
|
records = get_automation_records(dnt_id, since) if since else []
|
||||||
|
latest_wave = get_latest_wave_data(dnt_id)
|
||||||
|
wave_records = get_wave_records(dnt_id, since) if since else []
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"stats": stats,
|
"stats": stats,
|
||||||
"latest": latest,
|
"latest": latest,
|
||||||
"averages": averages,
|
"averages": averages,
|
||||||
"records": records,
|
"records": records,
|
||||||
|
"latest_wave": latest_wave,
|
||||||
|
"wave_records": wave_records,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,11 +13,13 @@ async function searchData(page = 1) {
|
|||||||
const serial = document.getElementById("search-serial").value;
|
const serial = document.getElementById("search-serial").value;
|
||||||
const dateFrom = document.getElementById("search-date-from").value;
|
const dateFrom = document.getElementById("search-date-from").value;
|
||||||
const dateTo = document.getElementById("search-date-to").value;
|
const dateTo = document.getElementById("search-date-to").value;
|
||||||
|
const testMode = document.getElementById("search-test-mode").value;
|
||||||
|
|
||||||
const params = new URLSearchParams({ page, per_page: 20 });
|
const params = new URLSearchParams({ page, per_page: 20 });
|
||||||
if (serial) params.set("serial", serial);
|
if (serial) params.set("serial", serial);
|
||||||
if (dateFrom) params.set("date_from", dateFrom);
|
if (dateFrom) params.set("date_from", dateFrom);
|
||||||
if (dateTo) params.set("date_to", dateTo);
|
if (dateTo) params.set("date_to", dateTo);
|
||||||
|
if (testMode) params.set("test_mode", testMode);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await fetch(`/api/test-data?${params}`);
|
const resp = await fetch(`/api/test-data?${params}`);
|
||||||
@@ -33,7 +35,7 @@ async function searchData(page = 1) {
|
|||||||
function renderTable(records) {
|
function renderTable(records) {
|
||||||
const tbody = document.querySelector("#test-data-table tbody");
|
const tbody = document.querySelector("#test-data-table tbody");
|
||||||
if (!records.length) {
|
if (!records.length) {
|
||||||
tbody.innerHTML = '<tr><td colspan="17" style="text-align:center;color:#999;">暂无数据</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="24" style="text-align:center;color:#999;">暂无数据</td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tbody.innerHTML = records.map(r => `
|
tbody.innerHTML = records.map(r => `
|
||||||
@@ -43,6 +45,8 @@ function renderTable(records) {
|
|||||||
<td>${r.dpg430_addr}</td>
|
<td>${r.dpg430_addr}</td>
|
||||||
<td>${r.sub_type === 1 ? 'PD132' : r.sub_type === 2 ? 'DLD110' : '-'}</td>
|
<td>${r.sub_type === 1 ? 'PD132' : r.sub_type === 2 ? 'DLD110' : '-'}</td>
|
||||||
<td>${r.str_type || '-'}</td>
|
<td>${r.str_type || '-'}</td>
|
||||||
|
<td>${r.test_mode === 1 ? '波动测试' : '灵敏度测试'}</td>
|
||||||
|
<td>${r.data_source || '-'}</td>
|
||||||
<td>${r.iffinish === '1' ? '是' : '否'}</td>
|
<td>${r.iffinish === '1' ? '是' : '否'}</td>
|
||||||
<td>${r.fault_info || '无'}</td>
|
<td>${r.fault_info || '无'}</td>
|
||||||
<td>${r.relay_out || '无'}</td>
|
<td>${r.relay_out || '无'}</td>
|
||||||
@@ -54,6 +58,11 @@ function renderTable(records) {
|
|||||||
<td>${r.exit_dist || '-'}</td>
|
<td>${r.exit_dist || '-'}</td>
|
||||||
<td>${toSpeed(r.enter_speed)}</td>
|
<td>${toSpeed(r.enter_speed)}</td>
|
||||||
<td>${toSpeed(r.exit_speed)}</td>
|
<td>${toSpeed(r.exit_speed)}</td>
|
||||||
|
<td>${r.remain_count || '-'}</td>
|
||||||
|
<td>${r.curr_dist || '-'}</td>
|
||||||
|
<td>${r.speed || '-'}</td>
|
||||||
|
<td>${r.near_dist || '-'}</td>
|
||||||
|
<td>${r.far_dist || '-'}</td>
|
||||||
<td>${r.create_time || '-'}</td>
|
<td>${r.create_time || '-'}</td>
|
||||||
</tr>
|
</tr>
|
||||||
`).join("");
|
`).join("");
|
||||||
@@ -78,11 +87,13 @@ function exportCSV() {
|
|||||||
const serial = document.getElementById("search-serial").value;
|
const serial = document.getElementById("search-serial").value;
|
||||||
const dateFrom = document.getElementById("search-date-from").value;
|
const dateFrom = document.getElementById("search-date-from").value;
|
||||||
const dateTo = document.getElementById("search-date-to").value;
|
const dateTo = document.getElementById("search-date-to").value;
|
||||||
|
const testMode = document.getElementById("search-test-mode").value;
|
||||||
|
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
if (serial) params.set("serial", serial);
|
if (serial) params.set("serial", serial);
|
||||||
if (dateFrom) params.set("date_from", dateFrom);
|
if (dateFrom) params.set("date_from", dateFrom);
|
||||||
if (dateTo) params.set("date_to", dateTo);
|
if (dateTo) params.set("date_to", dateTo);
|
||||||
|
if (testMode) params.set("test_mode", testMode);
|
||||||
|
|
||||||
window.location.href = `/api/test-data/export?${params}`;
|
window.location.href = `/api/test-data/export?${params}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ async function startAuto() {
|
|||||||
// 清空显示
|
// 清空显示
|
||||||
resetAverages();
|
resetAverages();
|
||||||
document.getElementById("latest-result").innerHTML = '<p class="placeholder">等待测试...</p>';
|
document.getElementById("latest-result").innerHTML = '<p class="placeholder">等待测试...</p>';
|
||||||
|
document.getElementById("latest-wave").innerHTML = '<p class="placeholder">暂无波动数据...</p>';
|
||||||
document.getElementById("progress-bar").style.width = "0%";
|
document.getElementById("progress-bar").style.width = "0%";
|
||||||
document.getElementById("progress-text").textContent = "0/" + count + " (0 失败)";
|
document.getElementById("progress-text").textContent = "0/" + count + " (0 失败)";
|
||||||
document.getElementById("stat-done").textContent = "0";
|
document.getElementById("stat-done").textContent = "0";
|
||||||
@@ -145,6 +146,11 @@ async function pollProgress() {
|
|||||||
renderAverages(data.averages);
|
renderAverages(data.averages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示波动测试数据
|
||||||
|
if (data.latest_wave) {
|
||||||
|
renderLatestWave(data.latest_wave);
|
||||||
|
}
|
||||||
|
|
||||||
// 显示本轮测试明细
|
// 显示本轮测试明细
|
||||||
if (data.records) {
|
if (data.records) {
|
||||||
renderRecords(data.records);
|
renderRecords(data.records);
|
||||||
@@ -209,6 +215,7 @@ function renderLatest(data) {
|
|||||||
const div = document.getElementById("latest-result");
|
const div = document.getElementById("latest-result");
|
||||||
div.innerHTML = `
|
div.innerHTML = `
|
||||||
<p>设备型号:<strong>${data.str_type || '-'}</strong></p>
|
<p>设备型号:<strong>${data.str_type || '-'}</strong></p>
|
||||||
|
<p>测试模式:<strong>${data.test_mode === 1 ? '波动测试' : '灵敏度测试'}</strong></p>
|
||||||
<p>峰峰值:${data.ppvalue?.toFixed(2) || '-'} V</p>
|
<p>峰峰值:${data.ppvalue?.toFixed(2) || '-'} V</p>
|
||||||
<p>开始工作频率:${data.idle_freq || '-'} Hz</p>
|
<p>开始工作频率:${data.idle_freq || '-'} Hz</p>
|
||||||
<p>进入工作频率:${data.enter_freq || '-'} Hz</p>
|
<p>进入工作频率:${data.enter_freq || '-'} Hz</p>
|
||||||
@@ -242,6 +249,28 @@ function resetAverages() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── 显示波动测试数据 ──────────────────────────
|
||||||
|
|
||||||
|
function renderLatestWave(data) {
|
||||||
|
const div = document.getElementById("latest-wave");
|
||||||
|
if (!data || !data.work_freq) {
|
||||||
|
div.innerHTML = '<p class="placeholder">暂无波动数据...</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
div.innerHTML = `
|
||||||
|
<p>剩余次数:<strong>${data.remain_count || 0}</strong></p>
|
||||||
|
<p>工作频率:${data.work_freq || '-'} Hz</p>
|
||||||
|
<p>当前距离:${data.curr_dist || '-'} mm</p>
|
||||||
|
<p>当前速度:${toSpeed(data.speed)} m/s</p>
|
||||||
|
<p>最近距离:${data.near_dist || '-'} mm</p>
|
||||||
|
<p>最远距离:${data.far_dist || '-'} mm</p>
|
||||||
|
<p>进入高度 (B4):${data.b4_enter_dist || '-'} mm</p>
|
||||||
|
<p>离开高度 (B4):${data.b4_leave_dist || '-'} mm</p>
|
||||||
|
<p>继电器:${data.relay_out || '无'}</p>
|
||||||
|
<p>时间:${data.create_time || '-'}</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
// ─── 显示本轮测试明细 ──────────────────────────
|
// ─── 显示本轮测试明细 ──────────────────────────
|
||||||
|
|
||||||
function renderRecords(records) {
|
function renderRecords(records) {
|
||||||
@@ -260,6 +289,7 @@ function renderRecords(records) {
|
|||||||
<td style="color:${r.sn_state === 2 ? '#27ae60' : r.sn_state === 3 ? '#e74c3c' : '#888'}">
|
<td style="color:${r.sn_state === 2 ? '#27ae60' : r.sn_state === 3 ? '#e74c3c' : '#888'}">
|
||||||
${r.sn_state === 2 ? 'OK' : r.sn_state === 3 ? '超时' : '?'}
|
${r.sn_state === 2 ? 'OK' : r.sn_state === 3 ? '超时' : '?'}
|
||||||
</td>
|
</td>
|
||||||
|
<td>${r.test_mode === 1 ? '波动' : '灵敏度'}</td>
|
||||||
<td>${r.ppvalue?.toFixed(2) || '-'}</td>
|
<td>${r.ppvalue?.toFixed(2) || '-'}</td>
|
||||||
<td>${r.idle_freq || '-'}</td>
|
<td>${r.idle_freq || '-'}</td>
|
||||||
<td>${r.enter_dist || '-'}</td>
|
<td>${r.enter_dist || '-'}</td>
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
设备编码:
|
设备编码:
|
||||||
<input type="text" id="search-serial" placeholder="输入设备编码搜索...">
|
<input type="text" id="search-serial" placeholder="输入设备编码搜索...">
|
||||||
</label>
|
</label>
|
||||||
|
<label>
|
||||||
|
测试模式:
|
||||||
|
<select id="search-test-mode">
|
||||||
|
<option value="">全部</option>
|
||||||
|
<option value="0">灵敏度测试</option>
|
||||||
|
<option value="1">波动测试</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
<label>
|
<label>
|
||||||
日期范围:
|
日期范围:
|
||||||
<input type="date" id="search-date-from">
|
<input type="date" id="search-date-from">
|
||||||
@@ -27,6 +35,8 @@
|
|||||||
<th>DG430地址</th>
|
<th>DG430地址</th>
|
||||||
<th>设备型号</th>
|
<th>设备型号</th>
|
||||||
<th>类型</th>
|
<th>类型</th>
|
||||||
|
<th>测试模式</th>
|
||||||
|
<th>数据来源</th>
|
||||||
<th>是否完成</th>
|
<th>是否完成</th>
|
||||||
<th>故障信息</th>
|
<th>故障信息</th>
|
||||||
<th>继电器</th>
|
<th>继电器</th>
|
||||||
@@ -38,6 +48,11 @@
|
|||||||
<th>离开距离(mm)</th>
|
<th>离开距离(mm)</th>
|
||||||
<th>进入速度(m/s)</th>
|
<th>进入速度(m/s)</th>
|
||||||
<th>离开速度(m/s)</th>
|
<th>离开速度(m/s)</th>
|
||||||
|
<th>剩余次数</th>
|
||||||
|
<th>当前距离(mm)</th>
|
||||||
|
<th>速度(dm/s)</th>
|
||||||
|
<th>最近距离(mm)</th>
|
||||||
|
<th>最远距离(mm)</th>
|
||||||
<th>时间</th>
|
<th>时间</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
@@ -49,6 +49,11 @@
|
|||||||
<p class="placeholder">等待设备上报...</p>
|
<p class="placeholder">等待设备上报...</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h3>波动测试数据</h3>
|
||||||
|
<div id="latest-wave">
|
||||||
|
<p class="placeholder">暂无波动数据...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>自动化平均值</h3>
|
<h3>自动化平均值</h3>
|
||||||
<table id="avg-table">
|
<table id="avg-table">
|
||||||
<tr><td>平均峰峰值</td><td id="avg-ppvalue">-</td><td>V</td></tr>
|
<tr><td>平均峰峰值</td><td id="avg-ppvalue">-</td><td>V</td></tr>
|
||||||
@@ -65,7 +70,7 @@
|
|||||||
<table id="records-table" style="font-size:11px;">
|
<table id="records-table" style="font-size:11px;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th><th>串口状态</th><th>峰峰值(V)</th><th>开始频率</th><th>进入距离</th><th>离开距离</th><th>速度(m/s)</th><th>时间</th>
|
<th>#</th><th>串口状态</th><th>模式</th><th>峰峰值(V)</th><th>开始频率</th><th>进入距离</th><th>离开距离</th><th>速度(m/s)</th><th>时间</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody></tbody>
|
<tbody></tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user