feat: 保存并展示 PDD 店铺与价格采样信息 (#31)

This commit is contained in:
chengma
2026-08-07 17:13:25 +08:00
parent a2fc1501c4
commit 93beef8b36
17 changed files with 492 additions and 73 deletions
+18 -7
View File
@@ -29,8 +29,11 @@ var (
// 客户端提交的完整内容会原样存进 tasks.result_data,这里只挑业务要用的解析出来。
// 用不到的字段不写进结构体,多余的 JSON 字段会被忽略,不影响向前兼容。
type collectedData struct {
GoodsID string `json:"goods_id"`
Title string `json:"title"`
GoodsID string `json:"goods_id"`
Title string `json:"title"`
ShopName string `json:"shop_name"`
// PriceGranularity 说明价格是逐个 SKU 实测,还是只按颜色采样。
PriceGranularity string `json:"price_granularity"`
// Dimensions 决定规格各维度的显示顺序。
// 少了它就只能按 Go 的 map 遍历,而 map 是无序的——
// 同一个商品每次刷新页面「颜色/尺码」的先后都可能变。
@@ -39,10 +42,12 @@ type collectedData struct {
Name string `json:"name"`
} `json:"dimensions"`
SKUs []struct {
Options map[string]string `json:"options"`
PriceCent *int64 `json:"price_cent"` // 指针:采不到价格时是 null,不是 0
Available bool `json:"available"`
RawPrice string `json:"raw_price"`
Options map[string]string `json:"options"`
PriceCent *int64 `json:"price_cent"` // 指针:采不到价格时是 null,不是 0
ListPriceCent *int64 `json:"list_price_cent"`
PriceObservedAt map[string]string `json:"price_observed_at"`
Available bool `json:"available"`
RawPrice string `json:"raw_price"`
} `json:"skus"`
}
@@ -53,6 +58,12 @@ func parseCollected(raw string) (*collectedData, error) {
if err := json.Unmarshal([]byte(raw), &c); err != nil {
return nil, fmt.Errorf("采集结果不是合法结构: %w", err)
}
if c.PriceGranularity != "" && c.PriceGranularity != "color" &&
c.PriceGranularity != "sku" {
return nil, fmt.Errorf(
"price_granularity 只能是 color 或 sku,收到 %q",
c.PriceGranularity)
}
return &c, nil
}
@@ -153,7 +164,7 @@ func SubmitResult(db *sql.DB, taskID, clientID, idemKey string, rawBody []byte)
return nil, err
}
} else if err := repository.SetCollectResult(
tx, info.PddGoodsID, collected.Title, pddData); err != nil {
tx, info.PddGoodsID, collected.Title, collected.ShopName, pddData); err != nil {
return nil, err
}
}