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.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| 测试管理系统h5:冷启动文件 [2026/10/08 12:06] – 4.42 撤销表压传感器测试项 172.17.0.1 | 测试管理系统h5:冷启动文件 [2026/10/26 10:06] (current) – 4.71 开度4个手动槽位 172.17.0.1 | ||
|---|---|---|---|
| Line 898: | Line 898: | ||
| **回归验证(删除后)**:# | **回归验证(删除后)**:# | ||
| + | |||
| + | ====== 4.43 结构测试·其他测试 新增「表压气密性测试-常温」(2026-09-25) ====== | ||
| + | |||
| + | **需求**:在**结构测试**组的「其他测试」中新增测试项「**表压气密性测试-常温**」,**完全复制**阀体测试中的「气密性测试-常温」。 | ||
| + | |||
| + | **执行**(`templates.json`) | ||
| + | < | ||
| + | new = copy.deepcopy(源项) | ||
| + | new[' | ||
| + | items[' | ||
| + | </ | ||
| + | - **内容校验**:`deepcopy(new)` 改回原名后与源项 **完全相等** ✅(method/ | ||
| + | - 源项未改动:阀体测试仍 **23 项** ✅ | ||
| + | |||
| + | **复制的内容** | ||
| + | - method:`【操作步骤】第一步:堵住A,调节A口;第二步:堵住B口,调节B口` + `【测试条件】不同开度(0/ | ||
| + | - tool:`气密测试台` | ||
| + | |||
| + | **记录方式**(自动继承,无需额外开发) | ||
| + | - 项名含「气密」→ `isQtyStruct()` 命中 → **自动获得**:记录方式(全量/ | ||
| + | |||
| + | **验证(浏览器实测)** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 结构组 其他测试 | 扭力测试 + **表压气密性测试-常温** ✅ | | ||
| + | | 记录方式 全量/ | ||
| + | | 压力档 | `1.0bar / 2.0bar / 3.0bar / 4.0bar`(新项用标准档)| | ||
| + | | 对比 # | ||
| + | | 回归 | 阀体测试 23 项 ✅|其他测试2 = 三防漆 ✅|真实文档正常 ✅|无 JS 错误 ✅ | | ||
| + | |||
| + | > 💡 提示:若该测试项实际使用 **0.4 MPa**(像表压传感器那样),可在 `_pressBase()` 中把匹配条件从「表压传感器」扩展到「表压」,即可自动获得 0.4MPa 档位。 | ||
| + | |||
| + | ====== 4.44 阀体启闭扭矩测试:循环次数与测试数量可设置(2026-10-10) ====== | ||
| + | |||
| + | **需求**:结构测试 → 阀体测试 → 「阀体启闭扭矩测试-常温」: | ||
| + | ① **循环测试次数**改为可设置(**1~10 次**,原固定 5 次) | ||
| + | ② **测试数量**可设置(**1~500 台**,原上限 50) | ||
| + | |||
| + | **① 循环次数可设(新增 `tocSetLoops`)** | ||
| + | - 新增 `tocBlank(n)` 取代原 `tocBlank5()`(保留 `tocBlank5()` 作兼容包装) | ||
| + | - `cfg.loops`(默认 `' | ||
| + | - 表单新增输入框:`循环测试次数 [n] 次(1~10)` | ||
| + | - **改次数时的数据保护**:增加次数 → 补空行;减少次数 → 按序截断;**行号重排,已有数据按位置保留** ✅ | ||
| + | - 边界:输入 `0` → 钳到 **1**(注意 `0` 是合法输入,不能用 `|| 5` 兜底,否则会变 5);输入 `11` → 10;留空 → 5 | ||
| + | |||
| + | **② 测试数量上限 50 → 500** | ||
| + | - 表单 `max=" | ||
| + | - `tocSetQty()` 钳位 `Math.min(50, | ||
| + | - **`tocStruct()` 内 units 生成上限** `if(qty> | ||
| + | |||
| + | **③ 旧数据兼容(关键)** | ||
| + | - 旧记录无 `cfg.loops` 字段 → **不写回数据**,改为**按现有表格行数最大值推断显示** | ||
| + | - 会话 # | ||
| + | - 会话 # | ||
| + | - 用户不主动改次数时,原有行数与数据**完全不动** ✅ | ||
| + | |||
| + | **④ 验证** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 循环次数输入框 | min=1 max=10 ✅ | | ||
| + | | 测试数量输入框 | min=1 max=500 ✅ | | ||
| + | | 改 3 次 → 表格行数 | 3 ✅ | | ||
| + | | 填 2 行后改 5 次 | 行数 5,原 2 行数据保留 ✅ | | ||
| + | | 改 1 次(截断) | 行数 1 ✅ | | ||
| + | | 数量 500 | qty=500,units=**500** ✅ | | ||
| + | | 边界 | 0→1|11→10|空→5 ✅;数量 0→1|501→500 ✅ | | ||
| + | | **回归** | # | ||
| + | | 后端报告 | `_toc_stats` 按行数动态遍历,无需改动 ✅ | | ||
| + | |||
| + | ====== 4.45 表压气密性测试-常温:填入默认测试工具/ | ||
| + | |||
| + | **需求**:为该测试项填入三项默认内容(用户提供),★要求不影响其他测试项与测试文档。 | ||
| + | ① **测试工具**:压力管道(带分口)及配套气管;水泵;表压传感器(待测,按不同组合编号);水碗(用于气泡法检漏);记号笔(用于水位刻线、问题标注);计时器;测试记录表 | ||
| + | ② **测试方法**:试验压力:0.4 MPa;保压观察时间:30 分钟。 | ||
| + | ③ **测试步骤**:6 步(安装接线 → 加压至 0.4MPa → 初检与基准刻线 → 定时观察 10/20/30 分钟 → 泄漏点定位(水碗气泡法)→ 结束与记录,形成《传感器测试清单》) | ||
| + | |||
| + | **实现** | ||
| + | | 位置 | 改动 | | ||
| + | |---|---| | ||
| + | | `templates.json`(智慧阀门: | ||
| + | | `test.html` 新建会话勾选映射(约 576 行)| `t_steps:'' | ||
| + | | `test.html`「+添加测试项」面板映射(约 2808 行)| `t_steps:'' | ||
| + | |||
| + | > ★ 踩坑:模板字段名与测试项字段名的映射链为 | ||
| + | > `templates: name/ | ||
| + | > 原代码两处映射把 `t_steps` **硬编码为空字符串**,导致模板里写 `steps` 也不会带入测试项 → 已修复(该字段对所有项通用,无 `steps` 的模板仍为空,无副作用) | ||
| + | |||
| + | **显示位置**(管理员 & 测试员均可看到) | ||
| + | - 测试项详情页「📋 测试项信息」区:测试方法 / 测试工具 / 测试步骤 三个字段(归档只读视图同样显示) | ||
| + | - 编辑器:`i_method` / `i_tool` / `i_steps` | ||
| + | |||
| + | **验证** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 接口返回 | tool/ | ||
| + | | 新建会话勾选后字段 | t_tool/ | ||
| + | | 详情页显示 | 截图确认「测试项信息」区显示 测试方法/ | ||
| + | | **回归** | 阀体测试·气密性测试-常温 **未被改动**(tool=气密测试台、无 steps)✅;扭力测试 t_steps 为空 ✅ | | ||
| + | | 回归 | 阀体测试 23 项、其他测试 2 项、其他测试2 1 项,数量未变 ✅;无 JS 错误 ✅ | | ||
| + | | 数据 | 临时验证会话已清理,无残留 ✅ | | ||
| + | |||
| + | > 📌 提示:该测试项的压力档当前沿用阀门气密的 `1.0/ | ||
| + | |||
| + | ====== 4.46 表压气密性测试-常温:去掉开度/ | ||
| + | |||
| + | **用户需求(精确)**:① 去掉「开度(可多选)」「压力(可多选)」两行 → ② 去掉「第2步」。 | ||
| + | ★ 只改这一个测试项,其他测试项与已有文档不受影响。 | ||
| + | |||
| + | **新增判定**:`isTPQItem()` = 当前测试项名含「表压气密性测试」 | ||
| + | < | ||
| + | function isTPQItem(){ try{ var it=CUR_ITEMS[CUR_ITEM_IDX]; | ||
| + | </ | ||
| + | |||
| + | **改动清单(共 7 处,均带 `isTPQItem()` 条件)** | ||
| + | | 位置 | 改动 | | ||
| + | |---|---| | ||
| + | | `stepBlock()`(全量记录·管理员)| 不渲染 开度/ | ||
| + | | 全量渲染(2074 行附近)| `buildTable(2, | ||
| + | | `batchBlock()`(批量记录·管理员)| 表压气密只渲染一行:「第1步:加压至 0.4 MPa + 时间(单选)」| | ||
| + | | 测试员批量渲染(约 951 行)| `[' | ||
| + | | `batchGen()`(批次表生成)| 只处理第1步;无勾选行时**自动用默认值** `[' | ||
| + | | `buildTable()`(全量表生成)| 无勾选行时自动用默认值 `100%`/ | ||
| + | | `_pressBase()` | 匹配条件 `/ | ||
| + | |||
| + | **默认值设定**:开度固定 **100%**、压力固定 **0.4 MPa**(无开度概念 → 表格只出 1 张,行=批次/ | ||
| + | |||
| + | **验证** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 表压气密性测试-常温 | 「开度(可多选)」✅去掉|「压力(可多选)」✅去掉|「第2步」✅去掉|时间(单选)✅保留 | | ||
| + | | 生成表格 | 批量 1 张(100% / 0.4MPa),无" | ||
| + | | **回归·阀门气密性测试-常温(# | ||
| + | | 其他 | 检验部位、漏水等级、记录方式(全量/ | ||
| + | | 数据 | 验证时写入的临时配置已恢复(# | ||
| + | |||
| + | ====== 4.47 表压气密性测试-常温:检验部位改为 2 个(上漏 / 下漏)(2026-10-10) ====== | ||
| + | |||
| + | **需求**:该项的检验部位只保留 **1 上漏、2 下漏** 两个(默认内容),其他测试项不变。 | ||
| + | |||
| + | **前端**(`test.html`) | ||
| + | < | ||
| + | var DEFAULT_PARTS=[' | ||
| + | var TPQ_PARTS=[' | ||
| + | function _defaultParts(){ return isTPQItem()? | ||
| + | </ | ||
| + | - `partsEditor()` 默认清单:`DEFAULT_PARTS.slice()` → **`_defaultParts()`** | ||
| + | - `addMetaPart()` 补齐默认:同上 | ||
| + | - ★仅当当前项名含「表压气密性测试」时返回 2 个部位,其余项仍是原 6 个 | ||
| + | |||
| + | **后端**(`test_api.py`,修复报告硬编码) | ||
| + | - `_custom_row_name(key)` → **`_custom_row_name(key, | ||
| + | < | ||
| + | _pn = (part_names or []); _pname = _pn[int(pos)-1] if 0 <= int(pos)-1 < len(_pn) else None | ||
| + | if not _pname: _pname = PART_NAME.get(pos, | ||
| + | </ | ||
| + | - Web 报告、Word 报告两处调用改为传 `(st.get(" | ||
| + | - 效果:该项自定义记录行会显示「1-上漏 | E2-微漏」,不再错误显示「1-左侧出口」 | ||
| + | |||
| + | **验证** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 表压气密性测试-常温 | 检验部位 = **上漏 / 下漏**(2 个)✅,无旧部位 ✅ | | ||
| + | | **回归** 阀门气密性测试-常温(# | ||
| + | | **回归** #42 阀门气密 | 6 个部位 **未变** ✅ | | ||
| + | | 其他 | 表格 49 个正常 ✅;无 JS 错误 ✅ | | ||
| + | |||
| + | ====== 4.48 结构测试·其他测试 新增「表压气密性测试-交变」(2026-10-10) ====== | ||
| + | |||
| + | **需求**:在结构测试组「其他测试」新增 **表压气密性测试-交变**,完全复制 **表压气密性测试-常温**;★不影响其他测试项与文档。 | ||
| + | |||
| + | **执行**(`templates.json`) | ||
| + | < | ||
| + | new = copy.deepcopy(源项) | ||
| + | new[' | ||
| + | items[' | ||
| + | </ | ||
| + | - 内容校验:`tool`(74字)/ | ||
| + | |||
| + | **前端零改动自动继承**(关键) | ||
| + | - 判定 `isTPQItem()` 用的是 `/ | ||
| + | - 因此新项**自动获得**:检验部位 2 个(上漏/ | ||
| + | |||
| + | **当前「智慧阀门: | ||
| + | 1. 扭力测试 | ||
| + | 2. 表压气密性测试-常温 | ||
| + | 3. **表压气密性测试-交变** 🆕 | ||
| + | |||
| + | **验证** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 模板字段与常温项对比 | tool/ | ||
| + | | 新项详情页 | 测试方法/ | ||
| + | | 新项记录区 | 检验部位=上漏/ | ||
| + | | **回归** 表压气密性测试-常温 | 部位仍 上漏/ | ||
| + | | **回归** 阀门气密性测试-常温(# | ||
| + | | 其他 | 阀体测试 23 项不变 ✅;无 JS 错误 ✅ | | ||
| + | |||
| + | ====== 4.49 表压气密性测试-交变:专属温循界面 + 三格式报告(2026-10-10) ====== | ||
| + | |||
| + | **需求**:该项可设「低温温度 / 高温温度 / 交变间隔(小时) / 交变次数」;每达到预设交变次数后记录一次「测试总数量 / 漏水个数」,**漏水率自动计算**;**默认 2 行可手动增加**;**去掉**该测试项的全量/ | ||
| + | |||
| + | ===== 前端(`test.html`) ===== | ||
| + | **新增判定 `isTPQAlterItem()`** = 项名含「表压气密性测试-交变」;`isQtyStruct()` 排除该项。 | ||
| + | |||
| + | **新增函数** | ||
| + | | 函数 | 作用 | | ||
| + | |---|---| | ||
| + | | `tpaStruct(it)` | 结构初始化:`{mode:' | ||
| + | | `tpaForm(it)` | 渲染:温循配置行 + 记录表(序号|交变次数|测试总数量|漏水个数|漏水率(自动)|备注|✕) | | ||
| + | | `tpaCfg(k, | ||
| + | | `tpaAdd()` / `tpaDel(i)` | 增加/ | ||
| + | | `tpaRate(r)` | **漏水率 = 漏水个数 ÷ 测试总数量 × 100%** | | ||
| + | | `tpaPaint()` | 刷新各行漏水率 + **累计合计**(总测试数/ | ||
| + | |||
| + | **接入点(5 处)**:`renderStruct()`(管理员)、`wxStructTable()`(测试员)、openItem 测试员气密分支、归档只读分支。 | ||
| + | |||
| + | **默认值**:低温 `-30` ℃、高温 `80` ℃、交变间隔 `1` 小时、交变次数 `100` 次。 | ||
| + | |||
| + | > 已验证:320 台/5 个 → **1.56%**;320 台/8 个 → **2.5%**;两行合计 640 台/13 个 → **2.03%**;无「记录方式(全量/ | ||
| + | |||
| + | ===== 后端报告(`test_api.py`) ===== | ||
| + | - 新增 `_tpa_rate(qty, | ||
| + | - 三处接入:`_render_report`(Web)、**`_docx_v2`(Word / PDF 实际走此函数)**、明细名与标题(「交变(温循)测试明细」) | ||
| + | - ⚠️ **踩坑**:Word/ | ||
| + | |||
| + | **验证(临时会话,已清理)** | ||
| + | | 格式 | 结果 | | ||
| + | |---|---| | ||
| + | | Web | 含「交变(温循)测试明细」+ 条件 + 1.56% + 合计 640/ | ||
| + | | Word(docx) | 同上 ✅ | | ||
| + | | PDF | 同上 ✅(LibreOffice 由 docx 转换)| | ||
| + | | **回归** | 表压气密性测试-常温(上漏/ | ||
| + | |||
| + | ====== 4.50 交变项:去掉「累计/ | ||
| + | |||
| + | **用户反馈**:交变项底部的「累计:测试 N 台 | 漏水 N 个 | 总漏水率 X%」不对 → **去掉累计台数与总漏水率**。 | ||
| + | |||
| + | **改动** | ||
| + | | 位置 | 改动 | | ||
| + | |---|---| | ||
| + | | 前端 `tpaPaint()` | 删除累计计算与 `#tpa_sum` 更新,**只保留每行自动漏水率** | | ||
| + | | 前端 `tpaForm()` | 移除 `<span id=" | ||
| + | | 后端 `_tpa_html()`(Web 报告)| 删除「合计」行 | | ||
| + | | 后端 `_tpa_docx_table()`(Word/ | ||
| + | |||
| + | **保留内容**:温循条件(低温/ | ||
| + | |||
| + | **验证(临时会话,已清理)** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 界面含「累计」/ | ||
| + | | 每行漏水率 | 1000台/ | ||
| + | | Web 报告含「合计」 | ✅ 已去掉;0.5%/ | ||
| + | | docx/PDF 报告含「合计」 | **0 处** ✅;0.5%/ | ||
| + | | **回归** | 其他测试项与文档未受影响 ✅ | | ||
| + | |||
| + | ====== 4.58 所有测试项新增「测试数据」区(手动输入 + 附件上传)(2026-10-10) ====== | ||
| + | |||
| + | **需求**:所有测试项的**测试备注**下方增加**测试数据** —— 可手动输入测试数据、可上传测试文档附件。 | ||
| + | ★ **已归档文档与已生成文档一律不改动**。 | ||
| + | |||
| + | ===== 数据结构 ===== | ||
| + | | 位置 | 改动 | | ||
| + | |---|---| | ||
| + | | `items` 表 | 新增字段 **`t_files`**(测试文档附件,格式 `url|文件名; | ||
| + | | `t_data` | 复用已有字段(手动输入的测试数据文本)| | ||
| + | |||
| + | ===== 前端(`test.html`) ===== | ||
| + | | 函数 | 作用 | | ||
| + | |---|---| | ||
| + | | `filesList(it)` / `filesStr(list)` | 附件列表 ↔ 存储串 互转 | | ||
| + | | `dataBlockHtml(it, | ||
| + | | `fileCards(it, | ||
| + | | `uploadItemFile(input)` | 上传到 `/ | ||
| + | | `delItemFile(i)` | 删除附件(带确认)| | ||
| + | |||
| + | **接入点(覆盖全部测试项)** | ||
| + | - 管理员主表单(测试备注之后)✅ | ||
| + | - 测试员气密表单(2 处)✅ | ||
| + | - 测试员扭力表单 ✅ | ||
| + | - **专项项**:`renderStruct`/ | ||
| + | - **归档只读视图**:显示「测试数据」「测试文档附件」(只读,无输入框、无上传入口)✅ | ||
| + | |||
| + | **保存链路**:`collectItems()` 带 `t_data`/ | ||
| + | |||
| + | ===== 后端报告(`test_api.py`) ===== | ||
| + | - Web 报告:`data_html` 追加「📎 测试文档附件」可点击链接 | ||
| + | - **`_docx_v2`**(Word/ | ||
| + | - ⚠️ 踩坑:先改到了 `_test_doc`(旧函数)→ Word/PDF 无变化;**报文导出实际走 `_docx_v2`** | ||
| + | |||
| + | ===== 验证(真实执行) ===== | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 普通项/ | ||
| + | | 上传附件 | `/ | ||
| + | | 保存 → 重读 | `t_data`/ | ||
| + | | **归档文档(# | ||
| + | | 报告 | Web ✅ / docx(含测试数据 + 附件名)✅ / PDF ✅ | | ||
| + | | **数据零改动** | 原有 **14 个会话 / 87 条测试项保持原样** ✅;未重新生成任何已有报告 ✅ | | ||
| + | | 验证残留 | 全部临时会话已清理,残留守 0 ✅ | | ||
| + | |||
| + | ====== 4.59 测试系统:复制测试文档生成副本(2026-10-10) ====== | ||
| + | |||
| + | **需求**:对已生成的测试文档进行**复制**,生成副本;副本的**文档号重新生成且不重复**。 | ||
| + | |||
| + | ===== 文档号说明 ===== | ||
| + | 测试文档号 = `sessions.id`(数据库自增主键)→ 副本插入新行即为**全新且永不重复**的号。 | ||
| + | |||
| + | ===== 后端(`test_api.py`) ===== | ||
| + | 新增 **`POST / | ||
| + | < | ||
| + | s = SELECT * FROM sessions WHERE id=sid | ||
| + | ins = 复制除 id/ | ||
| + | · status 重置为「未开始」 | ||
| + | · remark 追加「| 副本自 #< | ||
| + | · archived 保持 0(默认未归档,可继续编辑) | ||
| + | nid = last_insert_rowid() | ||
| + | 逐条复制 items 全部字段(含 t_struct/ | ||
| + | 返回 {ok, id: nid, items: N, from: sid} | ||
| + | </ | ||
| + | |||
| + | ===== 前端(`test.html`) ===== | ||
| + | - 文档卡片右上角新增 **📋 复制**图标(`copyIc`):**管理员与测试员**可见;删除图标(🗑)左侧;`event.stopPropagation()` 防止误触打开文档 | ||
| + | - 新增 `copySession(id)`:二次确认(说明会生成副本、副本可编辑)→ 调复制接口 → toast 提示「✅ 已生成副本 #N(M 个测试项)」→ 刷新列表 | ||
| + | - ⚠️ 修复:原用不存在的 `USER.phone` → 改为 `UNAME || wxLocal() || curName()`(测试页实际的身份变量) | ||
| + | |||
| + | ===== 验证(真实点击实测) ===== | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 点 📋(源 #88)| 生成副本 **# | ||
| + | | 副本数据 | 测试项 **2 个全部复制**(气密性测试-常温、阀体启闭扭矩测试-常温),`t_struct` 字节数与原完全一致 ✅ | | ||
| + | | 副本属性 | `status=未开始`、`archived=0` → **可继续编辑** ✅ | | ||
| + | | 原文档 | **保持不变**,仍在列表中 ✅ | | ||
| + | | 独立性 | 改副本不影响原件(已实测)✅ | | ||
| + | | 副本出报告 | Web/ | ||
| + | | 图标 | 卡片右上角 🗑(管理员)+ 📋(管理员/ | ||
| + | | 数据完整性 | 验证副本已清理,原有 **14 个会话 / 87 条测试项**不受影响 ✅ | | ||
| + | |||
| + | ====== 4.60 事故复盘 + 修复:测试员保存 500 & #88 数据被覆盖(2026-10-10) ====== | ||
| + | |||
| + | ===== 事故一:测试员保存任何测试文档都 500(用户报「13933534044 保存 #88 无反应」) ===== | ||
| + | **根因**:4.58 加「测试数据/ | ||
| + | < | ||
| + | SET t_person=?, | ||
| + | -- 12 个占位符,却传了 14 个参数 → sqlite3.ProgrammingError → HTTP 500 | ||
| + | </ | ||
| + | 前端拿不到 ok 也不提示 → 用户看到「点了保存没反应」。 | ||
| + | |||
| + | **修复**:SQL 补上 `t_data=?, | ||
| + | |||
| + | ===== 事故二:# | ||
| + | **根因(我的操作失误)**:排查事故一时,我**用真实文档 #88 直接调保存接口**做复测,而该接口是「**先删原 items 再按传入 items 重建**」→ 我传的简易 payload 把原数据覆盖为空。 | ||
| + | |||
| + | **恢复**:从 `12:07` 全库备份精确恢复 | ||
| + | - # | ||
| + | - 顺带恢复 `# | ||
| + | - 最终全库与备份**零差异**:**14 个会话 / 87 条测试项** | ||
| + | |||
| + | ===== ★★ 纪律(立即生效,写入冷启动文件) ===== | ||
| + | 1. **绝对禁止用真实测试文档做保存类测试**——必须**新建临时会话**(supplier 标记「验证-可删」),测完立即删除。 | ||
| + | 2. **改 SQL 必须同步核对占位符数 == 参数个数**(`? | ||
| + | 3. **改动测试相关接口,必须同时验证「管理员」与「测试员」两条保存路径**(本次只验了管理员,导致测试员全线 500)。 | ||
| + | 4. 动数据库前**必须先备份**(本次能在 20 分钟内恢复,全靠 12:07 的备份)。 | ||
| + | 5. 删除类操作、数据写入类操作,**测试完成后必须回读校验并清理**。 | ||
| + | |||
| + | ====== 4.61 结构测试新增「表压测试」分类(2026-10-10) ====== | ||
| + | |||
| + | **需求**:结构测试下新建一个「表压测试」,并把「其他测试」下的两个表压测试项移进来。 | ||
| + | |||
| + | **执行** | ||
| + | | 位置 | 改动 | | ||
| + | |---|---| | ||
| + | | `templates.json` → `categories[' | ||
| + | | `templates.json` → `items[' | ||
| + | | `templates.json` → `items[' | ||
| + | | `test.html` → `GROUP_MAP[' | ||
| + | |||
| + | **当前结构(智慧阀门 · 结构测试)** | ||
| + | < | ||
| + | 结构测试 | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | **验证** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 导航 | 结构测试 → **阀体测试 / 其他测试 / 表压测试** ✅ | | ||
| + | | 新分类内容 | 2 项:表压气密性测试-常温、表压气密性测试-交变 ✅(内容长度与原一致:method 26 / tool 74 / steps 300 / condition 47 字)| | ||
| + | | 其他测试 | 仅剩 扭力测试 ✅ | | ||
| + | | 新建会话 | 选「表压测试」可选这 2 项 ✅ | | ||
| + | | **已有文档不受影响** | # | ||
| + | | 判题逻辑 | `isTPQItem` / `isTPQAlterItem` 按**项名**判定(与分类无关)→ 行为不变 ✅ | | ||
| + | | 其他 | 无 JS 错误 ✅ | | ||
| + | |||
| + | ====== 4.62 将 #91、#95 文档移入「表压测试」分类(2026-10-10) ====== | ||
| + | |||
| + | **需求**:把 91、95 号测试文档挪到新建的「表压测试」分类。 | ||
| + | |||
| + | **执行**(★改库前先备份 `/ | ||
| + | < | ||
| + | UPDATE sessions SET category=' | ||
| + | </ | ||
| + | |||
| + | | 文档 | 改前 | 改后 | 测试项 | 数据完整性 | | ||
| + | |---|---|---|---|---| | ||
| + | | #91 | 其他测试 | **表压测试** | 表压气密性测试-常温 / 交变 | t_struct 合计 2012 字节 ✅ | | ||
| + | | #95 | 其他测试 | **表压测试** | 表压气密性测试-常温 / 交变 | t_struct 合计 674 字节 ✅ | | ||
| + | |||
| + | **改后分类现状** | ||
| + | - **表压测试**:# | ||
| + | - **其他测试**:# | ||
| + | |||
| + | **验证**:接口按 category=表压测试 查询返回 3 个文档(含 # | ||
| + | |||
| + | ====== 4.63 自定义测试项自动加入模板(新建测试可选)(2026-10-10) ====== | ||
| + | |||
| + | **需求**:在测试文档里「+ 添加测试项 → 自定义测试项」手动添加的项,要**自动进入模板**,以后「新建测试」时在该分类下可选。 | ||
| + | |||
| + | ===== 后端(`test_api.py`) ===== | ||
| + | 新增 **`POST / | ||
| + | < | ||
| + | 入参:{device, | ||
| + | 权限:仅 admin / tester(普通用户、游客 → 403) | ||
| + | 逻辑:写入 templates.json 的 items["< | ||
| + | · 同名去重(已存在 → {ok:true, added: | ||
| + | · 分类不存在则补进 categories[device] | ||
| + | 返回:{ok, | ||
| + | </ | ||
| + | |||
| + | ===== 前端(`test.html`) ===== | ||
| + | `aiAddCustom()`(自定义测试项)在加入当前文档的同时,**同步 POST 到模板接口**: | ||
| + | - 成功且新增 → toast「✅ 已添加「XX」(已加入" | ||
| + | - 已存在 → toast「已添加「XX」(该项此前已在可选列表中)」 | ||
| + | - 失败/ | ||
| + | |||
| + | ===== 验证 ===== | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 管理员添加自定义项 | ✅ `added: | ||
| + | | 模板文件 | ✅ 含新项 | | ||
| + | | **模板接口**(前端新建测试读它)| ✅ 返回含新项 → **新建测试可选** ✅ | | ||
| + | | 重复添加 | ✅ 去重(`added: | ||
| + | | 权限 | 普通用户 **403** ✅ / 游客 **403** ✅ / 测试员(**手机号登录**)**200** ✅ | | ||
| + | | 测试数据 | ✅ 已清理,模板恢复原状(表压测试 2 项)| | ||
| + | | 全库模板 | ✅ 各分类项数与改动前一致 | | ||
| + | |||
| + | ⚠️ 注意:测试员身份由**手机号注册**决定,用**姓名**调用会被判为普通用户(403)——这是既有设计。 | ||
| + | |||
| + | ====== 4.67 产品系列下拉新增「普惠P1」「拓远T1」(2026-10-10) ====== | ||
| + | |||
| + | **需求**:「其他测试」类目表单里的「产品系列」下拉,增加 普惠P1、拓远T1。 | ||
| + | |||
| + | **原有机制** | ||
| + | - 字段:`# | ||
| + | - 选项来源:`SERIES_LIST` ← `/ | ||
| + | - 改动前实际选项:金穗S1、润禾R1、普惠P3(分别来自 # | ||
| + | |||
| + | **改动** | ||
| + | | 位置 | 内容 | | ||
| + | |---|---| | ||
| + | | `templates.json` | 新增可配置基础清单 **`" | ||
| + | | `test_api.py` `/ | ||
| + | |||
| + | **验证(真实页面渲染 + 接口)** | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 接口 `series_list` | `[' | ||
| + | | 「其他测试」表单产品系列下拉 | 普惠P1 / 拓远T1 / 金穗S1 / 润禾R1 / 普惠P3 ✅ | | ||
| + | | 已有文档 #110 | 原选中值「普惠P3」保持不变 ✅ | | ||
| + | | **回归 · 阀体测试** | 字段仍是「阀体类型」(14 个硬编码阀体类型),**未混入** 普惠P1/ | ||
| + | | **回归 · 功能性能** | 表单正常渲染(系列为文本输入)✅ | | ||
| + | | 无 JS 错误 | ✅ | | ||
| + | |||
| + | **维护方式**:以后要在此下拉增删选项,改 `templates.json` 的 `series_list` 即可(无需动代码)。 | ||
| + | |||
| + | ====== 4.68 每个测试项增加「清空测试记录数据」(2026-10-18) ====== | ||
| + | |||
| + | **需求**:为每个测试项的测试文档,增加清空该测试项**测试记录数据**的功能。 | ||
| + | |||
| + | ===== 后端(`test_api.py`) ===== | ||
| + | 新增 **`POST / | ||
| + | < | ||
| + | 入参:{item_name, | ||
| + | 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 重置为「未开始」 | ||
| + | 保留:测试条件/ | ||
| + | </ | ||
| + | 权限兜底:手机号能对应到管理员姓名(`_wx_users()[phone].name in _admins()`)也放行。 | ||
| + | |||
| + | ===== 前端(`test.html`) ===== | ||
| + | - 测试项详情「测试项信息」标题右侧新增 **🧹 清空记录** 按钮(仅管理员可见/ | ||
| + | - 点击弹出**勾选式确认面板**: | ||
| + | < | ||
| + | ☑ 测试数据(表格 / 记录 / 时段日志 / 测试结果) | ||
| + | ☐ 测试照片(N 张) | ||
| + | ☐ 测试文档附件(N 个) | ||
| + | ☐ 测试状态重置为「未开始」 | ||
| + | 提示:保留 测试条件/ | ||
| + | </ | ||
| + | - 确认后调接口 → toast「🧹 已清空测试记录」→ 自动重载该文档并停留原测试项 | ||
| + | |||
| + | ===== 验证(临时文档实测,用完已删) ===== | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 只清 `data` | ✅ 表格/ | ||
| + | | 其他测试项 | ✅ 完全不受影响 | | ||
| + | | 全清(data+photo+files+status)| ✅ 照片、附件清空;状态重置「未开始」;备注仍保留 | | ||
| + | | 测试员调用 | ✅ **403** 仅管理员可清空 | | ||
| + | | 前端 | ✅ 按钮存在;面板标题/ | ||
| + | | 真实文档 #42 | 仅打开面板未确认 → **数据未被改动** | | ||
| + | |||
| + | ====== 4.69 修复:电路测试类文档导出报告失败(页面显示原始 JSON)(2026-10-23) ====== | ||
| + | |||
| + | **现象**(用户截图):智慧阀门 → 电路测试 → 导出报告 → 手机上整屏显示 | ||
| + | `{" | ||
| + | |||
| + | ===== 根因(写死分类名) ===== | ||
| + | `test_api.py` 报告接口的 mode 校验: | ||
| + | < | ||
| + | if mode == " | ||
| + | return jsonify({" | ||
| + | </ | ||
| + | 但 2026-09-16 分类拆分后,**电路测试组的实际分类是 功能性能 / 环境可靠性 / 机械应力**(很少再叫" | ||
| + | 所以这些文档导出 → 一律 400 → 前端 `window.open('/ | ||
| + | |||
| + | `_render_report()` 里还有一处同样的写死判断 → 就算放过校验,报告里的测试项也会被**全部跳过(空报告)**。 | ||
| + | |||
| + | ===== 修复 ===== | ||
| + | 1. 两处判断统一改用已有 helper **`_is_circuit_cat()`**(含历史" | ||
| + | 2. 报告类接口的错误响应 → **友好 HTML 错误页**(⚠️ 大标题 + 具体原因 + 返回按钮),不再返回裸 JSON | ||
| + | 3. 报告 HTML 响应加 `Cache-Control: | ||
| + | 4. **归档文档对非管理员只读 → 导出时跳过保存**(原来必先保存 → 被 403" | ||
| + | 5. 保存失败提示具体原因(原来只显示" | ||
| + | |||
| + | ===== 实测 ===== | ||
| + | | 场景 | 结果 | | ||
| + | |---|---| | ||
| + | | # | ||
| + | | #7 Word / PDF | ✅ 200 docx / 200 pdf | | ||
| + | | # | ||
| + | | # | ||
| + | | 错误场景(阀体文档用 circuit 模式导出)| ✅ 显示**友好错误页**「⚠️ 无法生成报告 + 原因 + 返回」 | | ||
| + | | 测试员 + 归档文档导出 | ✅ **0 次保存请求**,直接出报告 | | ||
| + | | 管理员 + 未归档副本 | ✅ 先保存再导出 | | ||
| + | | 数据核对 | 17 会话 / 66 测试项,与备份逐会话比对无丢失(少掉的 31 条是早已删除的 #6 会话遗留孤儿项)| | ||
| + | |||
| + | ⚠️ 提醒:手机上导 Word/ | ||
| + | |||
| + | ====== 4.70 气密性测试新增「第3步:全关」(2026-10-23) ====== | ||
| + | |||
| + | **需求**:气密性测试原来只有第1步(堵住A口)、第2步(堵住B口),**新增第3步 = 全关的情况**。 | ||
| + | |||
| + | ===== 三步定义(阀门气密) ===== | ||
| + | | 步骤 | 状态 | 说明 | | ||
| + | |---|---|---| | ||
| + | | 第1步 | 堵住A口 | 堵住A口,调节A口开度,调节水压 | | ||
| + | | 第2步 | 堵住B口 | 堵住B口,调节B口开度,调节水压 | | ||
| + | | **第3步** | **全关** | **阀门全部关闭,观察各部位渗漏** | | ||
| + | |||
| + | ⚠️ **表压气密性测试(表压测试分类)仍只有第1步**,不受影响。 | ||
| + | |||
| + | ===== 实现要点(`test.html`) ===== | ||
| + | < | ||
| + | function stepKeyOf(n){ return n===1?' | ||
| + | function stepNums(){ return isTPQItem()? | ||
| + | function stepTitle(n){ n=1→堵住A口… ; n=2→堵住B口… ; n=3→全关(阀门全部关闭,观察各部位渗漏)} | ||
| + | function _mergeAllSteps(container){ … } // 跨步配置并集支持 3 步 | ||
| + | </ | ||
| + | - 管理员 `renderStruct` 与 **测试员 `wxStructTable`** 两套渲染都支持三步 | ||
| + | - 默认 `t_struct` 增加 `step3: | ||
| + | - **全量**与**批量**两种记录方式都支持第3步(各自可配 开度/ | ||
| + | - 第3步默认沿用第1/ | ||
| + | |||
| + | ===== 报告(`test_api.py`) ===== | ||
| + | < | ||
| + | def _step_list(st): | ||
| + | </ | ||
| + | Web / Word / PDF **三种报告**都包含第3步;批量报告的三处表格也补齐第3步。 | ||
| + | |||
| + | ===== ★ 顺带修复的旧 bug ===== | ||
| + | 气密表格单元格的 `onchange` 行内**直接引用了函数局部变量** `o / p / j / bi2 / bi3`: | ||
| + | < | ||
| + | onchange=" | ||
| + | <!-- o/p/j 在事件触发时不存在 → Uncaught ReferenceError(步骤1/ | ||
| + | </ | ||
| + | 改为 **`logCell(this)`**:由函数从表格结构(首列" | ||
| + | 现在三步任意单元格改数据都**零报错**。 | ||
| + | |||
| + | ===== 验证 ===== | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 管理员视图(阀体气密)| ✅ 第1/2/3 步配置块与数据表齐全 | | ||
| + | | 测试员视图(`IS_WX`)| ✅ 三步齐全,第3步文案「全关」 | | ||
| + | | 第3步生成数据表 / 填值 / 保存 | ✅ cells 落库(如 `{" | ||
| + | | 改任意步骤单元格 | ✅ 无 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/ | ||
| + | | 组合 | 只能选那 6 个值 | 任意 4 个,如 0%/ | ||
| + | |||
| + | ===== 实现(`test.html`) ===== | ||
| + | < | ||
| + | var OPEN_STEPS = 0%, | ||
| + | function openSlotSelects(step, | ||
| + | function openValSort(list) | ||
| + | function openExtraHint(opens) | ||
| + | </ | ||
| + | - **全量模式**:`select.o-slot`(`stepBlock`) | ||
| + | - **批量模式**:三步都用 `select.bo-slot`(`batchBlock`) | ||
| + | - `buildTable()` / `batchGen()` 改为从下拉取值 | ||
| + | |||
| + | ===== 历史兼容规则(重要) ===== | ||
| + | < | ||
| + | · 打开老文档、四个槽位未被改动 → 保留原有【全部】开度(如原来 6 个,仍是 6 个表格) | ||
| + | · 一旦改动槽位 → 严格按这 4 个(或更少)生成 | ||
| + | · 原有超出 4 个的开度会在界面上提示" | ||
| + | </ | ||
| + | ⚠️ 表压气密性测试(表压测试分类)**没有开度概念**,仍隐藏开度行、固定 100%/ | ||
| + | |||
| + | ===== 验证 ===== | ||
| + | | 项 | 结果 | | ||
| + | |---|---| | ||
| + | | 全量:下拉数量/ | ||
| + | | 全量:老值回填 | ✅ 原 0%/100% 自动填入前两个槽位 | | ||
| + | | 全量:改选 0/30/60/100 | ✅ `step1.opens` 准确写入,数据表 34 行 | | ||
| + | | 批量:三步下拉 | ✅ 12 个(3 步 × 4)| | ||
| + | | 批量:未改动 | ✅ 历史 6 个开度全部保留 | | ||
| + | | 批量:改选 0%/50% | ✅ 严格按 2 个生成 | | ||
| + | | 表压气密(回归)| ✅ 无开度下拉、无第2/ | ||
| + | | JS 错误 | ✅ 无 | | ||
| + | | 数据安全 | 全部用「复制副本」验证,真实文档未动;副本已删 | | ||
| + | |||
| + | ⚠️ 踩坑:`batchGen()` 里 `b[key]` 与 `st.batch[key]` 是**同一个对象引用**, | ||
| + | 先 `b[key].opens=[]` 再取旧值 → 永远拿到空数组 → 必须**清空前先备份**。 | ||
| ====== 5. 测试项模板 ====== | ====== 5. 测试项模板 ====== | ||
测试管理系统h5/冷启动文件.1791461196.txt.gz · Last modified: by 172.17.0.1 · Currently locked by: 216.73.216.247
