PandaWiki/backend/usecase/comment.go

190 lines
5.9 KiB
Go
Raw Permalink Normal View History

2025-07-16 21:06:31 +08:00
package usecase
import (
"context"
2025-07-17 20:10:12 +08:00
"strings"
2025-07-16 21:06:31 +08:00
"time"
"github.com/google/uuid"
2025-07-17 15:02:18 +08:00
"github.com/samber/lo"
2025-07-16 21:06:31 +08:00
2025-08-14 18:04:09 +08:00
"github.com/chaitin/panda-wiki/consts"
2025-07-16 21:06:31 +08:00
"github.com/chaitin/panda-wiki/domain"
"github.com/chaitin/panda-wiki/log"
2025-07-17 15:02:18 +08:00
"github.com/chaitin/panda-wiki/repo/ipdb"
2025-07-16 21:06:31 +08:00
"github.com/chaitin/panda-wiki/repo/pg"
)
type CommentUsecase struct {
logger *log.Logger
CommentRepo *pg.CommentRepository
NodeRepo *pg.NodeRepository
2025-07-17 15:02:18 +08:00
ipRepo *ipdb.IPAddressRepo
2025-08-13 16:40:33 +08:00
authRepo *pg.AuthRepo
2025-07-16 21:06:31 +08:00
}
2025-07-17 15:02:18 +08:00
func NewCommentUsecase(commentRepo *pg.CommentRepository, logger *log.Logger,
2025-08-13 16:40:33 +08:00
nodeRepo *pg.NodeRepository, ipRepo *ipdb.IPAddressRepo, authRepo *pg.AuthRepo) *CommentUsecase {
2025-07-16 21:06:31 +08:00
return &CommentUsecase{
logger: logger.WithModule("usecase.comment"),
CommentRepo: commentRepo,
NodeRepo: nodeRepo,
2025-07-17 15:02:18 +08:00
ipRepo: ipRepo,
2025-08-13 16:40:33 +08:00
authRepo: authRepo,
2025-07-16 21:06:31 +08:00
}
}
2025-08-13 16:40:33 +08:00
func (u *CommentUsecase) CreateComment(ctx context.Context, commentReq *domain.CommentReq, KbID string, remoteIP string,
status domain.CommentStatus, userID uint) (string, error) {
2025-07-16 21:06:31 +08:00
// node
if _, err := u.NodeRepo.GetNodeByID(ctx, commentReq.NodeID); err != nil {
return "", err
}
// 构造结构体给下方数据库进行插入
CommentID, err := uuid.NewV7()
if err != nil {
return "", err
}
CommentStr := CommentID.String()
err = u.CommentRepo.CreateComment(ctx, &domain.Comment{
2025-10-22 18:34:49 +08:00
ID: CommentStr,
PicUrls: commentReq.PicUrls,
NodeID: commentReq.NodeID,
2025-07-16 21:06:31 +08:00
Info: domain.CommentInfo{
2025-08-13 16:40:33 +08:00
UserName: commentReq.UserName,
RemoteIP: remoteIP,
AuthUserID: userID, // default = 0. have no auth info
2025-07-16 21:06:31 +08:00
},
ParentID: commentReq.ParentID,
RootID: commentReq.RootID,
Content: commentReq.Content,
CreatedAt: time.Now(),
KbID: KbID,
2025-07-25 17:33:03 +08:00
Status: status,
2025-07-16 21:06:31 +08:00
})
if err != nil {
return "", err
}
// success
return CommentStr, nil
}
2025-08-14 18:04:09 +08:00
func (u *CommentUsecase) GetCommentListByNodeID(ctx context.Context, nodeID string, edition consts.LicenseEdition) (*domain.PaginatedResult[[]*domain.ShareCommentListItem], error) {
2025-07-25 17:33:03 +08:00
comments, total, err := u.CommentRepo.GetCommentList(ctx, nodeID, edition)
2025-07-16 21:06:31 +08:00
if err != nil {
return nil, err
}
2025-08-13 16:40:33 +08:00
// get auth userinfo --> auth_user_id is not 0
authIDs := make([]uint, 0, len(comments))
for _, comment := range comments {
if comment.Info.AuthUserID != 0 {
authIDs = append(authIDs, comment.Info.AuthUserID)
}
}
// get user info according authIDs
authMap, err := u.authRepo.GetAuthUserinfoByIDs(ctx, authIDs)
if err != nil {
u.logger.Error("get user info failed", log.Error(err))
}
2025-07-17 20:10:12 +08:00
// get ip address
ipAddressMap := make(map[string]*domain.IPAddress)
lo.Map(comments, func(comment *domain.ShareCommentListItem, _ int) *domain.ShareCommentListItem {
if _, ok := ipAddressMap[comment.Info.RemoteIP]; !ok {
ipAddress, err := u.ipRepo.GetIPAddress(ctx, comment.Info.RemoteIP)
if err != nil {
u.logger.Error("get ip address failed", log.Error(err), log.String("ip", comment.Info.RemoteIP))
return comment
}
ipAddressMap[comment.Info.RemoteIP] = ipAddress
comment.IPAddress = ipAddress
comment.Info.RemoteIP = maskIP(comment.Info.RemoteIP)
2025-07-17 20:47:41 +08:00
comment.IPAddress.IP = maskIP(comment.IPAddress.IP)
2025-07-17 20:10:12 +08:00
} else {
comment.IPAddress = ipAddressMap[comment.Info.RemoteIP]
}
2025-08-13 16:40:33 +08:00
if _, ok := authMap[comment.Info.AuthUserID]; ok { // moderate userinfo
comment.Info.UserName = authMap[comment.Info.AuthUserID].AuthUserInfo.Username
comment.Info.Avatar = authMap[comment.Info.AuthUserID].AuthUserInfo.AvatarUrl
comment.Info.Email = authMap[comment.Info.AuthUserID].AuthUserInfo.Email
}
2025-07-17 20:10:12 +08:00
return comment
})
2025-07-18 15:35:43 +08:00
// success
2025-07-16 21:06:31 +08:00
return domain.NewPaginatedResult(comments, uint64(total)), nil
}
2025-07-17 15:02:18 +08:00
2025-08-14 18:04:09 +08:00
func (u *CommentUsecase) GetCommentListByKbID(ctx context.Context, req *domain.CommentListReq, edition consts.LicenseEdition) (*domain.PaginatedResult[[]*domain.CommentListItem], error) {
2025-07-25 17:33:03 +08:00
comments, total, err := u.CommentRepo.GetCommentListByKbID(ctx, req, edition)
2025-07-17 15:02:18 +08:00
if err != nil {
return nil, err
}
2025-08-13 16:40:33 +08:00
// get auth userinfo --> auth_user_id is not 0
authIDs := make([]uint, 0, len(comments))
for _, comment := range comments {
if comment.Info.AuthUserID != 0 {
authIDs = append(authIDs, comment.Info.AuthUserID)
}
}
// get user info according authIDs
authMap, err := u.authRepo.GetAuthUserinfoByIDs(ctx, authIDs)
if err != nil {
u.logger.Error("get user info failed", log.Error(err))
}
2025-07-17 15:02:18 +08:00
// get ip address
ipAddressMap := make(map[string]*domain.IPAddress)
lo.Map(comments, func(comment *domain.CommentListItem, _ int) *domain.CommentListItem {
if _, ok := ipAddressMap[comment.Info.RemoteIP]; !ok {
ipAddress, err := u.ipRepo.GetIPAddress(ctx, comment.Info.RemoteIP)
if err != nil {
u.logger.Error("get ip address failed", log.Error(err), log.String("ip", comment.Info.RemoteIP))
return comment
}
ipAddressMap[comment.Info.RemoteIP] = ipAddress
comment.IPAddress = ipAddress
} else {
comment.IPAddress = ipAddressMap[comment.Info.RemoteIP]
}
2025-08-13 16:40:33 +08:00
if _, ok := authMap[comment.Info.AuthUserID]; ok { // moderate userinfo
comment.Info.UserName = authMap[comment.Info.AuthUserID].AuthUserInfo.Username
comment.Info.Avatar = authMap[comment.Info.AuthUserID].AuthUserInfo.AvatarUrl
comment.Info.Email = authMap[comment.Info.AuthUserID].AuthUserInfo.Email
}
2025-07-17 15:02:18 +08:00
return comment
})
return domain.NewPaginatedResult(comments, uint64(total)), nil
}
// 批量删除评论, 简单化只删除传入评论id
func (u *CommentUsecase) DeleteCommentList(ctx context.Context, req *domain.DeleteCommentListReq) error {
err := u.CommentRepo.DeleteCommentList(ctx, req.IDS)
if err != nil {
return err
}
return nil
}
2025-07-17 20:10:12 +08:00
func maskIP(ip string) string {
if ip == "" {
return ""
}
// 处理 IPv4 地址 (格式: a.b.c.d)
if strings.Contains(ip, ".") {
parts := strings.Split(ip, ".")
if len(parts) != 4 { // 非标准IPv4格式直接返回原值
return ""
}
return parts[0] + ".*.*." + parts[3]
}
// 处理 IPv6 地址 (标准格式包含冒号)
if strings.Contains(ip, ":") {
return ""
}
return ""
}