package developer import ( "fmt" "log" "strconv" "time" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" "verification-platform-backend/internal/service" "verification-platform-backend/pkg/response" "verification-platform-backend/pkg/utils" "github.com/gin-gonic/gin" "gorm.io/gorm" ) func SetupCardRoutes(r *gin.RouterGroup) { cardTypes := r.Group("/card-types") { cardTypes.GET("", handleGetCardTypes) cardTypes.GET("/:id", handleGetCardType) cardTypes.POST("", handleCreateCardType) cardTypes.PUT("/:id", handleUpdateCardType) cardTypes.DELETE("/:id", handleDeleteCardType) } cards := r.Group("/cards") { cards.GET("", handleGetCards) cards.POST("", handleCreateCards) cards.GET("/:id", handleGetCard) cards.PUT("/:id", handleUpdateCard) cards.DELETE("/:id", handleDeleteCard) cards.PUT("/:id/status", handleUpdateCardStatus) cards.PUT("/batch/status", handleBatchUpdateCardStatus) cards.DELETE("/batch", handleBatchDeleteCards) cards.POST("/use", handleUseCard) cards.GET("/export", handleExportCards) } } func SetupCardRoutesWithoutPackage(r *gin.RouterGroup) { cards := r.Group("/cards") { cards.POST("/batch", handleBatchGenerateCards) } } func checkDeveloperPackageValid(developerID uint) bool { var user model.User if err := database.DB.First(&user, developerID).Error; err != nil { return false } if user.CurrentPackageID == nil { return false } var userPackage model.UserPackage if err := database.DB.Where("user_id = ? AND package_id = ? AND status = ?", developerID, user.CurrentPackageID, "active").First(&userPackage).Error; err != nil { return false } if userPackage.ExpiredAt != nil && userPackage.ExpiredAt.Before(time.Now()) { return false } return true } func handleGetCardTypes(c *gin.Context) { userID := c.GetUint("user_id") applicationID := c.Query("application_id") log.Printf("[DEBUG] handleGetCardTypes called: userID=%d, applicationID=%s\n", userID, applicationID) var cardTypes []model.CardType var query *gorm.DB if applicationID != "" { appID, err := strconv.ParseUint(applicationID, 10, 32) if err == nil { var authorizedApps []model.AgentApplication database.DB.Where("agent_id = ? AND application_id = ? AND status = ?", userID, uint(appID), "active"). Preload("CardTypes"). Find(&authorizedApps) log.Printf("[DEBUG] Found %d authorized apps for user %d and application %d\n", len(authorizedApps), userID, uint(appID)) var authorizedCardTypeIDs []uint for _, aa := range authorizedApps { for _, ct := range aa.CardTypes { if ct.CanGenerate { authorizedCardTypeIDs = append(authorizedCardTypeIDs, ct.CardTypeID) log.Printf("[DEBUG] Authorized card type - ID: %d\n", ct.CardTypeID) } } } if len(authorizedCardTypeIDs) > 0 { query = database.DB.Where("(user_id = ? AND application_id = ?) OR (id IN (?))", userID, uint(appID), authorizedCardTypeIDs) log.Printf("[DEBUG] Querying card types with authorizedCardTypeIDs: %v\n", authorizedCardTypeIDs) } else { query = database.DB.Where("user_id = ? AND application_id = ?", userID, uint(appID)) } } else { query = database.DB.Where("user_id = ?", userID) } } else { query = database.DB.Where("user_id = ?", userID) } if err := query.Preload("Application").Find(&cardTypes).Error; err != nil { log.Printf("[ERROR] Failed to query card types: %v\n", err) response.Error(c, 500, "获取卡密类型失败") return } log.Printf("[DEBUG] Found %d card types\n", len(cardTypes)) for i, ct := range cardTypes { log.Printf("[DEBUG] CardType %d: ID=%d, Name=%s, ApplicationID=%v\n", i, ct.ID, ct.Name, ct.ApplicationID) } var cardTypesWithCount []map[string]interface{} for _, ct := range cardTypes { var count int64 database.DB.Model(&model.Card{}).Where("card_type_id = ?", ct.ID).Count(&count) log.Printf("[DEBUG] CardType ID=%d, Name=%s, GeneratedCount=%d\n", ct.ID, ct.Name, count) cardTypeMap := map[string]interface{}{ "id": ct.ID, "user_id": ct.UserID, "application_id": ct.ApplicationID, "name": ct.Name, "value": ct.Value, "price": ct.Price, "description": ct.Description, "status": ct.Status, "created_at": ct.CreatedAt, "updated_at": ct.UpdatedAt, "generatedCount": count, } if ct.Application != nil { cardTypeMap["application"] = ct.Application } cardTypesWithCount = append(cardTypesWithCount, cardTypeMap) } response.Success(c, gin.H{ "card_types": cardTypesWithCount, }) } func handleGetCardType(c *gin.Context) { userID := c.GetUint("user_id") id := c.Param("id") var cardType model.CardType if err := database.DB.Preload("Application").First(&cardType, id).Error; err != nil { response.Error(c, 404, "卡类不存在") return } if cardType.UserID != userID { var app model.Application if err := database.DB.First(&app, cardType.ApplicationID).Error; err != nil { response.Error(c, 403, "无权限查看该卡类") return } if app.UserID != userID { var agentApp model.AgentApplication if err := database.DB.Where("application_id = ? AND agent_id = ? AND is_received = ?", cardType.ApplicationID, userID, true).First(&agentApp).Error; err != nil { response.Error(c, 403, "无权限查看该卡类") return } } } response.Success(c, gin.H{ "card_type": cardType, }) } func handleCreateCardType(c *gin.Context) { userID := c.GetUint("user_id") var req struct { Name string `json:"name"` Description string `json:"description"` RechargeType string `json:"recharge_type"` Value float64 `json:"value"` ValueUnit string `json:"value_unit"` Price float64 `json:"price"` ApplicationID uint `json:"application_id"` } if err := c.ShouldBindJSON(&req); err != nil { fmt.Printf("创建卡密类型参数错误: %v\n", err) response.Error(c, 400, "参数错误") return } fmt.Printf("创建卡密类型请求: Name=%s, RechargeType=%s, Value=%f, ValueUnit=%s, Price=%f, ApplicationID=%d\n", req.Name, req.RechargeType, req.Value, req.ValueUnit, req.Price, req.ApplicationID) if req.Name == "" { response.Error(c, 400, "卡密类型名称不能为空") return } if req.ApplicationID == 0 { response.Error(c, 400, "所属应用不能为空") return } var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, userID).First(&app).Error; err != nil { response.Error(c, 400, "所属应用不存在或无权限") return } if req.Price < 0 { response.Error(c, 400, "价格不能为负数") return } if req.Value == 0 { response.Error(c, 400, "面值不能为0") return } if req.Value < -1 { response.Error(c, 400, "面值无效,必须大于0或为-1(表示永久有效)") return } rechargeType := req.RechargeType if rechargeType == "" { rechargeType = "balance" } valueUnit := req.ValueUnit if rechargeType == "subscription" && valueUnit == "" { valueUnit = "day" } cardType := model.CardType{ UserID: userID, Name: req.Name, Description: req.Description, RechargeType: rechargeType, Value: req.Value, ValueUnit: valueUnit, Price: req.Price, ApplicationID: req.ApplicationID, } if err := database.DB.Create(&cardType).Error; err != nil { response.Error(c, 500, "创建卡密类型失败") return } service.LogOperation(c, "create", "card_type", &cardType.ID, fmt.Sprintf("创建卡密类型: %s", cardType.Name), nil) response.Success(c, cardType) } func handleUpdateCardType(c *gin.Context) { userID := c.GetUint("user_id") var req struct { Name string `json:"name"` Description string `json:"description"` RechargeType string `json:"recharge_type"` Value float64 `json:"value"` ValueUnit string `json:"value_unit"` Price float64 `json:"price"` ApplicationID uint `json:"application_id"` Status string `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } id := c.Param("id") var cardType model.CardType if err := database.DB.Where("id = ? AND user_id = ?", id, userID).First(&cardType).Error; err != nil { response.Error(c, 404, "卡密类型不存在") return } if req.Name != "" { cardType.Name = req.Name } if req.Description != "" { cardType.Description = req.Description } if req.RechargeType != "" { cardType.RechargeType = req.RechargeType } if req.ValueUnit != "" { cardType.ValueUnit = req.ValueUnit } if req.Price >= 0 { cardType.Price = req.Price } if req.Value > 0 || req.Value == -1 { cardType.Value = req.Value } if req.Price > 0 { cardType.Price = req.Price } if req.ApplicationID > 0 { var app model.Application if err := database.DB.Where("id = ? AND user_id = ?", req.ApplicationID, userID).First(&app).Error; err != nil { response.Error(c, 400, "所属应用不存在或无权限") return } cardType.ApplicationID = req.ApplicationID } if req.Status != "" { cardType.Status = req.Status } if err := database.DB.Save(&cardType).Error; err != nil { response.Error(c, 500, "更新卡密类型失败") return } service.LogOperation(c, "update", "card_type", &cardType.ID, fmt.Sprintf("更新卡密类型: %s", cardType.Name), nil) response.Success(c, cardType) } func handleDeleteCardType(c *gin.Context) { userID := c.GetUint("user_id") id := c.Param("id") var cardType model.CardType if err := database.DB.Where("id = ? AND user_id = ?", id, userID).First(&cardType).Error; err != nil { response.Error(c, 404, "卡密类型不存在") return } if err := database.DB.Where("id = ? AND user_id = ?", id, userID).Delete(&model.CardType{}).Error; err != nil { response.Error(c, 500, "删除卡密类型失败") return } service.LogOperation(c, "delete", "card_type", &cardType.ID, fmt.Sprintf("删除卡密类型: %s", cardType.Name), nil) response.Success(c, nil) } func handleGetCards(c *gin.Context) { userID := c.GetUint("user_id") fmt.Printf("[DEBUG] handleGetCards called, userID: %d\n", userID) applicationID := c.Query("application_id") cardTypeID := c.Query("card_type_id") status := c.Query("status") search := c.Query("search") startDate := c.Query("start_date") endDate := c.Query("end_date") var cards []model.Card var authorizedAppIDs []uint database.DB.Model(&model.AgentApplication{}). Where("agent_id = ? AND status = ?", userID, "active"). Pluck("application_id", &authorizedAppIDs) fmt.Printf("[DEBUG] Authorized app IDs: %v\n", authorizedAppIDs) query := database.DB.Model(&model.Card{}). Joins("JOIN card_types ON cards.card_type_id = card_types.id"). Joins("JOIN applications ON card_types.application_id = applications.id"). Preload("Application"). Preload("CardType"). Preload("Creator"). Preload("AppUser") if len(authorizedAppIDs) > 0 { query = query.Where("applications.user_id = ? OR (cards.application_id IN ? AND cards.creator_id = ?)", userID, authorizedAppIDs, userID) } else { query = query.Where("applications.user_id = ?", userID) } if applicationID != "" { appID, err := strconv.ParseUint(applicationID, 10, 32) if err == nil { query = query.Where("cards.application_id = ?", uint(appID)) } } if cardTypeID != "" { ctID, err := strconv.ParseUint(cardTypeID, 10, 32) if err == nil { query = query.Where("cards.card_type_id = ?", uint(ctID)) } } if status != "" { query = query.Where("cards.status = ?", status) } if search != "" { searchPattern := "%" + search + "%" query = query.Where("cards.card_key LIKE ? OR card_types.name LIKE ? OR applications.name LIKE ?", searchPattern, searchPattern, searchPattern) } if startDate != "" { query = query.Where("cards.created_at >= ?", startDate+" 00:00:00") } if endDate != "" { query = query.Where("cards.created_at <= ?", endDate+" 23:59:59") } if err := query.Order("cards.created_at DESC").Find(&cards).Error; err != nil { fmt.Printf("[DEBUG] Error fetching cards: %v\n", err) response.Error(c, 500, "获取卡密列表失败") return } fmt.Printf("[DEBUG] Found %d cards for user %d\n", len(cards), userID) response.Success(c, cards) } func handleCreateCards(c *gin.Context) { userID := c.GetUint("user_id") var req struct { CardTypeID uint `json:"card_type_id"` Count int `json:"count"` Prefix string `json:"prefix"` Length int `json:"length"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } var cardType model.CardType if err := database.DB.Where("id = ? AND user_id = ?", req.CardTypeID, userID).First(&cardType).Error; err != nil { response.Error(c, 404, "卡密类型不存在") return } response.Success(c, gin.H{ "message": "卡密创建成功", "count": req.Count, }) } func handleUpdateCard(c *gin.Context) { userID := c.GetUint("user_id") var req struct { Status string `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } id := c.Param("id") var card model.Card if err := database.DB.Joins("JOIN card_types ON cards.card_type_id = card_types.id"). Joins("JOIN applications ON card_types.application_id = applications.id"). Where("cards.id = ? AND applications.user_id = ?", id, userID).First(&card).Error; err != nil { response.Error(c, 404, "卡密不存在") return } card.Status = req.Status if err := database.DB.Save(&card).Error; err != nil { response.Error(c, 500, "更新卡密失败") return } response.Success(c, card) } func handleDeleteCard(c *gin.Context) { userID := c.GetUint("user_id") id := c.Param("id") fmt.Printf("删除卡密请求: ID=%s, UserID=%d\n", id, userID) var card model.Card if err := database.DB.Preload("CardType").Preload("CardType.Application").First(&card, id).Error; err != nil { fmt.Printf("卡密不存在: %v\n", err) response.Error(c, 404, "卡密不存在") return } fmt.Printf("查询到的卡密: ID=%d, CardTypeID=%d, CreatorID=%d\n", card.ID, card.CardTypeID, card.CreatorID) // 如果创建者是当前用户,直接允许删除 if card.CreatorID == userID { fmt.Printf("创建者匹配,允许删除\n") if err := database.DB.Delete(&card).Error; err != nil { fmt.Printf("删除卡密失败: %v\n", err) response.Error(c, 500, "删除卡密失败") return } fmt.Printf("删除卡密成功: ID=%s\n", id) response.Success(c, nil) return } // 如果创建者不匹配,检查应用的所有者 if card.CardType.ID > 0 && card.CardType.Application != nil { fmt.Printf("卡密类型和应用存在,检查应用所有者\n") if card.CardType.Application.UserID == userID { fmt.Printf("应用所有者匹配,允许删除\n") if err := database.DB.Delete(&card).Error; err != nil { fmt.Printf("删除卡密失败: %v\n", err) response.Error(c, 500, "删除卡密失败") return } fmt.Printf("删除卡密成功: ID=%s\n", id) response.Success(c, nil) return } } // 如果卡密类型或应用不存在,尝试通过ApplicationID查询应用(包括软删除的) if card.CardType.ID == 0 || card.CardType.Application == nil { fmt.Printf("卡密类型或应用不存在,尝试查询应用\n") if card.CardType.ID == 0 { // 卡密类型不存在,直接通过CardTypeID查询卡密类型(包括软删除的) var cardType model.CardType if err := database.DB.Unscoped().First(&cardType, card.CardTypeID).Error; err != nil { fmt.Printf("卡密类型不存在: %v\n", err) response.Error(c, 404, "卡密类型不存在") return } card.CardType = cardType } if card.CardType.Application == nil { // 应用不存在,直接通过ApplicationID查询应用(包括软删除的) var app model.Application if err := database.DB.Unscoped().First(&app, card.CardType.ApplicationID).Error; err != nil { fmt.Printf("应用不存在: %v\n", err) response.Error(c, 404, "应用不存在") return } card.CardType.Application = &app } fmt.Printf("查询到的应用: ID=%d, UserID=%d\n", card.CardType.Application.ID, card.CardType.Application.UserID) if card.CardType.Application.UserID == userID { fmt.Printf("应用所有者匹配,允许删除\n") if err := database.DB.Delete(&card).Error; err != nil { fmt.Printf("删除卡密失败: %v\n", err) response.Error(c, 500, "删除卡密失败") return } fmt.Printf("删除卡密成功: ID=%s\n", id) response.Success(c, nil) return } } fmt.Printf("无权限删除此卡密\n") response.Error(c, 403, "无权限删除此卡密") } func handleGetCard(c *gin.Context) { userID := c.GetUint("user_id") id := c.Param("id") var card model.Card if err := database.DB.Joins("JOIN card_types ON cards.card_type_id = card_types.id"). Joins("JOIN applications ON card_types.application_id = applications.id"). Where("cards.id = ? AND applications.user_id = ?", id, userID).First(&card).Error; err != nil { response.Error(c, 404, "卡密不存在") return } response.Success(c, card) } func handleUseCard(c *gin.Context) { var req struct { CardKey string `json:"card_key"` Username string `json:"username"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } var card model.Card if err := database.DB.Where("card_key = ?", req.CardKey).First(&card).Error; err != nil { response.Error(c, 404, "卡密不存在") return } if card.Status != "unused" { response.Error(c, 400, "卡密已被使用或已禁用") return } card.Status = "used" database.DB.Save(&card) response.Success(c, gin.H{ "message": "卡密使用成功", }) } func handleBatchGenerateCards(c *gin.Context) { userID := c.GetUint("user_id") fmt.Printf("[DEBUG] handleBatchGenerateCards called, userID: %d\n", userID) var req struct { ApplicationID uint `json:"application_id"` CardTypeID uint `json:"card_type_id"` Count int `json:"count"` Prefix string `json:"prefix"` Length int `json:"length"` } if err := c.ShouldBindJSON(&req); err != nil { fmt.Printf("[DEBUG] JSON bind error: %v\n", err) response.Error(c, 400, "参数错误") return } fmt.Printf("[DEBUG] Received parameters - ApplicationID: %v, CardTypeID: %d, Count: %d, Prefix: %s, Length: %d\n", req.ApplicationID, req.CardTypeID, req.Count, req.Prefix, req.Length) if req.Count <= 0 || req.Count > 1000 { response.Error(c, 400, "生成数量需在1-1000之间") return } if req.Length <= 0 { req.Length = 16 } if req.Prefix == "" { req.Prefix = "CK" } var cardType model.CardType if err := database.DB.Where("id = ?", req.CardTypeID).First(&cardType).Error; err != nil { fmt.Printf("[DEBUG] CardType not found error: %v\n", err) response.Error(c, 404, "卡密类型不存在") return } fmt.Printf("[DEBUG] CardType found - ID: %d, Name: %s, UserID: %d\n", cardType.ID, cardType.Name, cardType.UserID) if req.ApplicationID == 0 { req.ApplicationID = cardType.ApplicationID } var agentApp *model.AgentApplication var effectiveUserID uint = userID if cardType.UserID != userID { fmt.Printf("[DEBUG] CardType belongs to another user, checking authorization...\n") if req.ApplicationID == 0 { fmt.Printf("[DEBUG] ApplicationID is required for authorized card types\n") response.Error(c, 400, "生成授权应用的卡密需要指定应用ID") return } if err := database.DB.Where("agent_id = ? AND application_id = ? AND status = ?", userID, req.ApplicationID, "active"). Preload("CardTypes", "card_type_id = ?", req.CardTypeID). First(&agentApp).Error; err != nil { fmt.Printf("[DEBUG] Authorization not found error: %v\n", err) response.Error(c, 403, "您没有权限生成此卡密类型") return } fmt.Printf("[DEBUG] AgentApp found - ID: %d, DeveloperID: %d\n", agentApp.ID, agentApp.DeveloperID) var cardTypePerm *model.AgentApplicationCardType for _, ct := range agentApp.CardTypes { if ct.CardTypeID == req.CardTypeID { cardTypePerm = &ct break } } if cardTypePerm == nil || !cardTypePerm.CanGenerate { fmt.Printf("[DEBUG] No permission to generate this card type\n") response.Error(c, 403, "您没有权限生成此卡密类型") return } var agentUser model.User if err := database.DB.First(&agentUser, userID).Error; err != nil { response.Error(c, 500, "获取代理信息失败") return } totalCost := float64(req.Count) * cardType.Price fmt.Printf("[DEBUG] Total cost: %f, Balance: %f\n", totalCost, agentUser.Balance) if agentUser.Balance < totalCost { fmt.Printf("[DEBUG] Insufficient balance\n") response.Error(c, 400, "余额不足") return } if err := database.DB.Model(&agentUser).Update("balance", agentUser.Balance-totalCost).Error; err != nil { fmt.Printf("[DEBUG] Update balance error: %v\n", err) response.Error(c, 500, "扣款失败") return } fmt.Printf("[DEBUG] Balance updated successfully\n") } cards := make([]model.Card, 0, req.Count) for i := 0; i < req.Count; i++ { cardKey := req.Prefix + utils.GenerateRandomString(req.Length) card := model.Card{ ApplicationID: req.ApplicationID, CardTypeID: req.CardTypeID, CardKey: cardKey, CreatorID: effectiveUserID, Status: "unused", } cards = append(cards, card) } fmt.Printf("[DEBUG] Generated %d cards, saving to database...\n", len(cards)) if err := database.DB.Create(&cards).Error; err != nil { fmt.Printf("[DEBUG] Database create error: %v\n", err) response.Error(c, 500, "生成卡密失败") return } fmt.Printf("[DEBUG] Successfully created %d cards\n", len(cards)) response.Success(c, gin.H{ "message": "批量生成成功", "count": req.Count, }) } func handleExportCards(c *gin.Context) { userID := c.GetUint("user_id") applicationID := c.Query("application_id") cardTypeID := c.Query("card_type_id") status := c.Query("status") search := c.Query("search") startDate := c.Query("start_date") endDate := c.Query("end_date") var cards []model.Card query := database.DB.Model(&model.Card{}). Joins("JOIN card_types ON cards.card_type_id = card_types.id"). Joins("JOIN applications ON card_types.application_id = applications.id"). Preload("Application"). Preload("CardType"). Where("applications.user_id = ?", userID) if applicationID != "" { appID, err := strconv.ParseUint(applicationID, 10, 32) if err == nil { query = query.Where("cards.application_id = ?", uint(appID)) } } if cardTypeID != "" { ctID, err := strconv.ParseUint(cardTypeID, 10, 32) if err == nil { query = query.Where("cards.card_type_id = ?", uint(ctID)) } } if status != "" { query = query.Where("cards.status = ?", status) } if search != "" { searchPattern := "%" + search + "%" query = query.Where("cards.card_key LIKE ? OR card_types.name LIKE ? OR applications.name LIKE ?", searchPattern, searchPattern, searchPattern) } if startDate != "" { query = query.Where("cards.created_at >= ?", startDate+" 00:00:00") } if endDate != "" { query = query.Where("cards.created_at <= ?", endDate+" 23:59:59") } if err := query.Order("cards.created_at DESC").Find(&cards).Error; err != nil { response.Error(c, 500, "导出卡密失败") return } c.Header("Content-Type", "text/csv; charset=utf-8") c.Header("Content-Disposition", "attachment; filename=cards_export.csv") csv := "卡密,应用,卡类,状态,创建时间,使用时间\n" for _, card := range cards { statusMap := map[string]string{ "unused": "未使用", "used": "已使用", "banned": "已禁用", } statusText := statusMap[card.Status] if statusText == "" { statusText = card.Status } appName := "" if card.Application != nil { appName = card.Application.Name } cardTypeName := card.CardType.Name usedAt := "" if card.UsedAt != nil { usedAt = card.UsedAt.Format("2006-01-02 15:04:05") } csv += fmt.Sprintf("%s,%s,%s,%s,%s,%s\n", card.CardKey, appName, cardTypeName, statusText, card.CreatedAt.Format("2006-01-02 15:04:05"), usedAt, ) } c.String(200, csv) } func handleUpdateCardStatus(c *gin.Context) { userID := c.GetUint("user_id") id := c.Param("id") var req struct { Status string `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } if req.Status != "unused" && req.Status != "used" && req.Status != "banned" { response.Error(c, 400, "无效的状态") return } var card model.Card if err := database.DB.Preload("CardType").Preload("CardType.Application").First(&card, id).Error; err != nil { response.Error(c, 404, "卡密不存在") return } if card.CreatorID != userID && (card.CardType.Application == nil || card.CardType.Application.UserID != userID) { response.Error(c, 403, "无权限修改此卡密") return } card.Status = req.Status if err := database.DB.Save(&card).Error; err != nil { response.Error(c, 500, "更新状态失败") return } response.Success(c, card) } func handleBatchUpdateCardStatus(c *gin.Context) { userID := c.GetUint("user_id") var req struct { IDs []uint `json:"ids"` Status string `json:"status"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } if req.Status != "unused" && req.Status != "used" && req.Status != "banned" { response.Error(c, 400, "无效的状态") return } if len(req.IDs) == 0 { response.Error(c, 400, "请选择要更新的卡密") return } var cards []model.Card if err := database.DB.Preload("CardType").Preload("CardType.Application").Where("id IN ?", req.IDs).Find(&cards).Error; err != nil { response.Error(c, 500, "查询卡密失败") return } var validIDs []uint for _, card := range cards { if card.CreatorID == userID || (card.CardType.Application != nil && card.CardType.Application.UserID == userID) { validIDs = append(validIDs, card.ID) } } if len(validIDs) == 0 { response.Error(c, 403, "无权限修改选中的卡密") return } if err := database.DB.Model(&model.Card{}).Where("id IN ?", validIDs).Update("status", req.Status).Error; err != nil { response.Error(c, 500, "批量更新状态失败") return } response.Success(c, gin.H{"updated_count": len(validIDs)}) } func handleBatchDeleteCards(c *gin.Context) { userID := c.GetUint("user_id") var req struct { IDs []uint `json:"ids"` } if err := c.ShouldBindJSON(&req); err != nil { response.Error(c, 400, "参数错误") return } if len(req.IDs) == 0 { response.Error(c, 400, "请选择要删除的卡密") return } var cards []model.Card if err := database.DB.Preload("CardType").Preload("CardType.Application").Where("id IN ?", req.IDs).Find(&cards).Error; err != nil { response.Error(c, 500, "查询卡密失败") return } var validIDs []uint for _, card := range cards { if card.CreatorID == userID || (card.CardType.Application != nil && card.CardType.Application.UserID == userID) { validIDs = append(validIDs, card.ID) } } if len(validIDs) == 0 { response.Error(c, 403, "无权限删除选中的卡密") return } if err := database.DB.Where("id IN ?", validIDs).Delete(&model.Card{}).Error; err != nil { response.Error(c, 500, "批量删除失败") return } response.Success(c, gin.H{"deleted_count": len(validIDs)}) }