feat: 回填三个Excel关联PDD正式价格 (#226)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PDDPriceBackfillTarget 是一次性 Excel 价格回填需要的 PDD 原值。
|
||||
// 原值同时用于 dry-run、乐观锁和本机回退备份。
|
||||
type PDDPriceBackfillTarget struct {
|
||||
GoodsID string
|
||||
SKUsJSON string
|
||||
CollectStatus string
|
||||
CollectMsg *string
|
||||
ArtifactRef *string
|
||||
CollectedAt *string
|
||||
UpdatedAt string
|
||||
}
|
||||
|
||||
// ListShopPDDPriceBackfillTargets 读取指定蝦皮店铺当前关联的活动 PDD 商品。
|
||||
// 同一个 PDD 被多个蝦皮商品关联时只返回一份原值。
|
||||
func ListShopPDDPriceBackfillTargets(q Execer, shopName string) ([]PDDPriceBackfillTarget, error) {
|
||||
rows, err := q.Query(`
|
||||
SELECT DISTINCT pp.goods_id, COALESCE(pp.skus_json, ''), pp.collect_status,
|
||||
pp.collect_msg, pp.artifact_ref, pp.collected_at, pp.updated_at
|
||||
FROM shopee_products sp
|
||||
JOIN pdd_products pp ON pp.goods_id = sp.pdd_goods_id
|
||||
WHERE sp.deleted_at IS NULL AND pp.deleted_at IS NULL
|
||||
AND sp.shopee_shop_name = ?
|
||||
ORDER BY pp.goods_id`, strings.TrimSpace(shopName))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取店铺 PDD 价格回填目标失败: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var targets []PDDPriceBackfillTarget
|
||||
for rows.Next() {
|
||||
var target PDDPriceBackfillTarget
|
||||
var collectMsg, artifactRef, collectedAt sql.NullString
|
||||
if err := rows.Scan(&target.GoodsID, &target.SKUsJSON, &target.CollectStatus,
|
||||
&collectMsg, &artifactRef, &collectedAt, &target.UpdatedAt); err != nil {
|
||||
return nil, fmt.Errorf("解析 PDD 价格回填目标失败: %w", err)
|
||||
}
|
||||
target.CollectMsg = nullableStringPointer(collectMsg)
|
||||
target.ArtifactRef = nullableStringPointer(artifactRef)
|
||||
target.CollectedAt = nullableStringPointer(collectedAt)
|
||||
targets = append(targets, target)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("遍历 PDD 价格回填目标失败: %w", err)
|
||||
}
|
||||
return targets, nil
|
||||
}
|
||||
|
||||
func nullableStringPointer(value sql.NullString) *string {
|
||||
if !value.Valid {
|
||||
return nil
|
||||
}
|
||||
result := value.String
|
||||
return &result
|
||||
}
|
||||
|
||||
// ReplacePDDPricesAndMarkCollected 使用完整原值作乐观锁,写入价格并标记已采集。
|
||||
// 返回 false 表示 dry-run 后目标发生变化,调用方必须回滚整批,不能部分提交。
|
||||
func ReplacePDDPricesAndMarkCollected(q Execer, target PDDPriceBackfillTarget,
|
||||
newSKUsJSON, collectedAt, updatedAt string) (bool, error) {
|
||||
result, err := q.Exec(`
|
||||
UPDATE pdd_products
|
||||
SET skus_json = ?, collect_status = 'collected',
|
||||
collect_msg = NULL, artifact_ref = NULL,
|
||||
collected_at = ?, updated_at = ?
|
||||
WHERE goods_id = ? AND deleted_at IS NULL
|
||||
AND COALESCE(skus_json, '') = ?
|
||||
AND collect_status = ? AND updated_at = ?`,
|
||||
newSKUsJSON, collectedAt, updatedAt, target.GoodsID,
|
||||
target.SKUsJSON, target.CollectStatus, target.UpdatedAt)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("更新 PDD 商品 %s 的正式价格失败: %w", target.GoodsID, err)
|
||||
}
|
||||
rows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("读取 PDD 商品 %s 的价格回填结果失败: %w", target.GoodsID, err)
|
||||
}
|
||||
return rows == 1, nil
|
||||
}
|
||||
Reference in New Issue
Block a user