作者 yangfu

Merge branch 'test'

@@ -65,6 +65,9 @@ service Core { @@ -65,6 +65,9 @@ service Core {
65 @handler MiniArticleBackupSearch 65 @handler MiniArticleBackupSearch
66 post /article_backup/search (MiniArticleBackupSearchRequest) returns (MiniArticleBackupSearchResponse) 66 post /article_backup/search (MiniArticleBackupSearchRequest) returns (MiniArticleBackupSearchResponse)
67 67
  68 + @doc "小程序获取文章的编辑记录"
  69 + @handler MiniGetArticleBackup
  70 + get /article_backup/:id (MiniGetArticleBackupRequest) returns (MiniGetArticleBackupResponse)
68 71
69 @doc "小程序设置文章的定性标签" 72 @doc "小程序设置文章的定性标签"
70 @handler MiniArticleSetTag 73 @handler MiniArticleSetTag
@@ -172,10 +172,36 @@ type ( @@ -172,10 +172,36 @@ type (
172 Title string `json:"title"` 172 Title string `json:"title"`
173 Content string `json:"content"` 173 Content string `json:"content"`
174 Images []string `json:"images"` 174 Images []string `json:"images"`
  175 + Videos []Video `json:"videos"`
  176 + ChangeField []string `json:"changeField"`
175 CreatedAt int64 `json:"createdAt"` 177 CreatedAt int64 `json:"createdAt"`
176 Location Location `json:"location"` 178 Location Location `json:"location"`
  179 + Action string `json:"action"`
  180 + Show int `json:"show"`
177 } 181 }
178 ) 182 )
  183 +
  184 +type (
  185 + MiniGetArticleBackupRequest {
  186 + BackupId int64 `path:"id"`
  187 + CompanyId int64 `path:",optional"` // 服务端自动获取
  188 + }
  189 + MiniGetArticleBackupResponse {
  190 + Id int64 `json:"id"`
  191 + Title string `json:"title"`
  192 + Content string `json:"content"`
  193 + Images []string `json:"images"`
  194 + Videos []Video `json:"videos"`
  195 + ChangeField []string `json:"changeField"`
  196 + CreatedAt int64 `json:"createdAt"`
  197 + Location Location `json:"location"`
  198 + Action string `json:"action"`
  199 + Show int `json:"show"`
  200 + }
  201 +)
  202 +
  203 +
  204 +
179 // 标记人员浏览了那个文章 205 // 标记人员浏览了那个文章
180 type ( 206 type (
181 MiniArticleMarkUserReadRequest { 207 MiniArticleMarkUserReadRequest {
@@ -391,6 +417,7 @@ type ( @@ -391,6 +417,7 @@ type (
391 Tags []int64 `json:"tags,optional"` //标签 417 Tags []int64 `json:"tags,optional"` //标签
392 Page int `json:"page"` //页码 418 Page int `json:"page"` //页码
393 Size int `json:"size"` //每页行数 419 Size int `json:"size"` //每页行数
  420 + OrderMode string `json:"orderMode,optional"` //排序方式
394 } 421 }
395 422
396 SystemArticleSearchResponse { 423 SystemArticleSearchResponse {
@@ -417,7 +444,7 @@ type ( @@ -417,7 +444,7 @@ type (
417 SystemArticleUpdateRequest { 444 SystemArticleUpdateRequest {
418 Id int64 `json:"id"` 445 Id int64 `json:"id"`
419 CompanyId int64 `json:"companyId,optional"` 446 CompanyId int64 `json:"companyId,optional"`
420 - Template int `json:"template"` // 使用哪个模板进行编辑 0、无 1、演绎式 2、归纳式 447 + Template int `json:"template,optional"` // 使用哪个模板进行编辑 0、无 1、演绎式 2、归纳式
421 Section []ArticleSection `json:"section"` // 填写的内容 448 Section []ArticleSection `json:"section"` // 填写的内容
422 Title string `json:"title"` // 标题 449 Title string `json:"title"` // 标题
423 Images []string `json:"images"` // 图片 450 Images []string `json:"images"` // 图片
  1 +package article
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/article"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
  10 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result"
  11 +)
  12 +
  13 +func MiniGetArticleBackupHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  14 + return func(w http.ResponseWriter, r *http.Request) {
  15 + var req types.MiniGetArticleBackupRequest
  16 + if err := httpx.Parse(r, &req); err != nil {
  17 + result.HttpResult(r, w, nil, err)
  18 + return
  19 + }
  20 +
  21 + l := article.NewMiniGetArticleBackupLogic(r.Context(), svcCtx)
  22 + resp, err := l.MiniGetArticleBackup(&req)
  23 + result.HttpResult(r, w, resp, err)
  24 + }
  25 +}
@@ -529,6 +529,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -529,6 +529,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
529 Handler: article.MiniArticleBackupSearchHandler(serverCtx), 529 Handler: article.MiniArticleBackupSearchHandler(serverCtx),
530 }, 530 },
531 { 531 {
  532 + Method: http.MethodGet,
  533 + Path: "/article_backup/:id",
  534 + Handler: article.MiniGetArticleBackupHandler(serverCtx),
  535 + },
  536 + {
532 Method: http.MethodPost, 537 Method: http.MethodPost,
533 Path: "/article/set_tag", 538 Path: "/article/set_tag",
534 Handler: article.MiniArticleSetTagHandler(serverCtx), 539 Handler: article.MiniArticleSetTagHandler(serverCtx),
@@ -51,18 +51,50 @@ func (l *MiniArticleBackupSearchLogic) MiniArticleBackupSearch(req *types.MiniAr @@ -51,18 +51,50 @@ 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 - resp.List[i] = types.MiniArticleBackupItem{ 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 + }
  64 + item := types.MiniArticleBackupItem{
55 Id: backupList[i].Id, 65 Id: backupList[i].Id,
56 - Title: backupList[i].Title,  
57 - Content: content.String(),  
58 - Images: images, 66 + Title: "",
  67 + Content: "",
  68 + Images: []string{},
  69 + Videos: []types.Video{},
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,
  77 + Action: backupList[i].Action,
  78 + Show: int(backupList[i].Show),
  79 + }
  80 + //根据修改的内容替换展示内容
  81 + changeFiled := []string{}
  82 + for _, val := range item.ChangeField {
  83 + switch val {
  84 + case "WhoRead":
  85 + changeFiled = append(changeFiled, "修改了分发对象")
  86 + case "WhoReview":
  87 + changeFiled = append(changeFiled, "修改了评论范围")
  88 + case "Section":
  89 + item.Title = backupList[i].Title
  90 + item.Content = content.String()
  91 + item.Images = images
  92 + item.Videos = videos
65 } 93 }
66 } 94 }
  95 + item.ChangeField = changeFiled
  96 + resp.List[i] = item
  97 +
  98 + }
67 return resp, nil 99 return resp, nil
68 } 100 }
@@ -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,19 @@ func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateR @@ -185,11 +185,19 @@ 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, &sectionList[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 + var backupData domain.ArticleBackup
  196 + backupData.MakeBackup(articleAuthor, newArticle, sectionList, "原始版本")
  197 + _, err = l.svcCtx.ArticleBackupRepository.Insert(l.ctx, conn, &backupData)
  198 + if err != nil {
  199 + return xerr.NewErrMsgErr("创建文章失败", err)
  200 + }
193 return nil 201 return nil
194 }, true) 202 }, true)
195 if err != nil { 203 if err != nil {
  1 +package article
  2 +
  3 +import (
  4 + "context"
  5 + "strings"
  6 +
  7 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
  8 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
  9 + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"
  10 +
  11 + "github.com/zeromicro/go-zero/core/logx"
  12 +)
  13 +
  14 +type MiniGetArticleBackupLogic struct {
  15 + logx.Logger
  16 + ctx context.Context
  17 + svcCtx *svc.ServiceContext
  18 +}
  19 +
  20 +func NewMiniGetArticleBackupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniGetArticleBackupLogic {
  21 + return &MiniGetArticleBackupLogic{
  22 + Logger: logx.WithContext(ctx),
  23 + ctx: ctx,
  24 + svcCtx: svcCtx,
  25 + }
  26 +}
  27 +
  28 +func (l *MiniGetArticleBackupLogic) MiniGetArticleBackup(req *types.MiniGetArticleBackupRequest) (resp *types.MiniGetArticleBackupResponse, err error) {
  29 + var conn = l.svcCtx.DefaultDBConn()
  30 +
  31 + backupInfo, err := l.svcCtx.ArticleBackupRepository.FindOne(l.ctx, conn, req.BackupId)
  32 + if err != nil {
  33 + return &types.MiniGetArticleBackupResponse{}, xerr.NewErrMsgErr("获取编辑记录失败", err)
  34 + }
  35 +
  36 + content := strings.Builder{}
  37 + for _, val2 := range backupInfo.Section {
  38 + content.WriteString(val2.Content)
  39 + }
  40 + images := []string{}
  41 + for _, val2 := range backupInfo.Images {
  42 + images = append(images, val2.Url)
  43 + }
  44 +
  45 + videos := []types.Video{}
  46 + for _, val2 := range backupInfo.Videos {
  47 + videos = append(videos, types.Video{
  48 + Url: val2.Url,
  49 + Cover: val2.Cover,
  50 + Width: val2.Width,
  51 + Height: val2.Height,
  52 + })
  53 + }
  54 +
  55 + resp = &types.MiniGetArticleBackupResponse{
  56 + Id: backupInfo.Id,
  57 + Title: backupInfo.Title,
  58 + Content: content.String(),
  59 + Images: images,
  60 + Videos: videos,
  61 + CreatedAt: backupInfo.CreatedAt,
  62 + Location: types.Location{
  63 + Longitude: backupInfo.Location.Longitude,
  64 + Latitude: backupInfo.Location.Latitude,
  65 + Descript: backupInfo.Location.Descript,
  66 + },
  67 + ChangeField: backupInfo.ChangeField,
  68 + Action: backupInfo.Action,
  69 + Show: int(backupInfo.Show),
  70 + }
  71 +
  72 + return
  73 +}
@@ -42,26 +42,9 @@ func (l *MiniGetArticleLogic) MiniGetArticle(req *types.MiniArticleGetRequest) ( @@ -42,26 +42,9 @@ func (l *MiniGetArticleLogic) MiniGetArticle(req *types.MiniArticleGetRequest) (
42 return nil, xerr.NewErrMsg("没有查看权限") 42 return nil, xerr.NewErrMsg("没有查看权限")
43 } 43 }
44 // 检查文章的可查看人 44 // 检查文章的可查看人
45 - if articleInfo.AuthorId != int64(req.UserId) {  
46 - if len(articleInfo.WhoRead) > 0 {  
47 - inWhoRead := false  
48 - for _, val := range articleInfo.WhoRead {  
49 - if req.UserId == int(val) {  
50 - inWhoRead = true  
51 - }  
52 - }  
53 - if !inWhoRead {  
54 - // 文章内容不显示  
55 - // resp = &types.MiniArticleGetResponse{  
56 - // Id: articleInfo.Id,  
57 - // Title: articleInfo.Title,  
58 - // Show: int(domain.ArticleShowDisable),  
59 - // }  
60 - // return resp, nil 45 + if ok := articleInfo.WhoCanRead(int64(req.UserId)); !ok {
61 return nil, xerr.NewErrMsg("没有查看权限") 46 return nil, xerr.NewErrMsg("没有查看权限")
62 } 47 }
63 - }  
64 - }  
65 if articleInfo.Show == domain.ArticleShowDisable { 48 if articleInfo.Show == domain.ArticleShowDisable {
66 // 文章内容不显示 49 // 文章内容不显示
67 // resp = &types.MiniArticleGetResponse{ 50 // resp = &types.MiniArticleGetResponse{
@@ -110,8 +93,8 @@ func (l *MiniGetArticleLogic) MiniGetArticle(req *types.MiniArticleGetRequest) ( @@ -110,8 +93,8 @@ func (l *MiniGetArticleLogic) MiniGetArticle(req *types.MiniArticleGetRequest) (
110 93
111 follow, _ := l.svcCtx.UserFollowRepository.FindOneUserFollowing(l.ctx, conn, int64(req.UserId), articleInfo.AuthorId) 94 follow, _ := l.svcCtx.UserFollowRepository.FindOneUserFollowing(l.ctx, conn, int64(req.UserId), articleInfo.AuthorId)
112 95
113 - queryOption = domain.NewQueryOptions().WithFindOnly().WithOffsetLimit(1, 1).WithKV("articleId", articleInfo.Id)  
114 - _, backupList, _ := l.svcCtx.ArticleBackupRepository.Find(l.ctx, conn, queryOption) 96 + queryOption = domain.NewQueryOptions().WithCountOnly().WithOffsetLimit(1, 1).WithKV("articleId", articleInfo.Id)
  97 + backupCount, _, _ := l.svcCtx.ArticleBackupRepository.Find(l.ctx, conn, queryOption)
115 98
116 sortBy := domain.SortArticleSection(sectionList) 99 sortBy := domain.SortArticleSection(sectionList)
117 sort.Sort(sortBy) 100 sort.Sort(sortBy)
@@ -157,7 +140,7 @@ func (l *MiniGetArticleLogic) MiniGetArticle(req *types.MiniArticleGetRequest) ( @@ -157,7 +140,7 @@ func (l *MiniGetArticleLogic) MiniGetArticle(req *types.MiniArticleGetRequest) (
157 MatchUrl: map[string]string{}, 140 MatchUrl: map[string]string{},
158 Videos: []types.Video{}, 141 Videos: []types.Video{},
159 } 142 }
160 - if len(backupList) > 0 { 143 + if backupCount > 1 {
161 resp.Edit = 1 144 resp.Edit = 1
162 } 145 }
163 if author != nil { 146 if author != nil {
@@ -39,6 +39,9 @@ func (l *MiniShowHomePageLogic) MiniShowHomePage(req *types.MiniHomePageRequest) @@ -39,6 +39,9 @@ func (l *MiniShowHomePageLogic) MiniShowHomePage(req *types.MiniHomePageRequest)
39 if err != nil { 39 if err != nil {
40 return nil, xerr.NewErrMsgErr("获取文章汇总数量失败", err) 40 return nil, xerr.NewErrMsgErr("获取文章汇总数量失败", err)
41 } 41 }
  42 +
  43 + //TODO 拆分统计
  44 +
42 countDataMap := map[int64]*domain.CountArticleTagRead{} 45 countDataMap := map[int64]*domain.CountArticleTagRead{}
43 for _, val := range countData { 46 for _, val := range countData {
44 countDataMap[val.TagId] = val 47 countDataMap[val.TagId] = val
@@ -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,24 +50,26 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl @@ -50,24 +50,26 @@ 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 + var newBackUp domain.ArticleBackup
  56 + newBackUp.MakeBackup(domain.UserSimple{
55 Id: userToken.UserId, 57 Id: userToken.UserId,
56 Name: userMe.User.NickName, 58 Name: userMe.User.NickName,
57 Avatar: userMe.User.Avatar, 59 Avatar: userMe.User.Avatar,
58 CompanyId: userToken.CompanyId, 60 CompanyId: userToken.CompanyId,
59 Company: userMe.CurrentCompany.Name, 61 Company: userMe.CurrentCompany.Name,
60 - }, sectionList)  
61 - newBackUp.Action = "恢复" 62 + }, article, sectionList, "恢复")
  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,13 +108,14 @@ func (l *SystemArticleRestoreLogic) SystemArticleRestore(req *types.SystemArticl @@ -106,13 +108,14 @@ 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 }
113 } 116 }
114 117
115 - _, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, newBackUp) 118 + _, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, &newBackUp)
116 if err != nil { 119 if err != nil {
117 return xerr.NewErrMsgErr("恢复文章版本失败", err) 120 return xerr.NewErrMsgErr("恢复文章版本失败", err)
118 } 121 }
@@ -2,6 +2,7 @@ package article @@ -2,6 +2,7 @@ package article
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 +
5 "github.com/samber/lo" 6 "github.com/samber/lo"
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"
@@ -33,7 +34,9 @@ func (l *SystemSearchArticleLogic) SystemSearchArticle(req *types.SystemArticleS @@ -33,7 +34,9 @@ func (l *SystemSearchArticleLogic) SystemSearchArticle(req *types.SystemArticleS
33 WithKV("authorId", req.Author). 34 WithKV("authorId", req.Author).
34 WithKV("tags", req.Tags). 35 WithKV("tags", req.Tags).
35 WithKV("beginCreatedAt", req.BeginTime). 36 WithKV("beginCreatedAt", req.BeginTime).
36 - WithKV("endCreatedAt", req.EndTime) 37 + WithKV("endCreatedAt", req.EndTime).
  38 + WithKV("orderMode", req.OrderMode)
  39 +
37 total, articles, err := l.svcCtx.ArticleRepository.Find(l.ctx, conn, req.CompanyId, queryOptions) 40 total, articles, err := l.svcCtx.ArticleRepository.Find(l.ctx, conn, req.CompanyId, queryOptions)
38 if err != nil { 41 if err != nil {
39 return nil, xerr.NewErrMsgErr("搜索帖子异常", err) 42 return nil, xerr.NewErrMsgErr("搜索帖子异常", err)
@@ -57,24 +57,26 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU @@ -57,24 +57,26 @@ 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 + var oldBackup domain.ArticleBackup
  79 + oldBackup.MakeBackup(operator, article, sectionList, "编辑")
78 80
79 // 获取图片的尺寸大小 81 // 获取图片的尺寸大小
80 images, err := l.getImages(req) 82 images, err := l.getImages(req)
@@ -126,6 +128,7 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU @@ -126,6 +128,7 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU
126 } 128 }
127 //文章内容 129 //文章内容
128 updateSectionIds := []int64{} 130 updateSectionIds := []int64{}
  131 + updateSection := []*domain.ArticleSection{}
129 for _, item := range articleSections { 132 for _, item := range articleSections {
130 if item.Id > 0 { 133 if item.Id > 0 {
131 section, err := l.svcCtx.ArticleSectionRepository.FindOne(ctx, c, item.Id) 134 section, err := l.svcCtx.ArticleSectionRepository.FindOne(ctx, c, item.Id)
@@ -142,23 +145,30 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU @@ -142,23 +145,30 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU
142 return xerr.NewErrMsgErr("保存文章段落内容失败", err) 145 return xerr.NewErrMsgErr("保存文章段落内容失败", err)
143 } 146 }
144 } else { 147 } else {
145 - _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, &item) 148 + _, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, item)
146 if err != nil { 149 if err != nil {
147 return xerr.NewErrMsgErr("保存文章段落内容失败", err) 150 return xerr.NewErrMsgErr("保存文章段落内容失败", err)
148 } 151 }
149 } 152 }
150 updateSectionIds = append(updateSectionIds, item.Id) 153 updateSectionIds = append(updateSectionIds, item.Id)
  154 + updateSection = append(updateSection, item)
151 } 155 }
152 if len(updateSectionIds) > 0 { 156 if len(updateSectionIds) > 0 {
153 - err = l.svcCtx.ArticleSectionRepository.DeleteBy(ctx, c, domain.NewQueryOptions().WithKV("articleId", article.Id).WithKV("notIds", updateSectionIds)) 157 + queryOption := domain.NewQueryOptions().WithKV("articleId", article.Id).WithKV("notIds", updateSectionIds)
  158 + err = l.svcCtx.ArticleSectionRepository.DeleteBy(ctx, c, queryOption)
154 if err != nil { 159 if err != nil {
155 return xerr.NewErrMsgErr("保存文章内容失败", err) 160 return xerr.NewErrMsgErr("保存文章内容失败", err)
156 } 161 }
157 } 162 }
158 - _, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, backup) 163 + var backup domain.ArticleBackup
  164 + backup.MakeBackup(operator, article, updateSection, "编辑")
  165 +
  166 + if ok := backup.CheckChangeField(&oldBackup); ok {
  167 + _, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, &backup)
159 if err != nil { 168 if err != nil {
160 return xerr.NewErrMsgErr("保存文章内容失败", err) 169 return xerr.NewErrMsgErr("保存文章内容失败", err)
161 } 170 }
  171 + }
162 //文章定性 172 //文章定性
163 err = l.setTags(c, article) 173 err = l.setTags(c, article)
164 if err != nil { 174 if err != nil {
@@ -307,8 +317,8 @@ func (l *SystemUpdateArticleLogic) getVideos(req *types.SystemArticleUpdateReque @@ -307,8 +317,8 @@ func (l *SystemUpdateArticleLogic) getVideos(req *types.SystemArticleUpdateReque
307 return videos, nil 317 return videos, nil
308 } 318 }
309 319
310 -func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateRequest, article *domain.Article) []domain.ArticleSection {  
311 - articleSections := make([]domain.ArticleSection, 0) 320 +func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateRequest, article *domain.Article) []*domain.ArticleSection {
  321 + articleSections := make([]*domain.ArticleSection, 0)
312 sortBy := 1 322 sortBy := 1
313 lo.ForEach(req.Section, func(item types.ArticleSection, index int) { 323 lo.ForEach(req.Section, func(item types.ArticleSection, index int) {
314 strList := strings.Split(item.Content, "\n") 324 strList := strings.Split(item.Content, "\n")
@@ -326,7 +336,7 @@ func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateReq @@ -326,7 +336,7 @@ func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateReq
326 if key == 0 { 336 if key == 0 {
327 section.Id = item.Id 337 section.Id = item.Id
328 } 338 }
329 - articleSections = append(articleSections, section) 339 + articleSections = append(articleSections, &section)
330 sortBy++ 340 sortBy++
331 } 341 }
332 }) 342 })
@@ -52,12 +52,9 @@ func (l *MiniCreateArticleCommentLogic) MiniCreateArticleComment(req *types.Mini @@ -52,12 +52,9 @@ func (l *MiniCreateArticleCommentLogic) MiniCreateArticleComment(req *types.Mini
52 return nil, xerr.NewErrMsg("没有评论权限") 52 return nil, xerr.NewErrMsg("没有评论权限")
53 } 53 }
54 //查看评论权限, 54 //查看评论权限,
55 - if len(articleInfo.WhoReview) > 0 {  
56 - ok := lo.IndexOf(articleInfo.WhoReview, req.FromUserId)  
57 - if ok < 0 { 55 + if ok := articleInfo.WhoCanReview(req.FromUserId); !ok {
58 return nil, xerr.NewErrMsg("没有评论权限") 56 return nil, xerr.NewErrMsg("没有评论权限")
59 } 57 }
60 - }  
61 // 对段落进行评论 58 // 对段落进行评论
62 var selctionInfo *domain.ArticleSection 59 var selctionInfo *domain.ArticleSection
63 if req.SectionId > 0 { 60 if req.SectionId > 0 {
@@ -184,15 +181,7 @@ func (l *MiniCreateArticleCommentLogic) MiniCreateArticleComment(req *types.Mini @@ -184,15 +181,7 @@ func (l *MiniCreateArticleCommentLogic) MiniCreateArticleComment(req *types.Mini
184 return err 181 return err
185 } 182 }
186 } 183 }
187 - //增加评论回复计数  
188 - // if pComment != nil {  
189 - // err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, 1, pComment.Id)  
190 - // if err != nil {  
191 - // return err  
192 - // }  
193 - // }  
194 // 增加最顶层的评论回复计数 184 // 增加最顶层的评论回复计数
195 - // if newComment.TopId != 0 && newComment.Pid != newComment.TopId {  
196 if newComment.TopId != 0 { 185 if newComment.TopId != 0 {
197 err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, 1, newComment.TopId) 186 err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, 1, newComment.TopId)
198 if err != nil { 187 if err != nil {
@@ -52,13 +52,6 @@ func (l *MiniDeleteArticleCommentLogic) MiniDeleteArticleComment(req *types.Mini @@ -52,13 +52,6 @@ func (l *MiniDeleteArticleCommentLogic) MiniDeleteArticleComment(req *types.Mini
52 if err != nil { 52 if err != nil {
53 return err 53 return err
54 } 54 }
55 - // 减少上级评论的回复数量  
56 - // if commentInfo.Pid != 0 {  
57 - // err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, -1, commentInfo.Pid)  
58 - // if err != nil {  
59 - // return err  
60 - // }  
61 - // }  
62 // 减少最顶层的评论回复计数 55 // 减少最顶层的评论回复计数
63 // if commentInfo.TopId != 0 && commentInfo.Pid != commentInfo.TopId { 56 // if commentInfo.TopId != 0 && commentInfo.Pid != commentInfo.TopId {
64 if commentInfo.TopId != 0 { 57 if commentInfo.TopId != 0 {
@@ -80,15 +80,6 @@ func (l *SystemEditAticleCommentShowLogic) disableShow(commentId int64, companyI @@ -80,15 +80,6 @@ func (l *SystemEditAticleCommentShowLogic) disableShow(commentId int64, companyI
80 if err != nil { 80 if err != nil {
81 return err 81 return err
82 } 82 }
83 - // 减少上级评论的回复数量  
84 - // if commentInfo.Pid != 0 {  
85 - // err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, -1, commentInfo.Pid)  
86 - // if err != nil {  
87 - // return err  
88 - // }  
89 - // }  
90 - // 减少最顶层的评论回复计数  
91 - // if commentInfo.TopId != 0 && commentInfo.Pid != commentInfo.TopId {  
92 if commentInfo.TopId != 0 { 83 if commentInfo.TopId != 0 {
93 err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, -1, commentInfo.TopId) 84 err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, -1, commentInfo.TopId)
94 if err != nil { 85 if err != nil {
@@ -157,15 +148,8 @@ func (l *SystemEditAticleCommentShowLogic) enableShow(commentId int64, companyId @@ -157,15 +148,8 @@ func (l *SystemEditAticleCommentShowLogic) enableShow(commentId int64, companyId
157 if err != nil { 148 if err != nil {
158 return err 149 return err
159 } 150 }
160 - // 增加上级评论的回复数量  
161 - // if commetInfo.Pid != 0 {  
162 - // err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, 1, commetInfo.Pid)  
163 - // if err != nil {  
164 - // return err  
165 - // }  
166 - // } 151 +
167 // 增加最顶层的评论回复计数 152 // 增加最顶层的评论回复计数
168 - // if commetInfo.TopId != 0 && commetInfo.Pid != commetInfo.TopId {  
169 if commetInfo.TopId != 0 { 153 if commetInfo.TopId != 0 {
170 err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, 1, commetInfo.TopId) 154 err = l.svcCtx.ArticleCommentRepository.IncreaseCountReply(l.ctx, c, 1, commetInfo.TopId)
171 if err != nil { 155 if err != nil {
@@ -489,7 +489,7 @@ type MiniHomepageUserNewsRequest struct { @@ -489,7 +489,7 @@ type MiniHomepageUserNewsRequest struct {
489 LastArticleId int64 `json:"lastArticleId,optional"` // 最后文章ID 489 LastArticleId int64 `json:"lastArticleId,optional"` // 最后文章ID
490 Size int `json:"size"` // 数量 490 Size int `json:"size"` // 数量
491 OrderByKey string `json:"orderByKey,options=HotScore|All|Time,optional,default=desc"` // 按规则排序 (热度:HotScore All:时间排序 Time:时间排序) 491 OrderByKey string `json:"orderByKey,options=HotScore|All|Time,optional,default=desc"` // 按规则排序 (热度:HotScore All:时间排序 Time:时间排序)
492 - OrderByValue string `json:"orderByValue,options=asc||desc,optional"` 492 + OrderByValue string `json:"orderByValue,options=asc||desc,optional"` // 排序值 升序 asc 降序 desc
493 Keywords string `json:"keywords,optional"` // 关键字 493 Keywords string `json:"keywords,optional"` // 关键字
494 BeginTime int64 `json:"beginTime,optional"` // 开始时间 494 BeginTime int64 `json:"beginTime,optional"` // 开始时间
495 EndTime int64 `json:"endTime,optional"` // 结束时间 495 EndTime int64 `json:"endTime,optional"` // 结束时间
@@ -1033,8 +1033,30 @@ type MiniArticleBackupItem struct { @@ -1033,8 +1033,30 @@ type MiniArticleBackupItem struct {
1033 Title string `json:"title"` 1033 Title string `json:"title"`
1034 Content string `json:"content"` 1034 Content string `json:"content"`
1035 Images []string `json:"images"` 1035 Images []string `json:"images"`
  1036 + Videos []Video `json:"videos"`
  1037 + ChangeField []string `json:"changeField"`
1036 CreatedAt int64 `json:"createdAt"` 1038 CreatedAt int64 `json:"createdAt"`
1037 Location Location `json:"location"` 1039 Location Location `json:"location"`
  1040 + Action string `json:"action"`
  1041 + Show int `json:"show"`
  1042 +}
  1043 +
  1044 +type MiniGetArticleBackupRequest struct {
  1045 + BackupId int64 `path:"id"`
  1046 + CompanyId int64 `path:",optional"` // 服务端自动获取
  1047 +}
  1048 +
  1049 +type MiniGetArticleBackupResponse struct {
  1050 + Id int64 `json:"id"`
  1051 + Title string `json:"title"`
  1052 + Content string `json:"content"`
  1053 + Images []string `json:"images"`
  1054 + Videos []Video `json:"videos"`
  1055 + ChangeField []string `json:"changeField"`
  1056 + CreatedAt int64 `json:"createdAt"`
  1057 + Location Location `json:"location"`
  1058 + Action string `json:"action"`
  1059 + Show int `json:"show"`
1038 } 1060 }
1039 1061
1040 type MiniArticleMarkUserReadRequest struct { 1062 type MiniArticleMarkUserReadRequest struct {
@@ -1226,6 +1248,7 @@ type SystemArticleSearchRequest struct { @@ -1226,6 +1248,7 @@ type SystemArticleSearchRequest struct {
1226 Tags []int64 `json:"tags,optional"` //标签 1248 Tags []int64 `json:"tags,optional"` //标签
1227 Page int `json:"page"` //页码 1249 Page int `json:"page"` //页码
1228 Size int `json:"size"` //每页行数 1250 Size int `json:"size"` //每页行数
  1251 + OrderMode string `json:"orderMode,optional"` //排序方式
1229 } 1252 }
1230 1253
1231 type SystemArticleSearchResponse struct { 1254 type SystemArticleSearchResponse struct {
@@ -1250,7 +1273,7 @@ type SystemArticleSearch struct { @@ -1250,7 +1273,7 @@ type SystemArticleSearch struct {
1250 type SystemArticleUpdateRequest struct { 1273 type SystemArticleUpdateRequest struct {
1251 Id int64 `json:"id"` 1274 Id int64 `json:"id"`
1252 CompanyId int64 `json:"companyId,optional"` 1275 CompanyId int64 `json:"companyId,optional"`
1253 - Template int `json:"template"` // 使用哪个模板进行编辑 0、无 1、演绎式 2、归纳式 1276 + Template int `json:"template,optional"` // 使用哪个模板进行编辑 0、无 1、演绎式 2、归纳式
1254 Section []ArticleSection `json:"section"` // 填写的内容 1277 Section []ArticleSection `json:"section"` // 填写的内容
1255 Title string `json:"title"` // 标题 1278 Title string `json:"title"` // 标题
1256 Images []string `json:"images"` // 图片 1279 Images []string `json:"images"` // 图片
@@ -23,6 +23,7 @@ type ArticleBackup struct { @@ -23,6 +23,7 @@ type ArticleBackup struct {
23 Section []domain.ArticleSection `gorm:"type:jsonb;serializer:json"` // 分段内容 23 Section []domain.ArticleSection `gorm:"type:jsonb;serializer:json"` // 分段内容
24 Images []domain.Image `gorm:"type:jsonb;serializer:json"` // 图片 24 Images []domain.Image `gorm:"type:jsonb;serializer:json"` // 图片
25 Videos []domain.Video `gorm:"type:jsonb;serializer:json"` // 视频 25 Videos []domain.Video `gorm:"type:jsonb;serializer:json"` // 视频
  26 + ChangeField []string `gorm:"type:jsonb;serializer:json"` //
26 Action string // 操作 27 Action string // 操作
27 WhoRead []int64 `gorm:"type:jsonb;serializer:json"` // 谁可以看 28 WhoRead []int64 `gorm:"type:jsonb;serializer:json"` // 谁可以看
28 WhoReview []int64 `gorm:"type:jsonb;serializer:json"` // 评论人 29 WhoReview []int64 `gorm:"type:jsonb;serializer:json"` // 评论人
@@ -30,6 +31,7 @@ type ArticleBackup struct { @@ -30,6 +31,7 @@ type ArticleBackup struct {
30 Location domain.Location `gorm:"type:jsonb;serializer:json"` // 坐标 31 Location domain.Location `gorm:"type:jsonb;serializer:json"` // 坐标
31 TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人 32 TargetUser int // 分发方式 0 分发给所有人 1 分发给指定的人
32 MatchUrl map[string]string `gorm:"type:jsonb;serializer:json"` // 匹配文章内容中的url文本 33 MatchUrl map[string]string `gorm:"type:jsonb;serializer:json"` // 匹配文章内容中的url文本
  34 + Show int
33 } 35 }
34 36
35 func (m *ArticleBackup) TableName() string { 37 func (m *ArticleBackup) TableName() string {
@@ -175,7 +175,9 @@ func (repository *ArticleBackupRepository) ModelToDomainModel(from *models.Artic @@ -175,7 +175,9 @@ func (repository *ArticleBackupRepository) ModelToDomainModel(from *models.Artic
175 WhoReview: from.WhoReview, 175 WhoReview: from.WhoReview,
176 Tags: from.Tags, 176 Tags: from.Tags,
177 MatchUrl: from.MatchUrl, 177 MatchUrl: from.MatchUrl,
  178 + ChangeField: from.ChangeField,
178 Videos: from.Videos, 179 Videos: from.Videos,
  180 + Show: domain.ArticleShow(from.Show),
179 } 181 }
180 // err := copier.Copy(to, from) 182 // err := copier.Copy(to, from)
181 return to, nil 183 return to, nil
@@ -203,6 +205,8 @@ func (repository *ArticleBackupRepository) DomainModelToModel(from *domain.Artic @@ -203,6 +205,8 @@ func (repository *ArticleBackupRepository) DomainModelToModel(from *domain.Artic
203 TargetUser: int(from.TargetUser), 205 TargetUser: int(from.TargetUser),
204 MatchUrl: from.MatchUrl, 206 MatchUrl: from.MatchUrl,
205 Videos: from.Videos, 207 Videos: from.Videos,
  208 + ChangeField: from.ChangeField,
  209 + Show: int(from.Show),
206 } 210 }
207 // err := copier.Copy(to, from) 211 // err := copier.Copy(to, from)
208 return to, nil 212 return to, nil
@@ -121,7 +121,22 @@ func (repository *ArticleRepository) Find(ctx context.Context, conn transaction. @@ -121,7 +121,22 @@ func (repository *ArticleRepository) Find(ctx context.Context, conn transaction.
121 total int64 121 total int64
122 ) 122 )
123 queryFunc := func() (interface{}, error) { 123 queryFunc := func() (interface{}, error) {
124 - tx = tx.Model(&ms).Order("id desc").Where("company_id=?", companyId) 124 + tx = tx.Model(&ms).Where("company_id=?", companyId)
  125 + if v, ok := queryOptions["orderMode"]; ok {
  126 + mode := v.(string)
  127 + switch mode {
  128 + case "countComment ascending":
  129 + tx = tx.Order("count_comment asc")
  130 + case "countComment descending":
  131 + tx = tx.Order("count_comment desc")
  132 + case "countLove ascending":
  133 + tx = tx.Order("count_love asc")
  134 + case "countLove descending":
  135 + tx = tx.Order("count_love desc")
  136 + default:
  137 + tx = tx.Order("id desc")
  138 + }
  139 + }
125 if v, ok := queryOptions["ids"]; ok { 140 if v, ok := queryOptions["ids"]; ok {
126 tx = tx.Where("id in (?)", v) 141 tx = tx.Where("id in (?)", v)
127 } 142 }
@@ -95,42 +95,7 @@ func (a ArticleShow) Named() string { @@ -95,42 +95,7 @@ func (a ArticleShow) Named() string {
95 return "" 95 return ""
96 } 96 }
97 97
98 -// 设置文章的备份数据  
99 -func (m *Article) MakeBackup(operator UserSimple, section []*ArticleSection) *ArticleBackup {  
100 - sectionBackup := make([]ArticleSection, len(section))  
101 - for i := range section {  
102 - sectionBackup[i] = *section[i]  
103 - }  
104 - b := ArticleBackup{  
105 - Id: 0,  
106 - CompanyId: m.CompanyId,  
107 - CreatedAt: 0,  
108 - UpdatedAt: 0,  
109 - DeletedAt: 0,  
110 - Version: m.Version,  
111 - Operator: operator,  
112 - ArticleId: m.Id,  
113 - Title: m.Title,  
114 - Section: sectionBackup,  
115 - Images: make([]Image, len(m.Images)),  
116 - Videos: make([]Video, len(m.Videos)),  
117 - Action: "",  
118 - TargetUser: m.TargetUser,  
119 - WhoRead: m.WhoRead,  
120 - WhoReview: m.WhoReview,  
121 - Tags: m.Tags,  
122 - MatchUrl: map[string]string{},  
123 - Location: m.Location,  
124 - }  
125 - copy(b.Videos, m.Videos)  
126 - copy(b.Images, m.Images)  
127 - for k, v := range m.MatchUrl {  
128 - b.MatchUrl[k] = v  
129 - }  
130 - return &b  
131 -}  
132 -  
133 -func (m *Article) SetSummary(sectionList []ArticleSection) { 98 +func (m *Article) SetSummary(sectionList []*ArticleSection) {
134 if len(sectionList) == 0 { 99 if len(sectionList) == 0 {
135 return 100 return
136 } 101 }
@@ -156,3 +121,33 @@ func (m *Article) SetSummary(sectionList []ArticleSection) { @@ -156,3 +121,33 @@ func (m *Article) SetSummary(sectionList []ArticleSection) {
156 } 121 }
157 m.Summary = content[0:stringIndex] 122 m.Summary = content[0:stringIndex]
158 } 123 }
  124 +
  125 +func (m *Article) WhoCanRead(userId int64) bool {
  126 + if m.AuthorId == userId {
  127 + return true
  128 + }
  129 + if len(m.WhoRead) == 0 {
  130 + return true
  131 + }
  132 + for _, val := range m.WhoRead {
  133 + if userId == val {
  134 + return true
  135 + }
  136 + }
  137 + return false
  138 +}
  139 +
  140 +func (m *Article) WhoCanReview(userId int64) bool {
  141 + if m.AuthorId == userId {
  142 + return true
  143 + }
  144 + if len(m.WhoReview) == 0 {
  145 + return true
  146 + }
  147 + for _, val := range m.WhoReview {
  148 + if userId == val {
  149 + return true
  150 + }
  151 + }
  152 + return false
  153 +}
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 )
@@ -21,12 +25,15 @@ type ArticleBackup struct { @@ -21,12 +25,15 @@ type ArticleBackup struct {
21 Images []Image `json:"images"` // 图片 25 Images []Image `json:"images"` // 图片
22 Videos []Video `json:"videos"` // 视频 26 Videos []Video `json:"videos"` // 视频
23 Action string `json:"action"` // 操作 27 Action string `json:"action"` // 操作
  28 + // 新的备份内容相对与旧的文章信息哪些内容发生了变更,可选值[WhoRead] 修改了分发对象, [WhoReview] 修改了评论范围,[Section] 修改了内容
  29 + ChangeField []string `json:"changeField"`
24 TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人 30 TargetUser ArticleTarget `json:"targetUser"` // 分发方式 0 分发给所有人 1 分发给指定的人
25 Location Location `json:"location"` // 定位坐标 31 Location Location `json:"location"` // 定位坐标
26 WhoRead []int64 `json:"whoRead"` // 谁可以看 32 WhoRead []int64 `json:"whoRead"` // 谁可以看
27 WhoReview []int64 `json:"whoReview"` // 评论人 33 WhoReview []int64 `json:"whoReview"` // 评论人
28 Tags []int64 `json:"tags"` // 标签 34 Tags []int64 `json:"tags"` // 标签
29 MatchUrl map[string]string `json:"matchUrl"` // 匹配文章内容中的url文本 35 MatchUrl map[string]string `json:"matchUrl"` // 匹配文章内容中的url文本
  36 + Show ArticleShow `json:"show"` // 评论的展示状态(1显示,2不显示、)
30 } 37 }
31 38
32 type ArticleBackupRepository interface { 39 type ArticleBackupRepository interface {
@@ -37,3 +44,137 @@ type ArticleBackupRepository interface { @@ -37,3 +44,137 @@ type ArticleBackupRepository interface {
37 FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ArticleBackup, error) 44 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) 45 Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ArticleBackup, error)
39 } 46 }
  47 +
  48 +// 检查新的备份内容相对与旧的文章信息哪些内容发生了变更
  49 +// 记录ArticleBackup中数据发生变更的的字段名
  50 +func (bk *ArticleBackup) CheckChangeField(oldBackup *ArticleBackup) bool {
  51 + bk.ChangeField = make([]string, 0)
  52 + //比较 WhoRead
  53 + {
  54 + whoReadChanged := false
  55 + sort.Slice(bk.WhoRead, func(i, j int) bool {
  56 + return bk.WhoRead[i] < bk.WhoRead[j]
  57 + })
  58 + sort.Slice(oldBackup.WhoRead, func(i, j int) bool {
  59 + return oldBackup.WhoRead[i] < oldBackup.WhoRead[j]
  60 + })
  61 +
  62 + if len(bk.WhoRead) != len(oldBackup.WhoRead) {
  63 + whoReadChanged = true
  64 + } else {
  65 + for i := range bk.WhoRead {
  66 + if bk.WhoRead[i] != oldBackup.WhoRead[i] {
  67 + whoReadChanged = true
  68 + }
  69 + }
  70 + }
  71 + if whoReadChanged {
  72 + bk.ChangeField = append(bk.ChangeField, "WhoRead")
  73 + }
  74 + }
  75 +
  76 + //比较 whoReview
  77 + {
  78 + whoReviewChanged := false
  79 + sort.Slice(bk.WhoReview, func(i, j int) bool {
  80 + return bk.WhoReview[i] < bk.WhoReview[j]
  81 + })
  82 + sort.Slice(oldBackup.WhoReview, func(i, j int) bool {
  83 + return oldBackup.WhoReview[i] < oldBackup.WhoReview[j]
  84 + })
  85 +
  86 + if len(bk.WhoReview) != len(oldBackup.WhoReview) {
  87 + whoReviewChanged = true
  88 + } else {
  89 + for i := range bk.WhoReview {
  90 + if bk.WhoReview[i] != oldBackup.WhoReview[i] {
  91 + whoReviewChanged = true
  92 + }
  93 + }
  94 + }
  95 + if whoReviewChanged {
  96 + bk.ChangeField = append(bk.ChangeField, "WhoReview")
  97 + }
  98 + }
  99 + //比较段落内容+图片+视频 是否发生变更
  100 + {
  101 + sectionChanged := false
  102 + newSectionData := map[string]string{
  103 + "title": bk.Title,
  104 + }
  105 +
  106 + oldSectionData := map[string]string{
  107 + "title": oldBackup.Title,
  108 + }
  109 +
  110 + for _, val := range bk.Section {
  111 + mkey := fmt.Sprintf("section-%d", val.SortBy)
  112 + newSectionData[mkey] = val.Content
  113 + }
  114 + for _, val := range bk.Images {
  115 + newSectionData[val.Url] = ""
  116 + }
  117 + for _, val := range bk.Videos {
  118 + newSectionData[val.Url] = ""
  119 + }
  120 +
  121 + for _, val := range oldBackup.Section {
  122 + mKey := fmt.Sprintf("section-%d", val.SortBy)
  123 + oldSectionData[mKey] = val.Content
  124 + }
  125 + for _, val := range oldBackup.Images {
  126 + oldSectionData[val.Url] = ""
  127 + }
  128 + for _, val := range oldBackup.Videos {
  129 + oldSectionData[val.Url] = ""
  130 + }
  131 + newSectionJson, _ := json.Marshal(newSectionData)
  132 + oldSectionJson, _ := json.Marshal(oldSectionData)
  133 + if ok := bytes.Equal(newSectionJson, oldSectionJson); !ok {
  134 + sectionChanged = true
  135 + }
  136 + if sectionChanged {
  137 + bk.ChangeField = append(bk.ChangeField, "Section")
  138 + }
  139 + }
  140 + return len(bk.ChangeField) > 0
  141 +}
  142 +
  143 +// 创建备份信息
  144 +func (bk *ArticleBackup) MakeBackup(operator UserSimple, article *Article, section []*ArticleSection, action string) {
  145 + sectionBackup := make([]ArticleSection, len(section))
  146 + for i := range section {
  147 + sectionBackup[i] = *section[i]
  148 + }
  149 + b := ArticleBackup{
  150 + Id: 0,
  151 + CompanyId: article.CompanyId,
  152 + CreatedAt: 0,
  153 + UpdatedAt: 0,
  154 + DeletedAt: 0,
  155 + Version: article.Version,
  156 + Operator: operator,
  157 + ArticleId: article.Id,
  158 + Title: article.Title,
  159 + Section: sectionBackup,
  160 + Images: make([]Image, len(article.Images)),
  161 + Videos: make([]Video, len(article.Videos)),
  162 + Action: action,
  163 + TargetUser: article.TargetUser,
  164 + WhoRead: article.WhoRead,
  165 + WhoReview: article.WhoReview,
  166 + Tags: article.Tags,
  167 + MatchUrl: map[string]string{},
  168 + Show: article.Show,
  169 + Location: article.Location,
  170 + }
  171 + if action == "原始版本" {
  172 + b.ChangeField = append(b.ChangeField, "Section")
  173 + }
  174 + copy(b.Videos, article.Videos)
  175 + copy(b.Images, article.Images)
  176 + for k, v := range article.MatchUrl {
  177 + b.MatchUrl[k] = v
  178 + }
  179 + *bk = b
  180 +}
@@ -3,14 +3,15 @@ package database @@ -3,14 +3,15 @@ package database
3 import ( 3 import (
4 "context" 4 "context"
5 "fmt" 5 "fmt"
  6 + "log"
  7 + "os"
  8 + "time"
  9 +
6 "github.com/zeromicro/go-zero/core/logx" 10 "github.com/zeromicro/go-zero/core/logx"
7 "gorm.io/driver/mysql" 11 "gorm.io/driver/mysql"
8 "gorm.io/driver/postgres" 12 "gorm.io/driver/postgres"
9 "gorm.io/gorm" 13 "gorm.io/gorm"
10 "gorm.io/gorm/logger" 14 "gorm.io/gorm/logger"
11 - "log"  
12 - "os"  
13 - "time"  
14 ) 15 )
15 16
16 func OpenGormDB(source string) *gorm.DB { 17 func OpenGormDB(source string) *gorm.DB {
@@ -44,6 +45,7 @@ func OpenGormPGDB(source string, logMode string) *gorm.DB { @@ -44,6 +45,7 @@ func OpenGormPGDB(source string, logMode string) *gorm.DB {
44 if err != nil { 45 if err != nil {
45 panic(err) 46 panic(err)
46 } 47 }
  48 +
47 return db 49 return db
48 } 50 }
49 51