在 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>
112 lines
2.9 KiB
Go
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
|
|
}
|
|
}
|