165 lines
4.0 KiB
Go
165 lines
4.0 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/topfans/backend/pkg/models"
|
|
pb "github.com/topfans/backend/pkg/proto/moderation"
|
|
"github.com/topfans/backend/services/moderationService/client"
|
|
"github.com/topfans/backend/services/moderationService/config"
|
|
"github.com/topfans/backend/services/moderationService/repository"
|
|
)
|
|
|
|
type FeedbackService struct {
|
|
repo *repository.ModerationRepository
|
|
category *CategoryService
|
|
notifClient *client.NotificationClient
|
|
cfg config.ModerationConfig
|
|
}
|
|
|
|
func NewFeedbackService(
|
|
repo *repository.ModerationRepository,
|
|
category *CategoryService,
|
|
notifClient *client.NotificationClient,
|
|
cfg config.ModerationConfig,
|
|
) *FeedbackService {
|
|
return &FeedbackService{repo: repo, category: category, notifClient: notifClient, cfg: cfg}
|
|
}
|
|
|
|
func (s *FeedbackService) SubmitFeedback(ctx context.Context, req *pb.SubmitFeedbackRequest) (*pb.SubmitFeedbackResponse, error) {
|
|
now := time.Now().UnixMilli()
|
|
|
|
// 验证分类启用
|
|
enabled, err := s.category.IsFeedbackCategoryEnabled(ctx, req.CategoryCode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if !enabled {
|
|
return nil, ErrFeedbackCatInvalid
|
|
}
|
|
if len(req.Title) > 100 {
|
|
return nil, ErrDescriptionTooLong
|
|
}
|
|
if len(req.Contact) > s.cfg.MaxContactLen {
|
|
return nil, ErrDescriptionTooLong
|
|
}
|
|
if len(req.EvidenceKeys) > s.cfg.MaxEvidenceCount {
|
|
return nil, ErrTooManyEvidence
|
|
}
|
|
|
|
feedback := &models.Feedback{
|
|
UserID: req.UserId,
|
|
CategoryCode: req.CategoryCode,
|
|
Title: req.Title,
|
|
Content: req.Content,
|
|
IsAnonymous: req.IsAnonymous,
|
|
Status: "pending",
|
|
ClaimedBy: nil,
|
|
ClaimedAt: nil,
|
|
CreatedAt: now,
|
|
UpdatedAt: now,
|
|
}
|
|
if req.StarId > 0 {
|
|
sid := req.StarId
|
|
feedback.StarID = &sid
|
|
}
|
|
if req.Contact != "" {
|
|
c := req.Contact
|
|
feedback.Contact = &c
|
|
}
|
|
|
|
if err := s.repo.CreateFeedback(ctx, feedback); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for i, key := range req.EvidenceKeys {
|
|
ev := &models.FeedbackEvidence{
|
|
FeedbackID: feedback.ID,
|
|
OSSKey: key,
|
|
SortOrder: int32(i),
|
|
CreatedAt: now,
|
|
}
|
|
if err := s.repo.CreateFeedbackEvidence(ctx, ev); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return &pb.SubmitFeedbackResponse{
|
|
FeedbackId: feedback.ID,
|
|
Status: feedback.Status,
|
|
ClaimedBy: 0,
|
|
ClaimedAt: 0,
|
|
CreatedAt: feedback.CreatedAt,
|
|
}, nil
|
|
}
|
|
|
|
func (s *FeedbackService) ListMyFeedbacks(ctx context.Context, req *pb.ListMyFeedbacksRequest) (*pb.ListMyFeedbacksResponse, error) {
|
|
page := int(req.Page)
|
|
if page < 1 {
|
|
page = 1
|
|
}
|
|
pageSize := int(req.PageSize)
|
|
if pageSize < 1 || pageSize > 100 {
|
|
pageSize = 20
|
|
}
|
|
fbs, total, err := s.repo.ListMyFeedbacks(ctx, req.UserId, req.Status, page, pageSize)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp := &pb.ListMyFeedbacksResponse{Total: int32(total)}
|
|
for _, fb := range fbs {
|
|
item := &pb.FeedbackSummary{
|
|
Id: fb.ID,
|
|
CategoryCode: fb.CategoryCode,
|
|
Title: fb.Title,
|
|
Status: fb.Status,
|
|
CreatedAt: fb.CreatedAt,
|
|
}
|
|
if fb.RepliedAt != nil {
|
|
item.RepliedAt = *fb.RepliedAt
|
|
}
|
|
resp.Feedbacks = append(resp.Feedbacks, item)
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *FeedbackService) GetFeedback(ctx context.Context, req *pb.GetFeedbackRequest) (*pb.GetFeedbackResponse, error) {
|
|
fb, err := s.repo.GetFeedbackByID(ctx, req.Id)
|
|
if err != nil {
|
|
return nil, ErrReportNotFound
|
|
}
|
|
if fb.UserID != req.UserId {
|
|
return nil, ErrReportNotFound
|
|
}
|
|
resp := &pb.GetFeedbackResponse{
|
|
Feedback: &pb.FeedbackSummary{
|
|
Id: fb.ID,
|
|
CategoryCode: fb.CategoryCode,
|
|
Title: fb.Title,
|
|
Status: fb.Status,
|
|
CreatedAt: fb.CreatedAt,
|
|
},
|
|
Content: fb.Content,
|
|
}
|
|
if fb.ReplyContent != nil {
|
|
resp.ReplyContent = *fb.ReplyContent
|
|
}
|
|
if fb.RepliedAt != nil {
|
|
resp.Feedback.RepliedAt = *fb.RepliedAt
|
|
}
|
|
evs, _ := s.repo.GetFeedbackEvidence(ctx, fb.ID)
|
|
for _, ev := range evs {
|
|
item := &pb.EvidenceSummary{OssKey: ev.OSSKey}
|
|
if ev.OSSURL != nil {
|
|
item.OssUrl = *ev.OSSURL
|
|
}
|
|
resp.Evidence = append(resp.Evidence, item)
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
// avoid unused import warning
|
|
var _ = errors.New
|