feat: 蝦皮数据页改为商品级列表与规格弹窗 (#41)
原来是 SKU 级一行,问题不在行数(6092→5195 只少 15%),在语义错了: pdd_goods_url / pdd_goods_id 在 shopee_products 上,是商品级字段。 商品 24420648774 有 62 个 SKU,列表里 62 行显示同一个 PDD 链接, 将来双击任意一行编辑的也是同一个字段,操作员会以为改的是这一行。 加了两列,都是防止聚合后丢信息: 「SKU 数」—— 只显示颜色数和尺码数会严重误导。实测 602 个商品(11.6%) 的颜色数×尺码数大于实际 SKU 数,最悬殊的 26886533818 是 15×5=75 但 实际只有 28 个。蝦皮报表只含有销售成绩的 SKU,数据本来就不全。 「待补」—— 原来解析失败的行整行标黄,聚合成数量后这个信号会丢。 23 条失败分布在 6 个商品里,其中 4 个是「部分失败」:数字看着正常, 坏数据被吃掉,永远没人去补。现在待补>0 整行标黄。 颜色数/尺码数只统计 parse_ok=1,否则空值会被算进 DISTINCT 多出 一个「空颜色」。 弹窗只读,待补的行显示 spec_raw 原文——不显示的话人工不知道该填什么, 保留原文这个设计就白做了。复用 #18 的弹窗机制,app.js 未改动。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,8 @@
|
||||
</div>
|
||||
|
||||
{{/* ── 第二段:带勾选的表格 ──────────────────────────── */}}
|
||||
{{/* 一个商品一行(不是一个 SKU 一行),见工单 #41。
|
||||
双击行打开详情弹窗,见 static/js/app.js。 */}}
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
@@ -37,7 +39,14 @@
|
||||
<th>商品名称</th>
|
||||
<th>颜色</th>
|
||||
<th>尺码</th>
|
||||
<th>建议</th>
|
||||
{{/* SKU 数是这个商品报表里实际出现过的规格条数。
|
||||
`[必须]` 必须单独显示——颜色数 × 尺码数经常大于它(蝦皮报表只含
|
||||
有销售成绩的 SKU),只看前两列会让人误以为要匹配的规格更多,见 #41。 */}}
|
||||
<th>SKU</th>
|
||||
{{/* `[必须]` 待补 > 0 说明该商品有 SKU 解析失败,整行标黄(.row-warn)。
|
||||
聚合成商品级之后,"部分失败"的行光看数字是正常的,
|
||||
不加这一列坏数据就会被悄悄吃掉,见 #41。 */}}
|
||||
<th>待补</th>
|
||||
<th>PDD 链接</th>
|
||||
<th>采集状态</th>
|
||||
<th>更新时间</th>
|
||||
@@ -45,22 +54,25 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Rows}}
|
||||
<tr{{if .ParseFailed}} class="row-warn"{{end}} title="SKU {{.SKUID}}">
|
||||
<tr data-detail-id="{{.GoodsID}}"{{if gt .PendingCount 0}} class="row-warn"{{end}}>
|
||||
<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>
|
||||
{{/* 商品名称列收窄到 30%,用独立的 .col-title 类设 max-width,
|
||||
不用 flex——表格单元格和工具条的 .search-narrow 那套不一样,见 #41。 */}}
|
||||
<td class="truncate col-title" title="{{.Title}}">{{.Title}}</td>
|
||||
<td>{{.ColorCount}}</td>
|
||||
<td>{{.SizeCount}}</td>
|
||||
<td>{{.SKUCount}}</td>
|
||||
<td>{{.PendingCount}}</td>
|
||||
<td{{if .PddMissing}} class="missing"{{end}}>{{.PddURL}}</td>
|
||||
<td>{{.StatusText}}</td>
|
||||
<td>{{.UpdatedAt}}</td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr class="empty">
|
||||
<td colspan="9">
|
||||
<td colspan="10">
|
||||
{{if .IsFiltered}}
|
||||
没有匹配的数据,换个商品 ID 试试。
|
||||
没有匹配的数据,换个商品 ID 或商品名称试试。
|
||||
{{else}}
|
||||
还没有数据,点左上角「导入 Excel」开始。<br>
|
||||
<small>样本文件不在仓库里,需向项目负责人索取,放到 raw_data/ 下。</small>
|
||||
@@ -72,6 +84,10 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p class="hint">
|
||||
双击任意一行可以查看这个商品的完整规格表。
|
||||
</p>
|
||||
|
||||
{{/* ── 导入失败行:全部列出来,不折叠、不只显示条数 ──── */}}
|
||||
{{if .Failures}}
|
||||
<div class="table-wrap">
|
||||
@@ -97,15 +113,20 @@
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{/* TODO(骨架): 编辑弹窗 templates/shopee/edit_modal.html
|
||||
这是从蝦皮商品出发录入 PDD 链接、发起采集的入口。
|
||||
采集按钮**在本页只出现在这个弹窗里**——不要放到表格每一行,
|
||||
一个商品有 N 个 SKU 行,放行上就是 N 个按钮干同一件事,
|
||||
还会建出 N 个重复任务。
|
||||
{{/* ── 详情弹窗的壳子 ───────────────────────────
|
||||
里面的内容双击行时由 /shopee/detail 返回,前端只负责放进来和显示,
|
||||
复用 #18 的机制(data-detail-url / data-detail-slot / data-detail-id),
|
||||
app.js 不需要改,见工单 #41。
|
||||
|
||||
PDD 商品页(templates/pdd/)也能录入链接和发起采集,两处并存;
|
||||
本页这个还是骨架(点了返回 501)。合并与否由
|
||||
「蝦皮↔PDD 关联入口」工单决定,不要在本页单独改。 */}}
|
||||
这个弹窗**只读**:商品信息 + 完整规格表,没有保存按钮。
|
||||
从蝦皮商品出发录入 PDD 链接、发起采集的入口(含 ShopeeSave/
|
||||
ShopeeCollect 的实现)由后续的「蝦皮↔PDD 关联入口」工单负责,
|
||||
本工单不做,ShopeeSave/ShopeeDelete/ShopeeCollect 仍是 501。 */}}
|
||||
<div class="modal-backdrop" id="detail-modal" data-detail-url="/shopee/detail" hidden>
|
||||
<div class="modal" role="dialog" aria-modal="true" data-detail-slot>
|
||||
<div class="modal-body">正在加载…</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "footer" .}}
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user