正在显示
10 个修改的文件
包含
265 行增加
和
125 行删除
@@ -168,12 +168,14 @@ type ( | @@ -168,12 +168,14 @@ type ( | ||
168 | List []MiniArticleBackupItem `json:"list"` | 168 | List []MiniArticleBackupItem `json:"list"` |
169 | } | 169 | } |
170 | MiniArticleBackupItem { | 170 | MiniArticleBackupItem { |
171 | - Id int64 `json:"id"` | ||
172 | - Title string `json:"title"` | ||
173 | - Content string `json:"content"` | ||
174 | - Images []string `json:"images"` | ||
175 | - CreatedAt int64 `json:"createdAt"` | ||
176 | - Location Location `json:"location"` | 171 | + Id int64 `json:"id"` |
172 | + Title string `json:"title"` | ||
173 | + Content string `json:"content"` | ||
174 | + Images []string `json:"images"` | ||
175 | + Videos []Video `json:"videos"` | ||
176 | + ChangeField []string `json:"changeField"` | ||
177 | + CreatedAt int64 `json:"createdAt"` | ||
178 | + Location Location `json:"location"` | ||
177 | } | 179 | } |
178 | ) | 180 | ) |
179 | // 标记人员浏览了那个文章 | 181 | // 标记人员浏览了那个文章 |
@@ -51,17 +51,29 @@ func (l *MiniArticleBackupSearchLogic) MiniArticleBackupSearch(req *types.MiniAr | @@ -51,17 +51,29 @@ func (l *MiniArticleBackupSearchLogic) MiniArticleBackupSearch(req *types.MiniAr | ||
51 | for _, val2 := range backupList[i].Images { | 51 | for _, val2 := range backupList[i].Images { |
52 | images = append(images, val2.Url) | 52 | images = append(images, val2.Url) |
53 | } | 53 | } |
54 | + | ||
55 | + videos := []types.Video{} | ||
56 | + for _, val2 := range backupList[i].Videos { | ||
57 | + videos = append(videos, types.Video{ | ||
58 | + Url: val2.Url, | ||
59 | + Cover: val2.Cover, | ||
60 | + Width: val2.Width, | ||
61 | + Height: val2.Height, | ||
62 | + }) | ||
63 | + } | ||
54 | resp.List[i] = types.MiniArticleBackupItem{ | 64 | resp.List[i] = types.MiniArticleBackupItem{ |
55 | Id: backupList[i].Id, | 65 | Id: backupList[i].Id, |
56 | Title: backupList[i].Title, | 66 | Title: backupList[i].Title, |
57 | Content: content.String(), | 67 | Content: content.String(), |
58 | Images: images, | 68 | Images: images, |
69 | + Videos: videos, | ||
59 | CreatedAt: backupList[i].CreatedAt, | 70 | CreatedAt: backupList[i].CreatedAt, |
60 | Location: types.Location{ | 71 | Location: types.Location{ |
61 | Longitude: backupList[i].Location.Longitude, | 72 | Longitude: backupList[i].Location.Longitude, |
62 | Latitude: backupList[i].Location.Latitude, | 73 | Latitude: backupList[i].Location.Latitude, |
63 | Descript: backupList[i].Location.Descript, | 74 | Descript: backupList[i].Location.Descript, |
64 | }, | 75 | }, |
76 | + ChangeField: backupList[i].ChangeField, | ||
65 | } | 77 | } |
66 | } | 78 | } |
67 | return resp, nil | 79 | return resp, nil |
@@ -127,7 +127,7 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | @@ -127,7 +127,7 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | ||
127 | } | 127 | } |
128 | 128 | ||
129 | //切分文章分段 | 129 | //切分文章分段 |
130 | - sectionList := []domain.ArticleSection{} | 130 | + sectionList := []*domain.ArticleSection{} |
131 | newStr := "" | 131 | newStr := "" |
132 | for i := range req.Section { | 132 | for i := range req.Section { |
133 | strList := strings.Split(req.Section[i], "\n") | 133 | strList := strings.Split(req.Section[i], "\n") |
@@ -141,7 +141,7 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | @@ -141,7 +141,7 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | ||
141 | SortBy: len(sectionList), | 141 | SortBy: len(sectionList), |
142 | TotalComment: 0, | 142 | TotalComment: 0, |
143 | } | 143 | } |
144 | - sectionList = append(sectionList, newSection) | 144 | + sectionList = append(sectionList, &newSection) |
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
@@ -185,11 +185,20 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | @@ -185,11 +185,20 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR | ||
185 | 185 | ||
186 | for i := range sectionList { | 186 | for i := range sectionList { |
187 | sectionList[i].ArticleId = newArticle.Id | 187 | sectionList[i].ArticleId = newArticle.Id |
188 | - _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, §ionList[i]) | 188 | + _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, sectionList[i]) |
189 | if err != nil { | 189 | if err != nil { |
190 | return xerr.NewErrMsgErr("创建文章内容失败", err) | 190 | return xerr.NewErrMsgErr("创建文章内容失败", err) |
191 | } | 191 | } |
192 | } | 192 | } |
193 | + | ||
194 | + // 生成 备份数据 | ||
195 | + backupData := newArticle.MakeBackup(articleAuthor, sectionList) | ||
196 | + backupData.Action = "原始版本" | ||
197 | + | ||
198 | + _, err = l.svcCtx.ArticleBackupRepository.Insert(l.ctx, conn, backupData) | ||
199 | + if err != nil { | ||
200 | + return xerr.NewErrMsgErr("创建文章失败", err) | ||
201 | + } | ||
193 | return nil | 202 | return nil |
194 | }, true) | 203 | }, true) |
195 | if err != nil { | 204 | if err != nil { |
@@ -32,7 +32,7 @@ func NewSystemArticleRestoreLogic(ctx context.Context, svcCtx *svc.ServiceContex | @@ -32,7 +32,7 @@ func NewSystemArticleRestoreLogic(ctx context.Context, svcCtx *svc.ServiceContex | ||
32 | 32 | ||
33 | func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticleRestoreRequest) (resp *types.SystemArticleRestoreResponse, err error) { | 33 | func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticleRestoreRequest) (resp *types.SystemArticleRestoreResponse, err error) { |
34 | var conn = l.svcCtx.DefaultDBConn() | 34 | var conn = l.svcCtx.DefaultDBConn() |
35 | - backup, err := l.svcCtx.ArticleBackupRepository.FindOne(l.ctx, conn, req.Id) | 35 | + oldBackup, err := l.svcCtx.ArticleBackupRepository.FindOne(l.ctx, conn, req.Id) |
36 | if err != nil { | 36 | if err != nil { |
37 | return nil, xerr.NewErrMsgErr("获取编辑历史记录失败", err) | 37 | return nil, xerr.NewErrMsgErr("获取编辑历史记录失败", err) |
38 | } | 38 | } |
@@ -42,7 +42,7 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | @@ -42,7 +42,7 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | ||
42 | if err != nil { | 42 | if err != nil { |
43 | return nil, xerr.NewErrMsgErr("获取当前用户信息失败", err) | 43 | return nil, xerr.NewErrMsgErr("获取当前用户信息失败", err) |
44 | } | 44 | } |
45 | - article, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, conn, backup.ArticleId) | 45 | + article, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, conn, oldBackup.ArticleId) |
46 | if err != nil { | 46 | if err != nil { |
47 | return nil, xerr.NewErrMsgErr("获取文章失败", err) | 47 | return nil, xerr.NewErrMsgErr("获取文章失败", err) |
48 | } | 48 | } |
@@ -50,6 +50,7 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | @@ -50,6 +50,7 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | ||
50 | if err != nil { | 50 | if err != nil { |
51 | return nil, xerr.NewErrMsgErr("获取文章段落内容失败", err) | 51 | return nil, xerr.NewErrMsgErr("获取文章段落内容失败", err) |
52 | } | 52 | } |
53 | + | ||
53 | // 备份数据 | 54 | // 备份数据 |
54 | newBackUp := article.MakeBackup(domain.UserSimple{ | 55 | newBackUp := article.MakeBackup(domain.UserSimple{ |
55 | Id: userToken.UserId, | 56 | Id: userToken.UserId, |
@@ -59,15 +60,16 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | @@ -59,15 +60,16 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | ||
59 | Company: userMe.CurrentCompany.Name, | 60 | Company: userMe.CurrentCompany.Name, |
60 | }, sectionList) | 61 | }, sectionList) |
61 | newBackUp.Action = "恢复" | 62 | newBackUp.Action = "恢复" |
63 | + _ = newBackUp.CheckChangeField(oldBackup) | ||
62 | 64 | ||
63 | article.Version = article.Version + 1 | 65 | article.Version = article.Version + 1 |
64 | - article.Images = backup.Images | ||
65 | - article.Videos = backup.Videos | ||
66 | - article.Title = backup.Title | ||
67 | - article.MatchUrl = backup.MatchUrl | ||
68 | - articleSections := make([]domain.ArticleSection, 0) | ||
69 | - lo.ForEach(backup.Section, func(item domain.ArticleSection, index int) { | ||
70 | - articleSections = append(articleSections, domain.ArticleSection{ | 66 | + article.Images = oldBackup.Images |
67 | + article.Videos = oldBackup.Videos | ||
68 | + article.Title = oldBackup.Title | ||
69 | + article.MatchUrl = oldBackup.MatchUrl | ||
70 | + articleSections := make([]*domain.ArticleSection, 0) | ||
71 | + lo.ForEach(oldBackup.Section, func(item domain.ArticleSection, index int) { | ||
72 | + articleSections = append(articleSections, &domain.ArticleSection{ | ||
71 | Id: item.Id, | 73 | Id: item.Id, |
72 | CompanyId: item.CompanyId, | 74 | CompanyId: item.CompanyId, |
73 | Version: article.Version, | 75 | Version: article.Version, |
@@ -98,7 +100,7 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | @@ -98,7 +100,7 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | ||
98 | return xerr.NewErrMsgErr("恢复文章版本失败", err) | 100 | return xerr.NewErrMsgErr("恢复文章版本失败", err) |
99 | } | 101 | } |
100 | } else { | 102 | } else { |
101 | - _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, &item) | 103 | + _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, item) |
102 | if err != nil { | 104 | if err != nil { |
103 | return xerr.NewErrMsgErr("恢复文章版本失败", err) | 105 | return xerr.NewErrMsgErr("恢复文章版本失败", err) |
104 | } | 106 | } |
@@ -106,7 +108,8 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | @@ -106,7 +108,8 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl | ||
106 | updateSectionIds = append(updateSectionIds, item.Id) | 108 | updateSectionIds = append(updateSectionIds, item.Id) |
107 | } | 109 | } |
108 | if len(updateSectionIds) > 0 { | 110 | if len(updateSectionIds) > 0 { |
109 | - err = l.svcCtx.ArticleSectionRepository.DeleteBy(ctx, c, domain.NewQueryOptions().WithKV("articleId", article.Id).WithKV("notIds", updateSectionIds)) | 111 | + queryOption := domain.NewQueryOptions().WithKV("articleId", article.Id).WithKV("notIds", updateSectionIds) |
112 | + err = l.svcCtx.ArticleSectionRepository.DeleteBy(ctx, c, queryOption) | ||
110 | if err != nil { | 113 | if err != nil { |
111 | return xerr.NewErrMsgErr("保存文章内容失败", err) | 114 | return xerr.NewErrMsgErr("保存文章内容失败", err) |
112 | } | 115 | } |
@@ -57,25 +57,25 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU | @@ -57,25 +57,25 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU | ||
57 | if err != nil { | 57 | if err != nil { |
58 | return nil, xerr.NewErrMsgErr("获取当前用户信息失败", err) | 58 | return nil, xerr.NewErrMsgErr("获取当前用户信息失败", err) |
59 | } | 59 | } |
60 | + operator := domain.UserSimple{ | ||
61 | + Id: userToken.UserId, | ||
62 | + Name: userMe.User.NickName, | ||
63 | + Avatar: userMe.User.Avatar, | ||
64 | + CompanyId: userToken.CompanyId, | ||
65 | + Company: userMe.CurrentCompany.Name, | ||
66 | + } | ||
60 | // 文章数据 | 67 | // 文章数据 |
61 | article, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, l.conn, req.Id) | 68 | article, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, l.conn, req.Id) |
62 | if err != nil { | 69 | if err != nil { |
63 | return nil, xerr.NewErrMsgErr("帖子不存在", err) | 70 | return nil, xerr.NewErrMsgErr("帖子不存在", err) |
64 | } | 71 | } |
65 | - _, sectionList, err := l.svcCtx.ArticleSectionRepository.Find(l.ctx, l.conn, map[string]interface{}{"articleId": article.Id}) | 72 | + // |
73 | + queryOption := domain.NewQueryOptions().WithFindOnly().MustWithKV("articleId", req.Id) | ||
74 | + _, sectionList, err := l.svcCtx.ArticleSectionRepository.Find(l.ctx, l.conn, queryOption) | ||
66 | if err != nil { | 75 | if err != nil { |
67 | - return nil, xerr.NewErrMsgErr("获取文章段落内容失败", err) | 76 | + return nil, xerr.NewErrMsgErr("帖子不存在", err) |
68 | } | 77 | } |
69 | - //备份数据 | ||
70 | - backup := article.MakeBackup(domain.UserSimple{ | ||
71 | - Id: userToken.UserId, | ||
72 | - Name: userMe.User.NickName, | ||
73 | - Avatar: userMe.User.Avatar, | ||
74 | - CompanyId: userToken.CompanyId, | ||
75 | - Company: userMe.CurrentCompany.Name, | ||
76 | - }, sectionList) | ||
77 | - backup.Action = "编辑" | ||
78 | - | 78 | + oldBackup := article.MakeBackup(operator, sectionList) |
79 | // 获取图片的尺寸大小 | 79 | // 获取图片的尺寸大小 |
80 | images, err := l.getImages(req) | 80 | images, err := l.getImages(req) |
81 | if err != nil { | 81 | if err != nil { |
@@ -126,6 +126,7 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU | @@ -126,6 +126,7 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU | ||
126 | } | 126 | } |
127 | //文章内容 | 127 | //文章内容 |
128 | updateSectionIds := []int64{} | 128 | updateSectionIds := []int64{} |
129 | + updateSection := []*domain.ArticleSection{} | ||
129 | for _, item := range articleSections { | 130 | for _, item := range articleSections { |
130 | if item.Id > 0 { | 131 | if item.Id > 0 { |
131 | section, err := l.svcCtx.ArticleSectionRepository.FindOne(ctx, c, item.Id) | 132 | section, err := l.svcCtx.ArticleSectionRepository.FindOne(ctx, c, item.Id) |
@@ -142,22 +143,29 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU | @@ -142,22 +143,29 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU | ||
142 | return xerr.NewErrMsgErr("保存文章段落内容失败", err) | 143 | return xerr.NewErrMsgErr("保存文章段落内容失败", err) |
143 | } | 144 | } |
144 | } else { | 145 | } else { |
145 | - _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, &item) | 146 | + _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, item) |
146 | if err != nil { | 147 | if err != nil { |
147 | return xerr.NewErrMsgErr("保存文章段落内容失败", err) | 148 | return xerr.NewErrMsgErr("保存文章段落内容失败", err) |
148 | } | 149 | } |
149 | } | 150 | } |
150 | updateSectionIds = append(updateSectionIds, item.Id) | 151 | updateSectionIds = append(updateSectionIds, item.Id) |
152 | + updateSection = append(updateSection, item) | ||
151 | } | 153 | } |
152 | if len(updateSectionIds) > 0 { | 154 | if len(updateSectionIds) > 0 { |
153 | - err = l.svcCtx.ArticleSectionRepository.DeleteBy(ctx, c, domain.NewQueryOptions().WithKV("articleId", article.Id).WithKV("notIds", updateSectionIds)) | 155 | + queryOption := domain.NewQueryOptions().WithKV("articleId", article.Id).WithKV("notIds", updateSectionIds) |
156 | + err = l.svcCtx.ArticleSectionRepository.DeleteBy(ctx, c, queryOption) | ||
154 | if err != nil { | 157 | if err != nil { |
155 | return xerr.NewErrMsgErr("保存文章内容失败", err) | 158 | return xerr.NewErrMsgErr("保存文章内容失败", err) |
156 | } | 159 | } |
157 | } | 160 | } |
158 | - _, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, backup) | ||
159 | - if err != nil { | ||
160 | - return xerr.NewErrMsgErr("保存文章内容失败", err) | 161 | + |
162 | + backup := article.MakeBackup(operator, updateSection) | ||
163 | + backup.Action = "编辑" | ||
164 | + if ok := backup.CheckChangeField(oldBackup); ok { | ||
165 | + _, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, backup) | ||
166 | + if err != nil { | ||
167 | + return xerr.NewErrMsgErr("保存文章内容失败", err) | ||
168 | + } | ||
161 | } | 169 | } |
162 | //文章定性 | 170 | //文章定性 |
163 | err = l.setTags(c, article) | 171 | err = l.setTags(c, article) |
@@ -307,8 +315,8 @@ func (l *SystemUpdateArticleLogic) getVideos(req *types.SystemArticleUpdateReque | @@ -307,8 +315,8 @@ func (l *SystemUpdateArticleLogic) getVideos(req *types.SystemArticleUpdateReque | ||
307 | return videos, nil | 315 | return videos, nil |
308 | } | 316 | } |
309 | 317 | ||
310 | -func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateRequest, article *domain.Article) []domain.ArticleSection { | ||
311 | - articleSections := make([]domain.ArticleSection, 0) | 318 | +func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateRequest, article *domain.Article) []*domain.ArticleSection { |
319 | + articleSections := make([]*domain.ArticleSection, 0) | ||
312 | sortBy := 1 | 320 | sortBy := 1 |
313 | lo.ForEach(req.Section, func(item types.ArticleSection, index int) { | 321 | lo.ForEach(req.Section, func(item types.ArticleSection, index int) { |
314 | strList := strings.Split(item.Content, "\n") | 322 | strList := strings.Split(item.Content, "\n") |
@@ -326,7 +334,7 @@ func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateReq | @@ -326,7 +334,7 @@ func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateReq | ||
326 | if key == 0 { | 334 | if key == 0 { |
327 | section.Id = item.Id | 335 | section.Id = item.Id |
328 | } | 336 | } |
329 | - articleSections = append(articleSections, section) | 337 | + articleSections = append(articleSections, §ion) |
330 | sortBy++ | 338 | sortBy++ |
331 | } | 339 | } |
332 | }) | 340 | }) |
@@ -1028,12 +1028,14 @@ type MiniArticleBackupSearchResponse struct { | @@ -1028,12 +1028,14 @@ type MiniArticleBackupSearchResponse struct { | ||
1028 | } | 1028 | } |
1029 | 1029 | ||
1030 | type MiniArticleBackupItem struct { | 1030 | type MiniArticleBackupItem struct { |
1031 | - Id int64 `json:"id"` | ||
1032 | - Title string `json:"title"` | ||
1033 | - Content string `json:"content"` | ||
1034 | - Images []string `json:"images"` | ||
1035 | - CreatedAt int64 `json:"createdAt"` | ||
1036 | - Location Location `json:"location"` | 1031 | + Id int64 `json:"id"` |
1032 | + Title string `json:"title"` | ||
1033 | + Content string `json:"content"` | ||
1034 | + Images []string `json:"images"` | ||
1035 | + Videos []Video `json:"videos"` | ||
1036 | + ChangeField []string `json:"changeField"` | ||
1037 | + CreatedAt int64 `json:"createdAt"` | ||
1038 | + Location Location `json:"location"` | ||
1037 | } | 1039 | } |
1038 | 1040 | ||
1039 | type MiniArticleMarkUserReadRequest struct { | 1041 | type MiniArticleMarkUserReadRequest struct { |
@@ -10,26 +10,27 @@ import ( | @@ -10,26 +10,27 @@ import ( | ||
10 | ) | 10 | ) |
11 | 11 | ||
12 | type ArticleBackup struct { | 12 | type ArticleBackup struct { |
13 | - Id int64 `gorm:"primaryKey"` // 唯一标识 | ||
14 | - CompanyId int64 | ||
15 | - CreatedAt int64 | ||
16 | - UpdatedAt int64 | ||
17 | - DeletedAt int64 | ||
18 | - IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` | ||
19 | - Version int | ||
20 | - Operator domain.UserSimple `gorm:"type:jsonb;serializer:json"` // 操作人 | ||
21 | - ArticleId int64 | ||
22 | - Title string // 标题 | ||
23 | - Section []domain.ArticleSection `gorm:"type:jsonb;serializer:json"` // 分段内容 | ||
24 | - Images []domain.Image `gorm:"type:jsonb;serializer:json"` // 图片 | ||
25 | - Videos []domain.Video `gorm:"type:jsonb;serializer:json"` // 视频 | ||
26 | - Action string // 操作 | ||
27 | - WhoRead []int64 `gorm:"type:jsonb;serializer:json"` // 谁可以看 | ||
28 | - WhoReview []int64 `gorm:"type:jsonb;serializer:json"` // 评论人 | ||
29 | - Tags []int64 `gorm:"type:jsonb;serializer:json"` // 标签 | ||
30 | - Location domain.Location `gorm:"type:jsonb;serializer:json"` // 坐标 | ||
31 | - TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人 | ||
32 | - MatchUrl map[string]string `gorm:"type:jsonb;serializer:json"` // 匹配文章内容中的url文本 | 13 | + Id int64 `gorm:"primaryKey"` // 唯一标识 |
14 | + CompanyId int64 | ||
15 | + CreatedAt int64 | ||
16 | + UpdatedAt int64 | ||
17 | + DeletedAt int64 | ||
18 | + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"` | ||
19 | + Version int | ||
20 | + Operator domain.UserSimple `gorm:"type:jsonb;serializer:json"` // 操作人 | ||
21 | + ArticleId int64 | ||
22 | + Title string // 标题 | ||
23 | + Section []domain.ArticleSection `gorm:"type:jsonb;serializer:json"` // 分段内容 | ||
24 | + Images []domain.Image `gorm:"type:jsonb;serializer:json"` // 图片 | ||
25 | + Videos []domain.Video `gorm:"type:jsonb;serializer:json"` // 视频 | ||
26 | + ChangeField []string `gorm:"type:jsonb;serializer:json"` // | ||
27 | + Action string // 操作 | ||
28 | + WhoRead []int64 `gorm:"type:jsonb;serializer:json"` // 谁可以看 | ||
29 | + WhoReview []int64 `gorm:"type:jsonb;serializer:json"` // 评论人 | ||
30 | + Tags []int64 `gorm:"type:jsonb;serializer:json"` // 标签 | ||
31 | + Location domain.Location `gorm:"type:jsonb;serializer:json"` // 坐标 | ||
32 | + TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人 | ||
33 | + MatchUrl map[string]string `gorm:"type:jsonb;serializer:json"` // 匹配文章内容中的url文本 | ||
33 | } | 34 | } |
34 | 35 | ||
35 | func (m *ArticleBackup) TableName() string { | 36 | func (m *ArticleBackup) TableName() string { |
@@ -157,25 +157,26 @@ func (repository *ArticleBackupRepository) Find(ctx context.Context, conn transa | @@ -157,25 +157,26 @@ func (repository *ArticleBackupRepository) Find(ctx context.Context, conn transa | ||
157 | 157 | ||
158 | func (repository *ArticleBackupRepository) ModelToDomainModel(from *models.ArticleBackup) (*domain.ArticleBackup, error) { | 158 | func (repository *ArticleBackupRepository) ModelToDomainModel(from *models.ArticleBackup) (*domain.ArticleBackup, error) { |
159 | to := &domain.ArticleBackup{ | 159 | to := &domain.ArticleBackup{ |
160 | - Id: from.Id, | ||
161 | - CompanyId: from.CompanyId, | ||
162 | - CreatedAt: from.CreatedAt, | ||
163 | - UpdatedAt: from.CreatedAt, | ||
164 | - DeletedAt: from.DeletedAt, | ||
165 | - Version: from.Version, | ||
166 | - Operator: from.Operator, | ||
167 | - ArticleId: from.ArticleId, | ||
168 | - Title: from.Title, | ||
169 | - Section: from.Section, | ||
170 | - Images: from.Images, | ||
171 | - Action: from.Action, | ||
172 | - TargetUser: domain.ArticleTarget(from.TargetUser), | ||
173 | - Location: from.Location, | ||
174 | - WhoRead: from.WhoRead, | ||
175 | - WhoReview: from.WhoReview, | ||
176 | - Tags: from.Tags, | ||
177 | - MatchUrl: from.MatchUrl, | ||
178 | - Videos: from.Videos, | 160 | + Id: from.Id, |
161 | + CompanyId: from.CompanyId, | ||
162 | + CreatedAt: from.CreatedAt, | ||
163 | + UpdatedAt: from.CreatedAt, | ||
164 | + DeletedAt: from.DeletedAt, | ||
165 | + Version: from.Version, | ||
166 | + Operator: from.Operator, | ||
167 | + ArticleId: from.ArticleId, | ||
168 | + Title: from.Title, | ||
169 | + Section: from.Section, | ||
170 | + Images: from.Images, | ||
171 | + Action: from.Action, | ||
172 | + TargetUser: domain.ArticleTarget(from.TargetUser), | ||
173 | + Location: from.Location, | ||
174 | + WhoRead: from.WhoRead, | ||
175 | + WhoReview: from.WhoReview, | ||
176 | + Tags: from.Tags, | ||
177 | + MatchUrl: from.MatchUrl, | ||
178 | + ChangeField: from.ChangeField, | ||
179 | + Videos: from.Videos, | ||
179 | } | 180 | } |
180 | // err := copier.Copy(to, from) | 181 | // err := copier.Copy(to, from) |
181 | return to, nil | 182 | return to, nil |
@@ -183,26 +184,27 @@ func (repository *ArticleBackupRepository) ModelToDomainModel(from *models.Artic | @@ -183,26 +184,27 @@ func (repository *ArticleBackupRepository) ModelToDomainModel(from *models.Artic | ||
183 | 184 | ||
184 | func (repository *ArticleBackupRepository) DomainModelToModel(from *domain.ArticleBackup) (*models.ArticleBackup, error) { | 185 | func (repository *ArticleBackupRepository) DomainModelToModel(from *domain.ArticleBackup) (*models.ArticleBackup, error) { |
185 | to := &models.ArticleBackup{ | 186 | to := &models.ArticleBackup{ |
186 | - Id: from.Id, | ||
187 | - CompanyId: from.CompanyId, | ||
188 | - CreatedAt: from.CreatedAt, | ||
189 | - UpdatedAt: from.CreatedAt, | ||
190 | - DeletedAt: from.DeletedAt, | ||
191 | - IsDel: 0, | ||
192 | - Version: from.Version, | ||
193 | - Operator: from.Operator, | ||
194 | - ArticleId: from.ArticleId, | ||
195 | - Title: from.Title, | ||
196 | - Section: from.Section, | ||
197 | - Images: from.Images, | ||
198 | - Action: from.Action, | ||
199 | - WhoRead: from.WhoRead, | ||
200 | - WhoReview: from.WhoReview, | ||
201 | - Tags: from.Tags, | ||
202 | - Location: from.Location, | ||
203 | - TargetUser: int(from.TargetUser), | ||
204 | - MatchUrl: from.MatchUrl, | ||
205 | - Videos: from.Videos, | 187 | + Id: from.Id, |
188 | + CompanyId: from.CompanyId, | ||
189 | + CreatedAt: from.CreatedAt, | ||
190 | + UpdatedAt: from.CreatedAt, | ||
191 | + DeletedAt: from.DeletedAt, | ||
192 | + IsDel: 0, | ||
193 | + Version: from.Version, | ||
194 | + Operator: from.Operator, | ||
195 | + ArticleId: from.ArticleId, | ||
196 | + Title: from.Title, | ||
197 | + Section: from.Section, | ||
198 | + Images: from.Images, | ||
199 | + Action: from.Action, | ||
200 | + WhoRead: from.WhoRead, | ||
201 | + WhoReview: from.WhoReview, | ||
202 | + Tags: from.Tags, | ||
203 | + Location: from.Location, | ||
204 | + TargetUser: int(from.TargetUser), | ||
205 | + MatchUrl: from.MatchUrl, | ||
206 | + Videos: from.Videos, | ||
207 | + ChangeField: from.ChangeField, | ||
206 | } | 208 | } |
207 | // err := copier.Copy(to, from) | 209 | // err := copier.Copy(to, from) |
208 | return to, nil | 210 | return to, nil |
@@ -130,7 +130,7 @@ func (m *Article) MakeBackup(operator UserSimple, section []*ArticleSection) *Ar | @@ -130,7 +130,7 @@ func (m *Article) MakeBackup(operator UserSimple, section []*ArticleSection) *Ar | ||
130 | return &b | 130 | return &b |
131 | } | 131 | } |
132 | 132 | ||
133 | -func (m *Article) SetSummary(sectionList []ArticleSection) { | 133 | +func (m *Article) SetSummary(sectionList []*ArticleSection) { |
134 | if len(sectionList) == 0 { | 134 | if len(sectionList) == 0 { |
135 | return | 135 | return |
136 | } | 136 | } |
1 | package domain | 1 | package domain |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "bytes" | ||
4 | "context" | 5 | "context" |
6 | + "encoding/json" | ||
7 | + "fmt" | ||
8 | + "sort" | ||
5 | 9 | ||
6 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | 10 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" |
7 | ) | 11 | ) |
8 | 12 | ||
9 | // 编辑文章后保存的历史记录 | 13 | // 编辑文章后保存的历史记录 |
10 | type ArticleBackup struct { | 14 | type ArticleBackup struct { |
11 | - Id int64 `json:"id"` | ||
12 | - CompanyId int64 `json:"companyId"` | ||
13 | - CreatedAt int64 `json:"createdAt,omitempty"` | ||
14 | - UpdatedAt int64 `json:"updatedAt,omitempty"` | ||
15 | - DeletedAt int64 `json:"deletedAt,omitempty"` | ||
16 | - Version int `json:"version,omitempty"` | ||
17 | - Operator UserSimple `json:"operator"` // 操作人 | ||
18 | - ArticleId int64 `json:"articleId"` // | ||
19 | - Title string `json:"title"` // 标题 | ||
20 | - Section []ArticleSection `json:"section"` // 分段内容 | ||
21 | - Images []Image `json:"images"` // 图片 | ||
22 | - Videos []Video `json:"videos"` // 视频 | ||
23 | - Action string `json:"action"` // 操作 | ||
24 | - TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人 | ||
25 | - Location Location `json:"location"` // 定位坐标 | ||
26 | - WhoRead []int64 `json:"whoRead"` // 谁可以看 | ||
27 | - WhoReview []int64 `json:"whoReview"` // 评论人 | ||
28 | - Tags []int64 `json:"tags"` // 标签 | ||
29 | - MatchUrl map[string]string `json:"matchUrl"` // 匹配文章内容中的url文本 | 15 | + Id int64 `json:"id"` |
16 | + CompanyId int64 `json:"companyId"` | ||
17 | + CreatedAt int64 `json:"createdAt,omitempty"` | ||
18 | + UpdatedAt int64 `json:"updatedAt,omitempty"` | ||
19 | + DeletedAt int64 `json:"deletedAt,omitempty"` | ||
20 | + Version int `json:"version,omitempty"` | ||
21 | + Operator UserSimple `json:"operator"` // 操作人 | ||
22 | + ArticleId int64 `json:"articleId"` // | ||
23 | + Title string `json:"title"` // 标题 | ||
24 | + Section []ArticleSection `json:"section"` // 分段内容 | ||
25 | + Images []Image `json:"images"` // 图片 | ||
26 | + Videos []Video `json:"videos"` // 视频 | ||
27 | + Action string `json:"action"` // 操作 | ||
28 | + // 新的备份内容相对与旧的文章信息哪些内容发生了变更,可选值[WhoRead] 修改了分发对象, [WhoReview] 修改了评论范围,[Section] 修改了内容 | ||
29 | + ChangeField []string `json:"changeField"` | ||
30 | + TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人 | ||
31 | + Location Location `json:"location"` // 定位坐标 | ||
32 | + WhoRead []int64 `json:"whoRead"` // 谁可以看 | ||
33 | + WhoReview []int64 `json:"whoReview"` // 评论人 | ||
34 | + Tags []int64 `json:"tags"` // 标签 | ||
35 | + MatchUrl map[string]string `json:"matchUrl"` // 匹配文章内容中的url文本 | ||
30 | } | 36 | } |
31 | 37 | ||
32 | type ArticleBackupRepository interface { | 38 | type ArticleBackupRepository interface { |
@@ -37,3 +43,98 @@ type ArticleBackupRepository interface { | @@ -37,3 +43,98 @@ type ArticleBackupRepository interface { | ||
37 | FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ArticleBackup, error) | 43 | FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ArticleBackup, error) |
38 | Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ArticleBackup, error) | 44 | Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ArticleBackup, error) |
39 | } | 45 | } |
46 | + | ||
47 | +// 检查新的备份内容相对与旧的文章信息哪些内容发生了变更 | ||
48 | +// 记录ArticleBackup中数据发生变更的的字段名 | ||
49 | +func (bk *ArticleBackup) CheckChangeField(oldBackup *ArticleBackup) bool { | ||
50 | + bk.ChangeField = make([]string, 0) | ||
51 | + //比较 WhoRead | ||
52 | + { | ||
53 | + whoReadChanged := false | ||
54 | + sort.Slice(bk.WhoRead, func(i, j int) bool { | ||
55 | + return bk.WhoRead[i] < bk.WhoRead[j] | ||
56 | + }) | ||
57 | + sort.Slice(oldBackup.WhoRead, func(i, j int) bool { | ||
58 | + return oldBackup.WhoRead[i] < oldBackup.WhoRead[j] | ||
59 | + }) | ||
60 | + | ||
61 | + if len(bk.WhoRead) != len(oldBackup.WhoRead) { | ||
62 | + whoReadChanged = true | ||
63 | + } else { | ||
64 | + for i := range bk.WhoRead { | ||
65 | + if bk.WhoRead[i] != oldBackup.WhoRead[i] { | ||
66 | + whoReadChanged = true | ||
67 | + } | ||
68 | + } | ||
69 | + } | ||
70 | + if whoReadChanged { | ||
71 | + bk.ChangeField = append(bk.ChangeField, "WhoRead") | ||
72 | + } | ||
73 | + } | ||
74 | + | ||
75 | + //比较 whoReview | ||
76 | + { | ||
77 | + whoReviewChanged := false | ||
78 | + sort.Slice(bk.WhoReview, func(i, j int) bool { | ||
79 | + return bk.WhoReview[i] < bk.WhoReview[j] | ||
80 | + }) | ||
81 | + sort.Slice(oldBackup.WhoReview, func(i, j int) bool { | ||
82 | + return oldBackup.WhoReview[i] < oldBackup.WhoReview[j] | ||
83 | + }) | ||
84 | + | ||
85 | + if len(bk.WhoReview) != len(oldBackup.WhoReview) { | ||
86 | + whoReviewChanged = true | ||
87 | + } else { | ||
88 | + for i := range bk.WhoReview { | ||
89 | + if bk.WhoReview[i] != oldBackup.WhoReview[i] { | ||
90 | + whoReviewChanged = true | ||
91 | + } | ||
92 | + } | ||
93 | + } | ||
94 | + if whoReviewChanged { | ||
95 | + bk.ChangeField = append(bk.ChangeField, "WhoReview") | ||
96 | + } | ||
97 | + } | ||
98 | + //比较段落内容+图片+视频 是否发生变更 | ||
99 | + { | ||
100 | + sectionChanged := false | ||
101 | + newSectionData := map[string]string{ | ||
102 | + "title": bk.Title, | ||
103 | + } | ||
104 | + | ||
105 | + oldSectionData := map[string]string{ | ||
106 | + "title": oldBackup.Title, | ||
107 | + } | ||
108 | + | ||
109 | + for _, val := range bk.Section { | ||
110 | + mkey := fmt.Sprintf("section-%d", val.SortBy) | ||
111 | + newSectionData[mkey] = val.Content | ||
112 | + } | ||
113 | + for _, val := range bk.Images { | ||
114 | + newSectionData[val.Url] = "" | ||
115 | + } | ||
116 | + for _, val := range bk.Videos { | ||
117 | + newSectionData[val.Url] = "" | ||
118 | + } | ||
119 | + | ||
120 | + for _, val := range oldBackup.Section { | ||
121 | + mKey := fmt.Sprintf("section-%d", val.SortBy) | ||
122 | + oldSectionData[mKey] = val.Content | ||
123 | + } | ||
124 | + for _, val := range oldBackup.Images { | ||
125 | + oldSectionData[val.Url] = "" | ||
126 | + } | ||
127 | + for _, val := range oldBackup.Videos { | ||
128 | + oldSectionData[val.Url] = "" | ||
129 | + } | ||
130 | + newSectionJson, _ := json.Marshal(newSectionData) | ||
131 | + oldSectionJson, _ := json.Marshal(oldSectionData) | ||
132 | + if ok := bytes.Equal(newSectionJson, oldSectionJson); !ok { | ||
133 | + sectionChanged = true | ||
134 | + } | ||
135 | + if sectionChanged { | ||
136 | + bk.ChangeField = append(bk.ChangeField, "Section") | ||
137 | + } | ||
138 | + } | ||
139 | + return len(bk.ChangeField) > 0 | ||
140 | +} |
-
请 注册 或 登录 后发表评论