155 lines
4.7 KiB
Go
155 lines
4.7 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"goalfymax-admin/internal/models"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// MessagePushStorage 消息推送存储接口
|
|
type MessagePushStorage interface {
|
|
Create(ctx context.Context, log *models.MessagePushLog) error
|
|
List(ctx context.Context, req *models.MessagePushListRequest) ([]models.MessagePushLog, int64, error)
|
|
GetByID(ctx context.Context, id int64) (*models.MessagePushLog, error)
|
|
UpdateStatus(ctx context.Context, id int64, status int, successCount, failCount int, errorMessage string) error
|
|
SearchUsers(ctx context.Context, keyword string, limit int) ([]models.UserSearchItem, error)
|
|
}
|
|
|
|
type messagePushStorage struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
// NewMessagePushStorage 创建消息推送存储实例
|
|
func NewMessagePushStorage() MessagePushStorage {
|
|
return &messagePushStorage{db: DB}
|
|
}
|
|
|
|
// Create 创建推送记录
|
|
func (s *messagePushStorage) Create(ctx context.Context, log *models.MessagePushLog) error {
|
|
if err := s.db.WithContext(ctx).Create(log).Error; err != nil {
|
|
return fmt.Errorf("创建推送记录失败: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// List 获取推送记录列表
|
|
func (s *messagePushStorage) List(ctx context.Context, req *models.MessagePushListRequest) ([]models.MessagePushLog, int64, error) {
|
|
var logs []models.MessagePushLog
|
|
var total int64
|
|
|
|
query := s.db.WithContext(ctx).Model(&models.MessagePushLog{})
|
|
|
|
if req.Status != nil {
|
|
query = query.Where("status = ?", *req.Status)
|
|
}
|
|
if req.SenderID != nil {
|
|
query = query.Where("sender_id = ?", *req.SenderID)
|
|
}
|
|
if req.StartTime != "" {
|
|
query = query.Where("created_at >= ?", req.StartTime)
|
|
}
|
|
if req.EndTime != "" {
|
|
query = query.Where("created_at <= ?", req.EndTime)
|
|
}
|
|
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("查询总数失败: %w", err)
|
|
}
|
|
|
|
if req.Page > 0 && req.PageSize > 0 {
|
|
offset := (req.Page - 1) * req.PageSize
|
|
query = query.Offset(offset).Limit(req.PageSize)
|
|
}
|
|
|
|
if err := query.Order("created_at DESC").Find(&logs).Error; err != nil {
|
|
return nil, 0, fmt.Errorf("查询推送记录失败: %w", err)
|
|
}
|
|
|
|
return logs, total, nil
|
|
}
|
|
|
|
// GetByID 根据ID获取推送记录
|
|
func (s *messagePushStorage) GetByID(ctx context.Context, id int64) (*models.MessagePushLog, error) {
|
|
var log models.MessagePushLog
|
|
if err := s.db.WithContext(ctx).First(&log, id).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
return nil, fmt.Errorf("推送记录不存在")
|
|
}
|
|
return nil, fmt.Errorf("获取推送记录失败: %w", err)
|
|
}
|
|
return &log, nil
|
|
}
|
|
|
|
// UpdateStatus 更新推送状态
|
|
func (s *messagePushStorage) UpdateStatus(ctx context.Context, id int64, status int, successCount, failCount int, errorMessage string) error {
|
|
updates := map[string]interface{}{
|
|
"status": status,
|
|
"success_count": successCount,
|
|
"fail_count": failCount,
|
|
}
|
|
|
|
if errorMessage != "" {
|
|
updates["error_message"] = errorMessage
|
|
}
|
|
|
|
if status == 2 || status == 3 { // 发送成功或失败时更新发送时间
|
|
now := time.Now()
|
|
updates["sent_at"] = &now
|
|
}
|
|
|
|
if err := s.db.WithContext(ctx).Model(&models.MessagePushLog{}).Where("id = ?", id).Updates(updates).Error; err != nil {
|
|
return fmt.Errorf("更新推送状态失败: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SearchUsers 搜索用户
|
|
func (s *messagePushStorage) SearchUsers(ctx context.Context, keyword string, limit int) ([]models.UserSearchItem, error) {
|
|
var users []models.UserSearchItem
|
|
|
|
// 从admin_goalfymax_users表搜索用户
|
|
query := s.db.WithContext(ctx).Table("admin_goalfymax_users").
|
|
Select("user_id as id, username, email").
|
|
Where("deleted_at IS NULL") // 排除已删除的用户
|
|
|
|
// 如果有关键词,添加搜索条件
|
|
if keyword != "" {
|
|
query = query.Where("username LIKE ? OR email LIKE ?", "%"+keyword+"%", "%"+keyword+"%")
|
|
}
|
|
|
|
query = query.Limit(limit)
|
|
|
|
// 添加调试日志
|
|
fmt.Printf("🔍 [SearchUsers] 搜索关键词: %s, 限制: %d\n", keyword, limit)
|
|
|
|
if err := query.Find(&users).Error; err != nil {
|
|
fmt.Printf("❌ [SearchUsers] 查询失败: %v\n", err)
|
|
return nil, fmt.Errorf("搜索用户失败: %w", err)
|
|
}
|
|
|
|
fmt.Printf("✅ [SearchUsers] 找到 %d 个用户\n", len(users))
|
|
return users, nil
|
|
}
|
|
|
|
// ParseTargetUsers 解析目标用户JSON
|
|
func ParseTargetUsers(targetUsersJSON string) ([]int, error) {
|
|
var userIDs []int
|
|
if err := json.Unmarshal([]byte(targetUsersJSON), &userIDs); err != nil {
|
|
return nil, fmt.Errorf("解析目标用户失败: %w", err)
|
|
}
|
|
return userIDs, nil
|
|
}
|
|
|
|
// SerializeTargetUsers 序列化目标用户为JSON
|
|
func SerializeTargetUsers(userIDs []int) (string, error) {
|
|
jsonData, err := json.Marshal(userIDs)
|
|
if err != nil {
|
|
return "", fmt.Errorf("序列化目标用户失败: %w", err)
|
|
}
|
|
return string(jsonData), nil
|
|
}
|