...
|
...
|
@@ -2,6 +2,8 @@ package article |
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
"github.com/jinzhu/copier"
|
|
|
"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/message"
|
|
|
"strconv"
|
|
|
"unicode/utf8"
|
|
|
|
...
|
...
|
@@ -25,6 +27,7 @@ type SystemUpdateArticleLogic struct { |
|
|
logx.Logger
|
|
|
ctx context.Context
|
|
|
svcCtx *svc.ServiceContext
|
|
|
conn transaction.Conn
|
|
|
}
|
|
|
|
|
|
func NewSystemUpdateArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SystemUpdateArticleLogic {
|
...
|
...
|
@@ -32,11 +35,12 @@ func NewSystemUpdateArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext |
|
|
Logger: logx.WithContext(ctx),
|
|
|
ctx: ctx,
|
|
|
svcCtx: svcCtx,
|
|
|
conn: svcCtx.DefaultDBConn(),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleUpdateRequest) (resp *types.SystemArticleUpdateResponse, err error) {
|
|
|
var conn = l.svcCtx.DefaultDBConn()
|
|
|
//var conn = l.svcCtx.DefaultDBConn()
|
|
|
userToken := contextdata.GetUserTokenFromCtx(l.ctx)
|
|
|
// 预处理参数
|
|
|
if req.TargetUser == 0 {
|
...
|
...
|
@@ -44,26 +48,20 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU |
|
|
req.WhoRead = make([]int64, 0)
|
|
|
}
|
|
|
// 检查文字数量
|
|
|
wordNum := 0
|
|
|
for i := range req.Section {
|
|
|
num := utf8.RuneCountInString(req.Section[i].Content)
|
|
|
wordNum += num
|
|
|
if err = l.validateTextLimit(req); err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if wordNum >= 1000 {
|
|
|
return nil, xerr.NewErrMsgErr("最多只能输入1000字", err)
|
|
|
}
|
|
|
|
|
|
// 获取当前用户信息
|
|
|
userMe, err := l.svcCtx.ApiAuthService.MeInfo(l.ctx, authlib.RequestUserMeQuery{Token: req.AccessToken})
|
|
|
if err != nil {
|
|
|
return nil, xerr.NewErrMsgErr("获取当前用户信息失败", err)
|
|
|
}
|
|
|
// 文章数据
|
|
|
article, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, conn, req.Id)
|
|
|
article, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, l.conn, req.Id)
|
|
|
if err != nil {
|
|
|
return nil, xerr.NewErrMsgErr("帖子不存在", err)
|
|
|
}
|
|
|
_, sectionList, err := l.svcCtx.ArticleSectionRepository.Find(l.ctx, conn, map[string]interface{}{"articleId": article.Id})
|
|
|
_, sectionList, err := l.svcCtx.ArticleSectionRepository.Find(l.ctx, l.conn, map[string]interface{}{"articleId": article.Id})
|
|
|
if err != nil {
|
|
|
return nil, xerr.NewErrMsgErr("获取文章段落内容失败", err)
|
|
|
}
|
...
|
...
|
@@ -78,110 +76,44 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU |
|
|
backup.Action = "编辑"
|
|
|
|
|
|
// 获取图片的尺寸大小
|
|
|
images := []domain.Image{}
|
|
|
for _, val := range req.Images {
|
|
|
fInfo, _ := oss.GetImageInfo(val)
|
|
|
w, _ := strconv.Atoi(fInfo.ImageWidth.Value)
|
|
|
h, _ := strconv.Atoi(fInfo.ImageHeight.Value)
|
|
|
images = append(images, domain.Image{
|
|
|
Url: val,
|
|
|
Width: w,
|
|
|
Height: h,
|
|
|
})
|
|
|
images, err := l.getImages(req)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
//视频
|
|
|
videos, err := l.getVideos(req)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
//检查文章可被哪些人查看
|
|
|
whoRead := []int64{}
|
|
|
if len(req.WhoRead) > 0 {
|
|
|
whoRead = lo.Uniq(req.WhoRead)
|
|
|
var u *domain.User
|
|
|
for _, val := range whoRead {
|
|
|
u, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, val)
|
|
|
if err != nil {
|
|
|
return nil, xerr.NewErrMsgErr("文章可查看人设置错误", err)
|
|
|
}
|
|
|
if u.CompanyId != article.CompanyId {
|
|
|
return nil, xerr.NewErrMsg("文章可查看人设置错误")
|
|
|
}
|
|
|
}
|
|
|
whoRead, err := l.validateAndGetWhoRead(req, article)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
//检查文章可被哪些人评论
|
|
|
whoReview := []int64{}
|
|
|
if len(req.WhoReview) > 0 {
|
|
|
whoReview = lo.Uniq(req.WhoReview)
|
|
|
}
|
|
|
//有指定可查看人的情况
|
|
|
if len(whoRead) > 0 {
|
|
|
if len(whoReview) > 0 {
|
|
|
// 检查 whoRead 是否 完全包含 whoReview
|
|
|
ok := lo.Every(whoRead, whoReview)
|
|
|
if !ok {
|
|
|
return nil, xerr.NewErrMsg("文章可评论人设置错误")
|
|
|
}
|
|
|
}
|
|
|
if len(whoReview) == 0 {
|
|
|
//有指定可查看人 ,但未指定可评论人
|
|
|
return nil, xerr.NewErrMsg("文章可评论人设置错误")
|
|
|
}
|
|
|
}
|
|
|
//没有指定可查看人的情况
|
|
|
if len(whoRead) == 0 {
|
|
|
if len(whoReview) > 0 {
|
|
|
// 未指定可查看人(全员可看),有指定可评论人,
|
|
|
var u *domain.User
|
|
|
for _, val := range whoReview {
|
|
|
u, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, val)
|
|
|
if err != nil {
|
|
|
return nil, xerr.NewErrMsgErr("文章可评论人设置错误", err)
|
|
|
}
|
|
|
if u.CompanyId != article.CompanyId {
|
|
|
return nil, xerr.NewErrMsg("文章可评论人设置错误")
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//验证可评论
|
|
|
if err = l.validateWhoReview(whoRead, whoReview, article); err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
//验证tag
|
|
|
if len(req.Tags) > 0 {
|
|
|
req.Tags = lo.Uniq(req.Tags)
|
|
|
for _, value := range req.Tags {
|
|
|
t, err := l.svcCtx.ArticleTagRepository.FindOne(l.ctx, conn, value)
|
|
|
if err != nil {
|
|
|
return nil, xerr.NewErrMsgErr("文章标签设置错误", err)
|
|
|
}
|
|
|
if t.CompanyId != article.CompanyId {
|
|
|
return nil, xerr.NewErrMsgErr("文章标签设置错误", err)
|
|
|
}
|
|
|
}
|
|
|
validTags := l.validateTags(req, article)
|
|
|
if validTags != nil {
|
|
|
return nil, validTags
|
|
|
}
|
|
|
article.Title = req.Title
|
|
|
article.Version = article.Version + 1
|
|
|
article.Images = images
|
|
|
article.Videos = videos
|
|
|
article.WhoRead = whoRead
|
|
|
article.WhoReview = whoReview
|
|
|
article.TargetUser = domain.ArticleTarget(req.TargetUser)
|
|
|
article.Tags = req.Tags
|
|
|
//文章内容
|
|
|
articleSections := []domain.ArticleSection{}
|
|
|
sortBy := 1
|
|
|
lo.ForEach(req.Section, func(item types.ArticleSection, index int) {
|
|
|
strList := strings.Split(item.Content, "\n")
|
|
|
for key, value := range strList {
|
|
|
if value == "" {
|
|
|
continue
|
|
|
}
|
|
|
section := domain.ArticleSection{
|
|
|
CompanyId: article.CompanyId,
|
|
|
Version: article.Version,
|
|
|
ArticleId: article.Id,
|
|
|
Content: value,
|
|
|
SortBy: sortBy,
|
|
|
}
|
|
|
if key == 0 {
|
|
|
section.Id = item.Id
|
|
|
}
|
|
|
articleSections = append(articleSections, section)
|
|
|
sortBy++
|
|
|
}
|
|
|
})
|
|
|
articleSections := l.getSections(req, article)
|
|
|
//设置内容概要
|
|
|
if len(req.Section) > 0 {
|
|
|
// 截取内容 50个字
|
...
|
...
|
@@ -197,7 +129,7 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU |
|
|
article.Summary = req.Section[0].Content[0:stringIndex]
|
|
|
}
|
|
|
|
|
|
err = transaction.UseTrans(l.ctx, conn.DB(), func(ctx context.Context, c transaction.Conn) error {
|
|
|
err = transaction.UseTrans(l.ctx, l.conn.DB(), func(ctx context.Context, c transaction.Conn) error {
|
|
|
_, err = l.svcCtx.ArticleRepository.Update(l.ctx, c, article)
|
|
|
if err != nil {
|
|
|
return xerr.NewErrMsgErr("保存文章失败", err)
|
...
|
...
|
@@ -238,8 +170,9 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU |
|
|
return xerr.NewErrMsgErr("保存文章内容失败", err)
|
|
|
}
|
|
|
//文章定性
|
|
|
if len(article.Tags) > 0 {
|
|
|
|
|
|
err = l.setTags(c, article)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
return nil
|
|
|
}, true)
|
...
|
...
|
@@ -254,9 +187,193 @@ func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleU |
|
|
TargetUser: int(article.TargetUser),
|
|
|
Tags: article.Tags,
|
|
|
}
|
|
|
_ = copier.Copy(&resp.Videos, videos)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// validateTextLimit 验证输入文本长度
|
|
|
func (l *SystemUpdateArticleLogic) validateTextLimit(req *types.SystemArticleUpdateRequest) error {
|
|
|
wordNum := 0
|
|
|
for i := range req.Section {
|
|
|
num := utf8.RuneCountInString(req.Section[i].Content)
|
|
|
wordNum += num
|
|
|
}
|
|
|
if wordNum >= 1000 {
|
|
|
return xerr.NewErrMsg("最多只能输入1000字")
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// validateAndGetWhoRead 验证并获取可阅读
|
|
|
func (l *SystemUpdateArticleLogic) validateAndGetWhoRead(req *types.SystemArticleUpdateRequest, article *domain.Article) ([]int64, error) {
|
|
|
whoRead := make([]int64, 0)
|
|
|
if len(req.WhoRead) > 0 {
|
|
|
whoRead = lo.Uniq(req.WhoRead)
|
|
|
var u *domain.User
|
|
|
var err error
|
|
|
for _, val := range whoRead {
|
|
|
u, err = l.svcCtx.UserRepository.FindOne(l.ctx, l.conn, val)
|
|
|
if err != nil {
|
|
|
return whoRead, xerr.NewErrMsgErr("文章可查看人设置错误", err)
|
|
|
}
|
|
|
if u.CompanyId != article.CompanyId {
|
|
|
return whoRead, xerr.NewErrMsg("文章可查看人设置错误")
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return whoRead, nil
|
|
|
}
|
|
|
|
|
|
// validateWhoReview 验证可评论
|
|
|
func (l *SystemUpdateArticleLogic) validateWhoReview(whoRead []int64, whoReview []int64, article *domain.Article) error {
|
|
|
//有指定可查看人的情况
|
|
|
if len(whoRead) > 0 {
|
|
|
if len(whoReview) > 0 {
|
|
|
// 检查 whoRead 是否 完全包含 whoReview
|
|
|
ok := lo.Every(whoRead, whoReview)
|
|
|
if !ok {
|
|
|
return xerr.NewErrMsg("文章可评论人设置错误")
|
|
|
}
|
|
|
}
|
|
|
if len(whoReview) == 0 {
|
|
|
//有指定可查看人 ,但未指定可评论人
|
|
|
return xerr.NewErrMsg("文章可评论人设置错误")
|
|
|
}
|
|
|
}
|
|
|
//没有指定可查看人的情况
|
|
|
if len(whoRead) == 0 {
|
|
|
if len(whoReview) > 0 {
|
|
|
// 未指定可查看人(全员可看),有指定可评论人,
|
|
|
var u *domain.User
|
|
|
var err error
|
|
|
for _, val := range whoReview {
|
|
|
u, err = l.svcCtx.UserRepository.FindOne(l.ctx, l.conn, val)
|
|
|
if err != nil {
|
|
|
return xerr.NewErrMsgErr("文章可评论人设置错误", err)
|
|
|
}
|
|
|
if u.CompanyId != article.CompanyId {
|
|
|
return xerr.NewErrMsg("文章可评论人设置错误")
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// validateTags 验证标签
|
|
|
func (l *SystemUpdateArticleLogic) validateTags(req *types.SystemArticleUpdateRequest, article *domain.Article) error {
|
|
|
if len(req.Tags) > 0 {
|
|
|
req.Tags = lo.Uniq(req.Tags)
|
|
|
for _, value := range req.Tags {
|
|
|
t, err := l.svcCtx.ArticleTagRepository.FindOne(l.ctx, l.conn, value)
|
|
|
if err != nil {
|
|
|
return xerr.NewErrMsgErr("文章标签设置错误", err)
|
|
|
}
|
|
|
if t.CompanyId != article.CompanyId {
|
|
|
return xerr.NewErrMsgErr("文章标签设置错误", err)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// getImages 获取图片信息
|
|
|
func (l *SystemUpdateArticleLogic) getImages(req *types.SystemArticleUpdateRequest) ([]domain.Image, error) {
|
|
|
// 获取图片的尺寸大小
|
|
|
images := make([]domain.Image, 0)
|
|
|
for _, val := range req.Images {
|
|
|
fInfo, err := oss.GetImageInfo(val)
|
|
|
if err != nil {
|
|
|
return images, xerr.NewErrMsg("获取图片失败")
|
|
|
}
|
|
|
w, _ := strconv.Atoi(fInfo.ImageWidth.Value)
|
|
|
h, _ := strconv.Atoi(fInfo.ImageHeight.Value)
|
|
|
images = append(images, domain.Image{
|
|
|
Url: val,
|
|
|
Width: w,
|
|
|
Height: h,
|
|
|
})
|
|
|
}
|
|
|
return images, nil
|
|
|
}
|
|
|
|
|
|
// getVideo 获取视频信息
|
|
|
func (l *SystemUpdateArticleLogic) getVideos(req *types.SystemArticleUpdateRequest) ([]domain.Video, error) {
|
|
|
videos := make([]domain.Video, 0)
|
|
|
if len(req.Videos) > 0 {
|
|
|
for _, item := range req.Videos {
|
|
|
cover, w, h, err := oss.GetVideoCover(item.Url)
|
|
|
if err != nil {
|
|
|
return videos, xerr.NewErrMsg("获取视频信息失败")
|
|
|
}
|
|
|
videos = append(videos, domain.Video{
|
|
|
Url: item.Url,
|
|
|
Cover: cover,
|
|
|
Width: w,
|
|
|
Height: h,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
return videos, nil
|
|
|
}
|
|
|
|
|
|
func (l *SystemUpdateArticleLogic) getSections(req *types.SystemArticleUpdateRequest, article *domain.Article) []domain.ArticleSection {
|
|
|
articleSections := make([]domain.ArticleSection, 0)
|
|
|
sortBy := 1
|
|
|
lo.ForEach(req.Section, func(item types.ArticleSection, index int) {
|
|
|
strList := strings.Split(item.Content, "\n")
|
|
|
for key, value := range strList {
|
|
|
if value == "" {
|
|
|
continue
|
|
|
}
|
|
|
section := domain.ArticleSection{
|
|
|
CompanyId: article.CompanyId,
|
|
|
Version: article.Version,
|
|
|
ArticleId: article.Id,
|
|
|
Content: value,
|
|
|
SortBy: sortBy,
|
|
|
}
|
|
|
if key == 0 {
|
|
|
section.Id = item.Id
|
|
|
}
|
|
|
articleSections = append(articleSections, section)
|
|
|
sortBy++
|
|
|
}
|
|
|
})
|
|
|
return articleSections
|
|
|
}
|
|
|
|
|
|
// setTags 设置定性标签
|
|
|
func (l *SystemUpdateArticleLogic) setTags(conn transaction.Conn, article *domain.Article) error {
|
|
|
_, oldTags, err := l.svcCtx.ArticleAndTagRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithFindOnly().WithKV("articleId", article.Id))
|
|
|
if err != nil {
|
|
|
return xerr.NewErrMsgErr("检查文章的标签失败", err)
|
|
|
}
|
|
|
//删除旧标签
|
|
|
for _, v := range oldTags {
|
|
|
_, err = l.svcCtx.ArticleAndTagRepository.Delete(l.ctx, conn, v)
|
|
|
if err != nil {
|
|
|
return xerr.NewErrMsg(err.Error())
|
|
|
}
|
|
|
}
|
|
|
if len(article.Tags) > 0 {
|
|
|
for _, tagId := range article.Tags {
|
|
|
articleTag := &domain.ArticleAndTag{
|
|
|
CompanyId: article.CompanyId,
|
|
|
ArticleId: article.Id,
|
|
|
TagId: tagId,
|
|
|
}
|
|
|
_, err = l.svcCtx.ArticleAndTagRepository.Insert(l.ctx, conn, articleTag)
|
|
|
if err != nil {
|
|
|
return xerr.NewErrMsg(err.Error())
|
|
|
}
|
|
|
}
|
|
|
//发送定性通知
|
|
|
messageLogic := message.NewMiniSystemLogic(l.ctx, l.svcCtx)
|
|
|
err = messageLogic.ArticleDefined(conn, article.CompanyId, article.AuthorId, article.Title)
|
|
|
if err != nil {
|
|
|
return xerr.NewErrMsg(err.Error())
|
|
|
}
|
|
|
}
|
|
|
return nil
|
|
|
} |
...
|
...
|
|