Site Tools


Hotfix release available: 2026-07-14c "Mort". upgrade now! [57.3] (what's this?)
测试管理系统h5:冷启动文件

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
测试管理系统h5:冷启动文件 [2026/10/13 08:24] – 4.61 新增表压测试分类 172.17.0.1测试管理系统h5:冷启动文件 [2026/10/26 10:06] (current) – 4.71 开度4个手动槽位 172.17.0.1
Line 1293: Line 1293:
 | 判题逻辑 | `isTPQItem` / `isTPQAlterItem` 按**项名**判定(与分类无关)→ 行为不变 ✅ | | 判题逻辑 | `isTPQItem` / `isTPQAlterItem` 按**项名**判定(与分类无关)→ 行为不变 ✅ |
 | 其他 | 无 JS 错误 ✅ | | 其他 | 无 JS 错误 ✅ |
 +
 +====== 4.62 将 #91、#95 文档移入「表压测试」分类(2026-10-10) ======
 +
 +**需求**:把 91、95 号测试文档挪到新建的「表压测试」分类。
 +
 +**执行**(★改库前先备份 `/tmp/test_db_bak_move_*.db`)
 +<code>
 +UPDATE sessions SET category='表压测试' WHERE id IN (91,95);
 +</code>
 +
 +| 文档 | 改前 | 改后 | 测试项 | 数据完整性 |
 +|---|---|---|---|---|
 +| #91 | 其他测试 | **表压测试** | 表压气密性测试-常温 / 交变 | t_struct 合计 2012 字节 ✅ |
 +| #95 | 其他测试 | **表压测试** | 表压气密性测试-常温 / 交变 | t_struct 合计 674 字节 ✅ |
 +
 +**改后分类现状**
 +- **表压测试**:#105(武燕青新建)、#95(席江锋)、#91(席江锋)
 +- **其他测试**:#32、#81
 +
 +**验证**:接口按 category=表压测试 查询返回 3 个文档(含 #91/#95)✅;页面列表可见 #91/#95 ✅;无 JS 错误 ✅
 +
 +====== 4.63 自定义测试项自动加入模板(新建测试可选)(2026-10-10) ======
 +
 +**需求**:在测试文档里「+ 添加测试项 → 自定义测试项」手动添加的项,要**自动进入模板**,以后「新建测试」时在该分类下可选。
 +
 +===== 后端(`test_api.py`) =====
 +新增 **`POST /api/test/templates/add`**
 +<code>
 +入参:{device, category, name, method?, tool?, steps?, condition?, purpose?}
 +权限:仅 admin / tester(普通用户、游客 → 403)
 +逻辑:写入 templates.json 的 items["<device>:<category>"]
 +      · 同名去重(已存在 → {ok:true, added:false})
 +      · 分类不存在则补进 categories[device]
 +返回:{ok, added, key, count}
 +</code>
 +
 +===== 前端(`test.html`) =====
 +`aiAddCustom()`(自定义测试项)在加入当前文档的同时,**同步 POST 到模板接口**:
 +- 成功且新增 → toast「✅ 已添加「XX」(已加入"表压测试"可选列表,新建测试时可选)」
 +- 已存在 → toast「已添加「XX」(该项此前已在可选列表中)」
 +- 失败/异常 → 降级为原提示(不影响文档内添加)
 +
 +===== 验证 =====
 +| 项 | 结果 |
 +|---|---|
 +| 管理员添加自定义项 | ✅ `added:true`,模板项数 2 → 3 |
 +| 模板文件 | ✅ 含新项 |
 +| **模板接口**(前端新建测试读它)| ✅ 返回含新项 → **新建测试可选** ✅ |
 +| 重复添加 | ✅ 去重(`added:false, msg:"已存在"`)|
 +| 权限 | 普通用户 **403** ✅ / 游客 **403** ✅ / 测试员(**手机号登录**)**200** ✅ |
 +| 测试数据 | ✅ 已清理,模板恢复原状(表压测试 2 项)|
 +| 全库模板 | ✅ 各分类项数与改动前一致 |
 +
 +⚠️ 注意:测试员身份由**手机号注册**决定,用**姓名**调用会被判为普通用户(403)——这是既有设计。
 +
 +====== 4.67 产品系列下拉新增「普惠P1」「拓远T1」(2026-10-10) ======
 +
 +**需求**:「其他测试」类目表单里的「产品系列」下拉,增加 普惠P1、拓远T1。
 +
 +**原有机制**
 +- 字段:`#f_valvetype`(保存到 `sessions.valve_type`),仅 `CAT==='其他测试'` 时出现
 +- 选项来源:`SERIES_LIST` ← `/api/test/templates` 的 `series_list`,其值 = `SELECT DISTINCT series FROM sessions WHERE series != ''`(即"各行文档填过的系列值")
 +- 改动前实际选项:金穗S1、润禾R1、普惠P3(分别来自 #67、#7、#6)
 +
 +**改动**
 +| 位置 | 内容 |
 +|---|---|
 +| `templates.json` | 新增可配置基础清单 **`"series_list": ["普惠P1","拓远T1"]`** |
 +| `test_api.py` `/api/test/templates` | 返回前合并:`基础清单 + 各行文档 series 值`,去重(**基础清单在前**)|
 +
 +**验证(真实页面渲染 + 接口)**
 +| 项 | 结果 |
 +|---|---|
 +| 接口 `series_list` | `['普惠P1','拓远T1','金穗S1','润禾R1','普惠P3']` ✅ |
 +| 「其他测试」表单产品系列下拉 | 普惠P1 / 拓远T1 / 金穗S1 / 润禾R1 / 普惠P3 ✅ |
 +| 已有文档 #110 | 原选中值「普惠P3」保持不变 ✅ |
 +| **回归 · 阀体测试** | 字段仍是「阀体类型」(14 个硬编码阀体类型),**未混入** 普惠P1/拓远T1 ✅ |
 +| **回归 · 功能性能** | 表单正常渲染(系列为文本输入)✅ |
 +| 无 JS 错误 | ✅ |
 +
 +**维护方式**:以后要在此下拉增删选项,改 `templates.json` 的 `series_list` 即可(无需动代码)。
 +
 +====== 4.68 每个测试项增加「清空测试记录数据」(2026-10-18) ======
 +
 +**需求**:为每个测试项的测试文档,增加清空该测试项**测试记录数据**的功能。
 +
 +===== 后端(`test_api.py`) =====
 +新增 **`POST /api/test/session/<int:sid>/item/clear`**(**仅管理员**)
 +<code>
 +入参:{item_name, scope:['data','photo','files','status']}   # scope 默认 ['data']
 +data   → 清空 t_struct(表格) / t_data(测试数据) / t_recs(测试时段) / t_logs(日志)
 +          / t_codes / t_result(测试结果) / t_followup(处理方式) / t_ecr(变更内容)
 +photo  → 清空 t_photo
 +files  → 清空 t_files
 +status → status 重置为「未开始」
 +保留:测试条件/方法/工具/步骤/目的、测试备注、测试人员与时间、测试数量
 +</code>
 +权限兜底:手机号能对应到管理员姓名(`_wx_users()[phone].name in _admins()`)也放行。
 +
 +===== 前端(`test.html`) =====
 +- 测试项详情「测试项信息」标题右侧新增 **🧹 清空记录** 按钮(仅管理员可见/可用)
 +- 点击弹出**勾选式确认面板**:
 +<code>
 +  ☑ 测试数据(表格 / 记录 / 时段日志 / 测试结果)   ← 默认勾选
 +  ☐ 测试照片(N 张)
 +  ☐ 测试文档附件(N 个)
 +  ☐ 测试状态重置为「未开始」
 +  提示:保留 测试条件/方法/工具/步骤、测试备注、测试人员与时间
 +</code>
 +- 确认后调接口 → toast「🧹 已清空测试记录」→ 自动重载该文档并停留原测试项
 +
 +===== 验证(临时文档实测,用完已删) =====
 +| 项 | 结果 |
 +|---|---|
 +| 只清 `data` | ✅ 表格/测试数据/结果/日志/编码全清;**照片、附件、备注、测试人员、状态、测试数量全部保留** |
 +| 其他测试项 | ✅ 完全不受影响 |
 +| 全清(data+photo+files+status)| ✅ 照片、附件清空;状态重置「未开始」;备注仍保留 |
 +| 测试员调用 | ✅ **403** 仅管理员可清空 |
 +| 前端 | ✅ 按钮存在;面板标题/4 个勾选项/照片张数正确;关闭正常;无 JS 错误 |
 +| 真实文档 #42 | 仅打开面板未确认 → **数据未被改动** |
 +
 +====== 4.69 修复:电路测试类文档导出报告失败(页面显示原始 JSON)(2026-10-23) ======
 +
 +**现象**(用户截图):智慧阀门 → 电路测试 → 导出报告 → 手机上整屏显示
 +`{"error":"\u8be5\u4f1a\u8bdd..."}` 一串乱码,报告出不来(Word/PDF 同样)。
 +
 +===== 根因(写死分类名) =====
 +`test_api.py` 报告接口的 mode 校验:
 +<code>
 +if mode == "circuit" and sess["category"] != "电路测试":   # ❌ 写死
 +    return jsonify({"error": "该会话不是电路测试"}), 400
 +</code>
 +但 2026-09-16 分类拆分后,**电路测试组的实际分类是 功能性能 / 环境可靠性 / 机械应力**(很少再叫"电路测试"),
 +所以这些文档导出 → 一律 400 → 前端 `window.open('/api/test/report/...')` 打开的就是这个 JSON → 手机满屏乱码。
 +
 +`_render_report()` 里还有一处同样的写死判断 → 就算放过校验,报告里的测试项也会被**全部跳过(空报告)**。
 +
 +===== 修复 =====
 +1. 两处判断统一改用已有 helper **`_is_circuit_cat()`**(含历史"电路测试"+ 拆分后三类)
 +2. 报告类接口的错误响应 → **友好 HTML 错误页**(⚠️ 大标题 + 具体原因 + 返回按钮),不再返回裸 JSON
 +3. 报告 HTML 响应加 `Cache-Control: no-store`(避免微信缓存旧的错误响应)
 +4. **归档文档对非管理员只读 → 导出时跳过保存**(原来必先保存 → 被 403"已归档不允许修改"拦下,导出不了)
 +5. 保存失败提示具体原因(原来只显示"保存失败")
 +
 +===== 实测 =====
 +| 场景 | 结果 |
 +|---|---|
 +| #7(功能性能·**已归档**)Web 报告 | ✅ 200,**2.5 MB / 4321 行**(修复前 400 且内容为空)|
 +| #7 Word / PDF | ✅ 200 docx / 200 pdf |
 +| #42(阀体测试)`mode=valve` | ✅ 200(回归正常)|
 +| #110(其他测试)`mode=other` | ✅ 200(回归正常)|
 +| 错误场景(阀体文档用 circuit 模式导出)| ✅ 显示**友好错误页**「⚠️ 无法生成报告 + 原因 + 返回」 |
 +| 测试员 + 归档文档导出 | ✅ **0 次保存请求**,直接出报告 |
 +| 管理员 + 未归档副本 | ✅ 先保存再导出 |
 +| 数据核对 | 17 会话 / 66 测试项,与备份逐会话比对无丢失(少掉的 31 条是早已删除的 #6 会话遗留孤儿项)|
 +
 +⚠️ 提醒:手机上导 Word/PDF,微信内置浏览器**不支持下载**,需点右上角「⋯」→「在浏览器打开」;Web 报告在微信里可直接看。
 +
 +====== 4.70 气密性测试新增「第3步:全关」(2026-10-23) ======
 +
 +**需求**:气密性测试原来只有第1步(堵住A口)、第2步(堵住B口),**新增第3步 = 全关的情况**。
 +
 +===== 三步定义(阀门气密) =====
 +| 步骤 | 状态 | 说明 |
 +|---|---|---|
 +| 第1步 | 堵住A口 | 堵住A口,调节A口开度,调节水压 |
 +| 第2步 | 堵住B口 | 堵住B口,调节B口开度,调节水压 |
 +| **第3步** | **全关** | **阀门全部关闭,观察各部位渗漏** |
 +
 +⚠️ **表压气密性测试(表压测试分类)仍只有第1步**,不受影响。
 +
 +===== 实现要点(`test.html`) =====
 +<code>
 +function stepKeyOf(n){ return n===1?'step1':(n===2?'step2':'step3'); }
 +function stepNums(){ return isTPQItem()?[1]:[1,2,3]; }   // 表压气密只有第1步
 +function stepTitle(n){ n=1→堵住A口… ; n=2→堵住B口… ; n=3→全关(阀门全部关闭,观察各部位渗漏)}
 +function _mergeAllSteps(container){ … }                  // 跨步配置并集支持 3 步
 +</code>
 +- 管理员 `renderStruct` 与 **测试员 `wxStructTable`** 两套渲染都支持三步
 +- 默认 `t_struct` 增加 `step3:{opens,press,time,cells}`
 +- **全量**与**批量**两种记录方式都支持第3步(各自可配 开度/压力/时间)
 +- 第3步默认沿用第1/2步的开度压力(`_mergeAllSteps`),不会出现空表
 +
 +===== 报告(`test_api.py`) =====
 +<code>
 +def _step_list(st):   # 第1/2步始终输出(历史兼容);第3步仅在已配置时输出
 +</code>
 +Web / Word / PDF **三种报告**都包含第3步;批量报告的三处表格也补齐第3步。
 +
 +===== ★ 顺带修复的旧 bug =====
 +气密表格单元格的 `onchange` 行内**直接引用了函数局部变量** `o / p / j / bi2 / bi3`:
 +<code>
 +onchange="setCell(...);logAdd('更新 '+o+'开度/'+p+' 第'+(j+1)+'台 …')"
 +<!-- o/p/j 在事件触发时不存在 → Uncaught ReferenceError(步骤1/2 同样报错)-->
 +</code>
 +改为 **`logCell(this)`**:由函数从表格结构(首列"开度/压力" + 表头"第N台")推导日志文案。
 +现在三步任意单元格改数据都**零报错**。
 +
 +===== 验证 =====
 +| 项 | 结果 |
 +|---|---|
 +| 管理员视图(阀体气密)| ✅ 第1/2/3 步配置块与数据表齐全 |
 +| 测试员视图(`IS_WX`)| ✅ 三步齐全,第3步文案「全关」 |
 +| 第3步生成数据表 / 填值 / 保存 | ✅ cells 落库(如 `{"0%|1.0bar":{"1":"微漏"}}`)|
 +| 改任意步骤单元格 | ✅ 无 JS 错误(旧版三步都报 ReferenceError)|
 +| Web / Word / PDF 报告 | ✅ 均含「第3步:全关」(28KB / 18.5MB / 957KB)|
 +| 老文档(无 step3)报告 | ✅ 不出现第3步(`_step_list` 按需输出)|
 +| 表压气密性测试 | ✅ 仍只有第1步 |
 +| 数据安全 | 用「复制」副本验证,真实文档未改动;副本已删除 |
 +
 +====== 4.71 气密性测试:开度改为「4 个手动选择槽位」(2026-10-26) ======
 +
 +**需求**:开度选择提供 **4 个选项位置**,每个位置可手动选开度(**0%~100%,步进 10%**)。
 +
 +===== 改前 / 改后 =====
 +| | 改前 | 改后 |
 +|---|---|---|
 +| 控件 | 6 个固定勾选框(0/20/40/60/80/100%,可多选)| **4 个下拉**,每个可选 0%~100% 步进10%(含"空")|
 +| 组合 | 只能选那 6 个值 | 任意 4 个,如 0%/30%/60%/100% |
 +
 +===== 实现(`test.html`) =====
 +<code>
 +var OPEN_STEPS = 0%,10%,…,100%;               // 步进 10%
 +function openSlotSelects(step,curOpens,cls,attr) // 生成 4 个下拉
 +function openValSort(list)                      // 去重 + 按数值排序
 +function openExtraHint(opens)                   // 超出4个的历史开度提示"已保留"
 +</code>
 +- **全量模式**:`select.o-slot`(`stepBlock`)
 +- **批量模式**:三步都用 `select.bo-slot`(`batchBlock`)
 +- `buildTable()` / `batchGen()` 改为从下拉取值
 +
 +===== 历史兼容规则(重要) =====
 +<code>
 +· 打开老文档、四个槽位未被改动 → 保留原有【全部】开度(如原来 6 个,仍是 6 个表格)
 +· 一旦改动槽位 → 严格按这 4 个(或更少)生成
 +· 原有超出 4 个的开度会在界面上提示"原有额外开度(已保留)"
 +</code>
 +⚠️ 表压气密性测试(表压测试分类)**没有开度概念**,仍隐藏开度行、固定 100%/0.4MPa。
 +
 +===== 验证 =====
 +| 项 | 结果 |
 +|---|---|
 +| 全量:下拉数量/选项 | ✅ 每步 4 个下拉;选项 `—,0%,10%,…,100%`(12 项)|
 +| 全量:老值回填 | ✅ 原 0%/100% 自动填入前两个槽位 |
 +| 全量:改选 0/30/60/100 | ✅ `step1.opens` 准确写入,数据表 34 行 |
 +| 批量:三步下拉 | ✅ 12 个(3 步 × 4)|
 +| 批量:未改动 | ✅ 历史 6 个开度全部保留 |
 +| 批量:改选 0%/50% | ✅ 严格按 2 个生成 |
 +| 表压气密(回归)| ✅ 无开度下拉、无第2/3步、仍 0.4MPa |
 +| JS 错误 | ✅ 无 |
 +| 数据安全 | 全部用「复制副本」验证,真实文档未动;副本已删 |
 +
 +⚠️ 踩坑:`batchGen()` 里 `b[key]` 与 `st.batch[key]` 是**同一个对象引用**,
 +先 `b[key].opens=[]` 再取旧值 → 永远拿到空数组 → 必须**清空前先备份**。
  
 ====== 5. 测试项模板 ====== ====== 5. 测试项模板 ======
测试管理系统h5/冷启动文件.1791879851.txt.gz · Last modified: by 172.17.0.1