Files
common-server-public/bbs-go-active/server/internal/services/topic_publish_service.go
2025-03-03 17:43:50 +08:00

152 lines
3.7 KiB
Go

package services
import (
"bbs-go/internal/models"
"bbs-go/internal/models/constants"
"bbs-go/internal/pkg/event"
"bbs-go/internal/pkg/iplocator"
"bbs-go/internal/pkg/search"
"bbs-go/internal/repositories"
"errors"
"log/slog"
"strings"
"github.com/mlogclub/simple/common/dates"
"github.com/mlogclub/simple/common/jsons"
"github.com/mlogclub/simple/common/strs"
"github.com/mlogclub/simple/sqls"
"gorm.io/gorm"
)
var TopicPublishService = new(topicPublishService)
type topicPublishService struct{}
// Publish 发表
func (s *topicPublishService) Publish(userId int64, form models.CreateTopicForm) (*models.Topic, error) {
if err := s._CheckParams(userId, form); err != nil {
return nil, err
}
now := dates.NowTimestamp()
topic := &models.Topic{
Type: form.Type,
UserId: userId,
NodeId: form.NodeId,
Title: form.Title,
Content: form.Content,
HideContent: form.HideContent,
Status: constants.StatusOk,
UserAgent: form.UserAgent,
Ip: form.Ip,
IpLocation: iplocator.IpLocation(form.Ip),
LastCommentTime: now,
CreateTime: now,
}
if len(form.ImageList) > 0 {
imageListStr, err := jsons.ToStr(form.ImageList)
if err == nil {
topic.ImageList = imageListStr
} else {
slog.Error(err.Error(), slog.Any("err", err))
}
}
// 检查是否需要审核
if s._IsNeedReview(userId, form) {
topic.Status = constants.StatusReview
}
if err := sqls.DB().Transaction(func(tx *gorm.DB) error {
var (
tagIds []int64
err error
)
// 帖子
if err := repositories.TopicRepository.Create(tx, topic); err != nil {
return err
}
// 标签
if tagIds, err = repositories.TagRepository.GetOrCreates(tx, form.Tags); err != nil {
return err
}
if err = repositories.TopicTagRepository.AddTopicTags(tx, topic.Id, tagIds); err != nil {
return err
}
// 用户计数
if err = UserService.IncrTopicCount(tx, userId); err != nil {
return err
}
// 积分
UserService.IncrScoreForPostTopic(topic)
return nil
}); err != nil {
return nil, err
}
// 添加索引
search.UpdateTopicIndex(topic)
// 发送事件
event.Send(event.TopicCreateEvent{
UserId: topic.UserId,
TopicId: topic.Id,
CreateTime: topic.CreateTime,
})
return topic, nil
}
// IsNeedReview 是否需要审核
func (s *topicPublishService) _IsNeedReview(userId int64, form models.CreateTopicForm) bool {
if hits := ForbiddenWordService.Check(form.Title); len(hits) > 0 {
slog.Info("帖子标题命中违禁词", slog.String("hits", strings.Join(hits, ",")))
return true
}
if hits := ForbiddenWordService.Check(form.Content); len(hits) > 0 {
slog.Info("帖子内容命中违禁词", slog.String("hits", strings.Join(hits, ",")))
return true
}
return false
}
func (s topicPublishService) _CheckParams(userId int64, form models.CreateTopicForm) (err error) {
if form.Type == constants.TopicTypeTweet {
if strs.IsBlank(form.Content) {
return errors.New("内容不能为空")
}
// if strs.IsBlank(form.Content) && len(form.ImageList) == 0 {
// return errors.New("内容或图片不能为空")
// }
} else {
if strs.IsBlank(form.Title) {
return errors.New("标题不能为空")
}
if strs.IsBlank(form.Content) {
return errors.New("内容不能为空")
}
if strs.RuneLen(form.Title) > 128 {
return errors.New("标题长度不能超过128")
}
}
if form.NodeId <= 0 {
form.NodeId = SysConfigService.GetConfig().DefaultNodeId
if form.NodeId <= 0 {
return errors.New("请选择节点")
}
}
node := repositories.TopicNodeRepository.Get(sqls.DB(), form.NodeId)
if node == nil || node.Status != constants.StatusOk {
return errors.New("节点不存在")
}
return nil
}