152 lines
3.7 KiB
Go
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
|
|
}
|