package main import ( "encoding/json" "fmt" "log" "bindbox-game/internal/repository/mysql/model" "gorm.io/driver/mysql" "gorm.io/gorm" "gorm.io/gorm/logger" ) // Payer 简单的结构体用于解析 Raw JSON type Payer struct { Openid string `json:"openid"` } type TransactionRaw struct { Payer Payer `json:"payer"` } func main() { // 连接数据库 (使用 docker-compose 中定义的密码) dsn := "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), }) if err != nil { log.Fatalf("连接数据库失败: %v", err) } fmt.Println("开始修复 payer_openid...") var txs []model.PaymentTransactions // 查找 payer_openid 为空 且 raw 不为空的记录 // 注意:这里需要分批处理如果数据量很大的话。这里演示简单逻辑。 // 使用 Raw SQL 为了避免 GORM 模型定义可能存在的缓存或不一致 if err := db.Where("payer_openid = ? AND raw != ?", "", "").Find(&txs).Error; err != nil { log.Fatalf("查询数据失败: %v", err) } fmt.Printf("找到 %d 条需要修复的记录\n", len(txs)) successCount := 0 failCount := 0 for _, tx := range txs { if tx.Raw == "" { continue } var rawObj TransactionRaw if err := json.Unmarshal([]byte(tx.Raw), &rawObj); err != nil { fmt.Printf("[Error] 解析 Raw 失败 ID=%d: %v\n", tx.ID, err) failCount++ continue } openid := rawObj.Payer.Openid if openid == "" { fmt.Printf("[Warn] Raw 中未包含 openid ID=%d\n", tx.ID) failCount++ continue } // 更新数据库 if err := db.Model(&model.PaymentTransactions{}).Where("id = ?", tx.ID).Update("payer_openid", openid).Error; err != nil { fmt.Printf("[Error] 更新数据库失败 ID=%d: %v\n", tx.ID, err) failCount++ } else { // fmt.Printf("[OK] ID=%d 修复 openid=%s\n", tx.ID, openid) successCount++ } } fmt.Printf("修复完成! 成功: %d, 失败/跳过: %d\n", successCount, failCount) }