diff --git a/app/hdl/friend_circle/hdl_comment.go b/app/hdl/friend_circle/hdl_comment.go index 435cc7d..6b82306 100644 --- a/app/hdl/friend_circle/hdl_comment.go +++ b/app/hdl/friend_circle/hdl_comment.go @@ -5,6 +5,7 @@ import ( "applet/app/md/friend_circles" "applet/app/svc" svc2 "applet/app/svc/friend_circle" + "applet/app/utils/cache" "code.fnuoos.com/EggPlanet/egg_system_rules.git/md" svc3 "code.fnuoos.com/EggPlanet/egg_system_rules.git/svc" "code.fnuoos.com/go_rely_warehouse/zyos_go_es.git/es" @@ -21,7 +22,7 @@ import ( // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" -// @Success 200 {string} "许可链接" +// @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/isCanComment [Get] func IsCanComment(c *gin.Context) { @@ -104,27 +105,32 @@ func Comment(c *gin.Context) { return } var commentId, replyCommentId string + var commentImUid, replyCommentImUid int64 if &comment != nil { if comment.CommentId != "" { replyCommentId = req.CommentIndexId + commentImUid = comment.ImUid } else { commentId = req.CommentIndexId + commentImUid = comment.ImUid } } createDocRet, err := es.CreateDoc(svc3.GetEggFriendCircleCommentEsIndex(user.Id), svc3.GetEggFriendCircleCommentEsIndexId(user.Id, req.CircleIndexId), md.EggFriendCircleCommentEs{ - Uid: user.Id, - ImUid: imUser.UserId, - Kind: 1, - CircleId: req.CircleIndexId, - CommentId: commentId, - ReplyCommentId: replyCommentId, - Content: req.Content, - LikesNums: 0, - CommentNums: 0, - State: 1, - IsPraise: 2, - CreatedAt: now.Format("2006-01-02 15:04:05"), - UpdatedAt: now.Format("2006-01-02 15:04:05"), + Uid: user.Id, + ImUid: imUser.UserId, + Kind: 1, + CircleId: req.CircleIndexId, + CommentId: commentId, + CommentImUid: commentImUid, + ReplyCommentId: replyCommentId, + ReplyCommentImUid: replyCommentImUid, + Content: req.Content, + LikesNums: 0, + CommentNums: 0, + State: 1, + IsPraise: 2, + CreatedAt: now.Format("2006-01-02 15:04:05"), + UpdatedAt: now.Format("2006-01-02 15:04:05"), }) fmt.Printf("CreateDoc ==> %+v \n\n", createDocRet) @@ -154,13 +160,156 @@ func Comment(c *gin.Context) { e.OutSuc(c, "success", nil) } +// CommentDelete +// @Summary 朋友圈-删除评论 +// @Tags 朋友圈 +// @Description 评论点赞 +// @Accept json +// @Produce json +// @param Authorization header string true "验证参数Bearer和token空格拼接" +// @Success 200 {string} "success" +// @Failure 400 {object} md.Response "具体错误" +// @Router /api/v1/circleFriends/CommentDelete/{$comment_index_id} [DELETE] func CommentDelete(c *gin.Context) { + commentIndexId := c.Param("comment_index_id") + doc1, err := es.FirstDoc(md.EggFriendCircleCommentEsAlias, commentIndexId) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if !doc1.Found { // 表示没找到数据 + e.OutErr(c, e.ERR_NOT_FAN, "评论文档记录不存在") + return + } + + //1、删除es数据 + _, err = es.DeleteDoc(md.EggFriendCircleCommentEsAlias, commentIndexId) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + + //2、删除redis数据 + key := fmt.Sprintf(md.CommentLikeCacheKey, commentIndexId) + cache.Del(key) + e.OutSuc(c, "success", nil) } +// CommentLike +// @Summary 朋友圈-评论点赞 +// @Tags 朋友圈 +// @Description 评论点赞 +// @Accept json +// @Produce json +// @param Authorization header string true "验证参数Bearer和token空格拼接" +// @Param comment_index_id query string "评论文档记录" +// @Success 200 {string} "success" +// @Failure 400 {object} md.Response "具体错误" +// @Router /api/v1/circleFriends/CommentLike [Get] func CommentLike(c *gin.Context) { + commentIndexId := c.DefaultQuery("comment_index_id", "") + doc, err := es.FirstDoc(md.EggFriendCircleCommentEsAlias, commentIndexId) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if !doc.Found { // 表示没找到数据 + e.OutErr(c, e.ERR_NOT_FAN, "评论文档记录不存在") + return + } + var comment md.EggFriendCircleCommentEs + err = json.Unmarshal(doc.Source, &comment) + if err != nil { + e.OutErr(c, e.ERR, err.Error()) + return + } + + //1、判断是否点赞 + user := svc.GetUser(c) + isLike, err := svc2.GetUserWithCommentLike(commentIndexId, user.Id) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if isLike { + e.OutErr(c, e.ERR, "重复点赞!") + return + } + + //2、修改es数据 + _, err = es.UpdateDoc(md.EggFriendCircleCommentEsAlias, commentIndexId, map[string]interface{}{ + "like_nums": comment.CommentNums + 1, + }) + if err != nil { + e.OutErr(c, e.ERR, err.Error()) + return + } + + //2、进行点赞 + key := fmt.Sprintf(md.CommentLikeCacheKey, commentIndexId) + _, err = cache.SetBit(key, user.Id, 1) + if err != nil { + e.OutErr(c, e.ERR, err.Error()) + return + } + + //3、设置过期时间 + _, err = cache.Expire(key, md.CommentLikeCacheTime) + if err != nil { + e.OutErr(c, e.ERR, err.Error()) + return + } + e.OutSuc(c, "success", nil) } + +// CommentCancelLike +// @Summary 朋友圈-评论取消点赞 +// @Tags 朋友圈 +// @Description 评论取消点赞 +// @Accept json +// @Produce json +// @param Authorization header string true "验证参数Bearer和token空格拼接" +// @Param comment_index_id query string "评论文档记录" +// @Success 200 {string} "success" +// @Failure 400 {object} md.Response "具体错误" +// @Router /api/v1/circleFriends/CommentLike [Get] func CommentCancelLike(c *gin.Context) { + commentIndexId := c.DefaultQuery("comment_index_id", "") + + doc, err := es.FirstDoc(md.EggFriendCircleCommentEsAlias, commentIndexId) + if err != nil { + e.OutErr(c, e.ERR_DB_ORM, err.Error()) + return + } + if !doc.Found { // 表示没找到数据 + e.OutErr(c, e.ERR_NOT_FAN, "评论文档记录不存在") + return + } + var comment md.EggFriendCircleCommentEs + err = json.Unmarshal(doc.Source, &comment) + if err != nil { + e.OutErr(c, e.ERR, err.Error()) + return + } + + //1、修改es数据 + _, err = es.UpdateDoc(md.EggFriendCircleCommentEsAlias, commentIndexId, map[string]interface{}{ + "like_nums": comment.CommentNums - 1, + }) + if err != nil { + e.OutErr(c, e.ERR, err.Error()) + return + } + + //2、修改redis数据 + key := fmt.Sprintf(md.CommentLikeCacheKey, commentIndexId) + user := svc.GetUser(c) + _, err = cache.SetBit(key, user.Id, 0) + if err != nil { + e.OutErr(c, e.ERR, err.Error()) + return + } e.OutSuc(c, "success", nil) } diff --git a/app/hdl/friend_circle/hdl_friend_circle.go b/app/hdl/friend_circle/hdl_friend_circle.go index 6a412b0..40225d7 100644 --- a/app/hdl/friend_circle/hdl_friend_circle.go +++ b/app/hdl/friend_circle/hdl_friend_circle.go @@ -119,7 +119,7 @@ func Publish(c *gin.Context) { // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param circle_index_id query string true "朋友圈文档记录" -// @Param req body comm.CommentListReq true "请求参数" +// @Param req body friend_circles.CommentListReq true "请求参数" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/commentList [POST] diff --git a/app/md/friend_circles/md_friend_circle.go b/app/md/friend_circles/md_friend_circle.go index e883a97..aa2cedd 100644 --- a/app/md/friend_circles/md_friend_circle.go +++ b/app/md/friend_circles/md_friend_circle.go @@ -1,16 +1,14 @@ package friend_circles -import "code.fnuoos.com/EggPlanet/egg_system_rules.git/md" - type CommentListReq struct { - CircleIndexId string `json:"circle_index_id"` - Page int `json:"page"` // 页码 - PageSize int `json:"page_size"` // 每页数量 + CircleIndexId string `json:"circle_index_id"` //朋友圈文档记录 + Page int `json:"page"` // 页码 + PageSize int `json:"page_size"` // 每页数量 } type CommentDetailReq struct { - CommentIndexId string `json:"comment_index_id"` - Page int `json:"page"` // 页码 - PageSize int `json:"page_size"` // 每页数量 + CommentIndexId string `json:"comment_index_id"` //评论文档记录 + Page int `json:"page"` // 页码 + PageSize int `json:"page_size"` // 每页数量 } type PublishReq struct { Content string `json:"content,required"` // 文本内容 @@ -22,11 +20,31 @@ type MySelfListReq struct { PageSize int `json:"page_size"` // 每页数量 } type MySelfListResp struct { - Page int `json:"page"` // 页码 - PageSize int `json:"page_size"` // 每页数量 - Total int64 `json:"total"` // 总量 - List []md.EggFriendCircleEs `json:"list"` + Page int `json:"page"` // 页码 + PageSize int `json:"page_size"` // 每页数量 + Total int64 `json:"total"` // 总量 + List []EggFriendCircleEsStruct `json:"list"` +} + +type EggFriendCircleEsStruct struct { + CircleIndexId string `json:"circle_index_id"` //朋友圈文档记录 + Uid int64 `json:"uid" label:"uid"` + ImUid int64 `json:"im_uid" label:"im_uid"` + Kind int32 `json:"kind" label:"类型(1:普通 2:官方)"` //类型(1:普通 2:官方) + Content string `json:"content" label:"文本内容"` //文本内容 + Image string `json:"image" label:"图片"` //图片 + Video string `json:"video" label:"视频"` //视频 + LikesNums int `json:"likes_nums" label:"点赞数"` //点赞数 + ShareNums int `json:"share_nums" label:"分享数"` //分享数 + CommentNums int `json:"comment_nums" label:"评论数"` //评论数 + IsLike bool `json:"is_like" label:"是否点赞"` //是否点赞 + //State int32 `json:"state" label:"状态(1:正常 2:隐藏)"` + //IsTopUp int32 `json:"is_top_up" label:"是否置顶(1:是 2:否)"` + //IsPraise int32 `json:"is_praise" label:"是否被表扬(1:是 2:否)"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` } + type CommentListResp struct { CircleIndexId string `json:"circle_index_id"` Total int64 `json:"total"` // 总评论数量 @@ -40,22 +58,24 @@ type CommentDetailResp struct { } type EggFriendCircleCommentEsStruct struct { + CommentIndexId string `json:"comment_index_id"` //评论文档记录 NickName string `json:"nickname"` AvatarUrl string `json:"avatar_url"` // 用户头像 Uid int64 `json:"uid" label:"uid"` ImUid int64 `json:"im_uid" label:"im_uid"` - Kind int32 `json:"kind" label:"类型(1:普通 2:官方)"` - CircleId string `json:"circle_id" label:"朋友圈id"` - CommentId string `json:"comment_id" label:"评论id"` - ReplyCommentNickname string `json:"reply_comment_nickname" label:"回复评论的用户昵称"` - ReplyCommentId string `json:"reply_comment_id" label:"回复评论id"` - ReplyCommentUserId int64 `json:"reply_comment_user_id" label:"回复评论用户id"` - ReplyCommentUserNickname string `json:"reply_comment_user_nickname" label:"回复评论用户昵称"` - Content string `json:"content" label:"文本内容"` - LikesNums int `json:"likes_nums" label:"点赞数"` - CommentNums int `json:"comment_nums" label:"评论数"` - State int32 `json:"state" label:"状态(1:正常 2:隐藏)"` - IsPraise int32 `json:"is_praise" label:"是否被表扬(1:是 2:否)"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` + Kind int32 `json:"kind" label:"类型(1:普通 2:官方)"` //类型(1:普通 2:官方) + CircleId string `json:"circle_id" label:"朋友圈id"` //朋友圈id + CommentId string `json:"comment_id" label:"评论id"` //评论id + CommentImUid int64 `json:"comment_im_uid" label:"回复评论用户id"` + ReplyCommentId string `json:"reply_comment_id" label:"回复评论id"` //回复评论id + ReplyCommentImUid int64 `json:"reply_comment_im_uid" label:"回复评论用户id"` + ReplyCommentUserNickname string `json:"reply_comment_user_nickname" label:"回复评论的用户昵称"` //回复评论的用户昵称 + Content string `json:"content" label:"文本内容"` //文本内容 + LikesNums int `json:"likes_nums" label:"点赞数"` //点赞数 + CommentNums int `json:"comment_nums" label:"评论数"` //评论数 + IsLike bool `json:"is_like" label:"是否点赞"` //是否点赞 + //State int32 `json:"state" label:"状态(1:正常 2:隐藏)"` //状态(1:正常 2:隐藏) + //IsPraise int32 `json:"is_praise" label:"是否被表扬(1:是 2:否)"` //是否被表扬(1:是 2:否) + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` } diff --git a/app/router/router.go b/app/router/router.go index 694bfd7..d0a9cd0 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -196,9 +196,9 @@ func rCircleFriends(r *gin.RouterGroup) { r.POST("/comment", friend_circle.Comment) // 评论 r.GET("/isCanComment", friend_circle.IsCanComment) // 是否可以评论 - r.DELETE("/commentDelete", friend_circle.CommentDelete) // 删除评论 - r.POST("/commentLike", friend_circle.CommentLike) // 点赞评论 - r.POST("/commentCancelLike", friend_circle.CommentCancelLike) // 取消点赞评论 + r.DELETE("/commentDelete/:comment_index_id", friend_circle.CommentDelete) // 删除评论 + r.GET("/commentLike", friend_circle.CommentLike) // 点赞评论 + r.POST("/commentCancelLike", friend_circle.CommentCancelLike) // 取消点赞评论 } func rComm(r *gin.RouterGroup) { diff --git a/app/svc/friend_circle/svc_comment.go b/app/svc/friend_circle/svc_comment.go index ed98755..5a1244b 100644 --- a/app/svc/friend_circle/svc_comment.go +++ b/app/svc/friend_circle/svc_comment.go @@ -3,11 +3,13 @@ package svc import ( "applet/app/db" "applet/app/svc" + "applet/app/utils/cache" "code.fnuoos.com/EggPlanet/egg_models.git/src/implement" "code.fnuoos.com/EggPlanet/egg_system_rules.git/md" "code.fnuoos.com/go_rely_warehouse/zyos_go_es.git/es" "context" "errors" + "fmt" "github.com/gin-gonic/gin" "github.com/olivere/elastic/v7" "time" @@ -60,3 +62,16 @@ func IsCanComment(c *gin.Context) (isCan bool, err error) { } return } + +func GetUserWithCommentLike(commentIndexId string, uid int64) (isLike bool, err error) { + // 定义 Bitmap 的键名 + key := fmt.Sprintf(md.CommentLikeCacheKey, commentIndexId) + isLiked, err := cache.GetBit(key, uid) + if err != nil { + return + } + if isLiked == 1 { + isLike = true + } + return +} diff --git a/app/svc/friend_circle/svc_firend_circle.go b/app/svc/friend_circle/svc_firend_circle.go index 084b11e..3b9862e 100644 --- a/app/svc/friend_circle/svc_firend_circle.go +++ b/app/svc/friend_circle/svc_firend_circle.go @@ -106,11 +106,12 @@ func MySelfList(c *gin.Context, req friend_circles.MySelfListReq) (resp friend_c // 解析结果 for _, hit := range searchResult.Hits.Hits { - var doc md.EggFriendCircleEs + var doc friend_circles.EggFriendCircleEsStruct err = json.Unmarshal(hit.Source, &doc) if err != nil { return } + doc.CircleIndexId = hit.Id resp.List = append(resp.List, doc) } @@ -158,6 +159,7 @@ func CommentList(req friend_circles.CommentListReq) (resp friend_circles.Comment } doc.NickName = user.Nickname doc.AvatarUrl = user.AvatarUrl + doc.CommentIndexId = hit.Id resp.List = append(resp.List, doc) } @@ -208,8 +210,13 @@ func CommentDetail(req friend_circles.CommentDetailReq) (resp friend_circles.Com doc.AvatarUrl = user.AvatarUrl if doc.ReplyCommentId != "" { - + replyUser, err2 := svc.GetImUser(doc.ReplyCommentImUid, "") + if err2 != nil { + return friend_circles.CommentDetailResp{}, err2 + } + doc.ReplyCommentUserNickname = replyUser.Nickname } + doc.CommentIndexId = hit.Id resp.List = append(resp.List, doc) } diff --git a/app/utils/cache/redis.go b/app/utils/cache/redis.go index 2199787..a1a5716 100644 --- a/app/utils/cache/redis.go +++ b/app/utils/cache/redis.go @@ -163,6 +163,14 @@ func Get(key string) (interface{}, error) { // get return Do("GET", key) } + +func GetBit(key string, offset int64) (int64, error) { + return redigo.Int64(Do("GETBIT", key, offset)) +} +func SetBit(key string, offset int64, value int) (interface{}, error) { + return Do("SETBIT", key, offset, value) +} + func GetTTL(key string) (time.Duration, error) { ttl, err := redigo.Int64(Do("TTL", key)) return time.Duration(ttl) * time.Second, err @@ -402,8 +410,7 @@ func Scan(cursor int64, pattern string, count int64) (int64, []string, error) { return newCursor, items, nil } - func LPushMax(key string, data ...interface{}) (interface{}, error) { // set return Do("LPUSH", key, data) -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 422d424..ae0ee02 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module applet -go 1.19 +go 1.21 + +toolchain go1.23.2 //replace code.fnuoos.com/EggPlanet/egg_models.git => E:/company/Egg/egg_models @@ -15,7 +17,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.20.0 github.com/go-redis/redis v6.15.9+incompatible - github.com/gomodule/redigo v2.0.0+incompatible + github.com/gomodule/redigo v1.9.2 github.com/jinzhu/copier v0.4.0 github.com/makiuchi-d/gozxing v0.0.0-20210324052758-57132e828831 github.com/qiniu/api.v7/v7 v7.8.2 @@ -33,13 +35,12 @@ require ( require ( code.fnuoos.com/EggPlanet/egg_models.git v0.2.1-0.20241203152302-b6aa8333c67e - code.fnuoos.com/EggPlanet/egg_system_rules.git v0.0.4-0.20241203152001-32c4b96d6029 + code.fnuoos.com/EggPlanet/egg_system_rules.git v0.0.4-0.20241204064333-9ce6762e478f code.fnuoos.com/go_rely_warehouse/zyos_go_es.git v1.0.1-0.20241118083738-0f22da9ba0be code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git v0.0.5 github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible - github.com/gin-contrib/sessions v1.0.1 github.com/go-pay/crypto v0.0.1 - github.com/go-pay/gopay v1.5.98 + github.com/go-pay/gopay v1.5.106 github.com/go-pay/xtime v0.0.2 github.com/go-sql-driver/mysql v1.8.1 github.com/gocolly/colly v1.2.0 @@ -115,7 +116,7 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/arch v0.7.0 // indirect - golang.org/x/crypto v0.23.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/sync v0.8.0 // indirect