🏗️ update
This commit is contained in:
@@ -19,6 +19,13 @@ type Config struct {
|
||||
MaxOpenConn int
|
||||
MaxIdleConn int
|
||||
}
|
||||
Mongo struct {
|
||||
Uri string
|
||||
Username string
|
||||
Password string
|
||||
AuthSource string
|
||||
Database string
|
||||
}
|
||||
Redis struct {
|
||||
Host string
|
||||
Pass string
|
||||
|
@@ -0,0 +1,25 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/comment"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func DislikeCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.CommentDisLikeRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := comment.NewDislikeCommentLogic(r.Context(), svcCtx)
|
||||
err := l.DislikeComment(&req)
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/comment"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func GetCommentListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.CommentListRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := comment.NewGetCommentListLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetCommentList(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/comment"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func GetReplyListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ReplyListRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := comment.NewGetReplyListLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetReplyList(&req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/comment"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func LikeCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.CommentLikeRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := comment.NewLikeCommentLogic(r.Context(), svcCtx)
|
||||
err := l.LikeComment(&req)
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/comment"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func SubmitCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.CommentRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := comment.NewSubmitCommentLogic(r.Context(), svcCtx)
|
||||
resp, err := l.SubmitComment(r, &req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/comment"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func SubmitReplyCommentHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ReplyCommentRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := comment.NewSubmitReplyCommentLogic(r.Context(), svcCtx)
|
||||
resp, err := l.SubmitReplyComment(r, &req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/comment"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func SubmitReplyReplyHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ReplyReplyRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := comment.NewSubmitReplyReplyLogic(r.Context(), svcCtx)
|
||||
resp, err := l.SubmitReplyReply(r, &req)
|
||||
if err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
} else {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -9,9 +9,11 @@ import (
|
||||
|
||||
captcha "schisandra-album-cloud-microservices/app/auth/api/internal/handler/captcha"
|
||||
client "schisandra-album-cloud-microservices/app/auth/api/internal/handler/client"
|
||||
comment "schisandra-album-cloud-microservices/app/auth/api/internal/handler/comment"
|
||||
oauth "schisandra-album-cloud-microservices/app/auth/api/internal/handler/oauth"
|
||||
sms "schisandra-album-cloud-microservices/app/auth/api/internal/handler/sms"
|
||||
token "schisandra-album-cloud-microservices/app/auth/api/internal/handler/token"
|
||||
upscale "schisandra-album-cloud-microservices/app/auth/api/internal/handler/upscale"
|
||||
user "schisandra-album-cloud-microservices/app/auth/api/internal/handler/user"
|
||||
websocket "schisandra-album-cloud-microservices/app/auth/api/internal/handler/websocket"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
@@ -57,6 +59,53 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware, serverCtx.CasbinVerifyMiddleware, serverCtx.AuthorizationMiddleware, serverCtx.NonceMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/dislike",
|
||||
Handler: comment.DislikeCommentHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/like",
|
||||
Handler: comment.LikeCommentHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/list",
|
||||
Handler: comment.GetCommentListHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/reply/list",
|
||||
Handler: comment.GetReplyListHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/reply/reply/submit",
|
||||
Handler: comment.SubmitReplyReplyHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/reply/submit",
|
||||
Handler: comment.SubmitReplyCommentHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/submit",
|
||||
Handler: comment.SubmitCommentHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||
rest.WithPrefix("/api/auth/comment"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware},
|
||||
@@ -151,6 +200,22 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware, serverCtx.NonceMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/upload",
|
||||
Handler: upscale.UploadImageHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/auth/upscale"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
rest.WithMaxBytes(10485760),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware, serverCtx.NonceMiddleware},
|
||||
@@ -190,6 +255,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/file",
|
||||
Handler: websocket.FileWebsocketHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/message",
|
||||
|
@@ -0,0 +1,25 @@
|
||||
package upscale
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/upscale"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
)
|
||||
|
||||
func UploadImageHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.UploadRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := upscale.NewUploadImageLogic(r.Context(), svcCtx)
|
||||
err := l.UploadImage(r, &req)
|
||||
xhttp.JsonBaseResponseCtx(r.Context(), w, err)
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/websocket"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
)
|
||||
|
||||
func FileWebsocketHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := websocket.NewFileWebsocketLogic(r.Context(), svcCtx)
|
||||
l.FileWebsocket(w, r)
|
||||
}
|
||||
}
|
59
app/auth/api/internal/logic/comment/dislike_comment_logic.go
Normal file
59
app/auth/api/internal/logic/comment/dislike_comment_logic.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
errors2 "schisandra-album-cloud-microservices/common/errors"
|
||||
"schisandra-album-cloud-microservices/common/i18n"
|
||||
)
|
||||
|
||||
type DislikeCommentLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewDislikeCommentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DislikeCommentLogic {
|
||||
return &DislikeCommentLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DislikeCommentLogic) DislikeComment(req *types.CommentDisLikeRequest) (err error) {
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return errors.New("user_id not found")
|
||||
}
|
||||
tx := l.svcCtx.DB.Begin()
|
||||
commentLike := l.svcCtx.DB.ScaCommentLike
|
||||
resultInfo, err := tx.ScaCommentLike.Where(commentLike.TopicID.Eq(req.TopicId), commentLike.CommentID.Eq(req.CommentId), commentLike.UserID.Eq(uid)).Delete()
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if resultInfo.RowsAffected == 0 {
|
||||
_ = tx.Rollback()
|
||||
return errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.LikeError"))
|
||||
}
|
||||
comment := l.svcCtx.DB.ScaCommentReply
|
||||
updates, err := tx.ScaCommentReply.Where(comment.TopicID.Eq(req.TopicId), comment.ID.Eq(req.CommentId)).Update(comment.Likes, comment.Likes.Sub(1))
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if updates.RowsAffected == 0 {
|
||||
_ = tx.Rollback()
|
||||
return errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.LikeError"))
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
162
app/auth/api/internal/logic/comment/get_comment_list_logic.go
Normal file
162
app/auth/api/internal/logic/comment/get_comment_list_logic.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"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"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"gorm.io/gen/field"
|
||||
)
|
||||
|
||||
type GetCommentListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewGetCommentListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCommentListLogic {
|
||||
return &GetCommentListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetCommentListLogic) GetCommentList(req *types.CommentListRequest) (resp *types.CommentListPageResponse, err error) {
|
||||
// 获取用户ID
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
}
|
||||
var commentQueryList []types.CommentListQueryResult
|
||||
comment := l.svcCtx.DB.ScaCommentReply
|
||||
user := l.svcCtx.DB.ScaAuthUser
|
||||
var orderConditions []field.Expr
|
||||
|
||||
if req.IsHot {
|
||||
orderConditions = append(orderConditions, comment.Likes.Desc(), comment.ReplyCount.Desc())
|
||||
} else {
|
||||
orderConditions = append(orderConditions, comment.CreatedAt.Desc())
|
||||
}
|
||||
count, err := comment.Select(
|
||||
comment.ID,
|
||||
comment.UserID,
|
||||
comment.TopicID,
|
||||
comment.Content,
|
||||
comment.CreatedAt,
|
||||
comment.Author,
|
||||
comment.Likes,
|
||||
comment.ReplyCount,
|
||||
comment.Browser,
|
||||
comment.OperatingSystem,
|
||||
comment.Location,
|
||||
user.Avatar,
|
||||
user.Nickname,
|
||||
).LeftJoin(user, comment.UserID.EqCol(user.UID)).
|
||||
Where(comment.TopicID.Eq(req.TopicId), comment.CommentType.Eq(constant.COMMENT)).
|
||||
Order(orderConditions...).
|
||||
ScanByPage(&commentQueryList, (req.Page-1)*req.Size, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count == 0 || len(commentQueryList) == 0 {
|
||||
return &types.CommentListPageResponse{
|
||||
Total: count,
|
||||
Size: req.Size,
|
||||
Current: req.Page,
|
||||
Comments: []types.CommentContent{},
|
||||
}, nil
|
||||
}
|
||||
// **************** 获取评论Id和用户Id ************
|
||||
commentIds := make([]int64, 0, len(commentQueryList))
|
||||
for _, commentList := range commentQueryList {
|
||||
commentIds = append(commentIds, commentList.ID)
|
||||
}
|
||||
l.wg.Add(2)
|
||||
|
||||
// *************** 获取评论点赞状态 **********
|
||||
likeMap := make(map[int64]bool)
|
||||
go func() {
|
||||
defer l.wg.Done()
|
||||
commentLike := l.svcCtx.DB.ScaCommentLike
|
||||
likeList, err := commentLike.Where(
|
||||
commentLike.TopicID.Eq(req.TopicId),
|
||||
commentLike.UserID.Eq(uid),
|
||||
commentLike.CommentID.In(commentIds...)).
|
||||
Find()
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
for _, like := range likeList {
|
||||
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 {
|
||||
commentContent := types.CommentContent{
|
||||
Avatar: commentData.Avatar,
|
||||
NickName: commentData.Nickname,
|
||||
Content: commentData.Content,
|
||||
CreatedTime: commentData.CreatedAt.Format(constant.TimeFormat),
|
||||
Level: 0,
|
||||
Id: commentData.ID,
|
||||
UserId: commentData.UserID,
|
||||
TopicId: commentData.TopicID,
|
||||
IsAuthor: commentData.Author,
|
||||
Likes: commentData.Likes,
|
||||
ReplyCount: commentData.ReplyCount,
|
||||
Location: commentData.Location,
|
||||
Browser: commentData.Browser,
|
||||
OperatingSystem: commentData.OperatingSystem,
|
||||
IsLiked: likeMap[commentData.ID],
|
||||
Images: commentImageMap[commentData.ID],
|
||||
}
|
||||
result = append(result, commentContent)
|
||||
}
|
||||
commentListPageResponse := &types.CommentListPageResponse{
|
||||
Total: count,
|
||||
Size: req.Size,
|
||||
Current: req.Page,
|
||||
Comments: result,
|
||||
}
|
||||
return commentListPageResponse, nil
|
||||
}
|
166
app/auth/api/internal/logic/comment/get_reply_list_logic.go
Normal file
166
app/auth/api/internal/logic/comment/get_reply_list_logic.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"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"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetReplyListLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
wg sync.WaitGroup
|
||||
}
|
||||
|
||||
func NewGetReplyListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetReplyListLogic {
|
||||
return &GetReplyListLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetReplyListLogic) GetReplyList(req *types.ReplyListRequest) (resp *types.CommentListPageResponse, err error) {
|
||||
// 获取用户ID
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found")
|
||||
}
|
||||
var replyQueryList []types.ReplyListQueryResult
|
||||
reply := l.svcCtx.DB.ScaCommentReply
|
||||
user := l.svcCtx.DB.ScaAuthUser
|
||||
commentUser := user.As("comment_user")
|
||||
replyUser := user.As("reply_user")
|
||||
|
||||
count, err := reply.Select(
|
||||
reply.ID,
|
||||
reply.UserID,
|
||||
reply.TopicID,
|
||||
reply.Content,
|
||||
reply.CreatedAt,
|
||||
reply.Author,
|
||||
reply.ReplyCount,
|
||||
reply.Likes,
|
||||
reply.Browser,
|
||||
reply.OperatingSystem,
|
||||
reply.Location,
|
||||
reply.ReplyUser,
|
||||
reply.ReplyTo,
|
||||
reply.ReplyID,
|
||||
commentUser.Avatar,
|
||||
commentUser.Nickname,
|
||||
replyUser.Nickname.As("reply_nickname"),
|
||||
).LeftJoin(commentUser, reply.UserID.EqCol(commentUser.UID)).
|
||||
LeftJoin(replyUser, reply.ReplyUser.EqCol(replyUser.UID)).
|
||||
Where(reply.TopicID.Eq(req.TopicId), reply.ReplyID.Eq(req.CommentId), reply.CommentType.Eq(constant.REPLY)).
|
||||
Order(reply.Likes.Desc(), reply.CreatedAt.Desc()).
|
||||
ScanByPage(&replyQueryList, (req.Page-1)*req.Size, req.Size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count == 0 || len(replyQueryList) == 0 {
|
||||
return &types.CommentListPageResponse{
|
||||
Total: count,
|
||||
Size: req.Size,
|
||||
Current: req.Page,
|
||||
}, nil
|
||||
}
|
||||
// **************** 获取评论Id和用户Id ************
|
||||
commentIds := make([]int64, 0, len(replyQueryList))
|
||||
for _, commentList := range replyQueryList {
|
||||
commentIds = append(commentIds, commentList.ID)
|
||||
}
|
||||
l.wg.Add(2)
|
||||
|
||||
// *************** 获取评论点赞状态 **********
|
||||
likeMap := make(map[int64]bool)
|
||||
go func() {
|
||||
defer l.wg.Done()
|
||||
commentLike := l.svcCtx.DB.ScaCommentLike
|
||||
likeList, err := commentLike.Where(
|
||||
commentLike.TopicID.Eq(req.TopicId),
|
||||
commentLike.UserID.Eq(uid),
|
||||
commentLike.CommentID.In(commentIds...)).
|
||||
Find()
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return
|
||||
}
|
||||
for _, like := range likeList {
|
||||
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 {
|
||||
commentContent := types.CommentContent{
|
||||
Avatar: replyData.Avatar,
|
||||
NickName: replyData.Nickname,
|
||||
Content: replyData.Content,
|
||||
CreatedTime: replyData.CreatedAt.Format(constant.TimeFormat),
|
||||
Level: 0,
|
||||
Id: replyData.ID,
|
||||
UserId: replyData.UserID,
|
||||
TopicId: replyData.TopicID,
|
||||
IsAuthor: replyData.Author,
|
||||
Likes: replyData.Likes,
|
||||
ReplyCount: replyData.ReplyCount,
|
||||
Location: replyData.Location,
|
||||
Browser: replyData.Browser,
|
||||
OperatingSystem: replyData.OperatingSystem,
|
||||
IsLiked: likeMap[replyData.ID],
|
||||
Images: commentImageMap[replyData.ID],
|
||||
ReplyUser: replyData.ReplyUser,
|
||||
ReplyTo: replyData.ReplyTo,
|
||||
ReplyId: replyData.ReplyId,
|
||||
ReplyNickname: replyData.ReplyNickname,
|
||||
}
|
||||
result = append(result, commentContent)
|
||||
}
|
||||
commentListPageResponse := &types.CommentListPageResponse{
|
||||
Total: count,
|
||||
Size: req.Size,
|
||||
Current: req.Page,
|
||||
Comments: result,
|
||||
}
|
||||
return commentListPageResponse, nil
|
||||
}
|
61
app/auth/api/internal/logic/comment/like_comment_logic.go
Normal file
61
app/auth/api/internal/logic/comment/like_comment_logic.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"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"
|
||||
"schisandra-album-cloud-microservices/common/i18n"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type LikeCommentLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewLikeCommentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LikeCommentLogic {
|
||||
return &LikeCommentLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *LikeCommentLogic) LikeComment(req *types.CommentLikeRequest) (err error) {
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return errors.New("user_id not found")
|
||||
}
|
||||
tx := l.svcCtx.DB.Begin()
|
||||
commentLike := &model.ScaCommentLike{
|
||||
CommentID: req.CommentId,
|
||||
TopicID: req.TopicId,
|
||||
UserID: uid,
|
||||
LikeTime: time.Now(),
|
||||
}
|
||||
err = tx.ScaCommentLike.Create(commentLike)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
}
|
||||
comment := l.svcCtx.DB.ScaCommentReply
|
||||
updates, err := tx.ScaCommentReply.Where(comment.TopicID.Eq(req.TopicId), comment.ID.Eq(req.CommentId)).Update(comment.Likes, comment.Likes.Add(1))
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
}
|
||||
if updates.RowsAffected == 0 {
|
||||
_ = tx.Rollback()
|
||||
return errors.New(i18n.FormatText(l.ctx, "comment.LikeError"))
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
125
app/auth/api/internal/logic/comment/submit_comment_logic.go
Normal file
125
app/auth/api/internal/logic/comment/submit_comment_logic.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"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"
|
||||
"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"))
|
||||
}
|
||||
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"))
|
||||
}
|
||||
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
|
||||
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 = l.svcCtx.DB.ScaCommentReply.Create(comment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(req.Images) > 0 {
|
||||
imagesData, err := utils.ProcessImages(req.Images)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commentImages := &types.CommentImages{
|
||||
UserId: uid,
|
||||
TopicId: req.TopicId,
|
||||
CommentId: comment.ID,
|
||||
Images: imagesData,
|
||||
}
|
||||
|
||||
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
|
||||
_, err = newCollection.Creator().InsertOne(l.ctx, commentImages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
@@ -0,0 +1,146 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"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"
|
||||
"time"
|
||||
|
||||
"github.com/mssola/useragent"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SubmitReplyCommentLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSubmitReplyCommentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubmitReplyCommentLogic {
|
||||
return &SubmitReplyCommentLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SubmitReplyCommentLogic) SubmitReplyComment(r *http.Request, req *types.ReplyCommentRequest) (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"))
|
||||
}
|
||||
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"))
|
||||
}
|
||||
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()
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found in context")
|
||||
}
|
||||
var isAuthor int64 = 0
|
||||
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, '*')
|
||||
|
||||
tx := l.svcCtx.DB.Begin()
|
||||
topicType := constant.CommentTopicType
|
||||
commentType := constant.REPLY
|
||||
reply := &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,
|
||||
ReplyID: req.ReplyId,
|
||||
ReplyUser: req.ReplyUser,
|
||||
}
|
||||
err = tx.ScaCommentReply.Create(reply)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commentReply := l.svcCtx.DB.ScaCommentReply
|
||||
update, err := tx.ScaCommentReply.Where(commentReply.ID.Eq(req.ReplyId)).Update(commentReply.ReplyCount, commentReply.ReplyCount.Add(1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if update.RowsAffected == 0 {
|
||||
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.commentError"))
|
||||
|
||||
}
|
||||
|
||||
if len(req.Images) > 0 {
|
||||
imagesData, err := utils.ProcessImages(req.Images)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commentImages := &types.CommentImages{
|
||||
UserId: uid,
|
||||
TopicId: req.TopicId,
|
||||
CommentId: reply.ID,
|
||||
Images: imagesData,
|
||||
}
|
||||
|
||||
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
|
||||
_, err = newCollection.Creator().InsertOne(l.ctx, commentImages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
commentResponse := &types.CommentResponse{
|
||||
Id: reply.ID,
|
||||
Content: commentContent,
|
||||
UserId: uid,
|
||||
TopicId: reply.TopicID,
|
||||
Author: isAuthor,
|
||||
Location: location,
|
||||
Browser: browser,
|
||||
OperatingSystem: operatingSystem,
|
||||
CreatedTime: time.Now().Format(constant.TimeFormat),
|
||||
ReplyId: reply.ReplyID,
|
||||
ReplyUser: reply.ReplyUser,
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return commentResponse, nil
|
||||
}
|
156
app/auth/api/internal/logic/comment/submit_reply_reply_logic.go
Normal file
156
app/auth/api/internal/logic/comment/submit_reply_reply_logic.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"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"
|
||||
"time"
|
||||
|
||||
"github.com/mssola/useragent"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SubmitReplyReplyLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSubmitReplyReplyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubmitReplyReplyLogic {
|
||||
return &SubmitReplyReplyLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SubmitReplyReplyLogic) SubmitReplyReply(r *http.Request, req *types.ReplyReplyRequest) (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"))
|
||||
}
|
||||
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"))
|
||||
}
|
||||
ua := useragent.New(userAgent)
|
||||
|
||||
// 获取客户端IP及位置信息
|
||||
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()
|
||||
|
||||
uid, ok := l.ctx.Value("user_id").(string)
|
||||
if !ok {
|
||||
return nil, errors.New("user_id not found in context")
|
||||
}
|
||||
|
||||
// 判断作者身份
|
||||
var isAuthor int64 = 0
|
||||
if uid == req.Author {
|
||||
isAuthor = 1
|
||||
}
|
||||
|
||||
// XSS过滤
|
||||
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, '*')
|
||||
|
||||
tx := l.svcCtx.DB.Begin()
|
||||
topicType := constant.CommentTopicType
|
||||
commentType := constant.REPLY
|
||||
replyReply := &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,
|
||||
ReplyID: req.ReplyId,
|
||||
ReplyUser: req.ReplyUser,
|
||||
ReplyTo: req.ReplyTo,
|
||||
}
|
||||
err = tx.ScaCommentReply.Create(replyReply)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commentReply := l.svcCtx.DB.ScaCommentReply
|
||||
update, err := tx.ScaCommentReply.Where(commentReply.ID.Eq(req.ReplyId)).Update(commentReply.ReplyCount, commentReply.ReplyCount.Add(1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if update.RowsAffected == 0 {
|
||||
return nil, errors2.New(http.StatusInternalServerError, i18n.FormatText(l.ctx, "comment.commentError"))
|
||||
|
||||
}
|
||||
|
||||
// 处理图片
|
||||
if len(req.Images) > 0 {
|
||||
imagesData, err := utils.ProcessImages(req.Images)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commentImages := &types.CommentImages{
|
||||
UserId: uid,
|
||||
TopicId: req.TopicId,
|
||||
CommentId: replyReply.ID,
|
||||
Images: imagesData,
|
||||
}
|
||||
|
||||
newCollection := mongodb.MustNewCollection[types.CommentImages](l.svcCtx.MongoClient, constant.COMMENT_IMAGES)
|
||||
_, err = newCollection.Creator().InsertOne(l.ctx, commentImages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 构建响应
|
||||
commentResponse := &types.CommentResponse{
|
||||
Id: replyReply.ID,
|
||||
Content: commentContent,
|
||||
UserId: uid,
|
||||
TopicId: replyReply.TopicID,
|
||||
Author: isAuthor,
|
||||
Location: location,
|
||||
Browser: browser,
|
||||
OperatingSystem: operatingSystem,
|
||||
CreatedTime: time.Now().Format(constant.TimeFormat),
|
||||
ReplyId: replyReply.ReplyID,
|
||||
ReplyUser: replyReply.ReplyUser,
|
||||
ReplyTo: replyReply.ReplyTo,
|
||||
}
|
||||
|
||||
// 提交事务
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return commentResponse, nil
|
||||
}
|
@@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/model"
|
||||
model2 "schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
"strconv"
|
||||
@@ -119,7 +119,7 @@ func (l *GiteeCallbackLogic) GiteeCallback(r *http.Request, req *types.OAuthCall
|
||||
// 创建用户
|
||||
uid := idgen.NextId()
|
||||
uidStr := strconv.FormatInt(uid, 10)
|
||||
addUser := &model.ScaAuthUser{
|
||||
addUser := &model2.ScaAuthUser{
|
||||
UID: uidStr,
|
||||
Avatar: giteeUser.AvatarURL,
|
||||
Username: giteeUser.Login,
|
||||
@@ -134,7 +134,7 @@ func (l *GiteeCallbackLogic) GiteeCallback(r *http.Request, req *types.OAuthCall
|
||||
return "", err
|
||||
}
|
||||
gitee := constant.OAuthSourceGitee
|
||||
newSocialUser := &model.ScaAuthUserSocial{
|
||||
newSocialUser := &model2.ScaAuthUserSocial{
|
||||
UserID: uidStr,
|
||||
OpenID: Id,
|
||||
Source: gitee,
|
||||
@@ -180,7 +180,7 @@ func (l *GiteeCallbackLogic) GiteeCallback(r *http.Request, req *types.OAuthCall
|
||||
}
|
||||
|
||||
// HandleOauthLoginResponse 处理登录响应
|
||||
func HandleOauthLoginResponse(scaAuthUser *model.ScaAuthUser, svcCtx *svc.ServiceContext, r *http.Request, ctx context.Context) (string, error) {
|
||||
func HandleOauthLoginResponse(scaAuthUser *model2.ScaAuthUser, svcCtx *svc.ServiceContext, r *http.Request, ctx context.Context) (string, error) {
|
||||
data, err := user.HandleLoginJWT(scaAuthUser, svcCtx, true, r, ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/model"
|
||||
model2 "schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"strconv"
|
||||
|
||||
@@ -117,7 +117,7 @@ func (l *GithubCallbackLogic) GithubCallback(r *http.Request, req *types.OAuthCa
|
||||
uidStr := strconv.FormatInt(uid, 10)
|
||||
|
||||
male := constant.Male
|
||||
addUser := &model.ScaAuthUser{
|
||||
addUser := &model2.ScaAuthUser{
|
||||
UID: uidStr,
|
||||
Avatar: gitHubUser.AvatarURL,
|
||||
Username: gitHubUser.Login,
|
||||
@@ -133,7 +133,7 @@ func (l *GithubCallbackLogic) GithubCallback(r *http.Request, req *types.OAuthCa
|
||||
return "", err
|
||||
}
|
||||
githubUser := constant.OAuthSourceGithub
|
||||
newSocialUser := &model.ScaAuthUserSocial{
|
||||
newSocialUser := &model2.ScaAuthUserSocial{
|
||||
UserID: uidStr,
|
||||
OpenID: Id,
|
||||
Source: githubUser,
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/model"
|
||||
model2 "schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -119,7 +119,7 @@ func (l *QqCallbackLogic) QqCallback(r *http.Request, req *types.OAuthCallbackRe
|
||||
|
||||
male := constant.Male
|
||||
avatarUrl := strings.Replace(qqUserInfo.FigureurlQq1, "http://", "https://", 1)
|
||||
addUser := &model.ScaAuthUser{
|
||||
addUser := &model2.ScaAuthUser{
|
||||
UID: uidStr,
|
||||
Avatar: avatarUrl,
|
||||
Username: authQQme.OpenID,
|
||||
@@ -133,7 +133,7 @@ func (l *QqCallbackLogic) QqCallback(r *http.Request, req *types.OAuthCallbackRe
|
||||
}
|
||||
|
||||
githubUser := constant.OAuthSourceQQ
|
||||
newSocialUser := &model.ScaAuthUserSocial{
|
||||
newSocialUser := &model2.ScaAuthUserSocial{
|
||||
UserID: uidStr,
|
||||
OpenID: authQQme.OpenID,
|
||||
Source: githubUser,
|
||||
|
60
app/auth/api/internal/logic/upscale/upload_image_logic.go
Normal file
60
app/auth/api/internal/logic/upscale/upload_image_logic.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package upscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/logic/websocket"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/types"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/xhttp"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/errors"
|
||||
"schisandra-album-cloud-microservices/common/jwt"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UploadImageLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewUploadImageLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadImageLogic {
|
||||
return &UploadImageLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UploadImageLogic) UploadImage(r *http.Request, req *types.UploadRequest) (err error) {
|
||||
token, ok := jwt.ParseAccessToken(l.svcCtx.Config.Auth.AccessSecret, req.AccessToken)
|
||||
if !ok {
|
||||
return errors.New(http.StatusForbidden, "invalid access token")
|
||||
}
|
||||
if token.UserID != req.UserId {
|
||||
return errors.New(http.StatusForbidden, "invalid user id")
|
||||
}
|
||||
|
||||
correct, err := l.svcCtx.CasbinEnforcer.Enforce(req.UserId, r.URL.Path, r.Method)
|
||||
if err != nil || !correct {
|
||||
return errors.New(http.StatusForbidden, "permission denied")
|
||||
}
|
||||
|
||||
data, err := json.Marshal(xhttp.BaseResponse[string]{
|
||||
Data: req.Image,
|
||||
Msg: "success",
|
||||
Code: http.StatusOK,
|
||||
})
|
||||
if err != nil {
|
||||
return errors.New(http.StatusForbidden, err.Error())
|
||||
}
|
||||
err = websocket.FileWebSocketHandler.SendMessageToClient(req.UserId, data)
|
||||
if err != nil {
|
||||
return errors.New(http.StatusForbidden, err.Error())
|
||||
}
|
||||
return nil
|
||||
}
|
@@ -6,8 +6,8 @@ import (
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"github.com/mssola/useragent"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/query"
|
||||
model2 "schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
query2 "schisandra-album-cloud-microservices/app/auth/model/mysql/query"
|
||||
"schisandra-album-cloud-microservices/common/captcha/verify"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/errors"
|
||||
@@ -44,7 +44,7 @@ func (l *AccountLoginLogic) AccountLogin(r *http.Request, req *types.AccountLogi
|
||||
}
|
||||
|
||||
user := l.svcCtx.DB.ScaAuthUser
|
||||
var selectedUser query.IScaAuthUserDo
|
||||
var selectedUser query2.IScaAuthUserDo
|
||||
|
||||
switch {
|
||||
case utils.IsPhone(req.Account):
|
||||
@@ -75,7 +75,7 @@ func (l *AccountLoginLogic) AccountLogin(r *http.Request, req *types.AccountLogi
|
||||
}
|
||||
|
||||
// HandleLoginJWT 处理用户登录
|
||||
func HandleLoginJWT(user *model.ScaAuthUser, svcCtx *svc.ServiceContext, autoLogin bool, r *http.Request, ctx context.Context) (*types.LoginResponse, error) {
|
||||
func HandleLoginJWT(user *model2.ScaAuthUser, svcCtx *svc.ServiceContext, autoLogin bool, r *http.Request, ctx context.Context) (*types.LoginResponse, error) {
|
||||
// 获取用户登录设备
|
||||
err := GetUserLoginDevice(user.UID, r, svcCtx.Ip2Region, svcCtx.DB)
|
||||
if err != nil {
|
||||
@@ -124,7 +124,7 @@ func HandleLoginJWT(user *model.ScaAuthUser, svcCtx *svc.ServiceContext, autoLog
|
||||
}
|
||||
|
||||
// GetUserLoginDevice 获取用户登录设备
|
||||
func GetUserLoginDevice(userId string, r *http.Request, ip2location *xdb.Searcher, DB *query.Query) error {
|
||||
func GetUserLoginDevice(userId string, r *http.Request, ip2location *xdb.Searcher, DB *query2.Query) error {
|
||||
userAgent := r.UserAgent()
|
||||
if userAgent == "" {
|
||||
return errors2.New("user agent not found")
|
||||
@@ -157,7 +157,7 @@ func GetUserLoginDevice(userId string, r *http.Request, ip2location *xdb.Searche
|
||||
if err != nil && !errors2.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
newDevice := &model.ScaAuthUserDevice{
|
||||
newDevice := &model2.ScaAuthUserDevice{
|
||||
UserID: userId,
|
||||
Bot: newIsBot,
|
||||
Agent: userAgent,
|
||||
|
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
constant2 "schisandra-album-cloud-microservices/common/constant"
|
||||
errors2 "schisandra-album-cloud-microservices/common/errors"
|
||||
"schisandra-album-cloud-microservices/common/i18n"
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/yitter/idgenerator-go/idgen"
|
||||
"gorm.io/gorm"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/model"
|
||||
model2 "schisandra-album-cloud-microservices/app/auth/model/mysql/model"
|
||||
"schisandra-album-cloud-microservices/common/constant"
|
||||
"schisandra-album-cloud-microservices/common/encrypt"
|
||||
errors2 "schisandra-album-cloud-microservices/common/errors"
|
||||
@@ -61,7 +61,7 @@ func (l *WechatOffiaccountLoginLogic) WechatOffiaccountLogin(r *http.Request, re
|
||||
avatar := utils.GenerateAvatar(uidStr)
|
||||
name := randomname.GenerateName()
|
||||
|
||||
addUser := &model.ScaAuthUser{
|
||||
addUser := &model2.ScaAuthUser{
|
||||
UID: uidStr,
|
||||
Avatar: avatar,
|
||||
Username: Openid,
|
||||
@@ -74,7 +74,7 @@ func (l *WechatOffiaccountLoginLogic) WechatOffiaccountLogin(r *http.Request, re
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newSocialUser := &model.ScaAuthUserSocial{
|
||||
newSocialUser := &model2.ScaAuthUserSocial{
|
||||
UserID: uidStr,
|
||||
OpenID: Openid,
|
||||
Source: constant.OAuthSourceWechat,
|
||||
|
126
app/auth/api/internal/logic/websocket/file_websocket_logic.go
Normal file
126
app/auth/api/internal/logic/websocket/file_websocket_logic.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/lxzan/gws"
|
||||
"net/http"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/svc"
|
||||
|
||||
"schisandra-album-cloud-microservices/common/jwt"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type FileWebsocketLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewFileWebsocketLogic(ctx context.Context, svcCtx *svc.ServiceContext) *FileWebsocketLogic {
|
||||
return &FileWebsocketLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
type FileWebSocket struct {
|
||||
ctx context.Context
|
||||
gws.BuiltinEventHandler
|
||||
sessions *gws.ConcurrentMap[string, *gws.Conn]
|
||||
}
|
||||
|
||||
var FileWebSocketHandler = NewFileWebSocket()
|
||||
|
||||
func (l *FileWebsocketLogic) FileWebsocket(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("Sec-Websocket-Protocol")
|
||||
accessToken, res := jwt.ParseAccessToken(l.svcCtx.Config.Auth.AccessSecret, token)
|
||||
if !res {
|
||||
return
|
||||
}
|
||||
upGrader := gws.NewUpgrader(FileWebSocketHandler, &gws.ServerOption{
|
||||
HandshakeTimeout: 5 * time.Second, // 握手超时时间
|
||||
ReadBufferSize: 1024, // 读缓冲区大小
|
||||
ParallelEnabled: true, // 开启并行消息处理
|
||||
Recovery: gws.Recovery, // 开启异常恢复
|
||||
CheckUtf8Enabled: false, // 关闭UTF8校验
|
||||
PermessageDeflate: gws.PermessageDeflate{
|
||||
Enabled: true, // 开启压缩
|
||||
},
|
||||
Authorize: func(r *http.Request, session gws.SessionStorage) bool {
|
||||
var clientId = r.URL.Query().Get("user_id")
|
||||
if clientId == "" {
|
||||
return false
|
||||
}
|
||||
if accessToken.UserID != clientId {
|
||||
return false
|
||||
}
|
||||
session.Store("user_id", clientId)
|
||||
return true
|
||||
},
|
||||
SubProtocols: []string{token},
|
||||
})
|
||||
socket, err := upGrader.Upgrade(w, r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
socket.ReadLoop()
|
||||
}()
|
||||
}
|
||||
|
||||
func NewFileWebSocket() *FileWebSocket {
|
||||
return &FileWebSocket{
|
||||
ctx: context.Background(),
|
||||
sessions: gws.NewConcurrentMap[string, *gws.Conn](64, 128),
|
||||
}
|
||||
}
|
||||
|
||||
// OnOpen 连接建立
|
||||
func (c *FileWebSocket) OnOpen(socket *gws.Conn) {
|
||||
clientId := MustLoad[string](socket.Session(), "user_id")
|
||||
c.sessions.Store(clientId, socket)
|
||||
// 订阅该用户的频道
|
||||
fmt.Printf("websocket client %s connected\n", clientId)
|
||||
}
|
||||
|
||||
// OnClose 关闭连接
|
||||
func (c *FileWebSocket) OnClose(socket *gws.Conn, err error) {
|
||||
name := MustLoad[string](socket.Session(), "user_id")
|
||||
sharding := c.sessions.GetSharding(name)
|
||||
c.sessions.Delete(name)
|
||||
sharding.Lock()
|
||||
defer sharding.Unlock()
|
||||
fmt.Printf("websocket closed, name=%s, msg=%s\n", name, err.Error())
|
||||
}
|
||||
|
||||
// OnPing 处理客户端的Ping消息
|
||||
func (c *FileWebSocket) OnPing(socket *gws.Conn, payload []byte) {
|
||||
_ = socket.SetDeadline(time.Now().Add(PingInterval + HeartbeatWaitTimeout))
|
||||
_ = socket.WritePong(payload)
|
||||
}
|
||||
|
||||
// OnPong 处理客户端的Pong消息
|
||||
func (c *FileWebSocket) OnPong(_ *gws.Conn, _ []byte) {}
|
||||
|
||||
// OnMessage 接受消息
|
||||
func (c *FileWebSocket) OnMessage(socket *gws.Conn, message *gws.Message) {
|
||||
defer message.Close()
|
||||
clientId := MustLoad[string](socket.Session(), "user_id")
|
||||
if conn, ok := c.sessions.Load(clientId); ok {
|
||||
_ = conn.WriteMessage(gws.OpcodeText, message.Bytes())
|
||||
}
|
||||
// fmt.Printf("received message from client %s\n", message.Data)
|
||||
}
|
||||
|
||||
// SendMessageToClient 向指定客户端发送消息
|
||||
func (c *FileWebSocket) SendMessageToClient(clientId string, message []byte) error {
|
||||
conn, ok := c.sessions.Load(clientId)
|
||||
if ok {
|
||||
return conn.WriteMessage(gws.OpcodeText, message)
|
||||
}
|
||||
return fmt.Errorf("client %s not found", clientId)
|
||||
}
|
@@ -8,14 +8,18 @@ import (
|
||||
"github.com/wenlng/go-captcha/v2/rotate"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
sensitive "github.com/zmexing/go-sensitive-word"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/config"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/internal/middleware"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql"
|
||||
"schisandra-album-cloud-microservices/app/auth/api/model/mysql/query"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mongodb"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql"
|
||||
"schisandra-album-cloud-microservices/app/auth/model/mysql/query"
|
||||
"schisandra-album-cloud-microservices/common/captcha/initialize"
|
||||
"schisandra-album-cloud-microservices/common/casbinx"
|
||||
"schisandra-album-cloud-microservices/common/ip2region"
|
||||
"schisandra-album-cloud-microservices/common/redisx"
|
||||
"schisandra-album-cloud-microservices/common/sensitivex"
|
||||
"schisandra-album-cloud-microservices/common/wechat_official"
|
||||
)
|
||||
|
||||
@@ -30,9 +34,10 @@ type ServiceContext struct {
|
||||
Ip2Region *xdb.Searcher
|
||||
CasbinEnforcer *casbin.SyncedCachedEnforcer
|
||||
WechatOfficial *officialAccount.OfficialAccount
|
||||
|
||||
RotateCaptcha rotate.Captcha
|
||||
SlideCaptcha slide.Captcha
|
||||
MongoClient *mongo.Database
|
||||
RotateCaptcha rotate.Captcha
|
||||
SlideCaptcha slide.Captcha
|
||||
Sensitive *sensitive.Manager
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@@ -52,5 +57,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
WechatOfficial: wechat_official.NewWechatPublic(c.Wechat.AppID, c.Wechat.AppSecret, c.Wechat.Token, c.Wechat.AESKey, c.Redis.Host, c.Redis.Pass, c.Redis.DB),
|
||||
RotateCaptcha: initialize.NewRotateCaptcha(),
|
||||
SlideCaptcha: initialize.NewSlideCaptcha(),
|
||||
MongoClient: mongodb.NewMongoDB(c.Mongo.Uri, c.Mongo.Username, c.Mongo.Password, c.Mongo.AuthSource, c.Mongo.Database),
|
||||
Sensitive: sensitivex.NewSensitive(),
|
||||
}
|
||||
}
|
||||
|
54
app/auth/api/internal/types/comment.go
Normal file
54
app/auth/api/internal/types/comment.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/chenmingyong0423/go-mongox/v2"
|
||||
)
|
||||
|
||||
// CommentImages 评论 图片
|
||||
type CommentImages struct {
|
||||
mongox.Model `bson:",inline"`
|
||||
TopicId string `json:"topic_id" bson:"topic_id"`
|
||||
CommentId int64 `json:"comment_id" bson:"comment_id"`
|
||||
UserId string `json:"user_id" bson:"user_id"`
|
||||
Images [][]byte `json:"images" bson:"images"`
|
||||
}
|
||||
|
||||
// CommentListQueryResult 评论列表查询结果
|
||||
type CommentListQueryResult struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID string `json:"user_id"`
|
||||
TopicID string `json:"topic_id"`
|
||||
Content string `json:"content"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Author int64 `json:"author"`
|
||||
Likes int64 `json:"likes"`
|
||||
ReplyCount int64 `json:"reply_count"`
|
||||
Browser string `json:"browser"`
|
||||
OperatingSystem string `json:"operating_system"`
|
||||
Location string `json:"location"`
|
||||
Avatar string `json:"avatar"`
|
||||
Nickname string `json:"nickname"`
|
||||
}
|
||||
|
||||
// ReplyListQueryResult 回复列表查询结果
|
||||
type ReplyListQueryResult struct {
|
||||
ID int64 `json:"id"`
|
||||
UserID string `json:"user_id"`
|
||||
TopicID string `json:"topic_id"`
|
||||
Content string `json:"content"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Author int64 `json:"author"`
|
||||
Likes int64 `json:"likes"`
|
||||
ReplyCount int64 `json:"reply_count"`
|
||||
Browser string `json:"browser"`
|
||||
OperatingSystem string `json:"operating_system"`
|
||||
Location string `json:"location"`
|
||||
Avatar string `json:"avatar"`
|
||||
Nickname string `json:"nickname"`
|
||||
ReplyUser string `json:"reply_user"`
|
||||
ReplyId int64 `json:"reply_id"`
|
||||
ReplyTo int64 `json:"reply_to"`
|
||||
ReplyNickname string `json:"reply_nickname"`
|
||||
}
|
@@ -11,6 +11,77 @@ type AccountLoginRequest struct {
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
type CommentContent struct {
|
||||
NickName string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
Level int64 `json:"level,omitempty" default:"0"`
|
||||
Id int64 `json:"id"`
|
||||
UserId string `json:"user_id"`
|
||||
TopicId string `json:"topic_id"`
|
||||
Content string `json:"content"`
|
||||
ReplyTo int64 `json:"reply_to,omitempty"`
|
||||
ReplyId int64 `json:"reply_id,omitempty"`
|
||||
ReplyUser string `json:"reply_user,omitempty"`
|
||||
ReplyNickname string `json:"reply_nickname,omitempty"`
|
||||
IsAuthor int64 `json:"is_author"`
|
||||
Likes int64 `json:"likes"`
|
||||
ReplyCount int64 `json:"reply_count"`
|
||||
CreatedTime string `json:"created_time"`
|
||||
Location string `json:"location"`
|
||||
Browser string `json:"browser"`
|
||||
OperatingSystem string `json:"operating_system"`
|
||||
IsLiked bool `json:"is_liked" default:"false"`
|
||||
Images []string `json:"images,omitempty"`
|
||||
}
|
||||
|
||||
type CommentDisLikeRequest struct {
|
||||
TopicId string `json:"topic_id"`
|
||||
CommentId int64 `json:"comment_id"`
|
||||
}
|
||||
|
||||
type CommentLikeRequest struct {
|
||||
TopicId string `json:"topic_id"`
|
||||
CommentId int64 `json:"comment_id"`
|
||||
}
|
||||
|
||||
type CommentListPageResponse struct {
|
||||
Size int `json:"size"`
|
||||
Total int64 `json:"total"`
|
||||
Current int `json:"current"`
|
||||
Comments []CommentContent `json:"comments"`
|
||||
}
|
||||
|
||||
type CommentListRequest struct {
|
||||
TopicId string `json:"topic_id"`
|
||||
Page int `json:"page,default=1,optional"`
|
||||
Size int `json:"size,default=5,optional"`
|
||||
IsHot bool `json:"is_hot,default=true,optional"`
|
||||
}
|
||||
|
||||
type CommentRequest struct {
|
||||
Content string `json:"content"`
|
||||
Images []string `json:"images,optional"`
|
||||
TopicId string `json:"topic_id"`
|
||||
Author string `json:"author"`
|
||||
Key string `json:"key"`
|
||||
Point []int64 `json:"point"`
|
||||
}
|
||||
|
||||
type CommentResponse struct {
|
||||
Id int64 `json:"id"`
|
||||
Content string `json:"content"`
|
||||
UserId string `json:"user_id"`
|
||||
TopicId string `json:"topic_id"`
|
||||
Author int64 `json:"author"`
|
||||
Location string `json:"location"`
|
||||
Browser string `json:"browser"`
|
||||
OperatingSystem string `json:"operating_system"`
|
||||
CreatedTime string `json:"created_time"`
|
||||
ReplyId int64 `json:"reply_id,omitempty"`
|
||||
ReplyUser string `json:"reply_user,omitempty"`
|
||||
ReplyTo int64 `json:"reply_to,omitempty"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpireAt int64 `json:"expire_at"`
|
||||
@@ -44,6 +115,36 @@ type RefreshTokenResponse struct {
|
||||
ExpireAt int64 `json:"expire_at"`
|
||||
}
|
||||
|
||||
type ReplyCommentRequest struct {
|
||||
Content string `json:"content"`
|
||||
Images []string `json:"images,optional"`
|
||||
TopicId string `json:"topic_id" `
|
||||
ReplyId int64 `json:"reply_id" `
|
||||
ReplyUser string `json:"reply_user" `
|
||||
Author string `json:"author"`
|
||||
Key string `json:"key"`
|
||||
Point []int64 `json:"point"`
|
||||
}
|
||||
|
||||
type ReplyListRequest struct {
|
||||
TopicId string `json:"topic_id"`
|
||||
CommentId int64 `json:"comment_id"`
|
||||
Page int `json:"page,default=1,optional"`
|
||||
Size int `json:"size,default=5,optional"`
|
||||
}
|
||||
|
||||
type ReplyReplyRequest struct {
|
||||
Content string `json:"content"`
|
||||
Images []string `json:"images,optional"`
|
||||
TopicId string `json:"topic_id"`
|
||||
ReplyTo int64 `json:"reply_to"`
|
||||
ReplyId int64 `json:"reply_id"`
|
||||
ReplyUser string `json:"reply_user" `
|
||||
Author string `json:"author"`
|
||||
Key string `json:"key"`
|
||||
Point []int64 `json:"point"`
|
||||
}
|
||||
|
||||
type ResetPasswordRequest struct {
|
||||
Phone string `json:"phone"`
|
||||
Captcha string `json:"captcha"`
|
||||
@@ -73,6 +174,12 @@ type SmsSendRequest struct {
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
type UploadRequest struct {
|
||||
Image string `json:"image"`
|
||||
AccessToken string `json:"access_token"`
|
||||
UserId string `json:"user_id"`
|
||||
}
|
||||
|
||||
type WechatOffiaccountLoginRequest struct {
|
||||
Openid string `json:"openid"`
|
||||
ClientId string `json:"client_id"`
|
||||
|
Reference in New Issue
Block a user