feat: 蝦皮 Excel 报表导入 (#38)

蝦皮数据模块此前整个是骨架,四个入口全返回 501,excelize 连依赖都没装。
本工单做导入和列表,Save/Delete/Collect 保持 501。

真实样本实测:5195 个商品 / 6092 个 SKU,23 行解析失败。

upsert 白名单式,pdd_goods_url / pdd_goods_id 既不在 INSERT 列清单里
也不在 DO UPDATE SET 里。报表没有这两列,写进去就是写空值——操作员
攒几周的 PDD 链接会被一次导入洗光,而且不报错,等到建采购任务才发现。
有独立测试守着:往 DO UPDATE SET 里加回这一行,测试立刻变红。

按 sheet 名字取「最佳表現商品」,不用第 0 个。工作簿有 5 个 sheet,
另外 4 个是广告报表,连 商品規格ID 列都没有;蝦皮调顺序时按下标
会静默导入一张完全不相干的表。

按列名找索引。40 列里 32 列是统计指标,蝦皮加一列所有列号就错位,
而且不报错——会把「點擊率」当成「商品規格」存进去。

规格解析三种格式:含【】53.4%、逗号+空格 26.4%、只有逗号 20.2%,
只认【】会漏掉 46.6%。括号不配对(21 行)和右半整个被【】包住(2 行)
一律判整体失败,不逐段硬凑——错法不统一,针对每种错法写规则等于在猜,
而且没有人工核对过的正确答案可验证。失败时 color/size/advice 必须全空,
原文存进 spec_raw 交人工补。

不写 DELETE + INSERT 的全量替换,将来手动新增的 SKU 会被删掉。

excelize v2.9.1 的 go 指令正好是 1.23.0,与项目固定版本一致。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
chengma
2026-08-08 09:57:12 +08:00
co-authored by Claude Opus 5
parent 18770f25e1
commit e29d6683ad
10 changed files with 1211 additions and 91 deletions
+40 -2
View File
@@ -45,13 +45,26 @@
</thead>
<tbody>
{{range .Rows}}
{{/* TODO(骨架): 行渲染。解析失败的行整行标黄(class="row-warn"),
PDD 链接为空的显示"未填写"并标红。双击行打开编辑弹窗。 */}}
<tr{{if .ParseFailed}} class="row-warn"{{end}} title="SKU {{.SKUID}}">
<td class="col-check"><input type="checkbox" name="ids" value="{{.GoodsID}}"></td>
<td>{{.GoodsID}}</td>
<td title="{{.Title}}">{{.Title}}{{if .IsManual}} <small>(人工新增)</small>{{end}}</td>
<td>{{.Color}}</td>
<td>{{.Size}}</td>
<td>{{.Advice}}</td>
<td{{if .PddMissing}} class="missing"{{end}}>{{.PddURL}}</td>
<td>{{.StatusText}}</td>
<td>{{.UpdatedAt}}</td>
</tr>
{{else}}
<tr class="empty">
<td colspan="9">
{{if .IsFiltered}}
没有匹配的数据,换个商品 ID 试试。
{{else}}
还没有数据,点左上角「导入 Excel」开始。<br>
<small>样本文件不在仓库里,需向项目负责人索取,放到 raw_data/ 下。</small>
{{end}}
</td>
</tr>
{{end}}
@@ -59,6 +72,31 @@
</table>
</div>
{{/* ── 导入失败行:全部列出来,不折叠、不只显示条数 ──── */}}
{{if .Failures}}
<div class="table-wrap">
<p>本次导入有 {{len .Failures}} 行解析失败,规格原文已按原样保存,需人工补颜色/尺码/建议:</p>
<table>
<thead>
<tr>
<th>行号</th>
<th>规格原文</th>
<th>原因</th>
</tr>
</thead>
<tbody>
{{range .Failures}}
<tr>
<td>{{.Row}}</td>
<td>{{.Raw}}</td>
<td>{{.Reason}}</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
{{/* TODO(骨架): 编辑弹窗 templates/shopee/edit_modal.html
这是从蝦皮商品出发录入 PDD 链接、发起采集的入口。
采集按钮**在本页只出现在这个弹窗里**——不要放到表格每一行,