package friend_circle import ( "applet/app/db" "applet/app/db/im/model" "applet/app/e" "applet/app/md/friend_circles" "applet/app/svc" svc2 "applet/app/svc/friend_circle" "applet/app/utils" "code.fnuoos.com/EggPlanet/egg_system_rules.git/md" svc3 "code.fnuoos.com/EggPlanet/egg_system_rules.git/svc" es2 "code.fnuoos.com/EggPlanet/egg_system_rules.git/utils/es" "code.fnuoos.com/go_rely_warehouse/zyos_go_es.git/es" "context" "encoding/json" "errors" "fmt" "github.com/gin-gonic/gin" "github.com/olivere/elastic/v7" "strconv" "strings" "time" ) // PersonalSendingList // @Summary 朋友圈-个人发送朋友圈列表 // @Tags 朋友圈 // @Description 个人发送朋友圈列表 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.PersonalSendingListReq true "签名上传url" // @Success 200 {object} friend_circles.PersonalSendingListResp "返回数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/personalSending [POST] func PersonalSendingList(c *gin.Context) { var req friend_circles.PersonalSendingListReq err := c.ShouldBindJSON(&req) if err != nil { err = svc.HandleValidateErr(err) err1 := err.(e.E) e.OutErr(c, err1.Code, err1.Error()) return } resp, err := svc2.GetPersonalSendingList(c, req) if err != nil { e.OutErr(c, e.ERR, err.Error()) } resp.Page = req.Page resp.PageSize = req.PageSize e.OutSuc(c, resp, nil) } // MySelfList // @Summary 朋友圈-我的朋友圈列表 // @Tags 朋友圈 // @Description 我的朋友圈列表 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.MySelfListReq true "签名上传url" // @Success 200 {object} friend_circles.MySelfListResp "返回数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/mySelfList [POST] func MySelfList(c *gin.Context) { var args friend_circles.MySelfListReq err := c.ShouldBindJSON(&args) if err != nil { err = svc.HandleValidateErr(err) err1 := err.(e.E) e.OutErr(c, err1.Code, err1.Error()) return } resp, err := svc2.MySelfList(c, args) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } imUserIds := make([]int64, len(resp.List)) for i, friendCircle := range resp.List { imUserIds[i] = friendCircle.ImUid } nicknameAndAvatarMap, err := svc2.GetImUserNicknameAndAvatar(imUserIds) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } for _, friendCircle := range resp.List { val, ok := nicknameAndAvatarMap[friendCircle.ImUid] if ok { friendCircle.ImNickname = val.NickName friendCircle.ImAvatar = val.Avatar } } resp.Page = args.Page resp.PageSize = args.PageSize e.OutSuc(c, resp, nil) } // IsCanPublish // @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/isCanPublish [GET] func IsCanPublish(c *gin.Context) { isCan, err := svc2.IsCanPublish(c) if err != nil { fmt.Println("IsPublish:::::", err.Error()) } resp := friend_circles.IsCanCommentResp{IsCan: isCan} e.OutSuc(c, resp, nil) } // FriendCircleLikeList // @Summary 朋友圈-朋友圈点赞列表 // @Tags 朋友圈 // @Description 朋友圈点赞列表 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.FriendCircleLikeListReq true "签名上传url" // @Success 200 {object} friend_circles.FriendCircleLikeListResp "返回数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/likeList [POST] func FriendCircleLikeList(c *gin.Context) { var req friend_circles.FriendCircleLikeListReq if err1 := c.ShouldBindJSON(&req); err1 != nil { e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error()) return } //查找朋友圈记录 doc, err := es.FirstDoc(md.EggFriendCircleEsIndex, req.CircleIndexId) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } if !doc.Found { // 表示没找到数据 e.OutErr(c, e.ERR_NOT_FAN, "朋友圈文档记录不存在") return } from := (req.Page - 1) * req.PageSize // 查找点赞列表 query := elastic.NewBoolQuery() query.Must(elastic.NewTermQuery("circle_id", req.CircleIndexId)) searchResult, err := es.EsClient.Search(). Index(md.EggFriendCircleLikeEsAlias). // 替换为你的索引名称 Query(query). From(from). Size(req.PageSize). Sort("created_at", false). // 按时间倒排 Pretty(true). Do(context.Background()) if err != nil { return } var docs []*md.EggFriendCircleLikeEs var docUserIds []int64 var total int64 // 检查是否有结果 if searchResult.Hits.TotalHits.Value != 0 { // 解析结果 total = searchResult.Hits.TotalHits.Value for _, hit := range searchResult.Hits.Hits { var like md.EggFriendCircleLikeEs err = json.Unmarshal(hit.Source, &like) if err != nil { return } docUserIds = append(docUserIds, like.ImUid) docs = append(docs, &like) } } nicknameAndAvatarMap, err := svc2.GetImUserNicknameAndAvatar(docUserIds) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } var list []*friend_circles.FriendCircleLikeEsStruct for _, like := range docs { temp := friend_circles.FriendCircleLikeEsStruct{ Uid: like.Uid, ImUid: like.ImUid, CircleId: like.CircleId, } val, ok := nicknameAndAvatarMap[like.ImUid] if ok { temp.ImNickname = val.NickName temp.ImAvatar = val.Avatar } list = append(list, &temp) } resp := friend_circles.FriendCircleLikeListResp{ List: list, Page: req.Page, PageSize: req.PageSize, Total: total, } e.OutSuc(c, resp, nil) } // Publish // @Summary 朋友圈-发布朋友圈 // @Tags 朋友圈 // @Description 发布朋友圈 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.PublishReq true "请求参数" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/publish [POST] func Publish(c *gin.Context) { var req friend_circles.PublishReq if err1 := c.ShouldBindJSON(&req); err1 != nil { e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error()) return } isCan, err := svc2.IsCanPublish(c) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } if !isCan { e.OutErr(c, e.ERR, "当前不允许发朋友圈") return } user := svc.GetUser(c) var imUser model.User _, err = db.DbIm.Where("phone_number = ?", user.Phone).Get(&imUser) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } scheme, domain := svc.ImageBucket(db.Db) var imageStr string if len(req.ImageList) > 0 { imageStr = utils.SerializeStr(req.ImageList) imageStr = strings.ReplaceAll(imageStr, fmt.Sprintf("%s://%s/", scheme, domain), "{{tempHost}}") } //插入es记录 now := time.Now() nowStr := now.Format("2006-01-02 15:04:05") createDocRet, err := es.CreateDoc(md.EggFriendCircleEsIndex, strconv.FormatInt(user.Id, 10)+"_"+utils.Int64ToStr(now.Unix()), md.EggFriendCircleEs{ Uid: user.Id, ImUid: imUser.Id, Kind: 1, Content: req.Content, Image: imageStr, Video: req.Video, LikesNums: 0, ShareNums: 0, CommentNums: 0, State: 1, IsTopUp: 2, IsPraise: 2, CreatedAt: nowStr, UpdatedAt: nowStr, }) fmt.Printf("CreateDoc ==> %+v \n\n", createDocRet) // 更新发朋友圈次数 year, week := time.Now().ISOWeek() yearStr := utils.IntToStr(year) weekStr := utils.IntToStr(week) index := es2.GetAppointIndexFromAlias(yearStr, weekStr) id := fmt.Sprintf("%d%d_%d", year, week, user.Id) _, err = es.FirstDoc(index, id) if err != nil { if err.Error() != "elastic: Error 404 (Not Found)" { e.OutErr(c, e.ERR, err.Error()) return } else { m := md.EggEnergyUserEggScoreEs{ Uid: user.Id, SendCircleOfFriendNums: 1, CreatedAt: nowStr, UpdatedAt: nowStr, } newCreateDoc, err1 := es.CreateDoc(index, id, &m) if err1 != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } fmt.Printf("newCreateDoc ==> %+v \n\n", newCreateDoc) } } else { script := elastic.NewScript("ctx._source.send_circle_of_friend_nums += params.inc").Param("inc", 1) _, err = es.EsClient.Update(). Index(index). Id(id). Script(script). Do(context.Background()) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } } e.OutSuc(c, "success", nil) } // RecommendList // @Summary 朋友圈-推荐列表 // @Tags 朋友圈 // @Description 推荐列表 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.RecommendListReq true "签名上传url" // @Success 200 {object} friend_circles.RecommendListResp "返回数据" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/recommendList [POST] func RecommendList(c *gin.Context) { var req friend_circles.RecommendListReq err := c.ShouldBindJSON(&req) if err != nil { err = svc.HandleValidateErr(err) err1 := err.(e.E) e.OutErr(c, err1.Code, err1.Error()) return } resp, err := svc2.GetRecommendList(req) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } imUserIds := make([]int64, len(resp.List)) for i, friendCircle := range resp.List { imUserIds[i] = friendCircle.ImUid } nicknameAndAvatarMap, err := svc2.GetImUserNicknameAndAvatar(imUserIds) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } for _, friendCircle := range resp.List { val, ok := nicknameAndAvatarMap[friendCircle.ImUid] if ok { friendCircle.ImNickname = val.NickName friendCircle.ImAvatar = val.Avatar } } e.OutSuc(c, resp, nil) } // CommentList // @Summary 朋友圈-评论列表 // @Tags 朋友圈 // @Description 评论列表 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param circle_index_id query string true "朋友圈文档记录" // @Param req body friend_circles.CommentListReq true "请求参数" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/commentList [POST] func CommentList(c *gin.Context) { var req friend_circles.CommentListReq if err1 := c.ShouldBindJSON(&req); err1 != nil { e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error()) return } //查找朋友圈记录 doc, err := es.FirstDoc(md.EggFriendCircleEsIndex, req.CircleIndexId) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } if !doc.Found { // 表示没找到数据 e.OutErr(c, e.ERR_NOT_FAN, "朋友圈文档记录不存在") return } resp, err := svc2.CommentList(req) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } e.OutSuc(c, resp, nil) } // CommentDetail // @Summary 朋友圈-评论详情 // @Tags 朋友圈 // @Description 评论详情 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param comment_index_id query string true "评论文档记录" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/commentDetail [GET] func CommentDetail(c *gin.Context) { var req friend_circles.CommentDetailReq if err1 := c.ShouldBindJSON(&req); err1 != nil { e.OutErr(c, e.ERR_INVALID_ARGS, err1.Error()) return } //查找评论记录 boolQuery := elastic.NewBoolQuery() boolQuery.Must(elastic.NewTermQuery("_id", req.CommentIndexId)) searchResult, err := es.EsClient.Search(). Index(md.EggFriendCircleCommentEsAlias). Query(boolQuery). Pretty(true). Do(context.Background()) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } var doc md.EggFriendCircleCommentEs // 检查是否有结果 if searchResult.Hits.TotalHits.Value != 0 { err = json.Unmarshal(searchResult.Hits.Hits[0].Source, &doc) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } } else { e.OutErr(c, e.ERR_NOT_FAN, "评论文档记录不存在") return } resp, err := svc2.CommentDetail(req) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } resp.CircleIndexId = doc.CircleId e.OutSuc(c, resp, nil) } // Delete // @Summary 朋友圈-删除朋友圈 // @Tags 朋友圈 // @Description 删除朋友圈 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.EggFriendCircleDelReq true "请求参数" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/delete [DELETE] func Delete(c *gin.Context) { var req friend_circles.EggFriendCircleDelReq err := c.ShouldBindJSON(&req) if err != nil { err = svc.HandleValidateErr(err) err1 := err.(e.E) e.OutErr(c, err1.Code, err1.Error()) return } user := svc.GetUser(c) aliasName := md.EggFriendCircleEsAlias // 1.判断是否是自己文章 doc, err := es.FirstDoc(md.EggFriendCircleEsIndex, req.CircleIndexId) 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 docInfo md.EggFriendCircleEs utils.Unserialize(doc.Source, &docInfo) if docInfo.Uid != user.Id { e.OutErr(c, e.ERR, errors.New("不允许删除别人的朋友圈")) return } // 2.删除文章 deleteDocRet, err := es.DeleteDoc(aliasName, req.CircleIndexId) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } fmt.Printf("CreateDoc ==> %+v \n\n", deleteDocRet) // 3.将评论id推入mq err = svc2.DelFriendCircleComment(req.CircleIndexId) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } e.OutSuc(c, "success", nil) } // Share // @Summary 朋友圈-分享后朋友圈分享数(增加) // @Tags 朋友圈 // @Description 分享后朋友圈分享数(增加) // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.EggFriendCircleShareReq true "请求参数" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/share [POST] func Share(c *gin.Context) { var req friend_circles.EggFriendCircleShareReq err := c.ShouldBindJSON(&req) if err != nil { err = svc.HandleValidateErr(err) err1 := err.(e.E) e.OutErr(c, err1.Code, err1.Error()) return } script := elastic.NewScript("ctx._source.share_nums += params.inc").Param("inc", 1) aliasName := md.EggFriendCircleEsAlias _, err = es.EsClient.Update(). Index(aliasName). Id(req.CircleIndexId). Script(script). Do(context.Background()) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } e.OutSuc(c, "success", nil) } // Like // @Summary 朋友圈-点赞朋友圈 // @Tags 朋友圈 // @Description 点赞朋友圈 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.EggFriendCircleLikeReq true "请求参数" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/like [POST] func Like(c *gin.Context) { var req friend_circles.EggFriendCircleLikeReq err := c.ShouldBindJSON(&req) if err != nil { err = svc.HandleValidateErr(err) err1 := err.(e.E) e.OutErr(c, err1.Code, err1.Error()) return } user := svc.GetUser(c) likeEsIndex := svc3.GetEggFriendCircleLikeEsIndex(user.Id) likeId := svc3.GetEggFriendCircleLikeEsIndexId(user.Id, req.CircleIndexId) // 判断是否已经点赞过 query := elastic.NewBoolQuery(). Must( elastic.NewTermQuery("_id", likeId), ) searchResult, err := es.EsClient.Search().Index(likeEsIndex). Query(query). Size(0). // 只关心总数,不实际返回文档 Do(context.Background()) if err != nil { return } total := searchResult.TotalHits() if int(total) > 0 { e.OutSuc(c, "success", nil) return } var imUser model.User _, err = db.DbIm.Where("phone_number = ?", user.Phone).Get(&imUser) if err != nil { e.OutErr(c, e.ERR_DB_ORM, err.Error()) return } // 新增点赞信息 now := time.Now() m := md.EggFriendCircleLikeEs{ Uid: user.Id, ImUid: imUser.Id, CircleId: req.CircleIndexId, CreatedAt: now.Format("2006-01-02 15:04:05"), UpdatedAt: now.Format("2006-01-02 15:04:05"), } createDocRet, err := es.CreateDoc(likeEsIndex, likeId, &m) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } fmt.Printf("CreateDoc ==> %+v \n\n", createDocRet) // 增加文章点赞数 script := elastic.NewScript("ctx._source.likes_nums += params.inc").Param("inc", 1) aliasName := md.EggFriendCircleEsAlias _, err = es.EsClient.Update(). Index(aliasName). Id(req.CircleIndexId). Script(script). Do(context.Background()) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } e.OutSuc(c, "success", nil) } // CancelLike // @Summary 朋友圈-取消点赞朋友圈 // @Tags 朋友圈 // @Description 取消点赞朋友圈 // @Accept json // @Produce json // @param Authorization header string true "验证参数Bearer和token空格拼接" // @Param req body friend_circles.EggFriendCircleCancelLikeReq true "请求参数" // @Success 200 {string} "success" // @Failure 400 {object} md.Response "具体错误" // @Router /api/v1/circleFriends/cancelLike [POST] func CancelLike(c *gin.Context) { // 减少文章点赞数 var req friend_circles.EggFriendCircleCancelLikeReq err := c.ShouldBindJSON(&req) if err != nil { err = svc.HandleValidateErr(err) err1 := err.(e.E) e.OutErr(c, err1.Code, err1.Error()) return } user := svc.GetUser(c) // 删除点赞信息 likeEsIndex := svc3.GetEggFriendCircleLikeEsIndex(user.Id) likeId := svc3.GetEggFriendCircleLikeEsIndexId(user.Id, req.CircleIndexId) deleteDocRet, err := es.DeleteDoc(likeEsIndex, likeId) if err != nil { if err.Error() == "elastic: Error 404 (Not Found)" { e.OutErr(c, e.ERR_BAD_REQUEST, errors.New("点赞已取消,请勿重复请求").Error()) return } e.OutErr(c, e.ERR, err.Error()) return } fmt.Printf("DeleteDoc ==> %+v \n\n", deleteDocRet) // 减少文章点赞数 script := elastic.NewScript("ctx._source.likes_nums -= params.inc").Param("inc", 1) aliasName := md.EggFriendCircleEsAlias _, err = es.EsClient.Update(). Index(aliasName). Id(req.CircleIndexId). Script(script). Do(context.Background()) if err != nil { e.OutErr(c, e.ERR, err.Error()) return } e.OutSuc(c, "success", nil) }