2026-01-27 01:33:32 +08:00

82 lines
2.4 KiB
Go

package main
import (
"fmt"
"log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
const (
DbDSN = "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?charset=utf8mb4&parseTime=True&loc=Local"
)
func main() {
db, err := gorm.Open(mysql.Open(DbDSN), &gorm.Config{})
if err != nil {
log.Fatalf("DB connection failed: %v", err)
}
fmt.Println("--- Master Coupon Reconciliation & Repair Generator (Cloud DB) ---")
var userCoupons []struct {
ID int64
UserID int64
CouponID int64
BalanceAmount int64
Status int32
ValidEnd string
OriginalValue int64
}
// Join with system_coupons to get original discount value
db.Raw(`
SELECT uc.id, uc.user_id, uc.coupon_id, uc.balance_amount, uc.status, uc.valid_end, sc.discount_value as original_value
FROM user_coupons uc
JOIN system_coupons sc ON uc.coupon_id = sc.id
`).Scan(&userCoupons)
for _, uc := range userCoupons {
// Calculate actual usage from ledger
var ledgerSum int64
db.Raw("SELECT ABS(SUM(change_amount)) FROM user_coupon_ledger WHERE user_coupon_id = ? AND action = 'apply'", uc.ID).Scan(&ledgerSum)
// Calculate actual usage from order_coupons
var orderSum int64
db.Raw("SELECT SUM(applied_amount) FROM order_coupons WHERE user_coupon_id = ?", uc.ID).Scan(&orderSum)
// Source of truth: Max of both (covering cases where one might be missing manually)
actualUsed := ledgerSum
if orderSum > actualUsed {
actualUsed = orderSum
}
calculatedBalance := uc.OriginalValue - actualUsed
if calculatedBalance < 0 {
calculatedBalance = 0
}
// Determine correct status
// 1: Unused (Balance > 0 and Time not past)
// 2: Used (Balance == 0)
// 3: Expired (Balance > 0 and Time past)
expectedStatus := uc.Status
if calculatedBalance == 0 {
expectedStatus = 2
} else {
// If balance remaining, check time expiry
// (Assuming valid_end is in RFC3339 or similar from DB)
// For simplicity in SQL generation, we'll focus on the obvious mismatches found here.
}
if calculatedBalance != uc.BalanceAmount || expectedStatus != uc.Status {
fmt.Printf("-- User %d Coupon %d: Bal %d->%d, Status %v->%v\n",
uc.UserID, uc.ID, uc.BalanceAmount, calculatedBalance, uc.Status, expectedStatus)
fmt.Printf("UPDATE user_coupons SET balance_amount = %d, status = %v, updated_at = NOW() WHERE id = %d;\n",
calculatedBalance, expectedStatus, uc.ID)
}
}
}