article_backup.go 7.2 KB
package domain

import (
	"bytes"
	"context"
	"gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction"
	"reflect"
)

// 编辑文章后保存的历史记录
type ArticleBackup struct {
	Id        int64            `json:"id"`
	CompanyId int64            `json:"companyId"`
	CreatedAt int64            `json:"createdAt,omitempty"`
	UpdatedAt int64            `json:"updatedAt,omitempty"`
	DeletedAt int64            `json:"deletedAt,omitempty"`
	Version   int              `json:"version,omitempty"`
	Operator  UserSimple       `json:"operator"`  // 操作人
	ArticleId int64            `json:"articleId"` //
	Title     string           `json:"title"`     // 标题
	Section   []ArticleSection `json:"section"`   // 分段内容
	Images    []Image          `json:"images"`    // 图片
	Videos    []Video          `json:"videos"`    // 视频
	Action    string           `json:"action"`    // 操作
	// 新的备份内容相对与旧的文章信息哪些内容发生了变更,可选值[WhoRead] 修改了分发对象, [WhoReview] 修改了评论范围,[Section] 修改了内容
	ChangeField []string          `json:"changeField"`
	TargetUser  ArticleTarget     `json:"targetUser"`  // 分发方式 0 分发给所有人 1 分发给指定的人
	Location    Location          `json:"location"`    // 定位坐标
	WhoRead     []int64           `json:"whoRead"`     // 谁可以看
	WhoReview   []int64           `json:"whoReview"`   // 评论人
	Tags        []int64           `json:"tags"`        // 标签
	MatchUrl    map[string]string `json:"matchUrl"`    // 匹配文章内容中的url文本
	Show        ArticleShow       `json:"show"`        // 评论的展示状态(1显示,2不显示、)
	Attachments []FileInfo        `json:"attachments"` // 附件
}

type ArticleBackupRepository interface {
	Insert(ctx context.Context, conn transaction.Conn, dm *ArticleBackup) (*ArticleBackup, error)
	Update(ctx context.Context, conn transaction.Conn, dm *ArticleBackup) (*ArticleBackup, error)
	UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *ArticleBackup) (*ArticleBackup, error)
	Delete(ctx context.Context, conn transaction.Conn, dm *ArticleBackup) (*ArticleBackup, error)
	FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ArticleBackup, error)
	Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ArticleBackup, error)
}

// 检查新的备份内容相对与旧的文章信息哪些内容发生了变更
// 记录ArticleBackup中数据发生变更的的字段名
func (bk *ArticleBackup) CheckChangeField(oldBackup *ArticleBackup) bool {
	bk.ChangeField = make([]string, 0)
	//比较 WhoRead
	{
		//whoReadChanged := false
		//sort.Slice(bk.WhoRead, func(i, j int) bool {
		//	return bk.WhoRead[i] < bk.WhoRead[j]
		//})
		//sort.Slice(oldBackup.WhoRead, func(i, j int) bool {
		//	return oldBackup.WhoRead[i] < oldBackup.WhoRead[j]
		//})
		//
		//if len(bk.WhoRead) != len(oldBackup.WhoRead) {
		//	whoReadChanged = true
		//} else {
		//	for i := range bk.WhoRead {
		//		if bk.WhoRead[i] != oldBackup.WhoRead[i] {
		//			whoReadChanged = true
		//		}
		//	}
		//}
		//if whoReadChanged {
		//	bk.ChangeField = append(bk.ChangeField, "WhoRead")
		//}
		if !reflect.DeepEqual(oldBackup.WhoRead, bk.WhoRead) {
			bk.ChangeField = append(bk.ChangeField, "WhoRead")
		}
	}

	//比较 whoReview
	{
		//whoReviewChanged := false
		//sort.Slice(bk.WhoReview, func(i, j int) bool {
		//	return bk.WhoReview[i] < bk.WhoReview[j]
		//})
		//sort.Slice(oldBackup.WhoReview, func(i, j int) bool {
		//	return oldBackup.WhoReview[i] < oldBackup.WhoReview[j]
		//})
		//
		//if len(bk.WhoReview) != len(oldBackup.WhoReview) {
		//	whoReviewChanged = true
		//} else {
		//	for i := range bk.WhoReview {
		//		if bk.WhoReview[i] != oldBackup.WhoReview[i] {
		//			whoReviewChanged = true
		//		}
		//	}
		//}
		//if whoReviewChanged {
		//	bk.ChangeField = append(bk.ChangeField, "WhoReview")
		//}
		if !reflect.DeepEqual(oldBackup.WhoReview, bk.WhoReview) {
			bk.ChangeField = append(bk.ChangeField, "WhoReview")
		}
	}
	//比较段落内容+图片+视频 是否发生变更
	{
		//sectionChanged := false
		//newSectionData := map[string]string{
		//	"title": bk.Title,
		//}
		//
		//oldSectionData := map[string]string{
		//	"title": oldBackup.Title,
		//}
		//
		//for _, val := range bk.Section {
		//	mkey := fmt.Sprintf("section-%d", val.SortBy)
		//	newSectionData[mkey] = val.Content
		//}
		//for _, val := range bk.Images {
		//	newSectionData[val.Url] = ""
		//}
		//for _, val := range bk.Videos {
		//	newSectionData[val.Url] = ""
		//}
		//
		//for _, val := range oldBackup.Section {
		//	mKey := fmt.Sprintf("section-%d", val.SortBy)
		//	oldSectionData[mKey] = val.Content
		//}
		//for _, val := range oldBackup.Images {
		//	oldSectionData[val.Url] = ""
		//}
		//for _, val := range oldBackup.Videos {
		//	oldSectionData[val.Url] = ""
		//}
		//newSectionJson, _ := json.Marshal(newSectionData)
		//oldSectionJson, _ := json.Marshal(oldSectionData)
		//if ok := bytes.Equal(newSectionJson, oldSectionJson); !ok {
		//	sectionChanged = true
		//}
		//if sectionChanged {
		//	bk.ChangeField = append(bk.ChangeField, "Section")
		//}
		if !reflect.DeepEqual(backUpContent(bk), backUpContent(oldBackup)) {
			bk.ChangeField = append(bk.ChangeField, "Section")
		}
	}
	return len(bk.ChangeField) > 0
}

func backUpContent(bk *ArticleBackup) string {
	buf := bytes.NewBuffer(nil)
	buf.WriteString(bk.Title)
	for _, val := range bk.Images {
		buf.WriteString(val.Url)
	}
	for _, val := range bk.Videos {
		buf.WriteString(val.Url)
	}
	for _, val := range bk.Section {
		buf.WriteString(val.Content)
	}
	return buf.String()
}

// 创建备份信息
func (bk *ArticleBackup) MakeBackup(operator UserSimple, article *Article, section []*ArticleSection, action string) {
	sectionBackup := make([]ArticleSection, len(section))
	for i := range section {
		sectionBackup[i] = *section[i]
	}
	b := ArticleBackup{
		Id:          0,
		CompanyId:   article.CompanyId,
		CreatedAt:   0,
		UpdatedAt:   0,
		DeletedAt:   0,
		Version:     article.Version,
		Operator:    operator,
		ArticleId:   article.Id,
		Title:       article.Title,
		Section:     sectionBackup,
		Images:      make([]Image, len(article.Images)),
		Videos:      make([]Video, len(article.Videos)),
		Action:      action,
		TargetUser:  article.TargetUser,
		WhoRead:     article.WhoRead,
		WhoReview:   article.WhoReview,
		Tags:        article.Tags,
		MatchUrl:    map[string]string{},
		Show:        article.Show,
		Location:    article.Location,
		ChangeField: []string{},
	}
	if action == "原始版本" {
		b.ChangeField = append(b.ChangeField, "Section")
	}
	copy(b.Videos, article.Videos)
	copy(b.Images, article.Images)
	for k, v := range article.MatchUrl {
		b.MatchUrl[k] = v
	}
	*bk = b
}

func (m *ArticleBackup) GetCover() string {
	if len(m.Images) > 0 {
		return m.Images[0].Url
	}
	for _, sec := range m.Section {
		if sec.ParagraphType == ParagraphTypeImages && len(sec.Images) > 0 {
			return sec.Images[0]
		}
	}
	return ""
}

func (m *ArticleBackup) GetImages() []string {
	cover := m.GetCover()
	var result = make([]string, 0)
	for _, img := range m.Images {
		result = append(result, img.Url)
	}
	if len(result) == 0 && len(cover) > 0 {
		result = append(result, cover)
	}
	return result
}