Files

98 lines
2.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// backfill-shop-pdd-specs 把指定蝦皮店铺的正式规格补成关联 PDD 的空规格骨架。
// 默认只预览;只有显式传入 --apply 才写数据库。
package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"os"
"strings"
"time"
"cmautobuy/admin/config"
"cmautobuy/admin/repository"
"cmautobuy/admin/service"
)
type backupFile struct {
Shop string `json:"shop"`
GeneratedAt string `json:"generated_at"`
Items []backupItem `json:"items"`
}
type backupItem struct {
PDDGoodsID string `json:"pdd_goods_id"`
SKUsJSON string `json:"skus_json"`
}
func main() {
shop := flag.String("shop", "", "要处理的蝦皮店铺名(精确匹配,必填)")
apply := flag.Bool("apply", false, "实际写入;不传时只做 dry-run")
flag.Parse()
if strings.TrimSpace(*shop) == "" {
log.Fatal("必须通过 --shop 指定店铺名")
}
cfg, err := config.LoadDatabase()
if err != nil {
log.Fatalf("读取 MySQL 配置失败: %v", err)
}
db, err := repository.OpenMySQL(cfg)
if err != nil {
log.Fatalf("连接 MySQL 失败: %v", err)
}
defer db.Close()
sources, err := repository.ListShopSpecSources(db, *shop)
if err != nil {
log.Fatal(err)
}
now := time.Now()
plan := service.BuildSpecBackfillPlan(*shop, sources, now)
if !*apply {
printReport(plan, 0, "dry-run")
return
}
backupPath, err := writeBackup(plan)
if err != nil {
log.Fatalf("创建本机回退备份失败,未写数据库: %v", err)
}
updated, err := service.ApplySpecBackfill(db, plan, now)
if err != nil {
log.Fatalf("规格回填失败: %v;本机备份位于 %s", err, backupPath)
}
printReport(plan, updated, "applied")
fmt.Printf("本机回退备份:%s\n", backupPath)
}
func printReport(plan service.SpecBackfillPlan, updated int, mode string) {
summary, _ := json.Marshal(plan.Summary)
fmt.Printf("模式:%s\n店铺:%s\n蝦皮商品:%d\n候选 PDD:%d\n已回填 PDD:%d\n本次更新 PDD:%d\n分类:%s\n",
mode, plan.Shop, plan.SourceProductCount, plan.CandidatePDDCount,
plan.BackfilledPDDCount, updated, summary)
}
func writeBackup(plan service.SpecBackfillPlan) (string, error) {
file, err := os.CreateTemp("", "cmautobuy_spec_backfill_backup_*.json")
if err != nil {
return "", err
}
path := file.Name()
defer file.Close()
if err := file.Chmod(0o600); err != nil {
return "", err
}
backup := backupFile{Shop: plan.Shop, GeneratedAt: time.Now().UTC().Format(time.RFC3339)}
for _, candidate := range plan.Candidates {
backup.Items = append(backup.Items, backupItem{PDDGoodsID: candidate.PDDGoodsID, SKUsJSON: candidate.OriginalSKUsJSON})
}
encoder := json.NewEncoder(file)
encoder.SetIndent("", " ")
if err := encoder.Encode(backup); err != nil {
return "", err
}
return path, nil
}