mini_create_article_logic.go 5.8 KB
package article

import (
	"context"
	"strings"

	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types"
	"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/pkg/xerr"

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

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

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

// 创建新文章
func (l *MiniCreateArticleLogic) MiniCreateArticle(req *types.MiniArticleCreateRequest) (resp *types.MiniArticleCreateResponse, err error) {
	var conn = l.svcCtx.DefaultDBConn()
	// 检查发布人
	author, err := l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.AuthorId)
	if err != nil {
		return nil, xerr.NewErrMsgErr("创建文章内容失败", err)
	}
	companyInfo, err := l.svcCtx.CompanyRepository.FindOne(l.ctx, conn, author.CompanyId)
	if err != nil {
		return nil, xerr.NewErrMsgErr("创建文章内容失败", err)
	}
	articleAuthor := domain.UserSimple{
		Id:        author.Id,
		Name:      author.Name,
		Avatar:    author.Avatar,
		Position:  author.Position,
		Company:   companyInfo.Name,
		CompanyId: author.CompanyId,
	}
	if len(req.Images) > 9 {
		return nil, xerr.NewErrMsg("图片数量最多9张")
	}
	//TODO 获取图片的尺寸大小
	images := []domain.Image{}
	for _, val := range req.Images {
		images = append(images, domain.Image{
			Url:    val,
			Width:  0,
			Height: 0,
		})
	}

	//检查文章可被哪些人查看
	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 != author.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 != author.CompanyId {
					return nil, xerr.NewErrMsg("文章可评论人设置错误")
				}
			}
		}
		// if len(whoReview) == 0 {
		// 未指定可查看人(全员可看),未指定可评论人 ,忽略判断
		// }
	}

	//切分文章分段
	sectionList := []domain.ArticleSection{}
	for i := range req.Section {
		strList := strings.Split(req.Section[i], "\n")
		for i2 := range strList {
			newStr := strings.TrimSpace(strList[i2])
			if len(newStr) == 0 {
				continue
			}
			newSection := domain.ArticleSection{
				Id:           0,
				CompanyId:    author.CompanyId,
				ArticleId:    0,
				Content:      newStr,
				SortBy:       len(sectionList),
				TotalComment: 0,
			}
			sectionList = append(sectionList, newSection)
		}
	}

	newArticle := &domain.Article{
		Id:        0,
		CompanyId: author.CompanyId,
		AuthorId:  author.Id,
		Author:    articleAuthor,
		Title:     req.Title,
		Images:    images,
		WhoRead:   whoRead,
		WhoReview: whoReview,
		Location: domain.Location{
			Longitude: req.Location.Latitude,
			Latitude:  req.Location.Latitude,
			Descript:  req.Location.Descript,
		},
		TargetUser:   domain.ArticleTargetAll,
		CountLove:    0,
		CountComment: 0,
		CountRead:    0,
		Show:         0,
		Tags:         []int64{},
	}
	if len(whoRead) > 0 {
		newArticle.TargetUser = domain.ArticleTargetLimit
	}
	//设置内容概要
	if len(sectionList) > 0 {
		// 截取内容 30个字
		runeNumber := 0  //字数
		stringIndex := 0 //字符串长度
		for i := range sectionList[0].Content {
			if runeNumber > 30 {
				break
			}
			runeNumber += 1
			stringIndex = i
		}
		newArticle.Summary = sectionList[0].Content[0:stringIndex]
	}

	err = transaction.UseTrans(l.ctx, conn.DB(), func(ctx context.Context, c transaction.Conn) error {
		newArticle, err = l.svcCtx.ArticleRepository.Insert(ctx, c, newArticle)
		if err != nil {
			return xerr.NewErrMsgErr("创建文章失败", err)
		}

		for i := range sectionList {
			sectionList[i].ArticleId = newArticle.Id
			_, err = l.svcCtx.ArticleSectionRepository.Insert(ctx, c, &sectionList[i])
			if err != nil {
				return xerr.NewErrMsgErr("创建文章内容失败", err)
			}
		}
		// 设置保存备份
		backup := newArticle.MakeBackup(newArticle.Author, sectionList)
		backup.Action = "新增"
		_, err = l.svcCtx.ArticleBackupRepository.Insert(ctx, c, backup)
		if err != nil {
			return xerr.NewErrMsgErr("创建文章内容失败", err)
		}
		return nil
	}, true)
	if err != nil {
		return nil, xerr.NewErrMsgErr("创建文章失败", err)
	}

	resp = &types.MiniArticleCreateResponse{
		Id: newArticle.Id,
	}
	return
}