style: 优化蝦皮列表关键信息展示 (#214)

This commit is contained in:
chengma
2026-08-13 12:07:27 +08:00
parent 121b12ac41
commit 5b7d92289e
6 changed files with 22 additions and 17 deletions
+1 -1
View File
@@ -378,7 +378,7 @@ func TestShopeePage_展示主图店铺且保留标题宽度(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
content := string(page) + string(detail) + string(css) + string(js) content := string(page) + string(detail) + string(css) + string(js)
for _, want := range []string{"蝦皮店铺", "data-image-preview-url", "loading=\"lazy\"", "data-image-thumb-fallback", "ImageSourceText", "max-width: 18%", ".col-shop", "setupImageThumbnails"} { for _, want := range []string{"蝦皮店铺", "data-image-preview-url", "loading=\"lazy\"", "data-image-thumb-fallback", "ImageSourceText", "max-width: 120px", ".col-shop", "setupImageThumbnails"} {
if !strings.Contains(content, want) { if !strings.Contains(content, want) {
t.Errorf("蝦皮图片店铺界面缺少 %q", want) t.Errorf("蝦皮图片店铺界面缺少 %q", want)
} }
+5 -3
View File
@@ -37,8 +37,10 @@ type ShopeeProductView struct {
PendingCount int PendingCount int
SourceText string SourceText string
// PddURL 为空且 PddMissing 为 true 时,模板显示"未填写"并标红—— // 列表正文只显示稳定、短小的 PDD 商品 ID,完整 URL 留在 title 中。
// 这是最需要操作员注意的状态,见 §4.2。 // PddMissing 为 true 时模板显示"未填写"并标红——这是最需要操作员
// 注意的状态,见 §4.2。
PddGoodsID string
PddURL string PddURL string
PddMissing bool PddMissing bool
@@ -123,9 +125,9 @@ func ListShopeeProducts(db *sql.DB, filter repository.ShopeeFilter, page int) (*
if r.PddGoodsID == "" { if r.PddGoodsID == "" {
v.PddMissing = true v.PddMissing = true
v.PddURL = "未填写"
v.StatusText = "未填链接" v.StatusText = "未填链接"
} else { } else {
v.PddGoodsID = r.PddGoodsID
v.PddURL = r.PddGoodsURL v.PddURL = r.PddGoodsURL
if r.CollectStatus.Valid { if r.CollectStatus.Valid {
v.StatusText = collectStatusText(model.CollectStatus(r.CollectStatus.String)) v.StatusText = collectStatusText(model.CollectStatus(r.CollectStatus.String))
+5 -2
View File
@@ -193,8 +193,8 @@ func TestListShopeeProducts_PDD链接未填写(t *testing.T) {
t.Fatalf("查询失败: %v", err) t.Fatalf("查询失败: %v", err)
} }
row := result.Rows[0] row := result.Rows[0]
if !row.PddMissing || row.PddURL != "未填写" { if !row.PddMissing || row.PddGoodsID != "" || row.PddURL != "" {
t.Errorf("PddMissing/PddURL = %v/%q,想要 true/\"未填写\"", row.PddMissing, row.PddURL) t.Errorf("未关联 PDD 视图错误:%+v", row)
} }
if row.StatusText != "未填链接" { if row.StatusText != "未填链接" {
t.Errorf("StatusText = %q,想要 \"未填链接\"", row.StatusText) t.Errorf("StatusText = %q,想要 \"未填链接\"", row.StatusText)
@@ -221,6 +221,9 @@ func TestListShopeeProducts_采集状态联查(t *testing.T) {
if row.PddMissing { if row.PddMissing {
t.Error("已填链接,PddMissing 应为 false") t.Error("已填链接,PddMissing 应为 false")
} }
if row.PddGoodsID != "9001" || row.PddURL != "https://mobile.yangkeduo.com/goods.html?goods_id=9001" {
t.Errorf("PDD 商品 ID/完整链接错误:%q/%q", row.PddGoodsID, row.PddURL)
}
if row.StatusText != "已采集" { if row.StatusText != "已采集" {
t.Errorf("StatusText = %q,想要 \"已采集\"", row.StatusText) t.Errorf("StatusText = %q,想要 \"已采集\"", row.StatusText)
} }
+5 -5
View File
@@ -240,17 +240,17 @@ tr.empty small { color: #aaa; }
text-overflow: ellipsis; text-overflow: ellipsis;
} }
/* 蝦皮数据页商品名称列收窄,配合 .truncate 一起用(见工单 #41)。 /* 蝦皮数据页商品名称列收窄,配合 .truncate 一起用(见工单 #214)。
用独立类设 max-width,不用 flex——.search-narrow 那套是给工具条用的, 用独立类设 max-width,不用 flex——.search-narrow 那套是给工具条用的,
表格单元格不是 flex 布局,flex 在这里不生效。放在 .truncate 之后, 表格单元格不是 flex 布局,flex 在这里不生效。放在 .truncate 之后,
同优先级下按 CSS 层叠顺序覆盖 .truncate 的 280px。 同优先级下按 CSS 层叠顺序覆盖 .truncate 的 280px。
18% = 初版 30% 的六成。蝦皮标题普遍很长(实测最长 60+ 字, 固定 120px 约等于原 18% 宽度的 45%,同时避免百分比列宽随浏览器
全是关键词堆砌),不收窄的话这一列会把后面的颜色/尺码/SKU/待补 表格算法和窗口宽度大幅波动。蝦皮标题普遍很长(实测最长 60+ 字),
几个关键数字挤出屏幕——而那几个数字才是这个页面要看的东西。
完整标题靠悬停的 title 属性看。 */ 完整标题靠悬停的 title 属性看。 */
.col-title { .col-title {
max-width: 18%; width: 120px;
max-width: 120px;
} }
.col-shop { max-width: 150px; } .col-shop { max-width: 150px; }
.thumb-placeholder, .thumb-fallback { color: #6b7280; font-size: 12px; white-space: nowrap; } .thumb-placeholder, .thumb-fallback { color: #6b7280; font-size: 12px; white-space: nowrap; }
+2 -2
View File
@@ -77,7 +77,7 @@
不加这一列坏数据就会被悄悄吃掉,见 #41。 */}} 不加这一列坏数据就会被悄悄吃掉,见 #41。 */}}
<th>待补</th> <th>待补</th>
<th>来源</th> <th>来源</th>
<th>PDD 链接</th> <th>PDD 商品 ID</th>
<th>采集状态</th> <th>采集状态</th>
<th>更新时间</th> <th>更新时间</th>
</tr> </tr>
@@ -98,7 +98,7 @@
<td>{{.SKUCount}}</td> <td>{{.SKUCount}}</td>
<td>{{.PendingCount}}</td> <td>{{.PendingCount}}</td>
<td>{{.SourceText}}</td> <td>{{.SourceText}}</td>
<td{{if .PddMissing}} class="missing"{{end}}>{{.PddURL}}</td> <td{{if .PddMissing}} class="missing"{{end}}>{{if .PddMissing}}未填写{{else}}<span title="{{.PddURL}}">{{.PddGoodsID}}</span>{{end}}</td>
<td>{{.StatusText}}</td> <td>{{.StatusText}}</td>
<td>{{.UpdatedAt}}</td> <td>{{.UpdatedAt}}</td>
</tr> </tr>
+4 -4
View File
@@ -179,11 +179,11 @@
| ☐ | 勾选 | | ☐ | 勾选 |
| 商品 ID | | | 商品 ID | |
| 图片 | 32×32 缩略图,可打开原图;加载失败显示文字占位 | | 图片 | 32×32 缩略图,可打开原图;加载失败显示文字占位 |
| 商品名称 | 截断 + 悬停完整 | | 商品名称 | 固定约 120px,截断 + 悬停完整 |
| 店铺 | 导入或同步得到的蝦皮店铺名称;为空显示 `—` | | 店铺 | 导入或同步得到的蝦皮店铺名称;为空显示 `—` |
| 数据来源 | 蝦皮报表 / 顺运宝补建;不只靠颜色区分 | | 数据来源 | 蝦皮报表 / 顺运宝补建;不只靠颜色区分 |
| 颜色 / 尺码 / 建议 | 解析失败的显示为 `—` 并**整行标黄**,提示需人工补 | | 颜色 / 尺码 / 建议 | 解析失败的显示为 `—` 并**整行标黄**,提示需人工补 |
| PDD 链接 | 空的显示"**未填写**"并标红,这是最需要操作员注意的状态 | | PDD 商品 ID | 正文显示 goods_id,悬停显示完整 URL;空的显示"**未填写**"并标红 |
| 采集状态 | 未填链接 / 未采集 / 采集中 / 已采集 / 采集失败。**数据来自两张表**,判断方式见 [01 需求](01-requirements.md) §6.1 | | 采集状态 | 未填链接 / 未采集 / 采集中 / 已采集 / 采集失败。**数据来自两张表**,判断方式见 [01 需求](01-requirements.md) §6.1 |
| 更新时间 | 本地时区 | | 更新时间 | 本地时区 |
@@ -908,8 +908,8 @@ placeholder 写「任务编号 / 订单号 / 商品 ID」,**不要写全「PDD
蝦皮商品列表在商品 ID 后显示 32×32 懒加载主图,在标题后显示“店铺”。主图可 蝦皮商品列表在商品 ID 后显示 32×32 懒加载主图,在标题后显示“店铺”。主图可
打开通用原图弹窗和新窗口,加载失败显示文字占位;无图不打开空弹窗。店铺列最大约 打开通用原图弹窗和新窗口,加载失败显示文字占位;无图不打开空弹窗。店铺列最大约
150px并省略,完整值放在 `title` 和详情中。商品标题继续使用 `.col-title` 的 18%, 150px并省略,完整值放在 `title` 和详情中。商品标题使用 `.col-title` 的固定 120px,
不得因新增列再次缩窄;1366×768 下通过表格横向滚动保留可读性。详情同时显示图片、 避免百分比列宽随窗口和浏览器算法波动;1366×768 下通过表格横向滚动保留可读性。详情同时显示图片、
店铺、各自来源和观测时间,顺运宝观测图仍只出现在观测区域。 店铺、各自来源和观测时间,顺运宝观测图仍只出现在观测区域。
店铺列显示导入或同步得到的蝦皮店铺原始值。`shop_id` 只作为精确匹配后的稳定内部关联, 店铺列显示导入或同步得到的蝦皮店铺原始值。`shop_id` 只作为精确匹配后的稳定内部关联,