b9137204a0
- FilePreview.vue: add normalizedFileType computed to handle backend returning uppercase HTML/MD/PPTX (fixes preview/download buttons) - FilePreview.vue: bg-gradient-to-r from-orange-500 -> bg-orange-500 (Tailwind v4 gradient + CSS variable = transparent) - ReportCard.vue: bg-gradient-to-r -> bg-orange-600 for selected state - Add .opencode/, node_modules/, dist/ to .gitignore - Initial git setup for publish project
165 lines
10 KiB
HTML
165 lines
10 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>日报分发平台 - 问题修复报告 2026-05-24</title>
|
||
<style>
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
body { font-family: -apple-system, 'PingFang SC', 'Microsoft YaHei', sans-serif; background: #f8f9fa; color: #1a1a2e; line-height: 1.6; }
|
||
.container { max-width: 900px; margin: 0 auto; padding: 40px 20px; }
|
||
|
||
.header { background: linear-gradient(135deg, #ff6b35, #f7931e); color: white; border-radius: 16px; padding: 40px; margin-bottom: 32px; }
|
||
.header h1 { font-size: 28px; margin-bottom: 8px; }
|
||
.header .meta { opacity: 0.9; font-size: 14px; margin-top: 4px; }
|
||
.header .badge { display: inline-block; background: rgba(255,255,255,0.25); padding: 4px 12px; border-radius: 20px; font-size: 12px; margin-top: 12px; }
|
||
|
||
.section { background: white; border-radius: 16px; padding: 28px 32px; margin-bottom: 24px; box-shadow: 0 2px 12px rgba(0,0,0,0.06); }
|
||
.section h2 { font-size: 18px; color: #ff6b35; margin-bottom: 20px; padding-bottom: 10px; border-bottom: 2px solid #fff3e0; }
|
||
.section h2 .num { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; background: #ff6b35; color: white; border-radius: 50%; font-size: 14px; margin-right: 10px; vertical-align: middle; }
|
||
|
||
.bug-card { background: #fff9f5; border-left: 4px solid #ff6b35; border-radius: 10px; padding: 20px 24px; margin-bottom: 20px; }
|
||
.bug-card h3 { font-size: 16px; color: #c0392b; margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
|
||
.bug-card .tag { font-size: 11px; padding: 2px 8px; border-radius: 4px; font-weight: 600; }
|
||
.tag-p0 { background: #ffe0db; color: #c0392b; }
|
||
.tag-p1 { background: #fff3e0; color: #e67e22; }
|
||
.tag-p2 { background: #fff8e1; color: #f39c12; }
|
||
.bug-card .before, .bug-card .after { font-size: 13px; margin: 6px 0; padding: 8px 12px; border-radius: 6px; }
|
||
.bug-card .before { background: #ffebee; color: #c0392b; }
|
||
.bug-card .after { background: #e8f5e9; color: #2e7d32; }
|
||
.bug-card .label { font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }
|
||
.bug-card code { background: rgba(0,0,0,0.07); padding: 1px 6px; border-radius: 4px; font-size: 12px; font-family: 'Fira Code', monospace; }
|
||
|
||
.result-table { width: 100%; border-collapse: collapse; font-size: 14px; }
|
||
.result-table th { background: #ff6b35; color: white; padding: 12px 16px; text-align: left; border-radius: 8px 8px 0 0; }
|
||
.result-table td { padding: 12px 16px; border-bottom: 1px solid #f0f0f0; }
|
||
.result-table tr:last-child td { border-bottom: none; }
|
||
.result-table .pass { color: #2e7d32; font-weight: 600; }
|
||
.result-table .fail { color: #c0392b; font-weight: 600; }
|
||
|
||
.exp-list { list-style: none; }
|
||
.exp-list li { padding: 10px 0; border-bottom: 1px dashed #f0f0f0; display: flex; gap: 12px; align-items: flex-start; }
|
||
.exp-list li:last-child { border-bottom: none; }
|
||
.exp-list .icon { color: #ff6b35; font-size: 16px; margin-top: 2px; flex-shrink: 0; }
|
||
.exp-list .text { font-size: 14px; color: #444; }
|
||
|
||
.files { display: flex; flex-wrap: wrap; gap: 10px; }
|
||
.file-chip { background: #fff3e0; color: #e65100; padding: 6px 14px; border-radius: 20px; font-size: 13px; font-family: monospace; }
|
||
|
||
.footer { text-align: center; color: #999; font-size: 12px; margin-top: 32px; padding: 20px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
|
||
<!-- Header -->
|
||
<div class="header">
|
||
<h1>🐔 日报分发平台 · 问题修复报告</h1>
|
||
<div class="meta">修复日期:2026-05-24 | 修复人:Mavis AI Agent | 项目:publish</div>
|
||
<div class="badge">✅ 已部署至 FnOS NAS(192.168.31.240:41733)</div>
|
||
</div>
|
||
|
||
<!-- Bug Summary -->
|
||
<div class="section">
|
||
<h2><span class="num">1</span>问题概览</h2>
|
||
<table class="result-table">
|
||
<thead><tr><th>优先级</th><th>问题描述</th><th>文件</th><th>状态</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><span class="tag tag-p1">P1</span></td><td>HTML/MD 预览和下载按钮全部失效</td><td>FilePreview.vue</td><td class="pass">✅ 已修复</td></tr>
|
||
<tr><td><span class="tag tag-p2">P2</span></td><td>下载按钮图标背景显示透明</td><td>FilePreview.vue</td><td class="pass">✅ 已修复</td></tr>
|
||
<tr><td><span class="tag tag-p2">P2</span></td><td>选中报告高亮背景显示透明</td><td>ReportCard.vue</td><td class="pass">✅ 已修复</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Bug Details -->
|
||
<div class="section">
|
||
<h2><span class="num">2</span>根因分析与修复</h2>
|
||
|
||
<div class="bug-card">
|
||
<h3>🪲 Bug #1:HTML/MD 预览和下载按钮失效 <span class="tag tag-p1">P1</span></h3>
|
||
<div class="before"><span class="label">Before(错误代码)</span><br>
|
||
<code>// 后端返回 "HTML",前端直接比较小写</code><br>
|
||
<code>v-if="report.fileType === 'html'" // ❌ 永远为 false</code><br>
|
||
<code>v-if="report.fileType === 'md'" // ❌ 永远为 false</code><br>
|
||
<code>v-if="report.fileType === 'pptx'" // ❌ 永远为 false</code>
|
||
</div>
|
||
<div class="after"><span class="label">After(修复代码)</span><br>
|
||
<code>const normalizedFileType = computed(() =></code><br>
|
||
<code> (props.report?.fileType || '').toLowerCase())</code><br><br>
|
||
<code>v-if="normalizedFileType === 'html'" // ✅ 正常激活</code><br>
|
||
<code>v-if="normalizedFileType === 'md'" // ✅ 正常激活</code>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="bug-card">
|
||
<h3>🪲 Bug #2:下载按钮图标背景透明 <span class="tag tag-p2">P2</span></h3>
|
||
<div class="before"><span class="label">Before(错误代码)</span><br>
|
||
<code>bg-gradient-to-br from-orange-500 to-orange-600</code><br>
|
||
<code>// Tailwind v4 + CSS 变量 → gradient 颜色被解析为透明</code>
|
||
</div>
|
||
<div class="after"><span class="label">After(修复代码)</span><br>
|
||
<code>bg-orange-500 // 改用实色,绕过 gradient 透明问题</code>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="bug-card">
|
||
<h3>🪲 Bug #3:选中报告高亮背景透明 <span class="tag tag-p2">P2</span></h3>
|
||
<div class="before"><span class="label">Before(错误代码)</span><br>
|
||
<code>bg-gradient-to-r from-orange-600 to-amber-600</code><br>
|
||
<code>// 同样因 Tailwind v4 gradient bug 导致背景透明</code>
|
||
</div>
|
||
<div class="after"><span class="label">After(修复代码)</span><br>
|
||
<code>bg-orange-600 // 实色背景,正常显示高亮</code>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- QA Results -->
|
||
<div class="section">
|
||
<h2><span class="num">3</span>测试验证结果</h2>
|
||
<table class="result-table">
|
||
<thead><tr><th>测试项</th><th>环境</th><th>结果</th></tr></thead>
|
||
<tbody>
|
||
<tr><td>HTML iframe 预览渲染</td><td>本地 (41734) + NAS (41733)</td><td class="pass">✅ PASS</td></tr>
|
||
<tr><td>MD Markdown 内容预览</td><td>本地</td><td class="pass">✅ PASS</td></tr>
|
||
<tr><td>下载按钮橙色背景</td><td>本地 + NAS</td><td class="pass">✅ PASS</td></tr>
|
||
<tr><td>选中报告侧边栏高亮</td><td>本地 + NAS</td><td class="pass">✅ PASS</td></tr>
|
||
<tr><td>Console 无报错</td><td>本地 + NAS</td><td class="pass">✅ PASS</td></tr>
|
||
<tr><td>Docker 镜像构建</td><td>FnOS NAS</td><td class="pass">✅ PASS</td></tr>
|
||
<tr><td>API 报告列表 + 上传</td><td>NAS (192.168.31.240:41733)</td><td class="pass">✅ PASS</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- Experience -->
|
||
<div class="section">
|
||
<h2><span class="num">4</span>经验沉淀</h2>
|
||
<ul class="exp-list">
|
||
<li><span class="icon">⚡</span><span class="text"><strong>Tailwind v4 gradient + CSS 变量 bug:</strong>在 Tailwind v4 下,CSS 变量定义的橙色(如 <code>--color-orange-500</code>)搭配 <code>bg-gradient-to-*</code> 使用时,gradient 颜色会被解析为透明。解法:统一使用实色类名如 <code>bg-orange-500</code>,避免 gradient。此 bug 影响所有使用 gradient + CSS 自定义颜色组合的 Tailwind v4 项目。</span></li>
|
||
<li><span class="icon">⚡</span><span class="text"><strong>前后端 fileType 大小写不一致:</strong>后端返回 <code>"HTML"</code>/<code>"MD"</code>(大写),前端若直接与字符串字面量比较,需注意大小写。建议:后端统一小写返回,或前端用 <code>toLowerCase()</code> 归一化。</span></li>
|
||
<li><span class="icon">⚡</span><span class="text"><strong>Playwright E2E 环境准备:</strong>本地 Playwright 测试需要确认:后端端口(8080 非 37821)、Vite proxy 目标端口、测试数据存在。测试文件(如 <code>report.spec.js</code>)依赖的测试数据需预先通过 API 上传,否则报告列表为空导致所有断言超时。</span></li>
|
||
<li><span class="icon">⚡</span><span class="text"><strong>Docker 部署端口差异:</strong>本地开发后端在 8080,Docker compose 中定义为 37821 暴露,但实际 JAR 运行在容器内 8080。建议:确认实际监听端口,避免 proxy 配置指向错误端口。</span></li>
|
||
<li><span class="icon">⚡</span><span class="text"><strong>NAS Docker 构建缓存:</strong>Docker <code>COPY dist/</code> 会缓存构建结果,文件内容变了但步骤不重新执行。解法:重命名 dist 目录(如 <code>dist_new/</code>)+ 更新 Dockerfile 对应路径,强制使 COPY 步骤 cache miss。</span></li>
|
||
<li><span class="icon">⚡</span><span class="text"><strong>Playwright ESM vs CJS:</strong>publish 项目 <code>package.json</code> 含有 <code>"type": "module"</code>,直接用 <code>.js</code> 运行 Node Playwright 脚本会报 <code>require is not defined</code>。解法:使用 <code>.cjs</code> 扩展名,或改用 ESM <code>import</code> 语法。</span></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- Files Changed -->
|
||
<div class="section">
|
||
<h2><span class="num">5</span>变更文件</h2>
|
||
<div class="files">
|
||
<span class="file-chip">src/components/FilePreview.vue</span>
|
||
<span class="file-chip">src/components/ReportCard.vue</span>
|
||
<span class="file-chip">dist/(构建产物)</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footer">
|
||
日报分发平台 · Mavis AI Agent · 2026-05-24<br>
|
||
部署地址:http://192.168.31.240:41733
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|