修复二维码库存与过期时间编辑

This commit is contained in:
yml
2026-06-17 20:02:41 +08:00
parent 12f589f0df
commit ac98841992
7 changed files with 286 additions and 95 deletions
@@ -58,11 +58,11 @@ func (h *Handler) ListQrCodesHandler(c *gin.Context) {
}
c.JSON(http.StatusOK, gin.H{
"data": qrcodes,
"pagination": gin.H{
"total": total,
"page": req.Page,
"limit": req.Limit,
"data": PaginatedResult{
Items: qrcodes,
Total: total,
Page: req.Page,
PageSize: req.Limit,
},
})
}
@@ -12,8 +12,8 @@ import (
// 会话类型常量
const (
ConversationTypeOrderGroup = "order_group"
ConversationTypeListingGroup = "listing_group"
ConversationTypeOrderGroup = "order_group"
ConversationTypeListingGroup = "listing_group"
ConversationTypeGeneralSupport = "general_support"
)
@@ -297,6 +297,7 @@ func checkQrCodeStockAndAlert(tx *gorm.DB, conversation *model.ChatConversation)
var count int64
if err := tx.Model(&model.ChatQrCode{}).
Where("status = ?", QrCodeStatusUnused).
Where("expires_at IS NULL OR expires_at > ?", time.Now()).
Count(&count).Error; err != nil {
return err
}
@@ -319,6 +320,7 @@ func checkQrCodeStockAndAlert(tx *gorm.DB, conversation *model.ChatConversation)
// 发送站内信给所有客服
var entries []interface{}
now := time.Now()
for _, admin := range csAdmins {
entries = append(entries, map[string]interface{}{
"admin_user_id": admin.ID,
@@ -326,13 +328,13 @@ func checkQrCodeStockAndAlert(tx *gorm.DB, conversation *model.ChatConversation)
"title": "二维码库存预警",
"content": alertContent,
"is_read": false,
"created_at": time.Now(),
"updated_at": time.Now(),
"created_at": now,
"updated_at": now,
})
}
if len(entries) > 0 {
// 批量插入通知
// 批量插入管理员通知
if err := tx.Table("admin_notifications").Create(entries).Error; err != nil {
return err
}
+30 -26
View File
@@ -36,9 +36,11 @@ type BatchCreateQrCodeRequest struct {
// UpdateQrCodeRequest 更新二维码请求
type UpdateQrCodeRequest struct {
Note *string `json:"note"`
Status *string `json:"status"`
ExpiresAt *time.Time `json:"expires_at"`
ImageURL *string `json:"image_url"`
Note *string `json:"note"`
Status *string `json:"status"`
ExpiresAt *time.Time `json:"expires_at"`
ClearExpiresAt bool `json:"clear_expires_at"`
}
// QrCodeListRequest 列表查询请求
@@ -140,32 +142,29 @@ func (r *Repository) ListQrCodes(ctx context.Context, req QrCodeListRequest) ([]
// GetQrCodeStats 获取二维码统计信息
func (r *Repository) GetQrCodeStats(ctx context.Context) (*QrCodeStats, error) {
stats := &QrCodeStats{}
now := time.Now()
// 统计各状态数量
type CountResult struct {
Status string
Count int64
}
var results []CountResult
if err := r.db.WithContext(ctx).
Model(&model.ChatQrCode{}).
Select("status, COUNT(*) as count").
Group("status").
Find(&results).Error; err != nil {
if err := r.db.WithContext(ctx).Model(&model.ChatQrCode{}).Count(&stats.TotalCount).Error; err != nil {
return nil, err
}
for _, r := range results {
stats.TotalCount += r.Count
switch r.Status {
case QrCodeStatusUnused:
stats.UnusedCount = r.Count
case QrCodeStatusUsed:
stats.UsedCount = r.Count
case QrCodeStatusDisabled:
stats.DisabledCount = r.Count
}
if err := r.db.WithContext(ctx).
Model(&model.ChatQrCode{}).
Where("status = ?", QrCodeStatusUsed).
Count(&stats.UsedCount).Error; err != nil {
return nil, err
}
if err := r.db.WithContext(ctx).
Model(&model.ChatQrCode{}).
Where("status = ?", QrCodeStatusDisabled).
Count(&stats.DisabledCount).Error; err != nil {
return nil, err
}
if err := r.db.WithContext(ctx).
Model(&model.ChatQrCode{}).
Where("status = ?", QrCodeStatusUnused).
Where("expires_at IS NULL OR expires_at > ?", now).
Count(&stats.UnusedCount).Error; err != nil {
return nil, err
}
return stats, nil
@@ -175,6 +174,9 @@ func (r *Repository) GetQrCodeStats(ctx context.Context) (*QrCodeStats, error) {
func (r *Repository) UpdateQrCode(ctx context.Context, id uint64, req UpdateQrCodeRequest) error {
updates := make(map[string]interface{})
if req.ImageURL != nil {
updates["image_url"] = *req.ImageURL
}
if req.Note != nil {
updates["note"] = *req.Note
}
@@ -187,6 +189,8 @@ func (r *Repository) UpdateQrCode(ctx context.Context, id uint64, req UpdateQrCo
}
if req.ExpiresAt != nil {
updates["expires_at"] = req.ExpiresAt
} else if req.ClearExpiresAt {
updates["expires_at"] = nil
}
if len(updates) == 0 {
@@ -113,7 +113,7 @@ func TestRepositoryUpdateAllowsOfflineListingResubmit(t *testing.T) {
if err := db.AutoMigrate(&model.GameAccount{}, &model.RentalListing{}); err != nil {
t.Fatalf("failed to migrate test db: %v", err)
}
repo := NewRepository(db)
repo := NewRepository(db, nil)
req := CreateRequest{
Title: "测试账号",
ServerRegion: "QQ",