正在显示
9 个修改的文件
包含
191 行增加
和
31 行删除
@@ -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, §ionList[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 | } |
-
请 注册 或 登录 后发表评论