336 lines
9.9 KiB
Go
336 lines
9.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strconv"
|
|
"time"
|
|
|
|
apperrors "carrotskin/internal/errors"
|
|
"carrotskin/internal/model"
|
|
"carrotskin/internal/repository"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// reportService ReportService的实现
|
|
type reportService struct {
|
|
reportRepo repository.ReportRepository
|
|
userRepo repository.UserRepository
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewReportService 创建ReportService实例
|
|
func NewReportService(
|
|
reportRepo repository.ReportRepository,
|
|
userRepo repository.UserRepository,
|
|
logger *zap.Logger,
|
|
) ReportService {
|
|
return &reportService{
|
|
reportRepo: reportRepo,
|
|
userRepo: userRepo,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// CreateReport 创建举报
|
|
func (s *reportService) CreateReport(ctx context.Context, reporterID int64, targetType model.ReportType, targetID int64, reason string) (*model.Report, error) {
|
|
// 验证举报人存在
|
|
reporter, err := s.userRepo.FindByID(ctx, reporterID)
|
|
if err != nil {
|
|
s.logger.Error("举报人不存在", zap.Int64("reporter_id", reporterID), zap.Error(err))
|
|
return nil, apperrors.ErrUserNotFound
|
|
}
|
|
if reporter == nil {
|
|
return nil, apperrors.ErrUserNotFound
|
|
}
|
|
|
|
// 验证举报原因
|
|
if reason == "" {
|
|
return nil, errors.New("举报原因不能为空")
|
|
}
|
|
if len(reason) > 500 {
|
|
return nil, errors.New("举报原因不能超过500字符")
|
|
}
|
|
|
|
// 验证目标类型
|
|
if targetType != model.ReportTypeTexture && targetType != model.ReportTypeUser {
|
|
return nil, errors.New("无效的举报类型")
|
|
}
|
|
|
|
// 检查是否重复举报
|
|
isDuplicate, err := s.reportRepo.CheckDuplicate(ctx, reporterID, targetType, targetID)
|
|
if err != nil {
|
|
s.logger.Error("检查重复举报失败", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
if isDuplicate {
|
|
return nil, errors.New("您已经举报过该对象,请勿重复举报")
|
|
}
|
|
|
|
// 创建举报记录
|
|
report := &model.Report{
|
|
ReporterID: reporterID,
|
|
TargetType: targetType,
|
|
TargetID: targetID,
|
|
Reason: reason,
|
|
Status: model.ReportStatusPending,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if err := s.reportRepo.Create(ctx, report); err != nil {
|
|
s.logger.Error("创建举报失败", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Info("创建举报成功", zap.Int64("report_id", report.ID), zap.Int64("reporter_id", reporterID))
|
|
return report, nil
|
|
}
|
|
|
|
// GetByID 根据ID查询举报
|
|
func (s *reportService) GetByID(ctx context.Context, id int64) (*model.Report, error) {
|
|
report, err := s.reportRepo.FindByID(ctx, id)
|
|
if err != nil {
|
|
s.logger.Error("查询举报失败", zap.Int64("report_id", id), zap.Error(err))
|
|
return nil, err
|
|
}
|
|
return report, nil
|
|
}
|
|
|
|
// GetByReporterID 根据举报人ID查询举报记录
|
|
func (s *reportService) GetByReporterID(ctx context.Context, reporterID, userID int64, page, pageSize int) ([]*model.Report, int64, error) {
|
|
// 验证用户存在
|
|
user, err := s.userRepo.FindByID(ctx, userID)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if user == nil {
|
|
return nil, 0, apperrors.ErrUserNotFound
|
|
}
|
|
|
|
// 只有本人或管理员可以查看自己的举报记录
|
|
if reporterID != userID && !(user.Role == "admin") {
|
|
return nil, 0, errors.New("无权查看其他用户的举报记录")
|
|
}
|
|
|
|
reports, total, err := s.reportRepo.FindByReporterID(ctx, reporterID, page, pageSize)
|
|
if err != nil {
|
|
s.logger.Error("查询举报记录失败", zap.Error(err))
|
|
return nil, 0, err
|
|
}
|
|
|
|
return reports, total, nil
|
|
}
|
|
|
|
// GetByTarget 根据目标对象查询举报记录
|
|
func (s *reportService) GetByTarget(ctx context.Context, targetType model.ReportType, targetID, userID int64, page, pageSize int) ([]*model.Report, int64, error) {
|
|
// 验证用户存在
|
|
user, err := s.userRepo.FindByID(ctx, userID)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if user == nil {
|
|
return nil, 0, apperrors.ErrUserNotFound
|
|
}
|
|
|
|
// 只有管理员可以查看目标对象的举报记录
|
|
if !(user.Role == "admin") {
|
|
return nil, 0, errors.New("无权查看举报记录")
|
|
}
|
|
|
|
reports, total, err := s.reportRepo.FindByTarget(ctx, targetType, targetID, page, pageSize)
|
|
if err != nil {
|
|
s.logger.Error("查询举报记录失败", zap.Error(err))
|
|
return nil, 0, err
|
|
}
|
|
|
|
return reports, total, nil
|
|
}
|
|
|
|
// GetByStatus 根据状态查询举报记录
|
|
func (s *reportService) GetByStatus(ctx context.Context, status model.ReportStatus, page, pageSize int) ([]*model.Report, int64, error) {
|
|
reports, total, err := s.reportRepo.FindByStatus(ctx, status, page, pageSize)
|
|
if err != nil {
|
|
s.logger.Error("查询举报记录失败", zap.Error(err))
|
|
return nil, 0, err
|
|
}
|
|
|
|
return reports, total, nil
|
|
}
|
|
|
|
// Search 搜索举报记录
|
|
func (s *reportService) Search(ctx context.Context, keyword, userID int64, page, pageSize int) ([]*model.Report, int64, error) {
|
|
// 验证用户存在
|
|
user, err := s.userRepo.FindByID(ctx, userID)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if user == nil {
|
|
return nil, 0, apperrors.ErrUserNotFound
|
|
}
|
|
|
|
// 只有管理员可以搜索举报记录
|
|
if !(user.Role == "admin") {
|
|
return nil, 0, errors.New("无权搜索举报记录")
|
|
}
|
|
|
|
reports, total, err := s.reportRepo.Search(ctx, strconv.FormatInt(keyword, 10), page, pageSize)
|
|
if err != nil {
|
|
s.logger.Error("搜索举报记录失败", zap.Error(err))
|
|
return nil, 0, err
|
|
}
|
|
|
|
return reports, total, nil
|
|
}
|
|
|
|
// Review 处理举报记录
|
|
func (s *reportService) Review(ctx context.Context, reportID, reviewerID int64, status model.ReportStatus, reviewNote string) (*model.Report, error) {
|
|
// 验证处理人存在且是管理员
|
|
reviewer, err := s.userRepo.FindByID(ctx, reviewerID)
|
|
if err != nil {
|
|
s.logger.Error("处理人不存在", zap.Int64("reviewer_id", reviewerID), zap.Error(err))
|
|
return nil, apperrors.ErrUserNotFound
|
|
}
|
|
if reviewer == nil || !(reviewer.Role == "admin") {
|
|
return nil, errors.New("只有管理员可以处理举报")
|
|
}
|
|
|
|
// 验证状态
|
|
if status != model.ReportStatusApproved && status != model.ReportStatusRejected {
|
|
return nil, errors.New("无效的举报处理状态")
|
|
}
|
|
|
|
// 处理举报
|
|
if err := s.reportRepo.Review(ctx, reportID, status, reviewerID, reviewNote); err != nil {
|
|
s.logger.Error("处理举报失败", zap.Int64("report_id", reportID), zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
// 返回更新后的举报记录
|
|
report, err := s.reportRepo.FindByID(ctx, reportID)
|
|
if err != nil {
|
|
s.logger.Error("查询举报记录失败", zap.Int64("report_id", reportID), zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
s.logger.Info("处理举报成功", zap.Int64("report_id", reportID), zap.Int64("reviewer_id", reviewerID), zap.String("status", string(status)))
|
|
return report, nil
|
|
}
|
|
|
|
// BatchReview 批量处理举报记录
|
|
func (s *reportService) BatchReview(ctx context.Context, ids []int64, reviewerID int64, status model.ReportStatus, reviewNote string) (int64, error) {
|
|
// 验证处理人存在且是管理员
|
|
reviewer, err := s.userRepo.FindByID(ctx, reviewerID)
|
|
if err != nil {
|
|
s.logger.Error("处理人不存在", zap.Int64("reviewer_id", reviewerID), zap.Error(err))
|
|
return 0, apperrors.ErrUserNotFound
|
|
}
|
|
if reviewer == nil || !(reviewer.Role == "admin") {
|
|
return 0, errors.New("只有管理员可以处理举报")
|
|
}
|
|
|
|
// 验证状态
|
|
if status != model.ReportStatusApproved && status != model.ReportStatusRejected {
|
|
return 0, errors.New("无效的举报处理状态")
|
|
}
|
|
|
|
// 批量处理举报
|
|
affected, err := s.reportRepo.BatchReview(ctx, ids, status, reviewerID, reviewNote)
|
|
if err != nil {
|
|
s.logger.Error("批量处理举报失败", zap.Error(err))
|
|
return 0, err
|
|
}
|
|
|
|
s.logger.Info("批量处理举报成功", zap.Int("count", int(affected)), zap.Int64("reviewer_id", reviewerID), zap.String("status", string(status)))
|
|
return affected, nil
|
|
}
|
|
|
|
// Delete 删除举报记录
|
|
func (s *reportService) Delete(ctx context.Context, reportID, userID int64) error {
|
|
// 验证用户存在
|
|
user, err := s.userRepo.FindByID(ctx, userID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if user == nil {
|
|
return apperrors.ErrUserNotFound
|
|
}
|
|
|
|
// 查询举报记录
|
|
report, err := s.reportRepo.FindByID(ctx, reportID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if report == nil {
|
|
return errors.New("举报记录不存在")
|
|
}
|
|
|
|
// 只有举报人、管理员或处理人可以删除举报记录
|
|
if report.ReporterID != userID && !(user.Role == "admin") && (report.ReviewerID == nil || *report.ReviewerID != userID) {
|
|
return errors.New("无权删除此举报记录")
|
|
}
|
|
|
|
if err := s.reportRepo.Delete(ctx, reportID); err != nil {
|
|
s.logger.Error("删除举报记录失败", zap.Int64("report_id", reportID), zap.Error(err))
|
|
return err
|
|
}
|
|
|
|
s.logger.Info("删除举报记录成功", zap.Int64("report_id", reportID))
|
|
return nil
|
|
}
|
|
|
|
// BatchDelete 批量删除举报记录
|
|
func (s *reportService) BatchDelete(ctx context.Context, ids []int64, userID int64) (int64, error) {
|
|
// 验证用户存在
|
|
user, err := s.userRepo.FindByID(ctx, userID)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if user == nil {
|
|
return 0, apperrors.ErrUserNotFound
|
|
}
|
|
|
|
// 只有管理员可以批量删除
|
|
if !(user.Role == "admin") {
|
|
return 0, errors.New("无权批量删除举报记录")
|
|
}
|
|
|
|
affected, err := s.reportRepo.BatchDelete(ctx, ids)
|
|
if err != nil {
|
|
s.logger.Error("批量删除举报记录失败", zap.Error(err))
|
|
return 0, err
|
|
}
|
|
|
|
s.logger.Info("批量删除举报记录成功", zap.Int("count", int(affected)))
|
|
return affected, nil
|
|
}
|
|
|
|
// GetStats 获取举报统计信息
|
|
func (s *reportService) GetStats(ctx context.Context) (map[string]int64, error) {
|
|
stats := make(map[string]int64)
|
|
|
|
// 统计各状态的举报数量
|
|
pendingCount, err := s.reportRepo.CountByStatus(ctx, model.ReportStatusPending)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stats["pending"] = pendingCount
|
|
|
|
approvedCount, err := s.reportRepo.CountByStatus(ctx, model.ReportStatusApproved)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stats["approved"] = approvedCount
|
|
|
|
rejectedCount, err := s.reportRepo.CountByStatus(ctx, model.ReportStatusRejected)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stats["rejected"] = rejectedCount
|
|
|
|
stats["total"] = pendingCount + approvedCount + rejectedCount
|
|
|
|
return stats, nil
|
|
}
|