You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

110 lines
3.1 KiB

// 一次性工具:把某个应用业务库 goods 表导出的 JSON 同步进 console 主库的 app_goods 表。
// 用法: go run ./cmd/syncgoods -dsn <postgres dsn> -file goods.json -app Voitrans-Test [-apply]
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"sort"
"time"
"yunyan/comm"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
type srcGoods struct {
Id string `json:"id"`
Enable int `json:"enable"`
Name string `json:"name"`
Localname string `json:"localname"`
Price int32 `json:"price"`
Usagetype int32 `json:"usagetype"`
Ainum int64 `json:"ainum"`
Meetnum int64 `json:"meetnum"`
Tradenum int64 `json:"tradenum"`
Viptime int32 `json:"viptime"`
}
func main() {
dsn := flag.String("dsn", "", "console 主库 postgres dsn")
file := flag.String("file", "", "源 goods JSON 文件")
app := flag.String("app", "", "目标应用名 app_goods.app_name")
remark := flag.String("remark", "", "备注")
apply := flag.Bool("apply", false, "真正写入(默认只做 dry-run 打印)")
flag.Parse()
if *dsn == "" || *file == "" || *app == "" {
fmt.Println("缺少参数 -dsn/-file/-app")
os.Exit(1)
}
buf, err := os.ReadFile(*file)
if err != nil {
panic(err)
}
var src []*srcGoods
if err = json.Unmarshal(buf, &src); err != nil {
panic(err)
}
sort.Slice(src, func(i, j int) bool { return src[i].Id < src[j].Id })
db, err := gorm.Open(postgres.Open(*dsn), &gorm.Config{Logger: logger.Default.LogMode(logger.Error)})
if err != nil {
panic(err)
}
if err = db.Table(comm.TableAppGoods).AutoMigrate(&comm.AppGoods{}); err != nil {
panic(err)
}
fmt.Printf("表 %s 就绪,源记录 %d 条,目标应用 %s,apply=%v\n", comm.TableAppGoods, len(src), *app, *apply)
now := time.Now().Unix()
var ins, upd int
for i, g := range src {
row := &comm.AppGoods{
AppName: *app,
GoodsId: g.Id,
Enable: g.Enable != 0,
Name: g.Name,
Price: g.Price,
Usagetype: g.Usagetype,
Ainum: g.Ainum,
Meetnum: g.Meetnum,
Tradenum: g.Tradenum,
Viptime: g.Viptime,
Localname: g.Localname,
Sort: int32((i + 1) * 10),
Remark: *remark,
Createtime: now,
Updatetime: now,
}
old := &comm.AppGoods{}
err := db.Table(comm.TableAppGoods).Where("app_name=? AND goods_id=?", *app, g.Id).Take(old).Error
switch {
case err == gorm.ErrRecordNotFound:
ins++
fmt.Printf(" + %-22s %-16s price=%d type=%d enable=%v\n", g.Id, g.Name, g.Price, g.Usagetype, row.Enable)
if *apply {
if err = db.Table(comm.TableAppGoods).Create(row).Error; err != nil {
panic(err)
}
}
case err != nil:
panic(err)
default:
upd++
row.Id = old.Id
row.Createtime = old.Createtime
fmt.Printf(" ~ %-22s %-16s (覆盖已有 id=%d)\n", g.Id, g.Name, old.Id)
if *apply {
if err = db.Table(comm.TableAppGoods).Where("id=?", old.Id).Updates(row).Error; err != nil {
panic(err)
}
}
}
}
fmt.Printf("完成:新增 %d,更新 %d%s\n", ins, upd, map[bool]string{false: "(dry-run,未写库)", true: ""}[*apply])
}