Files
backend/internal/repository/report_repository.go
2026-01-21 22:04:12 +08:00

226 lines
6.4 KiB
Go

package repository
import (
"carrotskin/internal/model"
"context"
"errors"
"time"
"gorm.io/gorm"
)
// reportRepository 举报仓储实现
type reportRepository struct {
db *gorm.DB
}
// NewReportRepository 创建举报仓储实例
func NewReportRepository(db *gorm.DB) ReportRepository {
return &reportRepository{db: db}
}
// Create 创建举报记录
func (r *reportRepository) Create(ctx context.Context, report *model.Report) error {
return r.db.WithContext(ctx).Create(report).Error
}
// FindByID 根据ID查找举报记录
func (r *reportRepository) FindByID(ctx context.Context, id int64) (*model.Report, error) {
var report model.Report
err := r.db.WithContext(ctx).Preload("Reporter").Preload("Reviewer").First(&report, id).Error
if err != nil {
return nil, err
}
return &report, nil
}
// FindByReporterID 根据举报人ID查找举报记录
func (r *reportRepository) FindByReporterID(ctx context.Context, reporterID int64, page, pageSize int) ([]*model.Report, int64, error) {
var reports []*model.Report
var total int64
offset := (page - 1) * pageSize
// 查询总数
if err := r.db.WithContext(ctx).Model(&model.Report{}).Where("reporter_id = ?", reporterID).Count(&total).Error; err != nil {
return nil, 0, err
}
// 查询数据
err := r.db.WithContext(ctx).
Preload("Reporter").
Preload("Reviewer").
Where("reporter_id = ?", reporterID).
Order("created_at DESC").
Limit(pageSize).
Offset(offset).
Find(&reports).Error
return reports, total, err
}
// FindByTarget 根据目标对象查找举报记录
func (r *reportRepository) FindByTarget(ctx context.Context, targetType model.ReportType, targetID int64, page, pageSize int) ([]*model.Report, int64, error) {
var reports []*model.Report
var total int64
offset := (page - 1) * pageSize
// 查询总数
if err := r.db.WithContext(ctx).Model(&model.Report{}).Where("target_type = ? AND target_id = ?", targetType, targetID).Count(&total).Error; err != nil {
return nil, 0, err
}
// 查询数据
err := r.db.WithContext(ctx).
Preload("Reporter").
Preload("Reviewer").
Where("target_type = ? AND target_id = ?", targetType, targetID).
Order("created_at DESC").
Limit(pageSize).
Offset(offset).
Find(&reports).Error
return reports, total, err
}
// FindByStatus 根据状态查找举报记录
func (r *reportRepository) FindByStatus(ctx context.Context, status model.ReportStatus, page, pageSize int) ([]*model.Report, int64, error) {
var reports []*model.Report
var total int64
offset := (page - 1) * pageSize
// 查询总数
if err := r.db.WithContext(ctx).Model(&model.Report{}).Where("status = ?", status).Count(&total).Error; err != nil {
return nil, 0, err
}
// 查询数据
err := r.db.WithContext(ctx).
Preload("Reporter").
Preload("Reviewer").
Where("status = ?", status).
Order("created_at DESC").
Limit(pageSize).
Offset(offset).
Find(&reports).Error
return reports, total, err
}
// Search 搜索举报记录
func (r *reportRepository) Search(ctx context.Context, keyword string, page, pageSize int) ([]*model.Report, int64, error) {
var reports []*model.Report
var total int64
offset := (page - 1) * pageSize
query := r.db.WithContext(ctx).Model(&model.Report{}).Where("reason LIKE ?", "%"+keyword+"%")
// 查询总数
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
// 查询数据
err := query.
Preload("Reporter").
Preload("Reviewer").
Order("created_at DESC").
Limit(pageSize).
Offset(offset).
Find(&reports).Error
return reports, total, err
}
// Update 更新举报记录
func (r *reportRepository) Update(ctx context.Context, report *model.Report) error {
return r.db.WithContext(ctx).Save(report).Error
}
// UpdateFields 更新举报记录的指定字段
func (r *reportRepository) UpdateFields(ctx context.Context, id int64, fields map[string]interface{}) error {
return r.db.WithContext(ctx).Model(&model.Report{}).Where("id = ?", id).Updates(fields).Error
}
// Review 处理举报记录
func (r *reportRepository) Review(ctx context.Context, id int64, status model.ReportStatus, reviewerID int64, reviewNote string) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
var report model.Report
if err := tx.First(&report, id).Error; err != nil {
return err
}
// 检查状态是否已被处理
if report.Status != model.ReportStatusPending {
return errors.New("report has already been reviewed")
}
// 更新举报状态
now := time.Now()
updates := map[string]interface{}{
"status": status,
"reviewer_id": reviewerID,
"review_note": reviewNote,
"reviewed_at": &now,
}
return tx.Model(&report).Updates(updates).Error
})
}
// BatchReview 批量处理举报记录
func (r *reportRepository) BatchReview(ctx context.Context, ids []int64, status model.ReportStatus, reviewerID int64, reviewNote string) (int64, error) {
var affected int64
err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
now := time.Now()
result := tx.Model(&model.Report{}).
Where("id IN ? AND status = ?", ids, model.ReportStatusPending).
Updates(map[string]interface{}{
"status": status,
"reviewer_id": reviewerID,
"review_note": reviewNote,
"reviewed_at": &now,
})
if result.Error != nil {
return result.Error
}
affected = result.RowsAffected
return nil
})
return affected, err
}
// Delete 删除举报记录
func (r *reportRepository) Delete(ctx context.Context, id int64) error {
return r.db.WithContext(ctx).Delete(&model.Report{}, id).Error
}
// BatchDelete 批量删除举报记录
func (r *reportRepository) BatchDelete(ctx context.Context, ids []int64) (int64, error) {
result := r.db.WithContext(ctx).Delete(&model.Report{}, ids)
return result.RowsAffected, result.Error
}
// CountByStatus 根据状态统计举报数量
func (r *reportRepository) CountByStatus(ctx context.Context, status model.ReportStatus) (int64, error) {
var count int64
err := r.db.WithContext(ctx).Model(&model.Report{}).Where("status = ?", status).Count(&count).Error
return count, err
}
// CheckDuplicate 检查是否重复举报
func (r *reportRepository) CheckDuplicate(ctx context.Context, reporterID int64, targetType model.ReportType, targetID int64) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&model.Report{}).
Where("reporter_id = ? AND target_type = ? AND target_id = ? AND status = ?",
reporterID, targetType, targetID, model.ReportStatusPending).
Count(&count).Error
return count > 0, err
}