diff --git a/README_cjs.md b/README_cjs.md index f0cb561..c237247 100644 --- a/README_cjs.md +++ b/README_cjs.md @@ -1,5 +1,11 @@ 本文的用于记录程季晟的一些改动和疑问 +# 客户端问题 + +1. 个人主页的关注数, 经postman与实际测试对比, 发现个人主页的关注数更新是按照"点击关注"的操作次数进行更新, 即直接发送关注请求, + 不使用客户端操作, 个人主页信息不会变, **以此为前提**, 客户端发生**取消关注**操作后, 个人信息主页不变, 由此推论, + 这个属于客户端的问题 + # 待办 1. `videoService`中上传云服务器等内容的拆分, 目前推荐放到`util`工具包下比较合适, **暂定** @@ -7,7 +13,11 @@ 2. ~~video方面的feed()内容~~ 3. ~~get请求获取不到token,不清楚原因~~ 4. 抓包, 查看访问author的publishlist等页面, 客户端发送的数据 -5. 没有对关注人数变更到负数的情况进行拦截 +5. ~~没有对关注人数变更到负数的情况进行拦截~~ +6. ~~评论之后feed流视频对应的评论数不会实时更新~~ +7. 粉丝列表 +8. 好友列表 +9. 我不能关注我, 这一点没有做逻辑过滤 # 改动 diff --git a/controller/commentCotroller.go b/controller/commentCotroller.go index b5c8e58..9361104 100644 --- a/controller/commentCotroller.go +++ b/controller/commentCotroller.go @@ -4,6 +4,7 @@ import ( "log" "net/http" "strconv" + "tiktok/mapper" "tiktok/pkg/common" "tiktok/pkg/middleware" "tiktok/service" @@ -54,7 +55,7 @@ func Comment(c *gin.Context) { FollowCount: commenter.FollowCount, FollowerCount: commenter.FollowerCount, // TODO: IsFollowing包含了DAO操作,后面要移到mapper里去 - IsFollow: service.IsFollowing(userId, author), + IsFollow: mapper.CheckFollowing(userId, author), }, }, }) diff --git a/controller/followerController.go b/controller/followerController.go index f56baa4..1c3dbe5 100644 --- a/controller/followerController.go +++ b/controller/followerController.go @@ -1,6 +1,7 @@ package controller import ( + "fmt" "github.com/gin-gonic/gin" "log" "net/http" @@ -47,7 +48,7 @@ func Follow(ctx *gin.Context) { if err != nil { ctx.JSON(http.StatusOK, common.BaseResponse{ StatusCode: 1, - StatusMsg: "关注/取关失败", + StatusMsg: fmt.Sprint("关注/取关失败", err), }) log.Panicln("关注/取关失败, 注意检查service.Follow的逻辑") return @@ -58,7 +59,7 @@ func Follow(ctx *gin.Context) { }) } -// FollowList +// FollowList 关注列表 //与发布列表类似, 用户未登录应该也可以查看某位作者关注的人, 这里先做好准备, 目前走jwt鉴权, 为以后更新准备, 先做好token为空的判断 func FollowList(ctx *gin.Context) { hostToken := ctx.Query("token") @@ -84,7 +85,7 @@ func FollowList(ctx *gin.Context) { StatusCode: 1, StatusMsg: "获取关注列表失败!", }) - log.Panicln("获取发布作品详情时失败") + log.Panicln("获取关注列表时失败") return } ctx.JSON(http.StatusOK, common.UserInfoListResp{ @@ -95,3 +96,79 @@ func FollowList(ctx *gin.Context) { UserList: userInfoList, }) } + +// FollowerList 粉丝列表 +//逻辑类似关注列表 +func FollowerList(ctx *gin.Context) { + hostToken := ctx.Query("token") + if hostToken == "" { + log.Println("没有获取到用户token") + log.Println(hostToken) + } + var guestID uint + guestIDStr := ctx.Query("user_id") + if atoi, err := strconv.Atoi(guestIDStr); err != nil || guestIDStr == "" { + ctx.JSON(http.StatusOK, common.BaseResponse{ + StatusCode: 1, + StatusMsg: "没有获取到用户ID", + }) + log.Panicln("userID获取失败") + return + } else { + guestID = uint(atoi) + } + userInfoList, err := service.FollowerList(hostToken, guestID) + if err != nil { + ctx.JSON(http.StatusOK, common.BaseResponse{ + StatusCode: 1, + StatusMsg: "获取粉丝列表失败!", + }) + log.Panicln("获取粉丝列表时失败") + return + } + ctx.JSON(http.StatusOK, common.UserInfoListResp{ + BaseResponse: common.BaseResponse{ + StatusCode: 0, + StatusMsg: "请求粉丝列表成功!", + }, + UserList: userInfoList, + }) +} + +// FriendList +//好友列表, 查询逻辑是互相关注 +func FriendList(ctx *gin.Context) { + hostToken := ctx.Query("token") + if hostToken == "" { + log.Println("没有获取到用户token") + log.Println(hostToken) + } + var guestID uint + guestIDStr := ctx.Query("user_id") + if atoi, err := strconv.Atoi(guestIDStr); err != nil || guestIDStr == "" { + ctx.JSON(http.StatusOK, common.BaseResponse{ + StatusCode: 1, + StatusMsg: "没有获取到用户ID", + }) + log.Panicln("userID获取失败") + return + } else { + guestID = uint(atoi) + } + userInfoList, err := service.FriendList(hostToken, guestID) + if err != nil { + ctx.JSON(http.StatusOK, common.BaseResponse{ + StatusCode: 1, + StatusMsg: "获取好友列表失败!", + }) + log.Panicln("获取好友列表时失败") + return + } + ctx.JSON(http.StatusOK, common.UserInfoListResp{ + BaseResponse: common.BaseResponse{ + StatusCode: 0, + StatusMsg: "请求好友列表成功!", + }, + UserList: userInfoList, + }) +} diff --git a/controller/routes.go b/controller/routes.go index e62d5d8..5637f4e 100644 --- a/controller/routes.go +++ b/controller/routes.go @@ -47,6 +47,8 @@ func InitRouter() *gin.Engine { { followGroup.POST("/action/", middleware.JwtMiddleware(), Follow) followGroup.GET("/follow/list/", middleware.JwtMiddleware(), FollowList) + followGroup.GET("/follower/list/", middleware.JwtMiddleware(), FollowerList) + followGroup.GET("/friend/list/", middleware.JwtMiddleware(), FriendList) //followGroup.GET("/follow/list/", FollowList) } // // comment路由组 diff --git a/mapper/connector_test.go b/mapper/connector_test.go index 767521f..16644ff 100644 --- a/mapper/connector_test.go +++ b/mapper/connector_test.go @@ -5,7 +5,7 @@ import ( ) func TestInitDBConnector(t *testing.T) { - err := InitDBConnector() + err := InitDBConnectorSupportTest() if err != nil { t.Error("连接数据库失败") } diff --git a/mapper/followerMapper.go b/mapper/followerMapper.go index cdf5ca9..31bac82 100644 --- a/mapper/followerMapper.go +++ b/mapper/followerMapper.go @@ -62,7 +62,16 @@ func UpdateFollowRecord(hostID, guestID uint, isConcern bool) error { // FindMultiConcern 返回关注id关注的人, 实现逻辑是将id作为粉丝id进行查询 func FindMultiConcern(id uint) (resUserIDList []uint, err error) { - tx := DBConn.Model(&model.Follower{}).Select("user_id").Where("follower_id = ?", id).Find(&resUserIDList) + tx := DBConn.Model(&model.Follower{}).Select("user_id").Where("follower_id = ? AND is_follow = ?", id, true).Find(&resUserIDList) + if tx.Error != nil { + log.Panicln("查询用户关注信息时失败") + return resUserIDList, tx.Error + } + return resUserIDList, nil +} + +func FindMultiFollower(id uint) (resUserIDList []uint, err error) { + tx := DBConn.Model(&model.Follower{}).Select("follower_id").Where("user_id = ? AND is_follow = ?", id, true).Find(&resUserIDList) if tx.Error != nil { log.Panicln("查询用户关注信息时失败") return resUserIDList, tx.Error diff --git a/mapper/userMapper.go b/mapper/userMapper.go index a678b97..43fe068 100644 --- a/mapper/userMapper.go +++ b/mapper/userMapper.go @@ -2,6 +2,7 @@ package mapper import ( "errors" + "fmt" "log" "tiktok/model" "tiktok/pkg/errno" @@ -92,28 +93,19 @@ func FindMultiUserInfo(multiUserID []uint) (map[uint]model.User, error) { // UpdateUserFollowCount host关注guest, 所以host是被关注的人, guest是up, 所以关注操作, host.follow+1, guest.follower+1 func UpdateUserFollowCount(hostID, guestID uint, isConcern bool) error { - if isConcern { - tx := DBConn.Model(&model.User{}).Where("id = ?", hostID).Update("follow_count", gorm.Expr("follow_count + 1")) - if tx.Error != nil { - log.Panicln("更新关注人数时出错") - return tx.Error - } - tx = DBConn.Model(&model.User{}).Where("id = ?", guestID).Update("follower_count", gorm.Expr("follower_count + 1")) - if tx.Error != nil { - log.Panicln("更新粉丝人数时出错") - return tx.Error - } - } else { - tx := DBConn.Model(&model.User{}).Where("id = ?", hostID).Update("follow_count", gorm.Expr("follow_count - 1")) - if tx.Error != nil { - log.Panicln("更新关注人数时出错") - return tx.Error - } - tx = DBConn.Model(&model.User{}).Where("id = ?", guestID).Update("follower_count", gorm.Expr("follower_count - 1")) - if tx.Error != nil { - log.Panicln("更新粉丝人数时出错") - return tx.Error - } + x := " + 1" + if !isConcern { + x = " - 1" + } + tx := DBConn.Model(&model.User{}).Where("id = ?", hostID).Update("follow_count", gorm.Expr(fmt.Sprint("follow_count", x))) + if tx.Error != nil { + log.Panicln("更新关注人数时出错") + return tx.Error + } + tx = DBConn.Model(&model.User{}).Where("id = ?", guestID).Update("follower_count", gorm.Expr(fmt.Sprint("follower_count ", x))) + if tx.Error != nil { + log.Panicln("更新粉丝人数时出错") + return tx.Error } return nil } diff --git a/pkg/middleware/log.go b/pkg/middleware/log.go index 1ba472d..0083835 100644 --- a/pkg/middleware/log.go +++ b/pkg/middleware/log.go @@ -3,5 +3,6 @@ package middleware import "log" func InitLog() { - log.SetFlags(log.Ltime | log.Lshortfile) + log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) + log.SetPrefix("[tiktok]项目中发生的错误") } diff --git a/service/followerService.go b/service/followerService.go index bede4a7..4c08862 100644 --- a/service/followerService.go +++ b/service/followerService.go @@ -1,6 +1,7 @@ package service import ( + "errors" "log" "tiktok/mapper" "tiktok/pkg/common" @@ -15,6 +16,9 @@ func Follow(token string, guestID uint, isConcern bool) error { if err != nil { return err } + if parseToken.UserId == guestID { + return errors.New("请不要自己关注自己!") + } record, exist := mapper.ExistFollowRecord(parseToken.UserId, guestID) //如果不存在的话, 向follow插入信息, 并更新user表的字段 if !exist { @@ -33,8 +37,8 @@ func Follow(token string, guestID uint, isConcern bool) error { //mapper.UpdateUserFollowCount(parseToken.UserId, guestID) } - if record.IsFollow == isConcern { - //关注关系没有变化 + if record.IsFollow == isConcern || (!record.IsFollow && !isConcern) { + //关注关系没有变化, 或者已经处于未关注状态 return nil } //更新host的关注数, 并增加host关注的up数量, 增加up的粉丝数量 @@ -53,26 +57,28 @@ func Follow(token string, guestID uint, isConcern bool) error { } // FollowList 用户token去请求guestID对应的关注列表 -func FollowList(token string, guestID uint) (returnList []common.UserInfoResp, err error) { +func FollowList(token string, guestID uint) (resList []common.UserInfoResp, err error) { hostID := getHostIDFromToken(token) //这里请求出来有两步, 如果tokenID==guestID, 直接返回, 默认全部关注 //如果tokenID!=guestID, 还需要判断请求出来的user和token的关注关系 userIDList, err := mapper.FindMultiConcern(guestID) if err != nil { - return returnList, err + log.Panicln("查找关注列表信息时失败") + return resList, err } //获取到guestID关注的up的用户信息 userInfoList, err := mapper.FindMultiUserInfo(userIDList) if err != nil { - return returnList, err + log.Panicln("查找关注用户的个人信息时失败") + return resList, err } - returnList = make([]common.UserInfoResp, 0, len(userInfoList)) + resList = make([]common.UserInfoResp, 0, len(userInfoList)) for _, upInfo := range userInfoList { if hostID != guestID { - returnList = append(returnList, packUserInfo(upInfo, hostID)) + resList = append(resList, packUserInfo(upInfo, hostID)) } else { - returnList = append(returnList, common.UserInfoResp{ + resList = append(resList, common.UserInfoResp{ AuthorId: upInfo.ID, Name: upInfo.Name, FollowCount: upInfo.FollowCount, @@ -81,5 +87,74 @@ func FollowList(token string, guestID uint) (returnList []common.UserInfoResp, e }) } } - return returnList, nil + return resList, nil +} + +// FollowerList 请求粉丝列表, 和请求关注列表逻辑一致, 不同的是需要更改一下查询数据库的信息 +func FollowerList(token string, guestID uint) (resList []common.UserInfoResp, err error) { + hostID := getHostIDFromToken(token) + + userIDList, err := mapper.FindMultiFollower(guestID) + if err != nil { + log.Panicln("查找粉丝列表信息时失败") + return resList, err + } + //获取到guestID关注的up的用户信息 + userInfoList, err := mapper.FindMultiUserInfo(userIDList) + if err != nil { + log.Panicln("查找粉丝个人信息时失败") + return resList, err + } + + resList = make([]common.UserInfoResp, 0, len(userInfoList)) + for _, upInfo := range userInfoList { + resList = append(resList, packUserInfo(upInfo, hostID)) + } + return resList, nil +} + +// FriendList 这里要做一下过滤, 只有自己能看自己的好友列表, 当guestID与token不符时应当直接返回 +func FriendList(token string, guestID uint) (resList []common.UserInfoResp, err error) { + hostID := getHostIDFromToken(token) + if hostID != guestID { + return resList, errors.New("请求好友列表的id和token不一致, 不允许偷看别人的好友列表") + } + //分别获取粉丝和关注的up列表, 对其过滤, 同时存在的为好友 + fans, err := mapper.FindMultiFollower(guestID) + if err != nil { + log.Panicln("查找粉丝列表信息时失败") + return resList, err + } + ups, err := mapper.FindMultiConcern(guestID) + if err != nil { + log.Panicln("查找关注列表信息时失败") + return resList, err + } + + mp := make(map[uint]interface{}) + for i := 0; i < len(fans); i++ { + mp[fans[i]] = struct{}{} + } + friends := make([]uint, len(fans)>>1) + for i := 0; i < len(ups); i++ { + if _, ok := mp[ups[i]]; ok { + friends = append(friends, ups[i]) + } + } + multiUserInfo, err := mapper.FindMultiUserInfo(friends) + if err != nil { + log.Panicln("获取好友信息时失败了") + return resList, err + } + resList = make([]common.UserInfoResp, 0, len(multiUserInfo)) + for _, userInfo := range multiUserInfo { + resList = append(resList, common.UserInfoResp{ + AuthorId: userInfo.ID, + Name: userInfo.Name, + FollowCount: userInfo.FollowCount, + FollowerCount: userInfo.FollowerCount, + IsFollow: true, + }) + } + return resList, nil } diff --git a/service/userService.go b/service/userService.go index 31f7c5d..38c02bc 100644 --- a/service/userService.go +++ b/service/userService.go @@ -56,6 +56,7 @@ func UserInfoService(rawId string) (common.UserInfoQueryResponse, error) { userId, err := strconv.ParseUint(rawId, 10, 64) if err != nil { log.Panicln("service-UserInfoService: 解析rawID时发生错误, ", err) + return userInfoQueryResponse, err } // 获取用户信息