作者 tangxvhui

新创建文章内容

@@ -61,6 +61,28 @@ type ( @@ -61,6 +61,28 @@ type (
61 } 61 }
62 ) 62 )
63 63
  64 +// 获取我的发文章记录
  65 +type (
  66 + MiniArticleSearchMeRequest {
  67 + AuthorId int64 `json:"-"`
  68 + }
  69 +
  70 + MiniArticleSearchMeResponse {
  71 + Total int `json:"total"`
  72 + List []ArticleSearchMe `json:"list"`
  73 + }
  74 +
  75 + ArticleSearchMe {
  76 + Id int64 `json:"id"` //id
  77 + Title string `json:"title"` //标题
  78 + Images []string `json:"images"` //图片
  79 + CreatedAt int64 `json:"createdAt"` //文章的创建日期
  80 + CountLove int `json:"countLove"` //点赞数量
  81 + CountComment int `json:"CountComment"` //评论数量
  82 + Show int `json:"show"` //是否隐藏 [0显示、1不显示]
  83 + }
  84 +)
  85 +
64 // 小程序接口 86 // 小程序接口
65 @server( 87 @server(
66 prefix: v1/mini 88 prefix: v1/mini
@@ -2,9 +2,11 @@ package article @@ -2,9 +2,11 @@ package article
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "strings"
5 6
6 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" 7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
7 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" 8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
8 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" 10 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
9 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" 11 "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
10 12
@@ -33,6 +35,18 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR @@ -33,6 +35,18 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR
33 if err != nil { 35 if err != nil {
34 return nil, xerr.NewErrMsgErr("创建文章内容失败", err) 36 return nil, xerr.NewErrMsgErr("创建文章内容失败", err)
35 } 37 }
  38 + //TODO 获取人员信息
  39 + articleAuthor := domain.UserSimple{
  40 + Id: author.Id,
  41 + Name: author.Name,
  42 + Avatar: author.Avatar,
  43 + GroupId: 0,
  44 + Group: "",
  45 + Position: author.Position,
  46 + Company: "",
  47 + CompanyId: author.CompanyId,
  48 + }
  49 +
36 //TODO 获取图片的尺寸大小 50 //TODO 获取图片的尺寸大小
37 images := []domain.Image{} 51 images := []domain.Image{}
38 for _, val := range req.Images { 52 for _, val := range req.Images {
@@ -59,24 +73,110 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR @@ -59,24 +73,110 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR
59 } 73 }
60 //检查文章可被哪些人评论 74 //检查文章可被哪些人评论
61 whoReview := []int64{} 75 whoReview := []int64{}
62 - if len(req.WhoReview) > 0 && len(whoRead) > 0 {  
63 - whoReview = lo.Uniq(req.WhoReview)  
64 - // 检查 whoRead 是否 完全包含 whoReview  
65 - ok := lo.Every(whoRead, whoReview)  
66 - if !ok { 76 + //有指定可查看人的情况
  77 + if len(whoRead) > 0 {
  78 + if len(whoReview) > 0 {
  79 + whoReview = lo.Uniq(req.WhoReview)
  80 + // 检查 whoRead 是否 完全包含 whoReview
  81 + ok := lo.Every(whoRead, whoReview)
  82 + if !ok {
  83 + return nil, xerr.NewErrMsg("文章可评论人设置错误")
  84 + }
  85 + }
  86 + if len(whoReview) == 0 {
  87 + //有指定可查看人 ,但未指定可评论人
67 return nil, xerr.NewErrMsg("文章可评论人设置错误") 88 return nil, xerr.NewErrMsg("文章可评论人设置错误")
68 } 89 }
69 } 90 }
70 - if len(whoRead) > 0 && len(whoReview) == 0 {  
71 - //有指定可查看人 ,但未指定可评论人  
72 - return nil, xerr.NewErrMsg("文章可评论人设置错误") 91 + //没有指定可查看人的情况
  92 + if len(whoRead) == 0 {
  93 + if len(whoReview) > 0 {
  94 + // 未指定可查看人(全员可看),有指定可评论人,
  95 + var u *domain.User
  96 + for _, val := range whoReview {
  97 + u, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, val)
  98 + if err != nil {
  99 + return nil, xerr.NewErrMsgErr("文章可评论人设置错误", err)
  100 + }
  101 + if u.CompanyId != author.CompanyId {
  102 + return nil, xerr.NewErrMsg("文章可评论人设置错误")
  103 + }
  104 + }
  105 + }
  106 + // if len(whoReview) == 0 {
  107 + // 未指定可查看人(全员可看),未指定可评论人 ,忽略判断
  108 + // }
  109 + }
  110 +
  111 + //切分文章分段
  112 + sectionList := []domain.ArticleSection{}
  113 + for i := range req.Section {
  114 + strList := strings.Split(req.Section[i], "\n")
  115 + for i2 := range strList {
  116 + newStr := strings.TrimSpace(strList[i2])
  117 + if len(newStr) == 0 {
  118 + continue
  119 + }
  120 + newSection := domain.ArticleSection{
  121 + Id: 0,
  122 + CompanyId: author.CompanyId,
  123 + ArticleId: 0,
  124 + Content: newStr,
  125 + SortBy: len(sectionList),
  126 + TotalComment: 0,
  127 + }
  128 + sectionList = append(sectionList, newSection)
  129 + }
  130 + }
  131 +
  132 + newArticle := &domain.Article{
  133 + Id: 0,
  134 + CompanyId: author.CompanyId,
  135 + AuthorId: author.Id,
  136 + Author: articleAuthor,
  137 + Title: req.Title,
  138 + Images: images,
  139 + WhoRead: whoRead,
  140 + WhoReview: whoReview,
  141 + Location: domain.Location{
  142 + Longitude: req.Location.Latitude,
  143 + Latitude: req.Location.Latitude,
  144 + Descript: req.Location.Descript,
  145 + },
  146 + TargetUser: domain.ArticleTargetAll,
  147 + }
  148 + if len(whoRead) > 0 {
  149 + newArticle.TargetUser = domain.ArticleTargetLimit
  150 + }
  151 +
  152 + err = transaction.UseTrans(l.ctx, conn.DB(), func(ctx context.Context, c transaction.Conn) error {
  153 + newArticle, err = l.svcCtx.ArticleRepository.Insert(ctx, c, newArticle)
  154 + if err != nil {
  155 + return xerr.NewErrMsgErr("创建文章失败", err)
  156 + }
  157 +
  158 + for i := range sectionList {
  159 + sectionList[i].ArticleId = newArticle.Id
  160 + _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, &sectionList[i])
  161 + if err != nil {
  162 + return xerr.NewErrMsgErr("创建文章内容失败", err)
  163 + }
  164 + }
  165 + // 设置保存备份
  166 + backup := newArticle.MakeBackup(newArticle.Author, sectionList)
  167 + backup.Action = "新增"
  168 + _, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, backup)
  169 + if err != nil {
  170 + return xerr.NewErrMsgErr("创建文章内容失败", err)
  171 + }
  172 + return nil
  173 + }, true)
  174 + if err != nil {
  175 + return nil, xerr.NewErrMsgErr("创建文章失败", err)
73 } 176 }
74 - // if len(whoRead) == 0 && len(whoReview) > 0 {  
75 - // 未指定可查看人(全员可看),有指定可评论人 ,忽略判断  
76 - // }  
77 - // if len(whoRead) == 0 && len(whoReview) == 0 {  
78 - // 未指定可查看人(全员可看),未指定可评论人 ,忽略判断  
79 - // }  
80 177
  178 + resp = &types.MiniArticleCreateResponse{
  179 + Id: newArticle.Id,
  180 + }
81 return 181 return
82 } 182 }
@@ -26,6 +26,7 @@ type Article struct { @@ -26,6 +26,7 @@ type Article struct {
26 Location domain.Location `gorm:"type:jsonb;serializer:json"` // 坐标 26 Location domain.Location `gorm:"type:jsonb;serializer:json"` // 坐标
27 TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人 27 TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人
28 CountLove int // 点赞数量 28 CountLove int // 点赞数量
  29 + CountRead int // 浏览数量
29 CountComment int // 评论数量 30 CountComment int // 评论数量
30 Show int // 评论的展示状态(0显示、1不显示) 31 Show int // 评论的展示状态(0显示、1不显示)
31 } 32 }
@@ -35,8 +36,9 @@ func (m *Article) TableName() string { @@ -35,8 +36,9 @@ func (m *Article) TableName() string {
35 } 36 }
36 37
37 func (m *Article) BeforeCreate(tx *gorm.DB) (err error) { 38 func (m *Article) BeforeCreate(tx *gorm.DB) (err error) {
38 - m.CreatedAt = time.Now().Unix()  
39 - m.UpdatedAt = time.Now().Unix() 39 + nowTime := time.Now().Unix()
  40 + m.CreatedAt = nowTime
  41 + m.UpdatedAt = nowTime
40 return 42 return
41 } 43 }
42 44
@@ -24,7 +24,7 @@ type ArticleBackup struct { @@ -24,7 +24,7 @@ type ArticleBackup struct {
24 Action string // 操作 24 Action string // 操作
25 WhoRead []int64 `gorm:"type:jsonb;serializer:json"` // 谁可以看 25 WhoRead []int64 `gorm:"type:jsonb;serializer:json"` // 谁可以看
26 WhoReview []int64 `gorm:"type:jsonb;serializer:json"` // 评论人 26 WhoReview []int64 `gorm:"type:jsonb;serializer:json"` // 评论人
27 - Tags []int `gorm:"type:jsonb;serializer:json"` // 标签 27 + Tags []int64 `gorm:"type:jsonb;serializer:json"` // 标签
28 TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人 28 TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人
29 } 29 }
30 30
@@ -158,6 +158,7 @@ func (repository *ArticleRepository) ModelToDomainModel(from *models.Article) (* @@ -158,6 +158,7 @@ func (repository *ArticleRepository) ModelToDomainModel(from *models.Article) (*
158 TargetUser: domain.ArticleTarget(from.TargetUser), 158 TargetUser: domain.ArticleTarget(from.TargetUser),
159 CountLove: from.CountLove, 159 CountLove: from.CountLove,
160 CountComment: from.CountComment, 160 CountComment: from.CountComment,
  161 + CountRead: from.CountRead,
161 Show: domain.ArticleShow(from.Show), 162 Show: domain.ArticleShow(from.Show),
162 } 163 }
163 return to, nil 164 return to, nil
@@ -170,6 +171,7 @@ func (repository *ArticleRepository) DomainModelToModel(from *domain.Article) (* @@ -170,6 +171,7 @@ func (repository *ArticleRepository) DomainModelToModel(from *domain.Article) (*
170 CreatedAt: from.CreatedAt, 171 CreatedAt: from.CreatedAt,
171 UpdatedAt: from.UpdatedAt, 172 UpdatedAt: from.UpdatedAt,
172 DeletedAt: from.DeletedAt, 173 DeletedAt: from.DeletedAt,
  174 + IsDel: 0,
173 Version: from.Version, 175 Version: from.Version,
174 AuthorId: from.AuthorId, 176 AuthorId: from.AuthorId,
175 Author: from.Author, 177 Author: from.Author,
@@ -180,6 +182,7 @@ func (repository *ArticleRepository) DomainModelToModel(from *domain.Article) (* @@ -180,6 +182,7 @@ func (repository *ArticleRepository) DomainModelToModel(from *domain.Article) (*
180 Location: from.Location, 182 Location: from.Location,
181 TargetUser: int(from.TargetUser), 183 TargetUser: int(from.TargetUser),
182 CountLove: from.CountLove, 184 CountLove: from.CountLove,
  185 + CountRead: from.CountRead,
183 CountComment: from.CountComment, 186 CountComment: from.CountComment,
184 Show: int(from.Show), 187 Show: int(from.Show),
185 } 188 }
@@ -24,10 +24,21 @@ type Article struct { @@ -24,10 +24,21 @@ type Article struct {
24 TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人 24 TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人
25 CountLove int `json:"countLove"` // 点赞数量 25 CountLove int `json:"countLove"` // 点赞数量
26 CountComment int `json:"countComment"` // 评论数量 26 CountComment int `json:"countComment"` // 评论数量
27 - Show ArticleShow `json:"showState"` // 评论的展示状态(0显示、1不显示) 27 + CountRead int `json:"countRead"` // 浏览数量
  28 + Show ArticleShow `json:"show"` // 评论的展示状态(0显示、1不显示)
  29 + Tags []int64 `json:"tags"`
28 // ...more 30 // ...more
29 } 31 }
30 32
  33 +type ArticleRepository interface {
  34 + Insert(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)
  35 + Update(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)
  36 + Delete(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)
  37 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)
  38 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Article, error)
  39 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Article, error)
  40 +}
  41 +
31 type ArticleTarget int 42 type ArticleTarget int
32 43
33 const ( 44 const (
@@ -63,11 +74,23 @@ func (a ArticleShow) Named() string { @@ -63,11 +74,23 @@ func (a ArticleShow) Named() string {
63 return "" 74 return ""
64 } 75 }
65 76
66 -type ArticleRepository interface {  
67 - Insert(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)  
68 - Update(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)  
69 - Delete(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)  
70 - UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error)  
71 - FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Article, error)  
72 - Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*Article, error) 77 +func (m *Article) MakeBackup(operator UserSimple, section []ArticleSection) *ArticleBackup {
  78 + b := ArticleBackup{
  79 + Id: 0,
  80 + CompanyId: 0,
  81 + CreatedAt: 0,
  82 + UpdatedAt: 0,
  83 + DeletedAt: 0,
  84 + Version: 0,
  85 + Operator: operator,
  86 + Title: m.Title,
  87 + Section: section,
  88 + Images: m.Images,
  89 + Action: "",
  90 + TargetUser: m.TargetUser,
  91 + WhoRead: m.WhoRead,
  92 + WhoReview: m.WhoReview,
  93 + Tags: m.Tags,
  94 + }
  95 + return &b
73 } 96 }
@@ -22,7 +22,7 @@ type ArticleBackup struct { @@ -22,7 +22,7 @@ type ArticleBackup struct {
22 TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人 22 TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人
23 WhoRead []int64 `json:"whoRead"` // 谁可以看 23 WhoRead []int64 `json:"whoRead"` // 谁可以看
24 WhoReview []int64 `json:"whoReview"` // 评论人 24 WhoReview []int64 `json:"whoReview"` // 评论人
25 - Tags []int `json:"tags"` // 标签 25 + Tags []int64 `json:"tags"` // 标签
26 } 26 }
27 27
28 type ArticleBackupRepository interface { 28 type ArticleBackupRepository interface {
@@ -28,3 +28,10 @@ type ArticleSectionRepository interface { @@ -28,3 +28,10 @@ type ArticleSectionRepository interface {
28 FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ArticleSection, error) 28 FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ArticleSection, error)
29 Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ArticleSection, error) 29 Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ArticleSection, error)
30 } 30 }
  31 +
  32 +// 排序文章分段列表
  33 +type SortArticleSection []*ArticleSection
  34 +
  35 +func (a SortArticleSection) Len() int { return len(a) }
  36 +func (a SortArticleSection) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
  37 +func (a SortArticleSection) Less(i, j int) bool { return a[i].SortBy < a[j].SortBy }
@@ -29,9 +29,12 @@ type Opinion struct { @@ -29,9 +29,12 @@ type Opinion struct {
29 } 29 }
30 30
31 type UserSimple struct { 31 type UserSimple struct {
32 - Id int64 `json:"id"` // 人员id  
33 - Name string `json:"name"` // 人员的名字  
34 - Avatar string `json:"avatar,omitempty"` // 人员头像URL  
35 - Group string `json:"group,omitempty"` // 人员的分组  
36 - Position string `json:"position,omitempty"` // 职位 32 + Id int64 `json:"id"` // 人员id
  33 + Name string `json:"name"` // 人员的名字
  34 + Avatar string `json:"avatar,omitempty"` // 人员头像URL
  35 + GroupId int64 `json:"groupId,omitempty"`
  36 + Group string `json:"group,omitempty"` // 人员的分组
  37 + Position string `json:"position,omitempty"` // 职位
  38 + Company string `json:"company,omitempty"` // 公司
  39 + CompanyId int64 `json:"companyId"`
37 } 40 }