153 lines
4.3 KiB
Go
153 lines
4.3 KiB
Go
package comment
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/ccpwcn/kgo"
|
|
"github.com/minio/minio-go/v7"
|
|
"net/http"
|
|
"path"
|
|
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
|
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
|
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
|
"strconv"
|
|
|
|
"schisandra-album-cloud-microservices/common/captcha/verify"
|
|
"schisandra-album-cloud-microservices/common/constant"
|
|
errors2 "schisandra-album-cloud-microservices/common/errors"
|
|
"schisandra-album-cloud-microservices/common/i18n"
|
|
"schisandra-album-cloud-microservices/common/utils"
|
|
"time"
|
|
|
|
"github.com/mssola/useragent"
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
)
|
|
|
|
type SubmitCommentLogic struct {
|
|
logx.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
func NewSubmitCommentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubmitCommentLogic {
|
|
return &SubmitCommentLogic{
|
|
Logger: logx.WithContext(ctx),
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
}
|
|
}
|
|
|
|
func (l *SubmitCommentLogic) SubmitComment(r *http.Request, req *types.CommentRequest) (resp *types.CommentResponse, err error) {
|
|
|
|
res := verify.VerifySlideCaptcha(l.ctx, l.svcCtx.RedisClient, req.Point, req.Key)
|
|
if !res {
|
|
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "captcha.verificationFailure"))
|
|
}
|
|
userAgent := r.Header.Get("User-Agent")
|
|
if userAgent == "" {
|
|
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.commentError"))
|
|
}
|
|
ua := useragent.New(userAgent)
|
|
|
|
ip := utils.GetClientIP(r)
|
|
location, err := l.svcCtx.Ip2Region.SearchByStr(ip)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
location = utils.RemoveZeroAndAdjust(location)
|
|
|
|
browser, _ := ua.Browser()
|
|
operatingSystem := ua.OS()
|
|
var isAuthor int64 = 0
|
|
uid, ok := l.ctx.Value("user_id").(string)
|
|
if !ok {
|
|
return nil, errors.New("user_id not found in context")
|
|
}
|
|
if uid == req.Author {
|
|
isAuthor = 1
|
|
}
|
|
xssFilterContent := utils.XssFilter(req.Content)
|
|
if xssFilterContent == "" {
|
|
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.commentError"))
|
|
}
|
|
commentContent := l.svcCtx.Sensitive.Replace(xssFilterContent, '*')
|
|
topicType := constant.CommentTopicType
|
|
commentType := constant.COMMENT
|
|
commentReply := l.svcCtx.DB.ScaCommentReply
|
|
comment := &model.ScaCommentReply{
|
|
Content: commentContent,
|
|
UserID: uid,
|
|
TopicID: req.TopicId,
|
|
TopicType: topicType,
|
|
CommentType: commentType,
|
|
Author: isAuthor,
|
|
CommentIP: ip,
|
|
Location: location,
|
|
Browser: browser,
|
|
OperatingSystem: operatingSystem,
|
|
Agent: userAgent,
|
|
}
|
|
err = commentReply.Create(comment)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if req.Images != "" {
|
|
imagesData, err := utils.Base64ToBytes(req.Images)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
objectKey := path.Join(
|
|
req.TopicId,
|
|
time.Now().Format("2006/01"), // 按年/月划分目录
|
|
strconv.FormatInt(comment.ID, 10),
|
|
fmt.Sprintf("%s_%s.jpg", uid, kgo.SimpleUuid()),
|
|
)
|
|
|
|
exists, err := l.svcCtx.MinioClient.BucketExists(l.ctx, constant.CommentImagesBucketName)
|
|
if err != nil || !exists {
|
|
err = l.svcCtx.MinioClient.MakeBucket(l.ctx, constant.CommentImagesBucketName, minio.MakeBucketOptions{Region: "us-east-1", ObjectLocking: true})
|
|
if err != nil {
|
|
logx.Errorf("Failed to create MinIO bucket: %v", err)
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// 上传到MinIO
|
|
_, err = l.svcCtx.MinioClient.PutObject(
|
|
l.ctx,
|
|
constant.CommentImagesBucketName,
|
|
objectKey,
|
|
bytes.NewReader(imagesData),
|
|
int64(len(imagesData)),
|
|
minio.PutObjectOptions{
|
|
ContentType: "image/jpeg",
|
|
},
|
|
)
|
|
if err != nil {
|
|
logx.Errorf("Failed to upload image to MinIO: %v", err)
|
|
return nil, err
|
|
}
|
|
info, err := commentReply.Where(commentReply.ID.Eq(comment.ID)).Update(commentReply.ImagePath, objectKey)
|
|
if err != nil || info.RowsAffected == 0 {
|
|
return nil, errors.New("update image path failed")
|
|
}
|
|
|
|
}
|
|
commentResponse := &types.CommentResponse{
|
|
Id: comment.ID,
|
|
Content: commentContent,
|
|
UserId: uid,
|
|
TopicId: req.TopicId,
|
|
Author: isAuthor,
|
|
Location: location,
|
|
Browser: browser,
|
|
OperatingSystem: operatingSystem,
|
|
CreatedTime: time.Now().Format(constant.TimeFormat),
|
|
}
|
|
return commentResponse, nil
|
|
}
|