system_update_article_logic.go 7.1 KB
package article

import (
	"context"
	"strconv"

	"strings"

	"github.com/samber/lo"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/gateway/authlib"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/tool/oss"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr"

	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type SystemUpdateArticleLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewSystemUpdateArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SystemUpdateArticleLogic {
	return &SystemUpdateArticleLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *SystemUpdateArticleLogic) SystemUpdateArticle(req *types.SystemArticleUpdateRequest) (resp *types.SystemArticleUpdateResponse, err error) {
	var conn = l.svcCtx.DefaultDBConn()
	userToken := contextdata.GetUserTokenFromCtx(l.ctx)
	article, err := l.svcCtx.ArticleRepository.FindOne(l.ctx, conn, req.Id)
	if err != nil {
		return nil, xerr.NewErrMsgErr("帖子不存在", err)
	}
	// 获取图片的尺寸大小
	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,
		})
	}
	//检查文章可被哪些人查看
	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("文章可查看人设置错误")
			}
		}
	}
	//检查文章可被哪些人评论
	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("文章可评论人设置错误")
				}
			}
		}
	}
	//验证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)
			}
		}
	}
	article.Title = req.Title
	article.Version = article.Version + 1
	article.Images = images
	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++
		}
	})
	//设置内容概要
	if len(req.Section) > 0 {
		// 截取内容 50个字
		runeNumber := 0  //字数
		stringIndex := 0 //字符串长度
		for i := range req.Section[0].Content {
			if runeNumber > 50 {
				break
			}
			runeNumber += 1
			stringIndex = i
		}
		article.Summary = req.Section[0].Content[0:stringIndex]
	}
	//获取当前用户信息
	userMe, err := l.svcCtx.ApiAuthService.MeInfo(l.ctx, authlib.RequestUserMeQuery{Token: req.AccessToken})
	if err != nil {
		return nil, xerr.NewErrMsgErr("获取当前用户信息失败", err)
	}
	err = transaction.UseTrans(l.ctx, 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)
		}
		//文章内容
		updateSectionIds := []int64{}
		for _, item := range articleSections {
			if item.Id > 0 {
				section, err := l.svcCtx.ArticleSectionRepository.FindOne(ctx, c, item.Id)
				if err != nil {
					return xerr.NewErrMsgErr("获取文章段落内容失败", err)
				}
				section.Content = item.Content
				section.ArticleId = item.ArticleId
				section.Version = item.Version
				section.SortBy = item.SortBy
				section.CompanyId = item.CompanyId
				_, err = l.svcCtx.ArticleSectionRepository.Update(ctx, c, section)
				if err != nil {
					return xerr.NewErrMsgErr("保存文章段落内容失败", err)
				}
			} else {
				_, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, &item)
				if err != nil {
					return xerr.NewErrMsgErr("保存文章段落内容失败", err)
				}
			}
			updateSectionIds = append(updateSectionIds, item.Id)
		}
		if len(updateSectionIds) > 0 {
			err = l.svcCtx.ArticleSectionRepository.DeleteBy(ctx, c, domain.NewQueryOptions().WithKV("articleId", article.Id).WithKV("notIds", updateSectionIds))
			if err != nil {
				return xerr.NewErrMsgErr("保存文章内容失败", err)
			}
		}
		//备份数据
		backup := article.MakeBackup(domain.UserSimple{
			Id:        userToken.UserId,
			Name:      userMe.User.NickName,
			Avatar:    userMe.User.Avatar,
			CompanyId: userToken.CompanyId,
			Company:   userMe.CurrentCompany.Name,
		}, articleSections)
		backup.Action = "编辑"
		_, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, backup)
		if err != nil {
			return xerr.NewErrMsgErr("保存文章内容失败", err)
		}
		return nil
	}, true)
	resp = &types.SystemArticleUpdateResponse{
		Id:           article.Id,
		Title:        article.Title,
		Images:       req.Images,
		CreatedAt:    article.CreatedAt,
		CountLove:    article.CountLove,
		CountComment: article.CountComment,
		Show:         int(article.Show),
		TargetUser:   int(article.TargetUser),
		Tags:         article.Tags,
	}
	return
}