修复代理商卡密管理页面:增加服务端筛选、批量导出、复制功能
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user