feat: add batch content report processing

This commit is contained in:
2026-01-16 17:59:18 +08:00
parent 028c462eaa
commit b796636b5d
11 changed files with 599 additions and 8 deletions

View File

@@ -396,6 +396,107 @@ func (s *SuperTestSuite) Test_ContentReportGovernance() {
})
}
func (s *SuperTestSuite) Test_BatchProcessContentReports() {
Convey("BatchProcessContentReports", s.T(), func() {
ctx := s.T().Context()
database.Truncate(ctx, s.DB, models.TableNameContentReport, models.TableNameContent, models.TableNameTenant, models.TableNameUser)
owner := &models.User{Username: "batch_report_owner"}
reporter := &models.User{Username: "batch_reporter"}
admin := &models.User{Username: "batch_report_admin"}
models.UserQuery.WithContext(ctx).Create(owner, reporter, admin)
tenant := &models.Tenant{UserID: owner.ID, Code: "t-report-batch", Name: "Report Batch Tenant", Status: consts.TenantStatusVerified}
models.TenantQuery.WithContext(ctx).Create(tenant)
contentA := &models.Content{
TenantID: tenant.ID,
UserID: owner.ID,
Title: "Batch Report A",
Status: consts.ContentStatusPublished,
}
contentB := &models.Content{
TenantID: tenant.ID,
UserID: owner.ID,
Title: "Batch Report B",
Status: consts.ContentStatusPublished,
}
models.ContentQuery.WithContext(ctx).Create(contentA, contentB)
Convey("should batch approve reports and unpublish contents", func() {
reportA := &models.ContentReport{
TenantID: tenant.ID,
ContentID: contentA.ID,
ReporterID: reporter.ID,
Reason: "spam",
Detail: "批量举报A",
Status: "pending",
}
reportB := &models.ContentReport{
TenantID: tenant.ID,
ContentID: contentB.ID,
ReporterID: reporter.ID,
Reason: "abuse",
Detail: "批量举报B",
Status: "pending",
}
models.ContentReportQuery.WithContext(ctx).Create(reportA, reportB)
err := Super.BatchProcessContentReports(ctx, admin.ID, &super_dto.SuperContentReportBatchProcessForm{
ReportIDs: []int64{reportA.ID, reportB.ID},
Action: "approve",
ContentAction: "unpublish",
Reason: "集中处理",
})
So(err, ShouldBeNil)
reloadedA, err := models.ContentReportQuery.WithContext(ctx).Where(models.ContentReportQuery.ID.Eq(reportA.ID)).First()
So(err, ShouldBeNil)
So(reloadedA.Status, ShouldEqual, "approved")
So(reloadedA.HandledBy, ShouldEqual, admin.ID)
So(reloadedA.HandledAction, ShouldEqual, "unpublish")
So(reloadedA.HandledReason, ShouldEqual, "集中处理")
So(reloadedA.HandledAt.IsZero(), ShouldBeFalse)
reloadedB, err := models.ContentReportQuery.WithContext(ctx).Where(models.ContentReportQuery.ID.Eq(reportB.ID)).First()
So(err, ShouldBeNil)
So(reloadedB.Status, ShouldEqual, "approved")
So(reloadedB.HandledAction, ShouldEqual, "unpublish")
contentReloadA, err := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(contentA.ID)).First()
So(err, ShouldBeNil)
So(contentReloadA.Status, ShouldEqual, consts.ContentStatusUnpublished)
contentReloadB, err := models.ContentQuery.WithContext(ctx).Where(models.ContentQuery.ID.Eq(contentB.ID)).First()
So(err, ShouldBeNil)
So(contentReloadB.Status, ShouldEqual, consts.ContentStatusUnpublished)
})
Convey("should reject when report already handled", func() {
report := &models.ContentReport{
TenantID: tenant.ID,
ContentID: contentA.ID,
ReporterID: reporter.ID,
Reason: "other",
Detail: "已处理",
Status: "approved",
}
models.ContentReportQuery.WithContext(ctx).Create(report)
err := Super.BatchProcessContentReports(ctx, admin.ID, &super_dto.SuperContentReportBatchProcessForm{
ReportIDs: []int64{report.ID},
Action: "reject",
Reason: "重复提交",
})
So(err, ShouldNotBeNil)
var appErr *errorx.AppError
So(errors.As(err, &appErr), ShouldBeTrue)
So(appErr.Code, ShouldEqual, errorx.ErrStatusConflict.Code)
})
})
}
func (s *SuperTestSuite) Test_FinanceAnomalies() {
Convey("Finance Anomalies", s.T(), func() {
ctx := s.T().Context()