From 5b7d92289e6ec5c5743f6865cb4cfdf4ad55e588 Mon Sep 17 00:00:00 2001 From: chengma Date: Thu, 13 Aug 2026 12:07:27 +0800 Subject: [PATCH] =?UTF-8?q?style:=20=E4=BC=98=E5=8C=96=E8=9D=A6=E7=9A=AE?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=85=B3=E9=94=AE=E4=BF=A1=E6=81=AF=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=20(#214)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/main_test.go | 2 +- admin/service/shopee_list.go | 8 +++++--- admin/service/shopee_list_test.go | 7 +++++-- admin/static/css/app.css | 10 +++++----- admin/templates/shopee/list.html | 4 ++-- docs/admin/05-ui-specification.md | 8 ++++---- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/admin/main_test.go b/admin/main_test.go index d7de274..58907f4 100644 --- a/admin/main_test.go +++ b/admin/main_test.go @@ -378,7 +378,7 @@ func TestShopeePage_展示主图店铺且保留标题宽度(t *testing.T) { t.Fatal(err) } 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) { t.Errorf("蝦皮图片店铺界面缺少 %q", want) } diff --git a/admin/service/shopee_list.go b/admin/service/shopee_list.go index 38f15f4..f4a2713 100644 --- a/admin/service/shopee_list.go +++ b/admin/service/shopee_list.go @@ -37,8 +37,10 @@ type ShopeeProductView struct { PendingCount int SourceText string - // PddURL 为空且 PddMissing 为 true 时,模板显示"未填写"并标红—— - // 这是最需要操作员注意的状态,见 §4.2。 + // 列表正文只显示稳定、短小的 PDD 商品 ID,完整 URL 留在 title 中。 + // PddMissing 为 true 时模板显示"未填写"并标红——这是最需要操作员 + // 注意的状态,见 §4.2。 + PddGoodsID string PddURL string PddMissing bool @@ -123,9 +125,9 @@ func ListShopeeProducts(db *sql.DB, filter repository.ShopeeFilter, page int) (* if r.PddGoodsID == "" { v.PddMissing = true - v.PddURL = "未填写" v.StatusText = "未填链接" } else { + v.PddGoodsID = r.PddGoodsID v.PddURL = r.PddGoodsURL if r.CollectStatus.Valid { v.StatusText = collectStatusText(model.CollectStatus(r.CollectStatus.String)) diff --git a/admin/service/shopee_list_test.go b/admin/service/shopee_list_test.go index e84848b..6f56a24 100644 --- a/admin/service/shopee_list_test.go +++ b/admin/service/shopee_list_test.go @@ -193,8 +193,8 @@ func TestListShopeeProducts_PDD链接未填写(t *testing.T) { t.Fatalf("查询失败: %v", err) } row := result.Rows[0] - if !row.PddMissing || row.PddURL != "未填写" { - t.Errorf("PddMissing/PddURL = %v/%q,想要 true/\"未填写\"", row.PddMissing, row.PddURL) + if !row.PddMissing || row.PddGoodsID != "" || row.PddURL != "" { + t.Errorf("未关联 PDD 视图错误:%+v", row) } if row.StatusText != "未填链接" { t.Errorf("StatusText = %q,想要 \"未填链接\"", row.StatusText) @@ -221,6 +221,9 @@ func TestListShopeeProducts_采集状态联查(t *testing.T) { if row.PddMissing { 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 != "已采集" { t.Errorf("StatusText = %q,想要 \"已采集\"", row.StatusText) } diff --git a/admin/static/css/app.css b/admin/static/css/app.css index 037927b..d283192 100644 --- a/admin/static/css/app.css +++ b/admin/static/css/app.css @@ -240,17 +240,17 @@ tr.empty small { color: #aaa; } text-overflow: ellipsis; } -/* 蝦皮数据页商品名称列收窄,配合 .truncate 一起用(见工单 #41)。 +/* 蝦皮数据页商品名称列收窄,配合 .truncate 一起用(见工单 #214)。 用独立类设 max-width,不用 flex——.search-narrow 那套是给工具条用的, 表格单元格不是 flex 布局,flex 在这里不生效。放在 .truncate 之后, 同优先级下按 CSS 层叠顺序覆盖 .truncate 的 280px。 - 18% = 初版 30% 的六成。蝦皮标题普遍很长(实测最长 60+ 字, - 全是关键词堆砌),不收窄的话这一列会把后面的颜色/尺码/SKU/待补 - 几个关键数字挤出屏幕——而那几个数字才是这个页面要看的东西。 + 固定 120px 约等于原 18% 宽度的 45%,同时避免百分比列宽随浏览器 + 表格算法和窗口宽度大幅波动。蝦皮标题普遍很长(实测最长 60+ 字), 完整标题靠悬停的 title 属性看。 */ .col-title { - max-width: 18%; + width: 120px; + max-width: 120px; } .col-shop { max-width: 150px; } .thumb-placeholder, .thumb-fallback { color: #6b7280; font-size: 12px; white-space: nowrap; } diff --git a/admin/templates/shopee/list.html b/admin/templates/shopee/list.html index 356e804..3b81ffe 100644 --- a/admin/templates/shopee/list.html +++ b/admin/templates/shopee/list.html @@ -77,7 +77,7 @@ 不加这一列坏数据就会被悄悄吃掉,见 #41。 */}} 待补 来源 - PDD 链接 + PDD 商品 ID 采集状态 更新时间 @@ -98,7 +98,7 @@ {{.SKUCount}} {{.PendingCount}} {{.SourceText}} - {{.PddURL}} + {{if .PddMissing}}未填写{{else}}{{.PddGoodsID}}{{end}} {{.StatusText}} {{.UpdatedAt}} diff --git a/docs/admin/05-ui-specification.md b/docs/admin/05-ui-specification.md index 74750ef..384b441 100644 --- a/docs/admin/05-ui-specification.md +++ b/docs/admin/05-ui-specification.md @@ -179,11 +179,11 @@ | ☐ | 勾选 | | 商品 ID | | | 图片 | 32×32 缩略图,可打开原图;加载失败显示文字占位 | -| 商品名称 | 截断 + 悬停完整 | +| 商品名称 | 固定约 120px,截断 + 悬停完整 | | 店铺 | 导入或同步得到的蝦皮店铺名称;为空显示 `—` | | 数据来源 | 蝦皮报表 / 顺运宝补建;不只靠颜色区分 | | 颜色 / 尺码 / 建议 | 解析失败的显示为 `—` 并**整行标黄**,提示需人工补 | -| PDD 链接 | 空的显示"**未填写**"并标红,这是最需要操作员注意的状态 | +| PDD 商品 ID | 正文显示 goods_id,悬停显示完整 URL;空的显示"**未填写**"并标红 | | 采集状态 | 未填链接 / 未采集 / 采集中 / 已采集 / 采集失败。**数据来自两张表**,判断方式见 [01 需求](01-requirements.md) §6.1 | | 更新时间 | 本地时区 | @@ -908,8 +908,8 @@ placeholder 写「任务编号 / 订单号 / 商品 ID」,**不要写全「PDD 蝦皮商品列表在商品 ID 后显示 32×32 懒加载主图,在标题后显示“店铺”。主图可 打开通用原图弹窗和新窗口,加载失败显示文字占位;无图不打开空弹窗。店铺列最大约 -150px并省略,完整值放在 `title` 和详情中。商品标题继续使用 `.col-title` 的 18%, -不得因新增列再次缩窄;1366×768 下通过表格横向滚动保留可读性。详情同时显示图片、 +150px并省略,完整值放在 `title` 和详情中。商品标题使用 `.col-title` 的固定 120px, +避免百分比列宽随窗口和浏览器算法波动;1366×768 下通过表格横向滚动保留可读性。详情同时显示图片、 店铺、各自来源和观测时间,顺运宝观测图仍只出现在观测区域。 店铺列显示导入或同步得到的蝦皮店铺原始值。`shop_id` 只作为精确匹配后的稳定内部关联,