Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

5 linhas
16 KiB

  1. <!doctype html>
  2. <html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>接口错误 Message 回归报告</title>
  3. <style>*{box-sizing:border-box}body{margin:0;background:#f3f6f7;color:#183739;font-family:"Microsoft YaHei",system-ui,sans-serif;line-height:1.65}main{max-width:1220px;margin:auto;padding:28px 24px 60px}header{padding:30px;border-radius:18px;background:#084d46;color:white}h1{margin:0 0 10px;font-size:28px}h2{font-size:20px;margin:28px 0 12px}h3{font-size:16px;margin:0;flex:1;min-width:0}p{margin:10px 0}.muted{color:#c9e8e1}.stats{display:flex;gap:12px;flex-wrap:wrap;margin-top:20px}.stats span{border:1px solid #67958c;border-radius:9px;padding:8px 14px;background:#ffffff0b}.links{display:flex;gap:18px;flex-wrap:wrap;margin:14px 0}a{color:#126f62}.stages{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px}.stage,.check,.scope{background:white;border:1px solid #dce7e4;border-radius:12px;padding:18px}.stage strong{color:#147160}.stage p{font-size:14px;color:#45615f}.check{margin:14px 0}.check-title{display:flex;align-items:flex-start;gap:12px}.badge{font-size:12px;border-radius:6px;padding:3px 8px;white-space:nowrap}.pass{background:#e6f5ed;color:#197344}.fail{background:#ffebeb;color:#a72e2e}small{color:#69817e;white-space:nowrap}.shots{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:16px}figure{margin:0;min-width:0}img{display:block;width:100%;height:auto;border:1px solid #dce7e4;border-radius:7px}figcaption{font-size:12px;color:#617b76;overflow-wrap:anywhere;margin-top:5px}.scope p{color:#45615f}code{overflow-wrap:anywhere;font-size:13px}footer{margin-top:24px;color:#69817e;font-size:12px;overflow-wrap:anywhere}@media(max-width:900px){.stages{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:620px){main{padding:14px 12px 35px}header{padding:20px}h1{font-size:23px}.stages,.shots{grid-template-columns:1fr}.check-title{flex-wrap:wrap}.check-title h3{flex-basis:75%}.check-title small{margin-left:60px}.check{padding:13px}}
  4. </style></head><body><main><header><h1>接口错误 Message 回归报告</h1><p class="muted">资料 → 原型 → 设计 → 开发 → 测试</p><p>主回归:代表性接口错误按统一 Message 展示;自动消失、重试与业务状态保留已通过浏览器验证。</p><p>认证附加:3 项通过,2 项旧改密入口受当前路由契约阻断;原始失败保留,未计为通过。</p><div class="stats"><span>主回归 9 / 9 通过</span><span>主回归 17 张截图</span><span>58 次模拟 API 请求</span><span>0 个未捕获页面异常</span></div></header>
  5. <div class="links"><a href="report.md">Markdown 报告</a><a href="evidence.json">结构化证据</a><a href="playwright/index.html">Playwright 报告</a></div><h2>审查与实施</h2><div class="stages"><section class="stage"><strong>资料</strong><p>按本轮“接口错误使用 Message,不保留常驻错误横条”的要求检查。沿用已确认的教学业务边界:离线识别回放、观察模式、步骤反馈和表单校验仍需可见。</p></section><section class="stage"><strong>原型</strong><p>错误发生时顶部短暂提示;可以手动关闭,约 4.5 秒自动消失。同一错误合并展示;失败后仍可重新加载,已成功取得的数据不因后续刷新失败消失。</p></section><section class="stage"><strong>设计</strong><p>共享 Message 处理负责统一展示与缓存页面生命周期;请求层保留业务错误码、HTTP 状态和 requestId,静默请求不会自行弹窗。未取得数据与空结果保持区分。</p></section><section class="stage"><strong>开发</strong><p>代表性覆盖内容制作、系统用户与教学实施,包括训练编辑器加载失败的重试入口。接口异常详情仅在 Message 中展示;表单必填错误、项目编码说明和离线运行模式继续保留。</p></section><section class="stage"><strong>测试</strong><p>使用真实 Vue / Element Plus 页面、Edge 无头浏览器和浏览器级 API mock。覆盖本机与局域网入口。身份及接口数据均为合成测试数据;不登录真实账号、不写业务库,不将本轮测试称为真实服务端或设备联调。</p></section></div><h2>浏览器验证(主回归)</h2><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>1. 内容列表:错误自动消失、重试恢复、再次失败保留旧数据</h3><small>12.8 秒</small></div><div class="shots"><figure><a href="screenshots/01-content-error-message.png" target="_blank" rel="noopener"><img src="screenshots/01-content-error-message.png" alt="01-content-error-message"></a><figcaption>01-content-error-message</figcaption></figure><figure><a href="screenshots/02-content-old-data-retained.png" target="_blank" rel="noopener"><img src="screenshots/02-content-old-data-retained.png" alt="02-content-old-data-retained"></a><figcaption>02-content-old-data-retained</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>2. 系统用户:并行同错合并一条,重复搜索可再次提示</h3><small>12.7 秒</small></div><div class="shots"><figure><a href="screenshots/03-users-grouped-message.png" target="_blank" rel="noopener"><img src="screenshots/03-users-grouped-message.png" alt="03-users-grouped-message"></a><figcaption>03-users-grouped-message</figcaption></figure><figure><a href="screenshots/04-users-retry-without-banner.png" target="_blank" rel="noopener"><img src="screenshots/04-users-retry-without-banner.png" alt="04-users-retry-without-banner"></a><figcaption>04-users-retry-without-banner</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>3. 训练编辑器:加载失败提示消失后保留重新加载按钮</h3><small>6.4 秒</small></div><div class="shots"><figure><a href="screenshots/05-legacy-training-message.png" target="_blank" rel="noopener"><img src="screenshots/05-legacy-training-message.png" alt="05-legacy-training-message"></a><figcaption>05-legacy-training-message</figcaption></figure><figure><a href="screenshots/06-legacy-training-retry.png" target="_blank" rel="noopener"><img src="screenshots/06-legacy-training-retry.png" alt="06-legacy-training-retry"></a><figcaption>06-legacy-training-retry</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>4. 实装预览:任务上下文错误用 Message,离线与教员模式持续可见</h3><small>6.5 秒</small></div><div class="shots"><figure><a href="screenshots/07-physical-context-message.png" target="_blank" rel="noopener"><img src="screenshots/07-physical-context-message.png" alt="07-physical-context-message"></a><figcaption>07-physical-context-message</figcaption></figure><figure><a href="screenshots/08-physical-mode-preserved.png" target="_blank" rel="noopener"><img src="screenshots/08-physical-mode-preserved.png" alt="08-physical-mode-preserved"></a><figcaption>08-physical-mode-preserved</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>5. 新建训练:业务说明与必填校验保留,不发起创建请求</h3><small>2.5 秒</small></div><div class="shots"><figure><a href="screenshots/09-create-validation-preserved.png" target="_blank" rel="noopener"><img src="screenshots/09-create-validation-preserved.png" alt="09-create-validation-preserved"></a><figcaption>09-create-validation-preserved</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>6. 缓存列表:失活时晚到错误不弹出,返回不重放旧错误</h3><small>1.9 秒</small></div><div class="shots"><figure><a href="screenshots/10-inactive-page-no-message.png" target="_blank" rel="noopener"><img src="screenshots/10-inactive-page-no-message.png" alt="10-inactive-page-no-message"></a><figcaption>10-inactive-page-no-message</figcaption></figure><figure><a href="screenshots/11-reactivated-no-stale-message.png" target="_blank" rel="noopener"><img src="screenshots/11-reactivated-no-stale-message.png" alt="11-reactivated-no-stale-message"></a><figcaption>11-reactivated-no-stale-message</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>7. HTTP 合同:真实 Axios 超时中文化,403/409 元数据保留,静默请求不自动弹窗</h3><small>1.9 秒</small></div><div class="shots"><figure><a href="screenshots/12-http-silent-errors.png" target="_blank" rel="noopener"><img src="screenshots/12-http-silent-errors.png" alt="12-http-silent-errors"></a><figcaption>12-http-silent-errors</figcaption></figure><figure><a href="screenshots/15-business-message-keeps-original-text.png" target="_blank" rel="noopener"><img src="screenshots/15-business-message-keeps-original-text.png" alt="15-business-message-keeps-original-text"></a><figcaption>15-business-message-keeps-original-text</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>8. 局域网教学列表:既有 ElMessage.error 使用全局关闭和自动消失配置</h3><small>6.9 秒</small></div><div class="shots"><figure><a href="screenshots/13-lan-teaching-message.png" target="_blank" rel="noopener"><img src="screenshots/13-lan-teaching-message.png" alt="13-lan-teaching-message"></a><figcaption>13-lan-teaching-message</figcaption></figure><figure><a href="screenshots/14-lan-teaching-after-dismiss.png" target="_blank" rel="noopener"><img src="screenshots/14-lan-teaching-after-dismiss.png" alt="14-lan-teaching-after-dismiss"></a><figcaption>14-lan-teaching-after-dismiss</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>9. 模型桥接 DOM 合同:初次错误与晚写详情转为重试说明,ready 恢复交互</h3><small>0.8 秒</small></div><div class="shots"><figure><a href="screenshots/16-model-bridge-neutral-retry.png" target="_blank" rel="noopener"><img src="screenshots/16-model-bridge-neutral-retry.png" alt="16-model-bridge-neutral-retry"></a><figcaption>16-model-bridge-neutral-retry</figcaption></figure><figure><a href="screenshots/17-model-bridge-ready.png" target="_blank" rel="noopener"><img src="screenshots/17-model-bridge-ready.png" alt="17-model-bridge-ready"></a><figcaption>17-model-bridge-ready</figcaption></figure></div></section><h2>认证附加回归(独立统计)</h2><section class="scope"><p><strong>共实际运行 5 项:3 项通过;2 项旧强制改密用例受当前路由契约阻断,未验证到原断言。主报告 9 项结果单独统计。</strong></p><p>Edge headless,http://127.0.0.1:6180,认证 API 全部由 Playwright 拦截模拟;trace/video 关闭。</p><p>仅模拟认证接口与浏览器交互,不使用真实账号,不验证后端认证规则或真实密码修改。</p><p>未运行依赖真实账号的 auth.spec.ts 全量;仅更新其中接口错误提示的断言选择器。</p><p>两条旧强制改密用例没有通过,不能作为当前改密功能验证证据;既有路由策略不在本轮提示展示调整范围。</p><div class="links"><a href="authentication/summary.json">认证汇总证据</a><a href="authentication/html/index.html">第 1 轮原始报告</a><a href="authentication/login-message/html/index.html">第 2 轮原始报告</a></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>859:无可登录教员时账号选择器禁用</h3></div><p>保留业务空态,选择器不可展开。</p><div class="shots"><figure><a href="authentication/screenshots/859-passed.png" target="_blank" rel="noopener"><img src="authentication/screenshots/859-passed.png" alt="无教员业务空态"></a><figcaption>无教员业务空态</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge fail">BLOCKED</span><h3>861:旧强制改密不一致校验</h3></div><p>当前 /change-password 对已认证用户重定向 /dashboard;旧 fixture 只有强制改密标记而无工作台权限,后续导航取消,停留在启动页,未进入改密表单。该旧用例不适用于当前路由契约,本次未改路由、未跳过或记为通过。</p><p>Playwright 原始状态:failed。</p><div class="shots"><figure><a href="authentication/screenshots/861-failed.png" target="_blank" rel="noopener"><img src="authentication/screenshots/861-failed.png" alt="旧改密入口阻断"></a><figcaption>旧改密入口阻断</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge fail">BLOCKED</span><h3>864:旧强制改密停用账号提示</h3></div><p>与 861 相同的既有路由契约阻断,未能提交初始改密接口,也未验证一次性登录提示。原始失败证据保留。</p><p>Playwright 原始状态:failed。</p><div class="shots"><figure><a href="authentication/screenshots/864-failed.png" target="_blank" rel="noopener"><img src="authentication/screenshots/864-failed.png" alt="旧停用账号流程阻断"></a><figcaption>旧停用账号流程阻断</figcaption></figure></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>普通会话过期不泄露后端内部详情</h3></div><p>跳转登录页,登录错误栏为空,不显示内部会话或刷新令牌详情,仅发起一次刷新请求。</p><div class="shots"></div></section><section class="check"><div class="check-title"><span class="badge pass">PASS</span><h3>当前管理员登录 API 401 错误使用自动消失的 Message</h3></div><p>实际点击登录;mock POST /auth/login 返回 401。只出现一条 .el-message--error,#login-error 始终为空;未点击关闭,Message 自动消失。登录请求 1 次,刷新请求 0 次。</p><div class="shots"><figure><a href="authentication/login-message/screenshots/login-api-error-message.png" target="_blank" rel="noopener"><img src="authentication/login-message/screenshots/login-api-error-message.png" alt="登录失败 Message"></a><figcaption>登录失败 Message</figcaption></figure><figure><a href="authentication/login-message/screenshots/login-api-error-message-dismissed.png" target="_blank" rel="noopener"><img src="authentication/login-message/screenshots/login-api-error-message-dismissed.png" alt="Message 自动消失后"></a><figcaption>Message 自动消失后</figcaption></figure></div></section><h2>构建与聚焦逻辑验证</h2><section class="scope"><p><strong>PASS · unreal_tran_web</strong><br><code>pnpm run build</code><br>最终 vue-tsc、Vite 与 legacy iframe public/dist 哈希校验通过;仍有既有 chunk 体积提示。 <a href="validation/build.log">日志</a></p><p><strong>PASS · ute2e</strong><br><code>node --test tools/scene-cover-api.test.mjs tools/guide-error-message.test.mjs</code><br>20/20 通过,包含保存失败只提示一次、阻断发布与离开,以及指导书/场景错误提示回归。 <a href="validation/runtime-tests.log">日志</a></p><p><strong>PASS · ute2e</strong><br><code>pnpm exec tsc --noEmit --target ES2022 --module ESNext --moduleResolution Bundler --strict --types &#39;node,@playwright/test&#39; tests/api-error-messages.spec.ts api-error-messages.config.ts</code><br>本轮新增浏览器测试与配置类型检查通过。</p><p><strong>PASS · unreal_tran_web、ute2e</strong><br><code>git diff --check</code><br>主任务检查通过;报告生成后再次核验本轮文件。</p></section><h2>范围与复现</h2><section class="scope"><p>这是接口失败展示的聚焦浏览器回归,未逐一遍历所有业务页面。</p><p>页面渲染、Element Plus Message、缓存路由和 Axios 超时均运行于真实浏览器;服务端响应由测试模拟。</p><p>模型 iframe 项为真实宿主桥接的 DOM 合同测试,使用空画布夹具,不代表完整 GLB 模型加载测试。</p><p>保留训练业务状态、表单校验与重试入口。未扩大教学流程、权限或接口合同。</p><p><code>pnpm exec playwright test -c api-error-messages.config.ts</code></p><p>报告重新生成:<code>node tools/build-api-error-message-report.mjs</code></p></section><footer>测试开始:2026-09-05T17:32:19.650Z · 报告生成:2026-09-05T17:36:20.720Z</footer></main></body></html>