Files
cmautobuy/admin/cmd/confirm-backfilled-pdd-availability/main.go
T

122 lines
3.9 KiB
Go
Raw 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.
// confirm-backfilled-pdd-availability 把三个固定 Excel 的完整 PDD 规格确认为可采购候选。
// 默认只预览;只有显式传入 -apply 才写数据库。
package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"os"
"time"
"cmautobuy/admin/config"
"cmautobuy/admin/repository"
"cmautobuy/admin/service"
)
type backupFile struct {
Shop string `json:"shop"`
GeneratedAt string `json:"generated_at"`
Files []string `json:"files"`
Items []backupItem `json:"items"`
}
type backupItem struct {
PDDGoodsID string `json:"pdd_goods_id"`
OriginalSKUsJSON string `json:"original_skus_json"`
OriginalCollectStatus string `json:"original_collect_status"`
OriginalCollectMsg *string `json:"original_collect_msg"`
OriginalArtifactRef *string `json:"original_artifact_ref"`
OriginalCollectedAt *string `json:"original_collected_at"`
OriginalUpdatedAt string `json:"original_updated_at"`
}
func main() {
dir := flag.String("dir", "../raw_data", "三个固定 Excel 所在目录")
apply := flag.Bool("apply", false, "实际写入;不传时只做 dry-run")
flag.Parse()
if flag.NArg() != 0 {
log.Fatal("不接受额外文件参数;只会读取 -dir 下三个固定文件名")
}
sources, err := service.LoadXLSXPriceSources(*dir)
if err != nil {
log.Fatalf("读取三个固定 Excel 失败: %v", err)
}
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()
targets, err := repository.ListShopPDDPriceBackfillTargets(db, service.XLSXPriceBackfillShop)
if err != nil {
log.Fatal(err)
}
plan := service.BuildXLSXAvailabilityPlan(sources, targets, time.Now())
if !*apply {
printReport(plan, 0, "dry-run")
return
}
if len(plan.Candidates) == 0 {
printReport(plan, 0, "applied-noop")
return
}
backupPath, err := writeBackup(plan)
if err != nil {
log.Fatalf("创建本机回退备份失败,未写数据库: %v", err)
}
updated, err := service.ApplyXLSXAvailabilityPlan(db, plan, time.Now())
if err != nil {
log.Fatalf("PDD 可售状态确认失败: %v;本机备份位于 %s", err, backupPath)
}
printReport(plan, updated, "applied")
fmt.Printf("本机回退备份:%s\n", backupPath)
}
func printReport(plan service.XLSXAvailabilityPlan, updated int, mode string) {
summary, _ := json.Marshal(plan.Summary)
skuCount := 0
for _, candidate := range plan.Candidates {
skuCount += candidate.SKUCount
}
fmt.Printf("模式:%s\n店铺:%s\nExcel 行:%d\n蝦皮商品:%d\nPDD 商品:%d\n候选 PDD:%d\n候选 SKU:%d\n本次更新 PDD:%d\n分类:%s\n",
mode, plan.Shop, plan.Sources.RowCount, plan.Sources.ShopeeProductCount,
plan.Sources.PDDProductCount, len(plan.Candidates), skuCount, updated, summary)
}
func writeBackup(plan service.XLSXAvailabilityPlan) (string, error) {
file, err := os.CreateTemp("", "cmautobuy_xlsx_availability_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),
Files: append([]string(nil), service.XLSXPriceBackfillFiles...),
}
for _, candidate := range plan.Candidates {
original := candidate.Original
backup.Items = append(backup.Items, backupItem{
PDDGoodsID: candidate.PDDGoodsID, OriginalSKUsJSON: original.SKUsJSON,
OriginalCollectStatus: original.CollectStatus, OriginalCollectMsg: original.CollectMsg,
OriginalArtifactRef: original.ArtifactRef, OriginalCollectedAt: original.CollectedAt,
OriginalUpdatedAt: original.UpdatedAt,
})
}
encoder := json.NewEncoder(file)
encoder.SetIndent("", " ")
if err := encoder.Encode(backup); err != nil {
return "", err
}
return path, nil
}