♻️ use minio instead of mongodb

This commit is contained in:
2025-02-05 18:08:29 +08:00
parent a3d4f2c8d1
commit d2b0d7b42e
53 changed files with 2446 additions and 702 deletions

View File

@@ -2,17 +2,14 @@ package comment
import (
"context"
"encoding/base64"
"errors"
"fmt"
"net/url"
"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/mongodb"
"schisandra-album-cloud-microservices/common/constant"
"schisandra-album-cloud-microservices/common/utils"
"sync"
"time"
"github.com/chenmingyong0423/go-mongox/v2/builder/query"
"github.com/zeromicro/go-zero/core/logx"
"gorm.io/gen/field"
)
@@ -60,6 +57,7 @@ func (l *GetCommentListLogic) GetCommentList(req *types.CommentListRequest) (res
comment.Browser,
comment.OperatingSystem,
comment.Location,
comment.ImagePath,
user.Avatar,
user.Nickname,
).LeftJoin(user, comment.UserID.EqCol(user.UID)).
@@ -82,7 +80,7 @@ func (l *GetCommentListLogic) GetCommentList(req *types.CommentListRequest) (res
for _, commentList := range commentQueryList {
commentIds = append(commentIds, commentList.ID)
}
l.wg.Add(2)
l.wg.Add(1)
// *************** 获取评论点赞状态 **********
likeMap := make(map[int64]bool)
@@ -102,36 +100,22 @@ func (l *GetCommentListLogic) GetCommentList(req *types.CommentListRequest) (res
likeMap[like.CommentID] = true
}
}()
// ***************获取评论图片 **********
commentImageMap := make(map[int64][]string)
go func() {
defer l.wg.Done()
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
commentImages, err := newCollection.Finder().
Filter(query.Eq("topic_id", req.TopicId)).
Filter(query.In("comment_id", commentIds...)).
Find(l.ctx)
if err != nil {
logx.Error(err)
return
}
for _, image := range commentImages {
if len(image.Images) == 0 {
continue
}
imagesBase64 := make([]string, len(image.Images))
for i, img := range image.Images {
imagesBase64[i] = fmt.Sprintf("data:%s;base64,%s", utils.GetMimeType(img), base64.StdEncoding.EncodeToString(img))
}
commentImageMap[image.CommentId] = imagesBase64
}
}()
l.wg.Wait()
// *************** 组装数据 **********
result := make([]types.CommentContent, 0, len(commentQueryList))
for _, commentData := range commentQueryList {
var imagePath string
if commentData.ImagePath != "" {
reqParams := make(url.Values)
presignedURL, err := l.svcCtx.MinioClient.PresignedGetObject(l.ctx, constant.CommentImagesBucketName, commentData.ImagePath, time.Hour*24, reqParams)
if err != nil {
logx.Error(err)
continue
}
imagePath = presignedURL.String()
}
commentContent := types.CommentContent{
Avatar: commentData.Avatar,
NickName: commentData.Nickname,
@@ -148,7 +132,7 @@ func (l *GetCommentListLogic) GetCommentList(req *types.CommentListRequest) (res
Browser: commentData.Browser,
OperatingSystem: commentData.OperatingSystem,
IsLiked: likeMap[commentData.ID],
Images: commentImageMap[commentData.ID],
Images: imagePath,
}
result = append(result, commentContent)
}

View File

@@ -2,17 +2,13 @@ package comment
import (
"context"
"encoding/base64"
"errors"
"fmt"
"net/url"
"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/mongodb"
"schisandra-album-cloud-microservices/common/constant"
"schisandra-album-cloud-microservices/common/utils"
"sync"
"github.com/chenmingyong0423/go-mongox/v2/builder/query"
"time"
"github.com/zeromicro/go-zero/core/logx"
)
@@ -59,6 +55,7 @@ func (l *GetReplyListLogic) GetReplyList(req *types.ReplyListRequest) (resp *typ
reply.ReplyUser,
reply.ReplyTo,
reply.ReplyID,
reply.ImagePath,
commentUser.Avatar,
commentUser.Nickname,
replyUser.Nickname.As("reply_nickname"),
@@ -82,7 +79,7 @@ func (l *GetReplyListLogic) GetReplyList(req *types.ReplyListRequest) (resp *typ
for _, commentList := range replyQueryList {
commentIds = append(commentIds, commentList.ID)
}
l.wg.Add(2)
l.wg.Add(1)
// *************** 获取评论点赞状态 **********
likeMap := make(map[int64]bool)
@@ -102,36 +99,22 @@ func (l *GetReplyListLogic) GetReplyList(req *types.ReplyListRequest) (resp *typ
likeMap[like.CommentID] = true
}
}()
// ***************获取评论图片 **********
commentImageMap := make(map[int64][]string)
go func() {
defer l.wg.Done()
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
commentImages, err := newCollection.Finder().
Filter(query.Eq("topic_id", req.TopicId)).
Filter(query.In("comment_id", commentIds...)).
Find(l.ctx)
if err != nil {
logx.Error(err)
return
}
for _, image := range commentImages {
if len(image.Images) == 0 {
continue
}
imagesBase64 := make([]string, len(image.Images))
for i, img := range image.Images {
imagesBase64[i] = fmt.Sprintf("data:%s;base64,%s", utils.GetMimeType(img), base64.StdEncoding.EncodeToString(img))
}
commentImageMap[image.CommentId] = imagesBase64
}
}()
l.wg.Wait()
// *************** 组装数据 **********
result := make([]types.CommentContent, 0, len(replyQueryList))
for _, replyData := range replyQueryList {
var imagePath string
if replyData.ImagePath != "" {
reqParams := make(url.Values)
presignedURL, err := l.svcCtx.MinioClient.PresignedGetObject(l.ctx, constant.CommentImagesBucketName, replyData.ImagePath, time.Hour*24, reqParams)
if err != nil {
logx.Error(err)
continue
}
imagePath = presignedURL.String()
}
commentContent := types.CommentContent{
Avatar: replyData.Avatar,
NickName: replyData.Nickname,
@@ -148,7 +131,7 @@ func (l *GetReplyListLogic) GetReplyList(req *types.ReplyListRequest) (resp *typ
Browser: replyData.Browser,
OperatingSystem: replyData.OperatingSystem,
IsLiked: likeMap[replyData.ID],
Images: commentImageMap[replyData.ID],
Images: imagePath,
ReplyUser: replyData.ReplyUser,
ReplyTo: replyData.ReplyTo,
ReplyId: replyData.ReplyId,

View File

@@ -1,13 +1,18 @@
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/mongodb"
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
"strconv"
"schisandra-album-cloud-microservices/common/captcha/verify"
"schisandra-album-cloud-microservices/common/constant"
@@ -41,9 +46,6 @@ func (l *SubmitCommentLogic) SubmitComment(r *http.Request, req *types.CommentRe
if !res {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "captcha.verificationFailure"))
}
if len(req.Images) > 3 {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.tooManyImages"))
}
userAgent := r.Header.Get("User-Agent")
if userAgent == "" {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.commentError"))
@@ -74,6 +76,7 @@ func (l *SubmitCommentLogic) SubmitComment(r *http.Request, req *types.CommentRe
commentContent := l.svcCtx.Sensitive.Replace(xssFilterContent, '*')
topicType := constant.CommentTopicType
commentType := constant.COMMENT
commentReply := l.svcCtx.DB.ScaCommentReply
comment := &model.ScaCommentReply{
Content: commentContent,
UserID: uid,
@@ -87,28 +90,52 @@ func (l *SubmitCommentLogic) SubmitComment(r *http.Request, req *types.CommentRe
OperatingSystem: operatingSystem,
Agent: userAgent,
}
err = l.svcCtx.DB.ScaCommentReply.Create(comment)
err = commentReply.Create(comment)
if err != nil {
return nil, err
}
if len(req.Images) > 0 {
imagesData, err := utils.ProcessImages(req.Images)
if req.Images != "" {
imagesData, err := utils.Base64ToBytes(req.Images)
if err != nil {
return nil, err
}
commentImages := &types.CommentImages{
UserId: uid,
TopicId: req.TopicId,
CommentId: comment.ID,
Images: imagesData,
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
}
}
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
_, err = newCollection.Creator().InsertOne(l.ctx, commentImages)
// 上传到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,

View File

@@ -1,18 +1,23 @@
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/mongodb"
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
"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"
"strconv"
"time"
"github.com/mssola/useragent"
@@ -39,9 +44,6 @@ func (l *SubmitReplyCommentLogic) SubmitReplyComment(r *http.Request, req *types
if !res {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "captcha.verificationFailure"))
}
if len(req.Images) > 3 {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.tooManyImages"))
}
userAgent := r.Header.Get("User-Agent")
if userAgent == "" {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.commentError"))
@@ -105,24 +107,47 @@ func (l *SubmitReplyCommentLogic) SubmitReplyComment(r *http.Request, req *types
}
if len(req.Images) > 0 {
imagesData, err := utils.ProcessImages(req.Images)
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(reply.ID, 10),
fmt.Sprintf("%s_%s.jpg", uid, kgo.SimpleUuid()),
)
commentImages := &types.CommentImages{
UserId: uid,
TopicId: req.TopicId,
CommentId: reply.ID,
Images: imagesData,
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
}
}
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
_, err = newCollection.Creator().InsertOne(l.ctx, commentImages)
// 上传到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(reply.ID)).Update(commentReply.ImagePath, objectKey)
if err != nil || info.RowsAffected == 0 {
return nil, errors.New("update image path failed")
}
}
commentResponse := &types.CommentResponse{

View File

@@ -1,18 +1,23 @@
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/mongodb"
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
"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"
"strconv"
"time"
"github.com/mssola/useragent"
@@ -39,9 +44,6 @@ func (l *SubmitReplyReplyLogic) SubmitReplyReply(r *http.Request, req *types.Rep
if !res {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "captcha.verificationFailure"))
}
if len(req.Images) > 3 {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.tooManyImages"))
}
userAgent := r.Header.Get("User-Agent")
if userAgent == "" {
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.commentError"))
@@ -112,24 +114,47 @@ func (l *SubmitReplyReplyLogic) SubmitReplyReply(r *http.Request, req *types.Rep
}
// 处理图片
if len(req.Images) > 0 {
imagesData, err := utils.ProcessImages(req.Images)
if req.Images != "" {
imagesData, err := utils.Base64ToBytes(req.Images)
if err != nil {
return nil, err
}
commentImages := &types.CommentImages{
UserId: uid,
TopicId: req.TopicId,
CommentId: replyReply.ID,
Images: imagesData,
objectKey := path.Join(
req.TopicId,
time.Now().Format("2006/01"), // 按年/月划分目录
strconv.FormatInt(replyReply.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
}
}
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
_, err = newCollection.Creator().InsertOne(l.ctx, commentImages)
// 上传到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(replyReply.ID)).Update(commentReply.ImagePath, objectKey)
if err != nil || info.RowsAffected == 0 {
return nil, errors.New("update image path failed")
}
}
// 构建响应