Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

47 Zeilen
12 KiB

  1. import fs from 'node:fs'
  2. import path from 'node:path'
  3. const dir='reports/guide-formal-20260910'
  4. const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]))
  5. // 报告只保留结论,不携带完整接口载荷、内部存储地址或上传凭据。
  6. for(const file of ['create.json','upload.json','publish.json']){
  7. const data=JSON.parse(fs.readFileSync(path.join(dir,file),'utf8'))
  8. for(const check of data.checks||[])if(check.detail?.startsWith('{'))check.detail='真实 HTTP 请求成功;响应内容已脱敏。'
  9. fs.writeFileSync(path.join(dir,file),JSON.stringify(data,null,2))
  10. }
  11. const suites=[['create.json','正式工程新建'],['upload.json','模型资源上传与恢复'],['scenes.json','固定场景版本与修订'],['publish.json','正式发布与交付物'],['review.json','教学阅读及真实 HTTP 查询'],['permissions.json','权限、私人记录与反馈'],['final.json','阅读、笔记、进度及 HTTP 写入'],['template.json','正式模板新建'],['media.json','图片、视频及截图引用'],['offline-browser.json','正式离线包运行']]
  12. const results=suites.map(([file,title])=>({file,title,...JSON.parse(fs.readFileSync(path.join(dir,file),'utf8'))}))
  13. const checks=results.flatMap(r=>r.checks),passed=checks.filter(c=>c.pass).length
  14. const release=JSON.parse(fs.readFileSync(path.join(dir,'release.json'),'utf8'))
  15. const offline=JSON.parse(fs.readFileSync(path.join(dir,'offline.json'),'utf8'))
  16. const shots=[
  17. ['01-formal-created.png','正式指导书新建,写入内容服务'],
  18. ['02-formal-assets.png','狐狸、牛奶卡车 GLB 上传至正式资源存储'],
  19. ['03-formal-fox.png','刷新后狐狸模型恢复显示'],
  20. ['04-formal-published.png','V3.0.0 正式发布及交付物'],
  21. ['05-reader-notes.png','教学阅读:笔记与收藏'],
  22. ['06-reader-layout.png','教学阅读:OFD 版式'],
  23. ['09-reader-model.png','教学动态阅读:狐狸模型'],
  24. ['10-two-scene-resources.png','两个已发布场景固定版本引用'],
  25. ['11-reader-truck.png','教学动态阅读:牛奶卡车'],
  26. ['12-reading-completed.png','完成阅读,进度与统计更新'],
  27. ['08-http-integration.png','对外接口:真实 HTTP 查询'],
  28. ['13-http-conflict.png','对外接口:旧版本写入返回 409'],
  29. ['14-formal-templates.png','正式模板库'],
  30. ['17-template-editor.png','模板生成章节与步骤并保存'],
  31. ['15-offline-fox-scene.png','离线包:场景 160 当前发布内容(维修车间与装备)'],
  32. ['16-offline-truck-scene.png','离线包:牛奶卡车场景'],
  33. ['18-formal-video.png','图片与截图引用保持,视频实际播放'],
  34. ]
  35. const html=`<!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>作业指导正式接口与教学闭环 · 实测报告</title>
  36. <style>*{box-sizing:border-box}body{margin:0;background:#eff5f4;color:#203e42;font:15px/1.7 system-ui,"Microsoft YaHei",sans-serif}main{max-width:1200px;margin:auto;padding:32px 24px}header,section{background:#fff;border:1px solid #d4e4e0;border-radius:12px;padding:24px;margin-bottom:22px}header{border-top:5px solid #10856e}h1{margin:0 0 10px;font-size:28px}h2{font-size:21px;margin:0 0 14px}h3{font-size:17px;margin:22px 0 8px}p{margin:8px 0}a{color:#087b66}nav{display:flex;gap:20px;flex-wrap:wrap;margin-top:15px}.metrics{display:flex;gap:12px;flex-wrap:wrap;margin:20px 0 0}.metric{background:#edf8f4;border-radius:8px;padding:12px 20px}.metric b{font-size:24px;color:#087b66;display:block}.note{background:#fff7e8;border-left:4px solid #e7a337;padding:12px 16px;margin-top:16px}table{width:100%;border-collapse:collapse;font-size:14px}th,td{border:1px solid #dce7e4;text-align:left;padding:10px 12px;vertical-align:top}th{background:#edf6f3}code{overflow-wrap:anywhere}.pass{color:#078064;font-weight:700}.fail{color:#ba3434}.gallery{display:grid;grid-template-columns:1fr 1fr;gap:18px}figure{margin:0;border:1px solid #dce7e4;border-radius:8px;overflow:hidden}figure img{display:block;width:100%;height:auto}figcaption{padding:10px 14px;background:#f4f8f7}.subtle{color:#637b7d;font-size:13px}li{margin:7px 0}@media(max-width:760px){main{padding:16px 10px}.gallery{grid-template-columns:1fr}header,section{padding:16px}table{font-size:12px}th,td{padding:7px}}</style>
  37. <main><header><p class="subtle">开发环境 · 2026-09-10 — 2026-09-11 · 顺序实施与回归</p><h1>作业指导正式接口与教学闭环</h1><p>已完成编辑器接入、教学阅读记录、真实 HTTP 联调三项实施。正式发布工程 ${esc(release.projectId)},版本 ${esc(release.versionCode)}(版本 ID ${esc(release.versionId)})。</p><div class="metrics"><div class="metric"><b>${passed}/${checks.length}</b>E2E 检查点通过</div><div class="metric"><b>391</b>后端测试通过</div><div class="metric"><b>17</b>关键截图</div><div class="metric"><b>3</b>保留复核工程</div></div><nav><a href="#scope">实施内容</a><a href="#tests">测试结果</a><a href="#screenshots">截图</a><a href="#delivery">交付与迁移</a><a href="#limits">复核说明</a></nav></header>
  38. <section id="scope"><h2>实施内容</h2><table><tr><th>顺序</th><th>落地结果</th><th>验证方式</th></tr><tr><td>1. 内容、资源、版本</td><td>完整编辑文档写入正式内容服务;上传资源进入受控存储;模板、模型和场景从正式接口加载;保存、发布、历史版本及恢复使用服务端版本。场景资源固定到发布版本,修改草稿不改变已发布教学内容。</td><td>新建、模板生成、保存重开、GLB/图片/视频上传、固定场景引用、修订与发布、OFD 和离线 ZIP 实际下载。</td></tr><tr><td>2. 教学阅读闭环</td><td>教学端消费正式发布文档与受控资源;阅读位置、笔记、收藏按用户和发布版本独立保存;记录开始/完成、反馈与处理,提供授权聚合统计。</td><td>翻页恢复、笔记增改删、收藏取消、动态步骤同步进度、学员权限及数据隔离、反馈回复、完成记录。</td></tr><tr><td>3. 真实 HTTP 联调</td><td>接口页面通过统一 HTTP 客户端调用 Gateway/业务服务,展示真实响应。涵盖内容、资源、版本、教学、个人阅读记录、统计与交付物。</td><td>浏览器实际 GET/PUT;旧版本返回 409;错误方法返回 405;未经授权内容和统计接口返回 403。</td></tr></table><p>接口沿用平台统一登录会话与权限体系。第三方系统需取得平台会话;数字人开放应用 APPID 不用于这组作业指导接口。</p>
  39. <h3>本轮修复</h3><ul><li>完整文档校验及正式资源 URI 保留;教学投影转换为受控下载地址,避免文件存储地址直接暴露或刷新后丢失。</li><li>大 GLB 流式下载被默认 30 秒中断;异步流响应超时调整为可配置的 30 分钟。</li><li>保存与发布并发造成旧版本冲突;发布前等待自动保存队列完成。</li><li>阅读器初始化零页记录、只读目录/动画选择被拦截、动态页进度未同步、笔记删除后编辑框残留。</li><li>离线模型切换后的矩阵与镜头适配错误,导致场景偏出画面。</li><li>图片、视频海报的正式 URI 被过滤;视频完成加载后动态预览未刷新。已验证受控视频实际播放。</li><li>发布弹窗与动态白纸内容的暗色主题文字对比度。</li></ul></section>
  40. <section id="tests"><h2>测试结果</h2><p>浏览器为 Edge / Playwright,主要视口 1920×1080。管理操作使用内部维护账号;教学权限使用临时学员账号,测试后已清理。HTTP 通过 Web 6180 → Gateway 6100 → Tran 6102。</p><p><code>mvn -pl ut_tran -am test package</code>:391 项通过,0 失败、0 错误、0 跳过。<br><code>pnpm run build</code>:类型检查、Vite 构建与模型编辑器发布资源校验通过;保留既有 chunk 大小及运行时资源 URL 警告。</p>${results.map(s=>`<h3>${esc(s.title)} <a class="subtle" href="${s.file}">JSON 证据</a></h3><table><tr><th>检查点</th><th style="width:80px">结果</th></tr>${s.checks.map(c=>`<tr><td>${esc(c.name)}${c.detail?`<div class="subtle">${esc(c.detail)}</div>`:''}</td><td class="${c.pass?'pass':'fail'}">${c.pass?'通过':'失败'}</td></tr>`).join('')}</table>`).join('')}<p class="subtle">检查点来自分阶段脚本,覆盖关键链路,不表示所有边缘输入均已穷举。create/scenes 等早期证据对应创建及 V1→V2 阶段;最新发布、阅读和离线回归对应 V3。</p></section>
  41. <section id="screenshots"><h2>关键截图</h2><p>点击图片查看原图。文件名中的“fox-scene”沿用测试场景名称,不代表该场景当前实际包含狐狸。</p><div class="gallery">${shots.map(([file,title])=>`<figure><a href="${file}" target="_blank"><img src="${file}" alt="${esc(title)}" loading="lazy"></a><figcaption>${esc(title)}</figcaption></figure>`).join('')}</div></section>
  42. <section id="delivery"><h2>交付与迁移</h2><p><a href="formal.ofd">下载实测正式 OFD</a> · <a href="formal-offline.zip">下载实测正式离线 ZIP(本地文件)</a> · <a href="release.json">发布摘要</a> · <a href="offline.json">ZIP 完整性证据</a></p><p>离线 ZIP:${Number(offline.zipBytes).toLocaleString('zh-CN')} 字节;4 个 GLB 文件通过头部与长度检查。从正式 V3 下载后解压并运行,禁止访问业务服务及公网仍能加载两个场景。镜头修复代码已经包含在正式交付包中。</p><p class="subtle">SHA-256:<code>${esc(offline.sha256)}</code></p><table><tr><th>开发环境迁移</th><th>说明</th></tr><tr><td>20260826_017_teaching_guide_reading_closed_loop.sql</td><td>补执行既有阅读与反馈表迁移,先回滚试执行再正式执行。</td></tr><tr><td>20260826_018_content_guide_template_library.sql</td><td>补执行既有正式模板库迁移,保留 4 个模板。</td></tr><tr><td>20260911_001_guide_reader_state.sql</td><td>新增按用户/项目/发布版本隔离的阅读位置、笔记、收藏及进度表;完整 DDL、数据库设计、迁移记录和 Wiki 已同步。</td></tr></table><p>其他环境部署前先检查既有表,避免重复执行。新增流下载配置 <code>UT_CONTENT_STREAM_TIMEOUT</code> 默认 <code>30m</code>。本轮不代表其他环境已完成数据库迁移。</p></section>
  43. <section id="limits"><h2>复核说明与保留数据</h2><ul><li>工程 412:正式闭环-狐狸与卡车指导书-20260910,已发布 V3.0.0 / 472。</li><li>工程 413:正式模板新建回归-20260911,保留草稿。</li><li>工程 414:正式图片视频资源回归-20260911,保留草稿。</li><li>临时学员账号已清理,正式测试阅读及反馈历史保留。阅读页进度与“完成阅读”分别记录,不等同于考核成绩。</li><li>既有内部维护账号头像存在单独的 404,属于原账号头像资源问题;本轮指导书资源、视频及交付下载检查通过。没有将该请求计入“无网络错误”的结论。</li><li>本轮未自动提交或推送 Git。大型测试 ZIP 仅保留在本地报告目录,不纳入 Git。</li></ul><div class="note">需要核对的数据差异:场景 160@463 名为“实测场景-狐狸野外训练区-20260905”,当前发布内容实际是维修车间与装备,不包含狐狸。已按其固定发布版本验证,未修改源场景;狐狸模型在指导书独立步骤中验证通过。牛奶卡车场景使用 159@209。</div><p>三项实施均在本次授权范围内,没有新增待批准的大幅功能调整。旧浏览器本地工程如需迁移,使用显式导入新工程;无法从服务端恢复的本地文件需重新上传。</p></section></main></html>`
  44. fs.writeFileSync(path.join(dir,'index.html'),html)
  45. console.log(`Report generated: ${passed}/${checks.length} checks, ${shots.length} screenshots`)
  46. if(passed!==checks.length)process.exitCode=1