createpostlogic.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package logic
  2. import (
  3. "context"
  4. "slowwild/internal/constants"
  5. "slowwild/internal/svc"
  6. "strings"
  7. "git.banshen.xyz/huangguangrong/slow_wild_protobuff/slowwild/slowwildserver"
  8. "slowwild/internal/errorx"
  9. "slowwild/internal/model"
  10. "time"
  11. "slowwild/internal/utils"
  12. "github.com/spf13/cast"
  13. "github.com/zeromicro/go-zero/core/logx"
  14. "gorm.io/gorm"
  15. )
  16. type CreatePostLogic struct {
  17. ctx context.Context
  18. svcCtx *svc.ServiceContext
  19. logx.Logger
  20. }
  21. func NewCreatePostLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatePostLogic {
  22. return &CreatePostLogic{
  23. ctx: ctx,
  24. svcCtx: svcCtx,
  25. Logger: logx.WithContext(ctx),
  26. }
  27. }
  28. // 发布帖子
  29. func (l *CreatePostLogic) CreatePost(in *slowwildserver.CreatePostReq) (*slowwildserver.CreatePostRsp, error) {
  30. userId, err := cast.ToInt64E(l.ctx.Value(constants.UserIDKey))
  31. if err != nil {
  32. return nil, errorx.NewCodeError(50001, "用户未登录")
  33. }
  34. if userId <= 0 || in.Content == "" {
  35. return nil, errorx.ErrInvalidParam
  36. }
  37. // 检查帖子类型是否合法
  38. if in.Type != 0 && in.Type != 1 {
  39. return nil, errorx.NewCodeError(20001, "帖子类型不合法")
  40. }
  41. // 开启事务
  42. err = l.svcCtx.UserModel.Transaction(l.ctx, func(tx *gorm.DB) error {
  43. postModel := model.NewPostModel(tx, l.svcCtx.Redis)
  44. postContentModel := model.NewPostContentModel(tx)
  45. userModel := model.NewUserModel(tx)
  46. tagModel := model.NewTagModel(tx, l.svcCtx.Redis)
  47. messageModel := model.NewMessageModel(tx)
  48. // 提取话题名称
  49. var tagNames []string
  50. for _, tag := range in.Tags {
  51. tagNames = append(tagNames, tag.Name)
  52. }
  53. // 检查话题是否存在
  54. existingTags, err := tagModel.FindByNames(l.ctx, tagNames)
  55. if err != nil {
  56. return err
  57. }
  58. // 找出不存在的话题名称
  59. existingTagMap := make(map[string]bool)
  60. for _, tag := range existingTags {
  61. existingTagMap[tag.Name] = true
  62. }
  63. // 需要新建的话题
  64. var newTags []*model.Tag
  65. for _, tag := range in.Tags {
  66. if !existingTagMap[tag.Name] {
  67. newTags = append(newTags, &model.Tag{
  68. Model: &model.Model{
  69. CreatedOn: time.Now().Unix(),
  70. ModifiedOn: time.Now().Unix(),
  71. },
  72. UserId: userId,
  73. Name: tag.Name,
  74. HotNum: 0,
  75. })
  76. }
  77. }
  78. // 创建新话题
  79. if len(newTags) > 0 {
  80. if err = tagModel.BatchCreate(l.ctx, newTags); err != nil {
  81. return err
  82. }
  83. }
  84. // 获取所有话题的ID
  85. var tagIds []int64
  86. for _, tag := range existingTags {
  87. tagIds = append(tagIds, tag.ID)
  88. }
  89. for _, tag := range newTags {
  90. tagIds = append(tagIds, tag.ID)
  91. }
  92. // 判断@用户是否重复,重复只发一次
  93. existUserMap := make(map[string]bool)
  94. if len(in.AtUserIds) > 0 {
  95. for _, id := range in.AtUserIds {
  96. existUserMap[cast.ToString(id)] = true
  97. }
  98. }
  99. atUserIds := make([]string, 0, len(existUserMap))
  100. if len(existUserMap) > 0 {
  101. for id := range existUserMap {
  102. atUserIds = append(atUserIds, id)
  103. }
  104. }
  105. // 创建帖子
  106. post := &model.Post{
  107. Model: &model.Model{
  108. CreatedOn: time.Now().Unix(),
  109. ModifiedOn: time.Now().Unix(),
  110. },
  111. UserId: userId,
  112. PostType: in.Type,
  113. Visibility: int8(in.Visibility),
  114. Tags: strings.Join(tagNames, ","),
  115. Ip: in.Ip,
  116. IpLoc: in.IpLoc,
  117. WithUserIds: strings.Join(atUserIds, ","),
  118. CommentCount: 0,
  119. CollectionCount: 0,
  120. UpvoteCount: 0,
  121. ShareCount: 0,
  122. IsTop: 0,
  123. IsEssence: 0,
  124. HotNum: 0,
  125. }
  126. // 创建帖子基本信息
  127. if err := postModel.Create(l.ctx, post); err != nil {
  128. return err
  129. }
  130. // 处理内容,生成摘要
  131. plainContent := utils.StripHTML(in.Content)
  132. contentSummary := utils.TruncateText(plainContent, 1000)
  133. // 创建帖子内容
  134. postContent := &model.PostContent{
  135. Model: &model.Model{
  136. CreatedOn: time.Now().Unix(),
  137. ModifiedOn: time.Now().Unix(),
  138. },
  139. PostId: post.ID,
  140. UserId: userId,
  141. Title: in.Title,
  142. Content: in.Content, // 保存原始内容
  143. ContentSummary: contentSummary, // 保存处理后的摘要
  144. PostVideoCover: in.VideoCover,
  145. PostCovers: strings.Join(in.Images, ","),
  146. PostVideoUrl: in.VideoUrl,
  147. Sort: 0,
  148. }
  149. if err := postContentModel.Create(l.ctx, postContent); err != nil {
  150. return err
  151. }
  152. // 创建帖子和话题的关联关系
  153. if err := tagModel.CreateTagWithPost(l.ctx, post.ID, tagIds); err != nil {
  154. return err
  155. }
  156. // 检查被艾特的用户是否存在
  157. if len(atUserIds) > 0 {
  158. atUsers, err := userModel.FindByIds(l.ctx, in.AtUserIds)
  159. if err != nil {
  160. return err
  161. }
  162. // 发送站内信给被艾特的用户
  163. for _, user := range atUsers {
  164. err = messageModel.SendNotification(l.ctx, userId, user.ID, 1, "你被艾特了", "你被艾特在一条动态中", post.ID, 0, 0)
  165. if err != nil {
  166. return err
  167. }
  168. }
  169. }
  170. // 增加用户的帖子数
  171. if err := userModel.IncrementTweetCount(l.ctx, userId); err != nil {
  172. return err
  173. }
  174. // 删除缓存
  175. postModel.ClearListCache(l.ctx)
  176. return nil
  177. })
  178. if err != nil {
  179. l.Logger.Errorf("发布帖子失败: %v", err)
  180. return nil, errorx.NewCodeError(20002, "发布帖子失败")
  181. }
  182. return &slowwildserver.CreatePostRsp{}, nil
  183. }