Files
backend/internal/repository/report_repo.go
lan d9aa4b46c3
All checks were successful
Build Backend / build (push) Successful in 4m55s
Build Backend / build-docker (push) Successful in 10m34s
refactor(server): decouple services and improve architecture
- Introduce interfaces for all major services (JWT, PostAI, Comment, Message, Notification, QRCodeLogin, Upload, Vote, etc.) to support dependency inversion.
- Move query parameters from `internal/dto` to a new `internal/query` package to separate request payloads from data transfer objects.
- Refactor `internal/router` to use embedded `RouterDeps` for cleaner dependency management.
- Decouple handlers from repositories by injecting services instead of direct repository access, ensuring proper layering.
- Improve database initialization by moving it from `internal/model` to `internal/database`.
- Optimize message decryption by implementing a more efficient `BatchDecrypt` method in `MessageEncryptor` using a worker pool.
- Enhance error handling and security by implementing fail-fast checks for encryption key length during startup.
- Clean up unused code, including the `avatar` package and several unused DTOs.
2026-06-15 03:41:59 +08:00

213 lines
7.2 KiB
Go

package repository
import (
"context"
"with_you/internal/model"
"with_you/internal/query"
"gorm.io/gorm"
)
// ReportRepository 举报仓储接口
type ReportRepository interface {
// Create 创建举报
Create(report *model.Report) error
// CreateWithContext 使用上下文创建举报(支持事务)
CreateWithContext(ctx context.Context, report *model.Report) error
// FindByID 根据ID查询举报
FindByID(id string) (*model.Report, error)
// FindByIDWithContext 使用上下文查询举报
FindByIDWithContext(ctx context.Context, id string) (*model.Report, error)
// List 查询举报列表
List(query query.AdminReportListQuery) ([]*model.Report, int64, error)
// GetReportCount 获取内容的举报次数
GetReportCount(targetType model.ReportTargetType, targetID string) (int64, error)
// HasUserReported 检查用户是否已举报过该内容
HasUserReported(reporterID string, targetType model.ReportTargetType, targetID string) (bool, error)
// GetPendingReportsByTarget 获取目标内容的待处理举报
GetPendingReportsByTarget(targetType model.ReportTargetType, targetID string) ([]*model.Report, error)
// UpdateStatus 更新举报状态
UpdateStatus(id string, status model.ReportStatus, handledBy string, result string) error
// UpdateStatusWithContext 使用上下文更新举报状态
UpdateStatusWithContext(ctx context.Context, id string, status model.ReportStatus, handledBy string, result string) error
// BatchUpdateStatus 批量更新举报状态
BatchUpdateStatus(ids []string, status model.ReportStatus, handledBy string, result string) (int64, error)
// BatchUpdateStatusWithContext 使用上下文批量更新举报状态
BatchUpdateStatusWithContext(ctx context.Context, ids []string, status model.ReportStatus, handledBy string, result string) (int64, error)
// GetByIDsWithContext 使用上下文批量查询举报
GetByIDsWithContext(ctx context.Context, ids []string) ([]*model.Report, error)
}
// reportRepository 举报仓储实现
type reportRepository struct {
db *gorm.DB
}
// NewReportRepository 创建举报仓储
func NewReportRepository(db *gorm.DB) ReportRepository {
return &reportRepository{db: db}
}
// getDB 获取数据库实例(支持事务)
func (r *reportRepository) getDB(ctx context.Context) *gorm.DB {
if tx := GetTxFromContext(ctx); tx != nil {
return tx
}
return r.db
}
// Create 创建举报
func (r *reportRepository) Create(report *model.Report) error {
return r.db.Create(report).Error
}
// CreateWithContext 使用上下文创建举报
func (r *reportRepository) CreateWithContext(ctx context.Context, report *model.Report) error {
return r.getDB(ctx).Create(report).Error
}
// FindByID 根据ID查询举报
func (r *reportRepository) FindByID(id string) (*model.Report, error) {
var report model.Report
err := r.db.Where("id = ?", id).First(&report).Error
if err != nil {
return nil, err
}
return &report, nil
}
// FindByIDWithContext 使用上下文查询举报
func (r *reportRepository) FindByIDWithContext(ctx context.Context, id string) (*model.Report, error) {
var report model.Report
err := r.getDB(ctx).Where("id = ?", id).First(&report).Error
if err != nil {
return nil, err
}
return &report, nil
}
// List 查询举报列表
func (r *reportRepository) List(query query.AdminReportListQuery) ([]*model.Report, int64, error) {
var reports []*model.Report
var total int64
db := r.db.Model(&model.Report{})
// 筛选条件
if query.TargetType != "" {
db = db.Where("target_type = ?", query.TargetType)
}
if query.Status != "" {
db = db.Where("status = ?", query.Status)
}
if query.StartDate != "" {
db = db.Where("created_at >= ?", query.StartDate)
}
if query.EndDate != "" {
db = db.Where("created_at <= ?", query.EndDate+" 23:59:59")
}
if query.Keyword != "" {
keyword := "%" + query.Keyword + "%"
db = db.Where("description LIKE ? OR reason LIKE ?", keyword, keyword)
}
// 获取总数
if err := db.Count(&total).Error; err != nil {
return nil, 0, err
}
// 分页查询
offset := (query.Page - 1) * query.PageSize
if query.PageSize <= 0 {
query.PageSize = 20
}
if query.Page <= 0 {
query.Page = 1
}
err := db.Order("created_at DESC").
Offset(offset).
Limit(query.PageSize).
Find(&reports).Error
if err != nil {
return nil, 0, err
}
return reports, total, nil
}
// GetReportCount 获取内容的举报次数
func (r *reportRepository) GetReportCount(targetType model.ReportTargetType, targetID string) (int64, error) {
var count int64
err := r.db.Model(&model.Report{}).
Where("target_type = ? AND target_id = ?", targetType, targetID).
Count(&count).Error
return count, err
}
// HasUserReported 检查用户是否已举报过该内容
func (r *reportRepository) HasUserReported(reporterID string, targetType model.ReportTargetType, targetID string) (bool, error) {
var count int64
err := r.db.Model(&model.Report{}).
Where("reporter_id = ? AND target_type = ? AND target_id = ?", reporterID, targetType, targetID).
Count(&count).Error
return count > 0, err
}
// GetPendingReportsByTarget 获取目标内容的待处理举报
func (r *reportRepository) GetPendingReportsByTarget(targetType model.ReportTargetType, targetID string) ([]*model.Report, error) {
var reports []*model.Report
err := r.db.Where("target_type = ? AND target_id = ? AND status = ?", targetType, targetID, model.ReportStatusPending).
Find(&reports).Error
return reports, err
}
// UpdateStatus 更新举报状态
func (r *reportRepository) UpdateStatus(id string, status model.ReportStatus, handledBy string, result string) error {
updates := map[string]any{
"status": status,
"handled_by": handledBy,
"result": result,
}
return r.db.Model(&model.Report{}).Where("id = ?", id).Updates(updates).Error
}
// UpdateStatusWithContext 使用上下文更新举报状态
func (r *reportRepository) UpdateStatusWithContext(ctx context.Context, id string, status model.ReportStatus, handledBy string, result string) error {
updates := map[string]any{
"status": status,
"handled_by": handledBy,
"result": result,
}
return r.getDB(ctx).Model(&model.Report{}).Where("id = ?", id).Updates(updates).Error
}
// BatchUpdateStatus 批量更新举报状态
func (r *reportRepository) BatchUpdateStatus(ids []string, status model.ReportStatus, handledBy string, result string) (int64, error) {
updates := map[string]any{
"status": status,
"handled_by": handledBy,
"result": result,
}
resultDB := r.db.Model(&model.Report{}).Where("id IN ?", ids).Updates(updates)
return resultDB.RowsAffected, resultDB.Error
}
// BatchUpdateStatusWithContext 使用上下文批量更新举报状态
func (r *reportRepository) BatchUpdateStatusWithContext(ctx context.Context, ids []string, status model.ReportStatus, handledBy string, result string) (int64, error) {
updates := map[string]any{
"status": status,
"handled_by": handledBy,
"result": result,
}
resultDB := r.getDB(ctx).Model(&model.Report{}).Where("id IN ?", ids).Updates(updates)
return resultDB.RowsAffected, resultDB.Error
}
// GetByIDsWithContext 使用上下文批量查询举报
func (r *reportRepository) GetByIDsWithContext(ctx context.Context, ids []string) ([]*model.Report, error) {
var reports []*model.Report
err := r.getDB(ctx).Where("id IN ?", ids).Find(&reports).Error
return reports, err
}