Files
goalfylearning-admin/internal/storage/message_push_storage.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
}