mirror of https://github.com/go-sonic/sonic.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
7.2 KiB
Go
220 lines
7.2 KiB
Go
package assembler
|
|
|
|
import (
|
|
"context"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/go-sonic/sonic/log"
|
|
"github.com/go-sonic/sonic/model/dto"
|
|
"github.com/go-sonic/sonic/model/entity"
|
|
"github.com/go-sonic/sonic/model/param"
|
|
"github.com/go-sonic/sonic/model/property"
|
|
"github.com/go-sonic/sonic/model/vo"
|
|
"github.com/go-sonic/sonic/service"
|
|
"github.com/go-sonic/sonic/util"
|
|
)
|
|
|
|
type BaseCommentAssembler interface {
|
|
ConvertToDTO(ctx context.Context, comment *entity.Comment) (*dto.Comment, error)
|
|
ConvertToDTOList(ctx context.Context, comments []*entity.Comment) ([]*dto.Comment, error)
|
|
PageConvertToVOs(ctx context.Context, comments []*entity.Comment, page param.Page) ([]*vo.Comment, int64, error)
|
|
ConvertToWithParentVO(ctx context.Context, comments []*entity.Comment) ([]*vo.CommentWithParent, error)
|
|
ConvertToWithHasChildren(ctx context.Context, comments []*entity.Comment) ([]*vo.CommentWithHasChildren, error)
|
|
ClearSensitiveField(ctx context.Context, comments []*entity.Comment) []*entity.Comment
|
|
}
|
|
|
|
func NewBaseCommentAssembler(
|
|
optionService service.OptionService,
|
|
baseCommentService service.BaseCommentService,
|
|
) BaseCommentAssembler {
|
|
return &baseCommentAssembler{
|
|
OptionService: optionService,
|
|
BaseCommentService: baseCommentService,
|
|
}
|
|
}
|
|
|
|
type baseCommentAssembler struct {
|
|
OptionService service.OptionService
|
|
BaseCommentService service.BaseCommentService
|
|
}
|
|
|
|
func (*baseCommentAssembler) ClearSensitiveField(ctx context.Context, comments []*entity.Comment) []*entity.Comment {
|
|
for _, comment := range comments {
|
|
comment.Email = ""
|
|
comment.IPAddress = ""
|
|
}
|
|
return comments
|
|
}
|
|
|
|
func (b *baseCommentAssembler) ConvertToWithHasChildren(ctx context.Context, comments []*entity.Comment) ([]*vo.CommentWithHasChildren, error) {
|
|
parentIDs := make([]int32, 0)
|
|
for _, comment := range comments {
|
|
parentIDs = append(parentIDs, comment.ID)
|
|
}
|
|
dtos, err := b.ConvertToDTOList(ctx, comments)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
countMap, err := b.BaseCommentService.CountChildren(ctx, parentIDs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result := make([]*vo.CommentWithHasChildren, 0, len(comments))
|
|
for _, commentDTO := range dtos {
|
|
commentWithHasChildren := &vo.CommentWithHasChildren{
|
|
Comment: commentDTO,
|
|
}
|
|
if count, ok := countMap[commentDTO.ID]; ok && count > 0 {
|
|
commentWithHasChildren.HasChildren = true
|
|
} else {
|
|
commentWithHasChildren.HasChildren = false
|
|
}
|
|
result = append(result, commentWithHasChildren)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (b *baseCommentAssembler) ConvertToDTO(ctx context.Context, comment *entity.Comment) (*dto.Comment, error) {
|
|
commentDTO := &dto.Comment{
|
|
ID: comment.ID,
|
|
Author: comment.Author,
|
|
Email: comment.Email,
|
|
IPAddress: comment.IPAddress,
|
|
AuthorURL: comment.AuthorURL,
|
|
GravatarMD5: comment.GravatarMd5,
|
|
Content: comment.Content,
|
|
Status: comment.Status,
|
|
UserAgent: comment.UserAgent,
|
|
ParentID: comment.ParentID,
|
|
IsAdmin: comment.IsAdmin,
|
|
AllowNotification: comment.AllowNotification,
|
|
CreateTime: comment.CreateTime.UnixMilli(),
|
|
}
|
|
avatarURL, err := b.BaseCommentService.BuildAvatarURL(ctx, comment.GravatarMd5, nil, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
commentDTO.Avatar = avatarURL
|
|
return commentDTO, nil
|
|
}
|
|
|
|
func (b *baseCommentAssembler) ConvertToDTOList(ctx context.Context, comments []*entity.Comment) ([]*dto.Comment, error) {
|
|
gravatarSource, err := b.OptionService.GetOrByDefaultWithErr(ctx, property.CommentGravatarSource, property.CommentGravatarSource.DefaultValue)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
gravatarDefault, err := b.OptionService.GetOrByDefaultWithErr(ctx, property.CommentGravatarDefault, property.CommentGravatarDefault.DefaultValue)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
result := make([]*dto.Comment, 0, len(comments))
|
|
for _, comment := range comments {
|
|
commentDTO := &dto.Comment{
|
|
ID: comment.ID,
|
|
Author: comment.Author,
|
|
Email: comment.Email,
|
|
IPAddress: comment.IPAddress,
|
|
AuthorURL: comment.AuthorURL,
|
|
GravatarMD5: comment.GravatarMd5,
|
|
Content: comment.Content,
|
|
Status: comment.Status,
|
|
UserAgent: comment.UserAgent,
|
|
ParentID: comment.ParentID,
|
|
IsAdmin: comment.IsAdmin,
|
|
AllowNotification: comment.AllowNotification,
|
|
CreateTime: comment.CreateTime.UnixMilli(),
|
|
}
|
|
avatarURL, err := b.BaseCommentService.BuildAvatarURL(ctx, comment.GravatarMd5, util.StringPtr(gravatarSource.(string)), util.StringPtr(gravatarDefault.(string)))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
commentDTO.Avatar = avatarURL
|
|
result = append(result, commentDTO)
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (b *baseCommentAssembler) buildCommentTree(ctx context.Context, comments []*entity.Comment) ([]*vo.Comment, error) {
|
|
commentIDMap := make(map[int32]*vo.Comment)
|
|
commentDTOs, err := b.ConvertToDTOList(ctx, comments)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, commentDTO := range commentDTOs {
|
|
commentVO := &vo.Comment{
|
|
Comment: commentDTO,
|
|
Children: make([]*vo.Comment, 0),
|
|
}
|
|
commentIDMap[commentDTO.ID] = commentVO
|
|
}
|
|
topComments := make([]*vo.Comment, 0)
|
|
for _, comment := range comments {
|
|
if comment.ParentID != 0 {
|
|
parentComment, ok := commentIDMap[comment.ParentID]
|
|
if !ok {
|
|
log.CtxWarn(ctx, "parent comment does not exist", zap.Int32("postID", comment.PostID), zap.Int32("parentID", comment.ParentID))
|
|
continue
|
|
}
|
|
parentComment.Children = append(parentComment.Children, commentIDMap[comment.ID])
|
|
} else {
|
|
topComments = append(topComments, commentIDMap[comment.ID])
|
|
}
|
|
}
|
|
return topComments, nil
|
|
}
|
|
|
|
func (b *baseCommentAssembler) PageConvertToVOs(ctx context.Context, allComments []*entity.Comment, page param.Page) ([]*vo.Comment, int64, error) {
|
|
topComments, err := b.buildCommentTree(ctx, allComments)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
startIndex := page.PageNum * page.PageSize
|
|
endIndex := startIndex + page.PageSize
|
|
if startIndex > len(topComments) || startIndex < 0 {
|
|
return make([]*vo.Comment, 0), 0, nil
|
|
}
|
|
if endIndex > len(topComments) {
|
|
endIndex = len(topComments)
|
|
}
|
|
return topComments[startIndex:endIndex], int64(len(topComments)), nil
|
|
}
|
|
|
|
func (b *baseCommentAssembler) ConvertToWithParentVO(ctx context.Context, comments []*entity.Comment) ([]*vo.CommentWithParent, error) {
|
|
parentIDs := make([]int32, 0)
|
|
for _, comment := range comments {
|
|
if comment.ParentID != 0 {
|
|
parentIDs = append(parentIDs, comment.ParentID)
|
|
}
|
|
}
|
|
dtos, err := b.ConvertToDTOList(ctx, comments)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
parentDTOMap := make(map[int32]*dto.Comment)
|
|
if len(parentIDs) > 0 {
|
|
parents, err := b.BaseCommentService.LGetByIDs(ctx, parentIDs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
parentDTOs, err := b.ConvertToDTOList(ctx, parents)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, parentDTO := range parentDTOs {
|
|
parentDTOMap[parentDTO.ID] = parentDTO
|
|
}
|
|
}
|
|
result := make([]*vo.CommentWithParent, 0, len(comments))
|
|
for _, commentDTO := range dtos {
|
|
commentWithParent := &vo.CommentWithParent{
|
|
Comment: commentDTO,
|
|
}
|
|
if parent, ok := parentDTOMap[commentDTO.ParentID]; ok {
|
|
commentWithParent.Parent = parent
|
|
}
|
|
result = append(result, commentWithParent)
|
|
}
|
|
return result, nil
|
|
}
|