Files
goalfylearning-admin/internal/storage/user_feedback_storage.go

189 lines
5.2 KiB
Go

package storage
import (
"context"
"fmt"
"goalfymax-admin/internal/models"
"time"
"gorm.io/gorm"
)
// UserFeedbackStorage 用户反馈存储层
type UserFeedbackStorage struct {
db *gorm.DB
}
// NewUserFeedbackStorage 创建用户反馈存储实例
func NewUserFeedbackStorage() *UserFeedbackStorage {
return &UserFeedbackStorage{db: DB}
}
// List 获取用户反馈列表
func (s *UserFeedbackStorage) List(ctx context.Context, req *models.UserFeedbackListRequest) ([]models.UserFeedback, int64, error) {
var feedbacks []models.UserFeedback
var total int64
query := s.db.WithContext(ctx).Model(&models.UserFeedback{})
// 状态筛选
if req.Status != nil {
query = query.Where("status = ?", *req.Status)
}
// 用户ID筛选
if req.UserID != nil {
query = query.Where("uid = ?", *req.UserID)
}
// 关键词搜索
if req.Keyword != "" {
query = query.Where("content LIKE ?", "%"+req.Keyword+"%")
}
// 时间范围筛选
if req.StartTime != "" {
if startTime, err := time.Parse("2006-01-02 15:04:05", req.StartTime); err == nil {
query = query.Where("created_at >= ?", startTime)
}
}
if req.EndTime != "" {
if endTime, err := time.Parse("2006-01-02 15:04:05", req.EndTime); err == nil {
query = query.Where("created_at <= ?", endTime)
}
}
// 获取总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("获取反馈总数失败: %w", err)
}
// 分页查询
offset := (req.Page - 1) * req.PageSize
if err := query.Order("created_at DESC").
Offset(offset).
Limit(req.PageSize).
Find(&feedbacks).Error; err != nil {
return nil, 0, fmt.Errorf("获取反馈列表失败: %w", err)
}
return feedbacks, total, nil
}
// GetByID 根据ID获取用户反馈
func (s *UserFeedbackStorage) GetByID(ctx context.Context, id int64) (*models.UserFeedback, error) {
var feedback models.UserFeedback
if err := s.db.WithContext(ctx).Where("id = ?", id).First(&feedback).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, nil
}
return nil, fmt.Errorf("获取用户反馈失败: %w", err)
}
return &feedback, nil
}
// MarkHandled 标记为已处理或未处理(切换状态)
func (s *UserFeedbackStorage) MarkHandled(ctx context.Context, id int64, handledBy int, note string) error {
// 先获取当前状态
feedback, err := s.GetByID(ctx, id)
if err != nil {
return fmt.Errorf("获取反馈信息失败: %w", err)
}
if feedback == nil {
return fmt.Errorf("反馈不存在")
}
// 切换状态:如果当前是已处理(1),则改为未处理(0);如果当前是未处理(0),则改为已处理(1)
newStatus := 0
var updates map[string]interface{}
if feedback.Status == 0 {
// 从未处理改为已处理
newStatus = 1
now := time.Now()
updates = map[string]interface{}{
"status": newStatus,
"handled_by": handledBy,
"handled_at": now,
}
} else {
// 从已处理改为未处理
newStatus = 0
updates = map[string]interface{}{
"status": newStatus,
"handled_by": nil,
"handled_at": nil,
}
}
result := s.db.WithContext(ctx).Model(&models.UserFeedback{}).
Where("id = ?", id).
Updates(updates)
if result.Error != nil {
return fmt.Errorf("切换状态失败: %w", result.Error)
}
if result.RowsAffected == 0 {
return fmt.Errorf("切换状态失败")
}
return nil
}
// Delete 删除用户反馈
func (s *UserFeedbackStorage) Delete(ctx context.Context, id int64) error {
if err := s.db.WithContext(ctx).Where("id = ?", id).Delete(&models.UserFeedback{}).Error; err != nil {
return fmt.Errorf("删除用户反馈失败: %w", err)
}
return nil
}
// Create 创建用户反馈(如果需要)
func (s *UserFeedbackStorage) Create(ctx context.Context, feedback *models.UserFeedback) error {
if err := s.db.WithContext(ctx).Create(feedback).Error; err != nil {
return fmt.Errorf("创建用户反馈失败: %w", err)
}
return nil
}
// GetStatistics 获取反馈统计信息
func (s *UserFeedbackStorage) GetStatistics(ctx context.Context) (map[string]interface{}, error) {
var stats struct {
Total int64 `json:"total"`
Unhandled int64 `json:"unhandled"`
Handled int64 `json:"handled"`
TodayCount int64 `json:"today_count"`
}
// 总数
if err := s.db.WithContext(ctx).Model(&models.UserFeedback{}).Count(&stats.Total).Error; err != nil {
return nil, fmt.Errorf("获取总数失败: %w", err)
}
// 未处理数
if err := s.db.WithContext(ctx).Model(&models.UserFeedback{}).Where("status = 0").Count(&stats.Unhandled).Error; err != nil {
return nil, fmt.Errorf("获取未处理数失败: %w", err)
}
// 已处理数
if err := s.db.WithContext(ctx).Model(&models.UserFeedback{}).Where("status = 1").Count(&stats.Handled).Error; err != nil {
return nil, fmt.Errorf("获取已处理数失败: %w", err)
}
// 今日新增
today := time.Now().Format("2006-01-02")
if err := s.db.WithContext(ctx).Model(&models.UserFeedback{}).
Where("DATE(created_at) = ?", today).
Count(&stats.TodayCount).Error; err != nil {
return nil, fmt.Errorf("获取今日新增数失败: %w", err)
}
return map[string]interface{}{
"total": stats.Total,
"unhandled": stats.Unhandled,
"handled": stats.Handled,
"today_count": stats.TodayCount,
}, nil
}