From ba7b6015eb6d9abce981aa1af2a8994e97ec25b3 Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 10 May 2026 04:44:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E5=8D=A1=E5=AF=86=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E7=BB=9F?= =?UTF-8?q?=E8=AE=A1=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=E4=B8=8D=E5=87=86?= =?UTF-8?q?=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/router/admin/cards.go | 36 ++++++++++++++++++++---- frontend/src/pages/admin/cards/index.vue | 11 +++++--- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/backend/internal/router/admin/cards.go b/backend/internal/router/admin/cards.go index 5ec43cf..c5c1654 100644 --- a/backend/internal/router/admin/cards.go +++ b/backend/internal/router/admin/cards.go @@ -446,6 +446,28 @@ func handleGetCards(c *gin.Context) { var total int64 query.Count(&total) + baseQuery := 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") + + if len(authorizedAppIDs) > 0 { + baseQuery = baseQuery.Where("applications.user_id = ? OR (cards.application_id IN ? AND cards.creator_id = ?)", userID, authorizedAppIDs, userID) + } else { + baseQuery = baseQuery.Where("applications.user_id = ?", userID) + } + + var unusedCount int64 + baseQuery.Where("cards.status = ?", "unused").Count(&unusedCount) + + var usedCount int64 + baseQuery.Where("cards.status = ?", "used").Count(&usedCount) + + var bannedCount int64 + baseQuery.Where("cards.status = ?", "banned").Count(&bannedCount) + + var expiredCount int64 + baseQuery.Where("cards.status = ?", "expired").Count(&expiredCount) + page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20")) offset := (page - 1) * pageSize @@ -459,11 +481,15 @@ func handleGetCards(c *gin.Context) { fmt.Printf("[DEBUG] Found %d cards for user %d\n", len(cards), userID) response.Success(c, gin.H{ - "cards": cards, - "total": total, - "page": page, - "page_size": pageSize, - "total_page": (total + int64(pageSize) - 1) / int64(pageSize), + "cards": cards, + "total": total, + "page": page, + "page_size": pageSize, + "total_page": (total + int64(pageSize) - 1) / int64(pageSize), + "unused_count": unusedCount, + "used_count": usedCount, + "banned_count": bannedCount, + "expired_count": expiredCount, }) } diff --git a/frontend/src/pages/admin/cards/index.vue b/frontend/src/pages/admin/cards/index.vue index 71b67c1..15ac11f 100644 --- a/frontend/src/pages/admin/cards/index.vue +++ b/frontend/src/pages/admin/cards/index.vue @@ -59,9 +59,9 @@ const filteredCardTypes = computed(() => { return cardTypes.value }) -const unusedCount = computed(() => cards.value.filter(card => card.status === 'unused').length) -const usedCount = computed(() => cards.value.filter(card => card.status === 'used').length) -const bannedCount = computed(() => cards.value.filter(card => card.status === 'banned').length) +const unusedCount = ref(0) +const usedCount = ref(0) +const bannedCount = ref(0) const applicationOptions = computed(() => { return applications.value.map(app => ({ @@ -132,9 +132,12 @@ async function fetchCards() { params.append('search', searchFilter.value.trim()) } - const data = await api.get<{ cards: Card[], total: number }>(`/dev/cards?${params.toString()}`) + const data = await api.get(`/dev/cards?${params.toString()}`) cards.value = data?.cards || [] total.value = data?.total || 0 + unusedCount.value = data?.unused_count || 0 + usedCount.value = data?.used_count || 0 + bannedCount.value = data?.banned_count || 0 } catch (error) { console.error('获取卡密列表失败:', error)