修复代理商卡密管理页面:增加服务端筛选、批量导出、复制功能

This commit is contained in:
2026-05-10 04:27:55 +08:00
parent 7a6cc2c698
commit c495f9b417
10 changed files with 507 additions and 52 deletions
+186 -6
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"math/rand"
"strconv"
"strings"
"time"
"verification-platform-backend/internal/database"
"verification-platform-backend/internal/model"
@@ -22,6 +23,7 @@ func SetupAgentRoutes(r *gin.RouterGroup) {
r.GET("/finance", handleGetFinance)
r.GET("/profile", handleGetProfile)
r.PUT("/profile", handleUpdateProfile)
r.GET("/cards/export", handleExportCards)
}
func handleGetStats(c *gin.Context) {
@@ -157,10 +159,65 @@ func handleGetCards(c *gin.Context) {
page := c.DefaultQuery("page", "1")
pageSize := c.DefaultQuery("page_size", "20")
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")
baseCondition := "agent_id = ? OR (agent_id IS NULL AND creator_id = ?)"
// 统计总数:包括 agent_id 或 creator_id 等于当前户的卡密
var total int64
database.DB.Model(&model.Card{}).Where("agent_id = ? OR (agent_id IS NULL AND creator_id = ?)", userID, userID).Count(&total)
database.DB.Model(&model.Card{}).Where(baseCondition, userID, userID).Count(&total)
var unusedCount int64
database.DB.Model(&model.Card{}).Where("("+baseCondition+") AND status = ?", userID, userID, "unused").Count(&unusedCount)
var usedCount int64
database.DB.Model(&model.Card{}).Where("("+baseCondition+") AND status = ?", userID, userID, "used").Count(&usedCount)
var expiredCount int64
database.DB.Model(&model.Card{}).Where("("+baseCondition+") AND status = ?", userID, userID, "expired").Count(&expiredCount)
var disabledCount int64
database.DB.Model(&model.Card{}).Where("("+baseCondition+") AND status = ?", userID, userID, "disabled").Count(&disabledCount)
query := database.DB.Model(&model.Card{}).Where(baseCondition, userID, userID)
if applicationID != "" {
appID, err := strconv.ParseUint(applicationID, 10, 32)
if err == nil {
query = query.Where("application_id = ?", uint(appID))
}
}
if cardTypeID != "" {
ctID, err := strconv.ParseUint(cardTypeID, 10, 32)
if err == nil {
query = query.Where("card_type_id = ?", uint(ctID))
}
}
if status != "" {
query = query.Where("status = ?", status)
}
if search != "" {
searchPattern := "%" + search + "%"
query = query.Where("card_key LIKE ?", searchPattern)
}
if startDate != "" {
query = query.Where("created_at >= ?", startDate+" 00:00:00")
}
if endDate != "" {
query = query.Where("created_at <= ?", endDate+" 23:59:59")
}
var filteredTotal int64
query.Count(&filteredTotal)
var cards []model.Card
offset := 0
@@ -173,8 +230,7 @@ func handleGetCards(c *gin.Context) {
limit = pageSizeInt
}
// 查询卡密:包括 agent_id 或 creator_id 等于当前用户的卡密
database.DB.Where("agent_id = ? OR (agent_id IS NULL AND creator_id = ?)", userID, userID).Order("created_at DESC").Limit(limit).Offset(offset).Find(&cards)
query.Order("created_at DESC").Limit(limit).Offset(offset).Find(&cards)
// 获取关联数据
cardTypeIDs := make([]uint, 0)
@@ -220,8 +276,13 @@ func handleGetCards(c *gin.Context) {
}
response.Success(c, gin.H{
"cards": cardList,
"total": total,
"cards": cardList,
"total": total,
"filtered_total": filteredTotal,
"unused_count": unusedCount,
"used_count": usedCount,
"expired_count": expiredCount,
"disabled_count": disabledCount,
})
}
@@ -451,3 +512,122 @@ func handleUpdateProfile(c *gin.Context) {
response.Success(c, nil)
}
func handleExportCards(c *gin.Context) {
userID := c.GetUint("user_id")
token := c.Query("token")
if token == "" {
response.Error(c, 401, "未授权")
return
}
baseCondition := "agent_id = ? OR (agent_id IS NULL AND creator_id = ?)"
query := database.DB.Model(&model.Card{}).Where(baseCondition, userID, userID)
if applicationID := c.Query("application_id"); applicationID != "" {
appID, err := strconv.ParseUint(applicationID, 10, 32)
if err == nil {
query = query.Where("application_id = ?", uint(appID))
}
}
if cardTypeID := c.Query("card_type_id"); cardTypeID != "" {
ctID, err := strconv.ParseUint(cardTypeID, 10, 32)
if err == nil {
query = query.Where("card_type_id = ?", uint(ctID))
}
}
if status := c.Query("status"); status != "" {
query = query.Where("status = ?", status)
}
if startDate := c.Query("start_date"); startDate != "" {
query = query.Where("created_at >= ?", startDate+" 00:00:00")
}
if endDate := c.Query("end_date"); endDate != "" {
query = query.Where("created_at <= ?", endDate+" 23:59:59")
}
if ids := c.Query("ids"); ids != "" {
idList := []uint{}
for _, idStr := range splitIDs(ids) {
if id, err := strconv.ParseUint(idStr, 10, 32); err == nil {
idList = append(idList, uint(id))
}
}
if len(idList) > 0 {
query = database.DB.Model(&model.Card{}).Where("id IN ? AND ("+baseCondition+")", idList, userID, userID)
}
}
var cards []model.Card
query.Order("created_at DESC").Find(&cards)
cardTypeIDs := make([]uint, 0)
appIDs := make([]uint, 0)
for _, card := range cards {
cardTypeIDs = append(cardTypeIDs, card.CardTypeID)
appIDs = append(appIDs, card.ApplicationID)
}
cardTypeMap := make(map[uint]model.CardType)
if len(cardTypeIDs) > 0 {
var cardTypes []model.CardType
database.DB.Where("id IN ?", cardTypeIDs).Find(&cardTypes)
for _, ct := range cardTypes {
cardTypeMap[ct.ID] = ct
}
}
appMap := make(map[uint]model.Application)
if len(appIDs) > 0 {
var apps []model.Application
database.DB.Where("id IN ?", appIDs).Find(&apps)
for _, app := range apps {
appMap[app.ID] = app
}
}
c.Header("Content-Type", "text/csv; charset=utf-8")
c.Header("Content-Disposition", "attachment; filename=cards_export.csv")
c.Writer.Write([]byte("\xEF\xBB\xBF"))
c.Writer.Write([]byte("卡号,应用,卡类,状态,创建时间,使用时间\n"))
for _, card := range cards {
ct := cardTypeMap[card.CardTypeID]
app := appMap[card.ApplicationID]
statusMap := map[string]string{"unused": "未使用", "used": "已使用", "expired": "已过期", "disabled": "已禁用"}
statusText := statusMap[card.Status]
if statusText == "" {
statusText = card.Status
}
usedAt := ""
if card.UsedAt != nil {
usedAt = card.UsedAt.Format("2006-01-02 15:04:05")
}
line := fmt.Sprintf("%s,%s,%s,%s,%s,%s\n",
card.CardKey,
app.Name,
ct.Name,
statusText,
card.CreatedAt.Format("2006-01-02 15:04:05"),
usedAt,
)
c.Writer.Write([]byte(line))
}
}
func splitIDs(ids string) []string {
result := []string{}
for _, id := range strings.Split(ids, ",") {
id = strings.TrimSpace(id)
if id != "" {
result = append(result, id)
}
}
return result
}