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

86 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("--- Activity-Based Coupon Data Repair Auditor (Cloud DB) ---")
var records []struct {
ID int64
UserID int64
CouponID int64
BalanceAmount int64
Status int32
ValidEnd string
OriginalValue int64
DiscountType int32
}
// Fetch all coupons joined with system data
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, sc.discount_type
FROM user_coupons uc
JOIN system_coupons sc ON uc.coupon_id = sc.id
`).Scan(&records)
for _, r := range records {
// Calculate total usage from order_coupons
var orderUsage int64
db.Raw("SELECT SUM(applied_amount) FROM order_coupons WHERE user_coupon_id = ?", r.ID).Scan(&orderUsage)
// Calculate total usage from ledger
var ledgerUsage int64
db.Raw("SELECT ABS(SUM(change_amount)) FROM user_coupon_ledger WHERE user_coupon_id = ? AND action = 'apply'", r.ID).Scan(&ledgerUsage)
// Max usage between sources
finalUsage := orderUsage
if ledgerUsage > finalUsage {
finalUsage = ledgerUsage
}
expectedBalance := r.OriginalValue - finalUsage
if expectedBalance < 0 {
expectedBalance = 0
}
// Determine Correct Status
// 1: Unused (or Partially Used but still valid)
// 2: Used (Exhausted)
// 3: Expired (Unused/Partially Used and time past)
expectedStatus := r.Status
if expectedBalance == 0 {
expectedStatus = 2
} else {
// Logic for expired vs unused would go here if needed,
// but we prioritize "Used" if balance is 0.
// Currently if balance > 0 and Status is 2, it's definitely an error.
if r.Status == 2 {
expectedStatus = 1 // Revert to unused/partial if balance > 0
}
}
if expectedBalance != r.BalanceAmount || expectedStatus != r.Status {
fmt.Printf("-- Coupon %d (User %d): Bal %d->%d, Status %v->%v, Usage %d/%d\n",
r.ID, r.UserID, r.BalanceAmount, expectedBalance, r.Status, expectedStatus, finalUsage, r.OriginalValue)
fmt.Printf("UPDATE user_coupons SET balance_amount = %d, status = %v, updated_at = NOW() WHERE id = %d;\n",
expectedBalance, expectedStatus, r.ID)
}
}
}