feat: 增加顺运宝店铺筛选 (#151)

This commit is contained in:
chengma
2026-08-11 14:39:13 +08:00
parent 30bdab3e2e
commit 9d4d6fc1e5
20 changed files with 313 additions and 56 deletions
+17 -7
View File
@@ -775,6 +775,7 @@ func writeStockDetail(db *sql.DB, baseURL string, stockRow syb.StockRow, detail
order := model.SybOrder{
SybID: sybID,
OrderNo: detail.Code,
ShopName: trimmedStringField(stockRaw, "shopName"),
Title: item.ProductTitle,
ProductSpec: item.ProductSpec,
ShopeeGoodsID: strconv.FormatInt(item.ProductID, 10),
@@ -799,6 +800,13 @@ func writeStockDetail(db *sql.DB, baseURL string, stockRow syb.StockRow, detail
return tx.Commit()
}
// trimmedStringField 读取顺运宝原始响应中的文本字段。
// 类型不对、缺字段或只有空白时都按空值处理,不猜测或格式化上游数据。
func trimmedStringField(raw map[string]any, name string) string {
value, _ := raw[name].(string)
return strings.TrimSpace(value)
}
// mergeRaw 合并"货运单列表"和"货运单明细"两次响应里同一张货运单的
// 外层字段(不含 details),后者字段优先覆盖前者——明细响应更贴近
// "拉这批数据当下"的状态,见工单 #46 字段映射表 syb_data 的说明。
@@ -919,6 +927,7 @@ func EnsureSybSession(db *sql.DB, client *syb.Client, username string, now time.
type SybOrderView struct {
SybID string
OrderNo string
ShopName string
Title string
ProductSpec string
ShopeeGoodsID string
@@ -1031,13 +1040,14 @@ type SybListResult struct {
//
// `[必须]` 处理阶段由顺运宝规格键、PDD 关联、采集状态和规格映射实时推导,
// 不额外保存一份容易过期的状态字段。
func ListSybOrdersView(db *sql.DB, keyword, stage string, page int) (*SybListResult, error) {
func ListSybOrdersView(db *sql.DB, keyword, shop, stage string, page int) (*SybListResult, error) {
shop = strings.TrimSpace(shop)
stage = ParseSybStage(stage)
if stage == SybStageMappingPending || stage == SybStagePurchaseReady ||
stage == SybStageTaskCreated || stage == SybStagePurchaseBlocked {
return listAdvancedSybStage(db, keyword, stage, page)
return listAdvancedSybStage(db, keyword, shop, stage, page)
}
filter := repository.SybOrderFilter{Keyword: keyword, Stage: stage}
filter := repository.SybOrderFilter{Keyword: keyword, Shop: shop, Stage: stage}
total, err := repository.CountSybOrders(db, filter)
if err != nil {
return nil, err
@@ -1060,7 +1070,7 @@ func ListSybOrdersView(db *sql.DB, keyword, stage string, page int) (*SybListRes
Rows: make([]SybOrderView, 0, len(rows)),
Total: total,
HasAny: hasAny > 0,
IsFiltered: strings.TrimSpace(keyword) != "" || stage != "",
IsFiltered: strings.TrimSpace(keyword) != "" || shop != "" || stage != "",
Stage: stage,
Page: page,
TotalPages: totalPages,
@@ -1075,9 +1085,9 @@ func ListSybOrdersView(db *sql.DB, keyword, stage string, page int) (*SybListRes
// 这四个阶段不能只靠 SQL 判断:同一个 option key 是否仍存在,需要走唯一的
// OptionKey 规范化逻辑。当前同步量是百到千级,先保证采购判断正确;普通列表
// 和其余阶段仍在数据库分页。
func listAdvancedSybStage(db *sql.DB, keyword, stage string, page int) (*SybListResult, error) {
func listAdvancedSybStage(db *sql.DB, keyword, shop, stage string, page int) (*SybListResult, error) {
contexts, err := repository.ListSybOrderContexts(db,
repository.SybOrderFilter{Keyword: keyword}, -1, 0)
repository.SybOrderFilter{Keyword: keyword, Shop: shop}, -1, 0)
if err != nil {
return nil, err
}
@@ -1114,7 +1124,7 @@ func listAdvancedSybStage(db *sql.DB, keyword, stage string, page int) (*SybList
func sybOrderViewFor(context repository.SybOrderContext) SybOrderView {
o := context.Order
v := SybOrderView{SybID: o.SybID, OrderNo: o.OrderNo, Title: o.Title,
v := SybOrderView{SybID: o.SybID, OrderNo: o.OrderNo, ShopName: o.ShopName, Title: o.Title,
ProductSpec: o.ProductSpec, ShopeeGoodsID: o.ShopeeGoodsID,
Quantity: o.Quantity, ImageURL: o.ImageURL,
UpdatedAt: formatLocalTime(o.UpdatedAt)}