spark-server/internal/module/admin/logic/complaints.go
zhr 13b42cef7b chore: 合并本地改动与 main(t_ 表名、lint、音乐分类)
在 fast-forward 到 origin/main 后解决 music logic/repo 冲突,SQL 与模型统一 t_* 表名;Makefile 修正 golangci-lint 变量并令 test/deploy 依赖 lint;补齐 admin/transport 等 lint 修复与 music logic 单测以满足覆盖率门禁。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-24 10:56:59 +08:00

112 lines
2.9 KiB
Go

package logic
import (
"context"
"strconv"
"strings"
"time"
adminmodel "spark-server/internal/module/admin/model"
friendentity "spark-server/internal/module/friend/entity"
"spark-server/internal/pkg/errs"
)
func (s *Service) ListComplaints(ctx context.Context) ([]ComplaintView, error) {
if !s.ready() {
return nil, ErrNotReady
}
rows, err := s.repo.ListComplaints(ctx, 200)
if err != nil {
return nil, err
}
return complaintViews(rows), nil
}
func (s *Service) AddComplaint(ctx context.Context, email, target, reason, detail string) (*ComplaintView, error) {
if s.ids == nil || !s.ready() {
return nil, ErrNotReady
}
email = strings.ToLower(strings.TrimSpace(email))
target = strings.TrimSpace(target)
var userID, targetID int64
if email != "" {
userID, _ = s.repo.LookupUserIDByEmail(ctx, email)
}
if target != "" {
if id, e := strconv.ParseInt(target, 10, 64); e == nil {
targetID = id
} else {
targetID, _ = s.repo.LookupUserIDByEmail(ctx, strings.ToLower(target))
}
}
if userID <= 0 || targetID <= 0 {
return nil, errs.ErrInvalidArgument
}
id, err := s.ids.NextID()
if err != nil {
return nil, err
}
reasonCode := parseReportReason(reason)
now := time.Now()
err = s.repo.InsertComplaint(ctx, &friendentity.Report{
ID: id, UserID: userID, TargetID: targetID,
Reason: reasonCode, Detail: strings.TrimSpace(detail), CreatedAt: now,
})
if err != nil {
return nil, err
}
return &ComplaintView{
ID: id, Email: email, Target: target,
Reason: reportReasonName(int(reasonCode)), Detail: detail,
Status: "open", CreatedAt: now.Format(time.RFC3339),
}, nil
}
func complaintViews(rows []adminmodel.ComplaintRow) []ComplaintView {
out := make([]ComplaintView, 0, len(rows))
for i := range rows {
target := rows[i].TargetMail
if target == "" {
target = strconv.FormatInt(rows[i].TargetID, 10)
}
out = append(out, ComplaintView{
ID: rows[i].ID, Email: rows[i].Email, Target: target,
Reason: reportReasonName(rows[i].Reason), Detail: rows[i].Detail,
Status: "open", CreatedAt: rows[i].CreatedAt.Format(time.RFC3339),
})
}
return out
}
const (
reportLabelSpam = "spam"
reportLabelHarassment = "harassment"
reportLabelFake = "fake"
)
func reportReasonName(r int) string {
switch friendentity.ReportReason(r) {
case friendentity.ReportSpam:
return reportLabelSpam
case friendentity.ReportHarassment:
return reportLabelHarassment
case friendentity.ReportFake:
return reportLabelFake
default:
return "other"
}
}
func parseReportReason(raw string) friendentity.ReportReason {
switch strings.ToLower(strings.TrimSpace(raw)) {
case "1", reportLabelSpam, "垃圾":
return friendentity.ReportSpam
case "2", reportLabelHarassment, "骚扰":
return friendentity.ReportHarassment
case "3", reportLabelFake, "不实身份":
return friendentity.ReportFake
default:
return friendentity.ReportOther
}
}