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

187 lines
5.5 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"time"
"github.com/golang-jwt/jwt/v4"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// Configs from dev_configs.toml
const (
DbDSN = "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?charset=utf8mb4&parseTime=True&loc=Local"
JwtSecret = "AppUserJwtSecret2025"
ApiURL = "http://127.0.0.1:9991/api/app/lottery/join"
)
type UserItemCards struct {
ID int64 `gorm:"column:id"`
Status int32 `gorm:"column:status"`
UsedAt time.Time `gorm:"column:used_at"`
UsedActivityID int64 `gorm:"column:used_activity_id"`
UsedIssueID int64 `gorm:"column:used_issue_id"`
UsedDrawLogID int64 `gorm:"column:used_draw_log_id"`
}
func (UserItemCards) TableName() string { return "user_item_cards" }
func main() {
// 1. Connect DB
db, err := gorm.Open(mysql.Open(DbDSN), &gorm.Config{})
if err != nil {
log.Fatalf("DB connection failed: %v", err)
}
// 2. Reset Item Card 836
cardID := int64(836)
fmt.Printf("Restoring UserItemCard %d...\n", cardID)
// We set status to 1 and clear used fields
res := db.Model(&UserItemCards{}).Where("id = ?", cardID).Updates(map[string]interface{}{
"status": 1,
"used_at": nil,
"used_activity_id": 0,
"used_issue_id": 0,
"used_draw_log_id": 0,
})
if res.Error != nil {
log.Fatalf("Failed to restore card: %v", res.Error)
}
fmt.Println("Card restored to Status 1.")
// 3. Generate JWT
tokenString, err := generateToken(9090, JwtSecret)
if err != nil {
log.Fatalf("Failed to generate token: %v", err)
}
fmt.Printf("Generated Token for User 9090.\n")
// 4. Send API Request
targetSlot := int64(1)
reqBody := map[string]interface{}{
"activity_id": 94,
"issue_id": 105,
"count": 1,
"slot_index": []int64{targetSlot},
"item_card_id": cardID,
"channel": "simulation",
}
jsonBody, _ := json.Marshal(reqBody)
req, _ := http.NewRequest("POST", ApiURL, bytes.NewBuffer(jsonBody))
req.Header.Set("Content-Type", "application/json")
// Backend seems to expect raw token string without Bearer prefix
req.Header.Set("Authorization", tokenString)
client := &http.Client{}
fmt.Println("Sending JoinLottery request...")
resp, err := client.Do(req)
if err != nil {
log.Fatalf("Request failed: %v", err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Printf("Response Status: %s\n", resp.Status)
fmt.Printf("Response Body: %s\n", string(body))
// If success (200 OK), parse order info, simulate payment, trigger draw
if resp.StatusCode == 200 {
var resMap map[string]interface{}
json.Unmarshal(body, &resMap)
// joinID := resMap["join_id"].(string) // Unused
orderNo := resMap["order_no"].(string)
fmt.Printf("Order Created: %s. Simulating Payment...\n", orderNo)
// Simulate Payment in DB
db.Table("orders").Where("order_no = ?", orderNo).Updates(map[string]interface{}{
"status": 2,
"paid_at": time.Now(),
})
fmt.Println("Order marked as PAID (Status 2).")
// Trigger Draw via GetLotteryResult with order_no
resultURL := fmt.Sprintf("http://127.0.0.1:9991/api/app/lottery/result?order_no=%s", orderNo)
reqResult, _ := http.NewRequest("GET", resultURL, nil)
reqResult.Header.Set("Authorization", tokenString)
fmt.Println("Triggering Draw (GetLotteryResult)...")
respResult, err := client.Do(reqResult)
if err != nil {
log.Fatalf("Result Request failed: %v", err)
}
defer respResult.Body.Close()
bodyResult, _ := io.ReadAll(respResult.Body)
fmt.Printf("Draw Response: %s\n", string(bodyResult))
time.Sleep(2 * time.Second)
checkLogs(db, cardID)
}
}
func generateToken(userID int64, secret string) (string, error) {
// Claims mimicking bindbox-game/internal/pkg/jwtoken/jwtoken.go structure
claims := jwt.MapClaims{
"id": int32(userID),
"username": "simulation",
"nickname": "simulation_user",
"is_super": 0,
"platform": "simulation",
// Standard claims
"exp": time.Now().Add(time.Hour).Unix(),
"iat": time.Now().Unix(),
"nbf": time.Now().Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(secret))
}
func checkLogs(db *gorm.DB, cardID int64) {
fmt.Println("\n--- Verification Results ---")
// Check Card Status
var card UserItemCards
if err := db.First(&card, cardID).Error; err != nil {
fmt.Printf("Error fetching card: %v\n", err)
return
}
fmt.Printf("Card Status: %d (Expected 2 if success)\n", card.Status)
if card.Status == 2 {
fmt.Printf("Card Used At: %v\n", card.UsedAt)
fmt.Printf("Used Draw Log ID: %d\n", card.UsedDrawLogID)
if card.UsedDrawLogID > 0 {
// Check Draw Log
type ActivityDrawLogs struct {
ID int64 `gorm:"column:id"`
RewardID int64 `gorm:"column:reward_id"`
OrderID int64 `gorm:"column:order_id"`
}
var dl ActivityDrawLogs
db.Table("activity_draw_logs").First(&dl, card.UsedDrawLogID)
fmt.Printf("Original Draw Reward ID: %d, Order ID: %d\n", dl.RewardID, dl.OrderID)
// Check Inventory Count for this Order (Should be > 1 if doubled)
var inventoryCount int64
db.Table("user_inventory").Where("order_id = ?", dl.OrderID).Count(&inventoryCount)
fmt.Printf("Total Inventory Items for Order %d: %d\n", dl.OrderID, inventoryCount)
if inventoryCount > 1 {
fmt.Println("SUCCESS: Double reward applied (Inventory count > 1)")
} else {
fmt.Println("WARNING: Inventory count is 1. Double reward might NOT have been applied.")
}
}
} else {
fmt.Println("FAILURE: Card status is still 1 (Not Consumed).")
}
}