From 16616e375503c1e6c7871f8e74fd5466d328242d Mon Sep 17 00:00:00 2001 From: landaiqing <3517283258@qq.com> Date: Thu, 3 Oct 2024 02:10:14 +0800 Subject: [PATCH] :hammer: refactor code --- common/enum/gender.go | 4 +- .../oauth_controller/gitee_controller.go | 195 ++++++++--------- .../oauth_controller/github_controller.go | 207 ++++++++---------- controller/oauth_controller/oauth.go | 143 ++++++------ controller/oauth_controller/qq_controller.go | 105 ++++----- controller/oauth_controller/request_param.go | 24 +- .../oauth_controller/wechat_controller.go | 119 ++++------ controller/user_controller/user_controller.go | 161 ++++++-------- dao/impl/user_dao_impl.go | 4 +- model/sca_auth_permission.go | 26 +-- model/sca_auth_role.go | 6 +- model/sca_auth_user.go | 32 +-- model/sca_auth_user_device.go | 30 +-- model/sca_auth_user_social.go | 14 +- service/impl/comment_reply_service_impl.go | 18 +- service/impl/user_service_impl.go | 65 ++++-- utils/generate_avatar.go | 71 +++--- 17 files changed, 563 insertions(+), 661 deletions(-) diff --git a/common/enum/gender.go b/common/enum/gender.go index 28f8c06..6b6afb5 100644 --- a/common/enum/gender.go +++ b/common/enum/gender.go @@ -1,6 +1,6 @@ package enum var ( - Male = "男" - Female = "女" + Male = "Male" + Female = "Female" ) diff --git a/controller/oauth_controller/gitee_controller.go b/controller/oauth_controller/gitee_controller.go index 05c7ebf..ffdef04 100644 --- a/controller/oauth_controller/gitee_controller.go +++ b/controller/oauth_controller/gitee_controller.go @@ -135,120 +135,103 @@ func GetGiteeUserInfo(token *Token) (map[string]interface{}, error) { // @Produce json // @Router /controller/oauth/gitee/callback [get] func (OAuthController) GiteeCallback(c *gin.Context) { - var err error // 获取 code - var code = c.Query("code") + code := c.Query("code") if code == "" { result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c) return } - // 异步获取 token - var tokenChan = make(chan *Token) - var errChan = make(chan error) - go func() { - var tokenAuthUrl = GetGiteeTokenAuthUrl(code) - token, err := GetGiteeToken(tokenAuthUrl) - if err != nil { - errChan <- err - return - } - tokenChan <- token - }() - - // 异步获取用户信息 - var userInfoChan = make(chan map[string]interface{}) - go func() { - token := <-tokenChan - if token == nil { - errChan <- errors.New("failed to get token") - return - } - userInfo, err := GetGiteeUserInfo(token) - if err != nil { - errChan <- err - return - } - userInfoChan <- userInfo - }() - - // 等待结果 - select { - case err = <-errChan: + // 获取 token + tokenAuthUrl := GetGiteeTokenAuthUrl(code) + token, err := GetGiteeToken(tokenAuthUrl) + if err != nil { global.LOG.Error(err) return - case userInfo := <-userInfoChan: - userInfoBytes, err := json.Marshal(userInfo) - if err != nil { - global.LOG.Error(err) - return - } - var giteeUser GiteeUser - err = json.Unmarshal(userInfoBytes, &giteeUser) - if err != nil { - global.LOG.Error(err) - return - } - - Id := strconv.Itoa(giteeUser.ID) - userSocial, err := userSocialService.QueryUserSocialByOpenIDService(Id, enum.OAuthSourceGitee) - if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { - db := global.DB - tx := db.Begin() // 开始事务 - if tx.Error != nil { - global.LOG.Error(tx.Error) - return - } - defer func() { - if r := recover(); r != nil { - tx.Rollback() - } - }() - // 第一次登录,创建用户 - uid := idgen.NextId() - uidStr := strconv.FormatInt(uid, 10) - user := model.ScaAuthUser{ - UID: &uidStr, - Username: &giteeUser.Login, - Nickname: &giteeUser.Name, - Avatar: &giteeUser.AvatarURL, - Blog: &giteeUser.Blog, - Email: &giteeUser.Email, - Gender: &enum.Male, - } - addUser, err := userService.AddUserService(user) - if err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - gitee := enum.OAuthSourceGitee - userSocial = model.ScaAuthUserSocial{ - UserID: &uidStr, - OpenID: &Id, - Source: &gitee, - } - err = userSocialService.AddUserSocialService(userSocial) - if err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - _, err = global.Casbin.AddRoleForUser(uidStr, enum.User) - if err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - if err := tx.Commit().Error; err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - HandleLoginResponse(c, *addUser.UID) - } else { - HandleLoginResponse(c, *userSocial.UserID) - } + } + if token == nil { + global.LOG.Error(errors.New("failed to get token")) return } + + // 获取用户信息 + userInfo, err := GetGiteeUserInfo(token) + if err != nil { + global.LOG.Error(err) + return + } + + // 处理用户信息 + userInfoBytes, err := json.Marshal(userInfo) + if err != nil { + global.LOG.Error(err) + return + } + var giteeUser GiteeUser + err = json.Unmarshal(userInfoBytes, &giteeUser) + if err != nil { + global.LOG.Error(err) + return + } + + Id := strconv.Itoa(giteeUser.ID) + userSocial, err := userSocialService.QueryUserSocialByOpenIDService(Id, enum.OAuthSourceGitee) + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { + db := global.DB + tx := db.Begin() // 开始事务 + if tx.Error != nil { + global.LOG.Error(tx.Error) + return + } + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + // 第一次登录,创建用户 + uid := idgen.NextId() + uidStr := strconv.FormatInt(uid, 10) + user := model.ScaAuthUser{ + UID: uidStr, + Username: giteeUser.Login, + Nickname: giteeUser.Name, + Avatar: giteeUser.AvatarURL, + Blog: giteeUser.Blog, + Email: giteeUser.Email, + Gender: enum.Male, + } + addUser, wrong := userService.AddUserService(user) + if wrong != nil { + tx.Rollback() + global.LOG.Error(wrong) + return + } + gitee := enum.OAuthSourceGitee + userSocial = model.ScaAuthUserSocial{ + UserID: uidStr, + OpenID: Id, + Source: gitee, + } + err = userSocialService.AddUserSocialService(userSocial) + if err != nil { + tx.Rollback() + global.LOG.Error(err) + return + } + _, err = global.Casbin.AddRoleForUser(uidStr, enum.User) + if err != nil { + tx.Rollback() + global.LOG.Error(err) + return + } + if err = tx.Commit().Error; err != nil { + tx.Rollback() + global.LOG.Error(err) + return + } + HandleLoginResponse(c, addUser.UID) + } else { + HandleLoginResponse(c, userSocial.UserID) + } } diff --git a/controller/oauth_controller/github_controller.go b/controller/oauth_controller/github_controller.go index 6f9d2cd..8228eb5 100644 --- a/controller/oauth_controller/github_controller.go +++ b/controller/oauth_controller/github_controller.go @@ -141,124 +141,111 @@ func GetUserInfo(token *Token) (map[string]interface{}, error) { // @Success 200 {string} string "登录成功" // @Router /controller/oauth/github/callback [get] func (OAuthController) Callback(c *gin.Context) { - var err error // 获取 code - var code = c.Query("code") + code := c.Query("code") if code == "" { result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c) return } - // 使用channel来接收异步操作的结果 - tokenChan := make(chan *Token) - userInfoChan := make(chan map[string]interface{}) - errChan := make(chan error) - - // 异步获取token - go func() { - var tokenAuthUrl = GetTokenAuthUrl(code) - token, err := GetToken(tokenAuthUrl) - if err != nil { - errChan <- err - return - } - tokenChan <- token - }() - - // 异步获取用户信息 - go func() { - token := <-tokenChan - if token == nil { - return - } - userInfo, err := GetUserInfo(token) - if err != nil { - errChan <- err - return - } - userInfoChan <- userInfo - }() - - select { - case err = <-errChan: + // 获取 token + tokenAuthUrl := GetTokenAuthUrl(code) + token, err := GetToken(tokenAuthUrl) + if err != nil { global.LOG.Error(err) return - case userInfo := <-userInfoChan: - if userInfo == nil { - global.LOG.Error(<-errChan) - return - } - // 继续处理用户信息 - userInfoBytes, err := json.Marshal(<-userInfoChan) - if err != nil { - global.LOG.Error(err) - return - } - var gitHubUser GitHubUser - err = json.Unmarshal(userInfoBytes, &gitHubUser) - if err != nil { - global.LOG.Error(err) - return - } - Id := strconv.Itoa(gitHubUser.ID) - userSocial, err := userSocialService.QueryUserSocialByOpenIDService(Id, enum.OAuthSourceGithub) - if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { - db := global.DB - tx := db.Begin() // 开始事务 - if tx.Error != nil { - global.LOG.Error(tx.Error) - return - } - defer func() { - if r := recover(); r != nil { - tx.Rollback() - } - }() - // 第一次登录,创建用户 - uid := idgen.NextId() - uidStr := strconv.FormatInt(uid, 10) - user := model.ScaAuthUser{ - UID: &uidStr, - Username: &gitHubUser.Login, - Nickname: &gitHubUser.Name, - Avatar: &gitHubUser.AvatarURL, - Blog: &gitHubUser.Blog, - Email: &gitHubUser.Email, - Gender: &enum.Male, - } - addUser, err := userService.AddUserService(user) - if err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - github := enum.OAuthSourceGithub - userSocial = model.ScaAuthUserSocial{ - UserID: &uidStr, - OpenID: &Id, - Source: &github, - } - err = userSocialService.AddUserSocialService(userSocial) - if err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - _, err = global.Casbin.AddRoleForUser(uidStr, enum.User) - if err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - if err := tx.Commit().Error; err != nil { - tx.Rollback() - global.LOG.Error(err) - return - } - HandleLoginResponse(c, *addUser.UID) - } else { - HandleLoginResponse(c, *userSocial.UserID) - } + } + if token == nil { + global.LOG.Error(errors.New("failed to get token")) return } + + // 获取用户信息 + userInfo, err := GetUserInfo(token) + if err != nil { + global.LOG.Error(err) + return + } + + if userInfo == nil { + global.LOG.Error(errors.New("failed to get user info")) + return + } + + // 处理用户信息 + userInfoBytes, err := json.Marshal(userInfo) + if err != nil { + global.LOG.Error(err) + return + } + var gitHubUser GitHubUser + err = json.Unmarshal(userInfoBytes, &gitHubUser) + if err != nil { + global.LOG.Error(err) + return + } + + Id := strconv.Itoa(gitHubUser.ID) + userSocial, err := userSocialService.QueryUserSocialByOpenIDService(Id, enum.OAuthSourceGithub) + + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { + db := global.DB + tx := db.Begin() // 开始事务 + if tx.Error != nil { + global.LOG.Error(tx.Error) + return + } + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + // 第一次登录,创建用户 + uid := idgen.NextId() + uidStr := strconv.FormatInt(uid, 10) + user := model.ScaAuthUser{ + UID: uidStr, + Username: gitHubUser.Login, + Nickname: gitHubUser.Name, + Avatar: gitHubUser.AvatarURL, + Blog: gitHubUser.Blog, + Email: gitHubUser.Email, + Gender: enum.Male, + } + addUser, wrong := userService.AddUserService(user) + if wrong != nil { + tx.Rollback() + global.LOG.Error(wrong) + return + } + + github := enum.OAuthSourceGithub + userSocial = model.ScaAuthUserSocial{ + UserID: uidStr, + OpenID: Id, + Source: github, + } + err = userSocialService.AddUserSocialService(userSocial) + if err != nil { + tx.Rollback() + global.LOG.Error(err) + return + } + + _, err = global.Casbin.AddRoleForUser(uidStr, enum.User) + if err != nil { + tx.Rollback() + global.LOG.Error(err) + return + } + if err = tx.Commit().Error; err != nil { + tx.Rollback() + global.LOG.Error(err) + return + } + HandleLoginResponse(c, addUser.UID) + } else { + HandleLoginResponse(c, userSocial.UserID) + } } diff --git a/controller/oauth_controller/oauth.go b/controller/oauth_controller/oauth.go index 4f9aa89..1b75cca 100644 --- a/controller/oauth_controller/oauth.go +++ b/controller/oauth_controller/oauth.go @@ -11,6 +11,7 @@ import ( "schisandra-cloud-album/global" "schisandra-cloud-album/service/impl" "schisandra-cloud-album/utils" + "sync" "time" ) @@ -31,12 +32,73 @@ var script = ` ` func HandleLoginResponse(c *gin.Context, uid string) { - res, data := HandelUserLogin(uid, c) - if !res { + // 查询用户信息 + user := userService.QueryUserByUuidService(&uid) + + var accessToken, refreshToken string + var expiresAt int64 + var err error + var wg sync.WaitGroup + var accessTokenErr error + + wg.Add(2) // 增加计数器,等待两个协程完成 + + // 使用goroutine生成accessToken + go func() { + defer wg.Done() // 完成时减少计数器 + accessToken, accessTokenErr = utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: &uid}) + }() + + // 使用goroutine生成refreshToken + go func() { + defer wg.Done() // 完成时减少计数器 + refreshToken, expiresAt = utils.GenerateRefreshToken(utils.RefreshJWTPayload{UserID: &uid}, time.Hour*24*7) + }() + + // 等待两个协程完成 + wg.Wait() + + // 检查生成accessToken时是否有错误 + if accessTokenErr != nil { + global.LOG.Error(accessTokenErr) return } - tokenData, err := json.Marshal(data) + data := ResponseData{ + AccessToken: accessToken, + RefreshToken: refreshToken, + ExpiresAt: expiresAt, + UID: &uid, + UserInfo: UserInfo{ + Username: user.Username, + Nickname: user.Nickname, + Avatar: user.Avatar, + Email: user.Email, + Phone: user.Phone, + Gender: user.Gender, + Status: user.Status, + CreateAt: *user.CreatedTime, + }, + } + + if err = utils.SetSession(c, constant.SessionKey, data); err != nil { + return + } + + // 将数据存入redis + if err = redis.Set(constant.UserLoginTokenRedisKey+uid, data, time.Hour*24*7).Err(); err != nil { + global.LOG.Error(err) + return + } + + responseData := result.Response{ + Data: data, + Message: "success", + Code: 200, + Success: true, + } + + tokenData, err := json.Marshal(responseData) if err != nil { global.LOG.Error(err) return @@ -46,78 +108,3 @@ func HandleLoginResponse(c *gin.Context, uid string) { c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(formattedScript)) return } - -// HandelUserLogin 处理用户登录 -func HandelUserLogin(userId string, c *gin.Context) (bool, result.Response) { - // 使用goroutine生成accessToken - accessTokenChan := make(chan string) - errChan := make(chan error) - go func() { - accessToken, err := utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: &userId}) - if err != nil { - errChan <- err - return - } - accessTokenChan <- accessToken - }() - - // 使用goroutine生成refreshToken - refreshTokenChan := make(chan string) - expiresAtChan := make(chan int64) - go func() { - refreshToken, expiresAt := utils.GenerateRefreshToken(utils.RefreshJWTPayload{UserID: &userId}, time.Hour*24*7) - refreshTokenChan <- refreshToken - expiresAtChan <- expiresAt - }() - - // 等待accessToken和refreshToken生成完成 - var accessToken string - var refreshToken string - var expiresAt int64 - var err error - select { - case accessToken = <-accessTokenChan: - case err = <-errChan: - global.LOG.Error(err) - return false, result.Response{} - } - select { - case refreshToken = <-refreshTokenChan: - case expiresAt = <-expiresAtChan: - } - - data := ResponseData{ - AccessToken: accessToken, - RefreshToken: refreshToken, - ExpiresAt: expiresAt, - UID: &userId, - } - wrong := utils.SetSession(c, constant.SessionKey, data) - if wrong != nil { - return false, result.Response{} - } - // 使用goroutine将数据存入redis - redisErrChan := make(chan error) - go func() { - fail := redis.Set(constant.UserLoginTokenRedisKey+userId, data, time.Hour*24*7).Err() - if fail != nil { - redisErrChan <- fail - return - } - redisErrChan <- nil - }() - - // 等待redis操作完成 - redisErr := <-redisErrChan - if redisErr != nil { - global.LOG.Error(redisErr) - return false, result.Response{} - } - responseData := result.Response{ - Data: data, - Message: "success", - Code: 200, - Success: true, - } - return true, responseData -} diff --git a/controller/oauth_controller/qq_controller.go b/controller/oauth_controller/qq_controller.go index b38ef6b..715192d 100644 --- a/controller/oauth_controller/qq_controller.go +++ b/controller/oauth_controller/qq_controller.go @@ -166,72 +166,40 @@ func GetQQUserUserInfo(token *QQToken, openId string) (map[string]interface{}, e // @Produce json // @Router /controller/oauth/qq/callback [get] func (OAuthController) QQCallback(c *gin.Context) { - var err error // 获取 code - var code = c.Query("code") + code := c.Query("code") if code == "" { result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c) return } - // 通过 code, 获取 token - var tokenAuthUrl = GetQQTokenAuthUrl(code) - tokenChan := make(chan *QQToken) - errChan := make(chan error) - go func() { - token, err := GetQQToken(tokenAuthUrl) - if err != nil { - errChan <- err - return - } - tokenChan <- token - }() - var token *QQToken - select { - case token = <-tokenChan: - case err = <-errChan: + // 通过 code 获取 token + tokenAuthUrl := GetQQTokenAuthUrl(code) + token, err := GetQQToken(tokenAuthUrl) + if err != nil { + global.LOG.Error(err) + return + } + if token == nil { + global.LOG.Error(errors.New("failed to get token")) + return + } + + // 通过 token 获取 openid + authQQme, err := GetQQUserOpenID(token) + if err != nil { global.LOG.Error(err) return } - // 通过 token,获取 openid - openIDChan := make(chan *AuthQQme) - errChan = make(chan error) - go func() { - authQQme, err := GetQQUserOpenID(token) - if err != nil { - errChan <- err - return - } - openIDChan <- authQQme - }() - var authQQme *AuthQQme - select { - case authQQme = <-openIDChan: - case err = <-errChan: - global.LOG.Error(err) - return - } - - // 通过token,获取用户信息 - userInfoChan := make(chan map[string]interface{}) - errChan = make(chan error) - go func() { - userInfo, err := GetQQUserUserInfo(token, authQQme.OpenID) - if err != nil { - errChan <- err - return - } - userInfoChan <- userInfo - }() - var userInfo map[string]interface{} - select { - case userInfo = <-userInfoChan: - case err = <-errChan: + // 通过 token 和 openid 获取用户信息 + userInfo, err := GetQQUserUserInfo(token, authQQme.OpenID) + if err != nil { global.LOG.Error(err) return } + // 处理用户信息 userInfoBytes, err := json.Marshal(userInfo) if err != nil { global.LOG.Error(err) @@ -244,6 +212,7 @@ func (OAuthController) QQCallback(c *gin.Context) { return } + // 查询用户社交信息 userSocial, err := userSocialService.QueryUserSocialByOpenIDService(authQQme.OpenID, enum.OAuthSourceQQ) if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { db := global.DB @@ -257,27 +226,29 @@ func (OAuthController) QQCallback(c *gin.Context) { tx.Rollback() } }() + // 第一次登录,创建用户 uid := idgen.NextId() uidStr := strconv.FormatInt(uid, 10) user := model.ScaAuthUser{ - UID: &uidStr, - Username: &authQQme.OpenID, - Nickname: &qqUserInfo.Nickname, - Avatar: &qqUserInfo.FigureurlQq1, - Gender: &qqUserInfo.Gender, + UID: uidStr, + Username: authQQme.OpenID, + Nickname: qqUserInfo.Nickname, + Avatar: qqUserInfo.FigureurlQq1, + Gender: qqUserInfo.Gender, } - addUser, err := userService.AddUserService(user) - if err != nil { + addUser, wrong := userService.AddUserService(user) + if wrong != nil { tx.Rollback() - global.LOG.Error(err) + global.LOG.Error(wrong) return } + qq := enum.OAuthSourceQQ userSocial = model.ScaAuthUserSocial{ - UserID: &uidStr, - OpenID: &authQQme.OpenID, - Source: &qq, + UserID: uidStr, + OpenID: authQQme.OpenID, + Source: qq, } err = userSocialService.AddUserSocialService(userSocial) if err != nil { @@ -285,20 +256,22 @@ func (OAuthController) QQCallback(c *gin.Context) { global.LOG.Error(err) return } + _, err = global.Casbin.AddRoleForUser(uidStr, enum.User) if err != nil { tx.Rollback() global.LOG.Error(err) return } - if err := tx.Commit().Error; err != nil { + + if err = tx.Commit().Error; err != nil { tx.Rollback() global.LOG.Error(err) return } - HandleLoginResponse(c, *addUser.UID) + HandleLoginResponse(c, addUser.UID) return } else { - HandleLoginResponse(c, *userSocial.UserID) + HandleLoginResponse(c, userSocial.UserID) } } diff --git a/controller/oauth_controller/request_param.go b/controller/oauth_controller/request_param.go index 17ff176..8c86cd4 100644 --- a/controller/oauth_controller/request_param.go +++ b/controller/oauth_controller/request_param.go @@ -1,13 +1,27 @@ package oauth_controller -import "encoding/json" +import ( + "encoding/json" + "time" +) // ResponseData 返回数据 type ResponseData struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - ExpiresAt int64 `json:"expires_at"` - UID *string `json:"uid"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + ExpiresAt int64 `json:"expires_at"` + UID *string `json:"uid"` + UserInfo UserInfo `json:"user_info"` +} +type UserInfo struct { + Username string `json:"username,omitempty"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` + Phone string `json:"phone,omitempty"` + Email string `json:"email,omitempty"` + Gender string `json:"gender"` + Status int64 `json:"status"` + CreateAt time.Time `json:"create_at"` } func (res ResponseData) MarshalBinary() ([]byte, error) { diff --git a/controller/oauth_controller/wechat_controller.go b/controller/oauth_controller/wechat_controller.go index f8f1b9e..f34bbac 100644 --- a/controller/oauth_controller/wechat_controller.go +++ b/controller/oauth_controller/wechat_controller.go @@ -169,6 +169,7 @@ func wechatLoginHandler(openId string, clientId string, c *gin.Context) bool { if openId == "" { return false } + authUserSocial, err := userSocialService.QueryUserSocialByOpenIDService(openId, enum.OAuthSourceWechat) if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { tx := global.DB.Begin() @@ -180,107 +181,63 @@ func wechatLoginHandler(openId string, clientId string, c *gin.Context) bool { uid := idgen.NextId() uidStr := strconv.FormatInt(uid, 10) - avatar, err := utils.GenerateAvatar(uidStr) + avatar := utils.GenerateAvatar(uidStr) name := randomname.GenerateName() - if err != nil { - global.LOG.Errorln(err) - return false - } createUser := model.ScaAuthUser{ - UID: &uidStr, - Username: &openId, - Avatar: &avatar, - Nickname: &name, - Gender: &enum.Male, + UID: uidStr, + Username: openId, + Avatar: avatar, + Nickname: name, + Gender: enum.Male, } - // 异步添加用户 - addUserChan := make(chan *model.ScaAuthUser, 1) - errChan := make(chan error, 1) - go func() { - addUser, err := userService.AddUserService(createUser) - if err != nil { - errChan <- err - return - } - addUserChan <- addUser - }() - - var addUser *model.ScaAuthUser - select { - case addUser = <-addUserChan: - case err := <-errChan: + // 添加用户 + addUser, worn := userService.AddUserService(createUser) + if worn != nil { tx.Rollback() - global.LOG.Error(err) + global.LOG.Error(worn) return false } wechat := enum.OAuthSourceWechat userSocial := model.ScaAuthUserSocial{ - UserID: &uidStr, - OpenID: &openId, - Source: &wechat, + UserID: uidStr, + OpenID: openId, + Source: wechat, } - // 异步添加用户社交信息 - wrongChan := make(chan error, 1) - go func() { - wrong := userSocialService.AddUserSocialService(userSocial) - wrongChan <- wrong - }() - - select { - case wrong := <-wrongChan: - if wrong != nil { - tx.Rollback() - global.LOG.Error(wrong) - return false - } + // 添加用户社交信息 + if wrong := userSocialService.AddUserSocialService(userSocial); wrong != nil { + tx.Rollback() + global.LOG.Error(wrong) + return false } - // 异步添加角色 - roleErrChan := make(chan error, 1) - go func() { - _, err := global.Casbin.AddRoleForUser(uidStr, enum.User) - roleErrChan <- err - }() - - select { - case err := <-roleErrChan: - if err != nil { - tx.Rollback() - global.LOG.Error(err) - return false - } + // 添加角色 + if _, err = global.Casbin.AddRoleForUser(uidStr, enum.User); err != nil { + tx.Rollback() + global.LOG.Error(err) + return false } - // 异步处理用户登录 - resChan := make(chan bool, 1) - go func() { - res := handelUserLogin(*addUser.UID, clientId, c) - resChan <- res - }() - - select { - case res := <-resChan: - if !res { - tx.Rollback() - return false - } + // 处理用户登录 + if res := handelUserLogin(addUser.UID, clientId, c); !res { + tx.Rollback() + return false } + tx.Commit() return true } else { - res := handelUserLogin(*authUserSocial.UserID, clientId, c) - if !res { - return false - } - return true + res := handelUserLogin(authUserSocial.UserID, clientId, c) + return res } } // handelUserLogin 处理用户登录 func handelUserLogin(userId string, clientId string, c *gin.Context) bool { + + user := userService.QueryUserByUuidService(&userId) resultChan := make(chan bool, 1) go func() { @@ -295,6 +252,16 @@ func handelUserLogin(userId string, clientId string, c *gin.Context) bool { RefreshToken: refreshToken, ExpiresAt: expiresAt, UID: &userId, + UserInfo: UserInfo{ + Username: user.Username, + Nickname: user.Nickname, + Avatar: user.Avatar, + Gender: user.Gender, + Phone: user.Phone, + Email: user.Email, + CreateAt: *user.CreatedTime, + Status: user.Status, + }, } fail := redis.Set(constant.UserLoginTokenRedisKey+userId, data, time.Hour*24*7).Err() if fail != nil { diff --git a/controller/user_controller/user_controller.go b/controller/user_controller/user_controller.go index bbd7531..d2976eb 100644 --- a/controller/user_controller/user_controller.go +++ b/controller/user_controller/user_controller.go @@ -139,7 +139,7 @@ func (UserController) AccountLogin(c *gin.Context) { return } - if !utils.Verify(*user.Password, password) { + if !utils.Verify(user.Password, password) { result.FailWithMessage(ginI18n.MustGetMessage(c, "PasswordError"), c) return } @@ -171,101 +171,66 @@ func (UserController) PhoneLogin(c *gin.Context) { result.FailWithMessage(ginI18n.MustGetMessage(c, "PhoneErrorFormat"), c) return } + // 获取验证码 + code := redis.Get(constant.UserLoginSmsRedisKey + phone).Val() + if code == "" { + result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaExpired"), c) + return + } - userChan := make(chan model.ScaAuthUser) - go func() { - user := userService.QueryUserByPhoneService(phone) - userChan <- user + if captcha != code { + result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaError"), c) + return + } + tx := global.DB.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } }() - - user := <-userChan - close(userChan) + // 查询用户 + user := userService.QueryUserByPhoneService(phone) if user.ID == 0 { // 未注册 - codeChan := make(chan *string) - go func() { - code := redis.Get(constant.UserLoginSmsRedisKey + phone).Val() - codeChan <- &code - }() - - code := <-codeChan - close(codeChan) - - if code == nil { - result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaExpired"), c) - return - } - uid := idgen.NextId() uidStr := strconv.FormatInt(uid, 10) - - avatar, err := utils.GenerateAvatar(uidStr) - if err != nil { - global.LOG.Errorln(err) - return - } + avatar := utils.GenerateAvatar(uidStr) name := randomname.GenerateName() createUser := model.ScaAuthUser{ - UID: &uidStr, - Phone: &phone, - Avatar: &avatar, - Nickname: &name, - Gender: &enum.Male, + UID: uidStr, + Phone: phone, + Avatar: avatar, + Nickname: name, + Gender: enum.Male, } - errChan := make(chan error) - go func() { - err = global.DB.Transaction(func(tx *gorm.DB) error { - addUser, w := userService.AddUserService(createUser) - if w != nil { - return w - } - _, err = global.Casbin.AddRoleForUser(uidStr, enum.User) - if err != nil { - return err - } - data, res := userService.HandelUserLogin(*addUser, autoLogin, c) - if !res { - result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c) - return errors.New("login failed") - } - result.OkWithData(data, c) - return nil - }) - errChan <- err - }() - - err = <-errChan - close(errChan) - + addUser, w := userService.AddUserService(createUser) + if w != nil { + tx.Rollback() + return + } + _, err = global.Casbin.AddRoleForUser(uidStr, enum.User) if err != nil { - result.FailWithMessage(ginI18n.MustGetMessage(c, "RegisterUserError"), c) + tx.Rollback() return } - } else { - codeChan := make(chan string) - go func() { - code := redis.Get(constant.UserLoginSmsRedisKey + phone).Val() - codeChan <- code - }() - - code := <-codeChan - close(codeChan) - - if code == "" { - result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaExpired"), c) - return - } - if captcha != code { - result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaError"), c) - return - } - data, res := userService.HandelUserLogin(user, autoLogin, c) + data, res := userService.HandelUserLogin(*addUser, autoLogin, c) if !res { + tx.Rollback() result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c) return } + tx.Commit() + result.OkWithData(data, c) + } else { + data, res := userService.HandelUserLogin(user, autoLogin, c) + if !res { + tx.Rollback() + result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c) + return + } + tx.Commit() result.OkWithData(data, c) } } @@ -360,7 +325,7 @@ func (UserController) ResetPassword(c *gin.Context) { return } - if err := userService.UpdateUserService(phone, encrypt); err != nil { + if err = userService.UpdateUserService(phone, encrypt); err != nil { tx.Rollback() result.FailWithMessage(ginI18n.MustGetMessage(c, "ResetPasswordError"), c) return @@ -430,36 +395,44 @@ func (UserController) GetUserLoginDevice(c *gin.Context) { platform := ua.Platform() engine, engineVersion := ua.Engine() device := model.ScaAuthUserDevice{ - UserID: &userId, - IP: &ip, - Location: &location, + UserID: userId, + IP: ip, + Location: location, Agent: userAgent, - Browser: &browser, - BrowserVersion: &browserVersion, - OperatingSystem: &os, - Mobile: &mobile, - Bot: &isBot, - Mozilla: &mozilla, - Platform: &platform, - EngineName: &engine, - EngineVersion: &engineVersion, + Browser: browser, + BrowserVersion: browserVersion, + OperatingSystem: os, + Mobile: mobile, + Bot: isBot, + Mozilla: mozilla, + Platform: platform, + EngineName: engine, + EngineVersion: engineVersion, } - mu.Lock() - defer mu.Unlock() + tx := global.DB.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() userDevice, err := userDeviceService.GetUserDeviceByUIDIPAgentService(userId, ip, userAgent) if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { err = userDeviceService.AddUserDeviceService(&device) if err != nil { + tx.Rollback() global.LOG.Errorln(err) return } + tx.Commit() return } else { - err := userDeviceService.UpdateUserDeviceService(userDevice.ID, &device) + err = userDeviceService.UpdateUserDeviceService(userDevice.ID, &device) if err != nil { + tx.Rollback() global.LOG.Errorln(err) return } + tx.Commit() return } } diff --git a/dao/impl/user_dao_impl.go b/dao/impl/user_dao_impl.go index 962c226..2ae1786 100644 --- a/dao/impl/user_dao_impl.go +++ b/dao/impl/user_dao_impl.go @@ -59,13 +59,13 @@ func (UserDaoImpl) AddUser(user model.ScaAuthUser) (*model.ScaAuthUser, error) { // UpdateUser 更新用户 func (UserDaoImpl) UpdateUser(phone string, password string) error { - return global.DB.Model(&model.ScaAuthUser{}).Where("phone = ? and deleted = 0", phone).Updates(&model.ScaAuthUser{Password: &password}).Error + return global.DB.Model(&model.ScaAuthUser{}).Where("phone = ? and deleted = 0", phone).Updates(&model.ScaAuthUser{Password: password}).Error } // DeleteUser 删除用户 func (UserDaoImpl) DeleteUser(uuid string) error { authUser := model.ScaAuthUser{} - return global.DB.Model(&authUser).Where("uid = ?", uuid).Updates(&model.ScaAuthUser{Deleted: &enum.DELETED}).Error + return global.DB.Model(&authUser).Where("uid = ?", uuid).Updates(&model.ScaAuthUser{Deleted: enum.DELETED}).Error } // QueryUserByPhone 根据手机号查询用户 diff --git a/model/sca_auth_permission.go b/model/sca_auth_permission.go index 68c171d..0e80b9a 100644 --- a/model/sca_auth_permission.go +++ b/model/sca_auth_permission.go @@ -10,21 +10,21 @@ const TableNameScaAuthPermission = "sca_auth_permission" // ScaAuthPermission 权限表 type ScaAuthPermission struct { ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - PermissionName *string `gorm:"column:permission_name;type:varchar(64);comment:权限名称" json:"permission_name"` // 权限名称 - ParentID *int64 `gorm:"column:parent_id;type:bigint(20);comment:父ID" json:"parent_id"` // 父ID - Type *int64 `gorm:"column:type;type:tinyint(4);comment:类型 0 菜单 1 接口" json:"type"` // 类型 0 菜单 1 目录 2 按钮 -1其他 - Path *string `gorm:"column:path;type:varchar(30);comment:路径" json:"path"` // 路径 - Status *int64 `gorm:"column:status;type:tinyint(4);comment:状态 0 启用 1 停用" json:"status"` // 状态 0 启用 1 停用 - Method *string `gorm:"column:method;type:varchar(20);comment:请求方式" json:"method"` // 请求方式 - Icon *string `gorm:"column:icon;type:varchar(128);comment:图标" json:"icon"` // 图标 - PermissionKey *string `gorm:"column:permission_key;type:varchar(64);comment:权限关键字" json:"permission_key"` // 权限关键字 - Order *int64 `gorm:"column:order;type:int(11);comment:排序" json:"order"` // 排序 + PermissionName string `gorm:"column:permission_name;type:varchar(64);comment:权限名称" json:"permission_name"` // 权限名称 + ParentID int64 `gorm:"column:parent_id;type:bigint(20);comment:父ID" json:"parent_id"` // 父ID + Type int64 `gorm:"column:type;type:tinyint(4);comment:类型 0 菜单 1 接口" json:"type"` // 类型 0 菜单 1 目录 2 按钮 -1其他 + Path string `gorm:"column:path;type:varchar(30);comment:路径" json:"path"` // 路径 + Status int64 `gorm:"column:status;type:tinyint(4);comment:状态 0 启用 1 停用" json:"status"` // 状态 0 启用 1 停用 + Method string `gorm:"column:method;type:varchar(20);comment:请求方式" json:"method"` // 请求方式 + Icon string `gorm:"column:icon;type:varchar(128);comment:图标" json:"icon"` // 图标 + PermissionKey string `gorm:"column:permission_key;type:varchar(64);comment:权限关键字" json:"permission_key"` // 权限关键字 + Order int64 `gorm:"column:order;type:int(11);comment:排序" json:"order"` // 排序 CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 - Remark *string `gorm:"column:remark;type:varchar(255);comment:备注 描述" json:"remark"` // 备注 描述 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` + Deleted int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 + Remark string `gorm:"column:remark;type:varchar(255);comment:备注 描述" json:"remark"` // 备注 描述 + CreatedBy string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` } // TableName ScaAuthPermission's table name diff --git a/model/sca_auth_role.go b/model/sca_auth_role.go index 9036216..f789186 100644 --- a/model/sca_auth_role.go +++ b/model/sca_auth_role.go @@ -14,9 +14,9 @@ type ScaAuthRole struct { RoleKey string `gorm:"column:role_key;type:varchar(64);not null;comment:角色关键字" json:"role_key"` // 角色关键字 CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除 0 未删除 1已删除" json:"deleted"` // 是否删除 0 未删除 1已删除 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` + Deleted int64 `gorm:"column:deleted;type:int(11);comment:是否删除 0 未删除 1已删除" json:"deleted"` // 是否删除 0 未删除 1已删除 + CreatedBy string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` } // TableName ScaAuthRole's table name diff --git a/model/sca_auth_user.go b/model/sca_auth_user.go index 1ce7e5a..a49bfb9 100644 --- a/model/sca_auth_user.go +++ b/model/sca_auth_user.go @@ -10,24 +10,24 @@ const TableNameScaAuthUser = "sca_auth_user" // ScaAuthUser 用户表 type ScaAuthUser struct { ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true;comment:自增ID" json:"-"` // 自增ID - UID *string `gorm:"column:uid;type:varchar(20);comment:唯一ID" json:"uid"` // 唯一ID - Username *string `gorm:"column:username;type:varchar(32);comment:用户名" json:"username"` // 用户名 - Nickname *string `gorm:"column:nickname;type:varchar(32);comment:昵称" json:"nickname"` // 昵称 - Email *string `gorm:"column:email;type:varchar(32);comment:邮箱" json:"email"` // 邮箱 - Phone *string `gorm:"column:phone;type:varchar(32);comment:电话" json:"phone"` // 电话 - Password *string `gorm:"column:password;type:varchar(64);comment:密码" json:"-"` // 密码 - Gender *string `gorm:"column:gender;type:varchar(32);comment:性别" json:"gender"` // 性别 - Avatar *string `gorm:"column:avatar;type:longtext;comment:头像" json:"avatar"` // 头像 - Status *int64 `gorm:"column:status;type:tinyint(4);default:0;comment:状态 0 正常 1 封禁" json:"status"` // 状态 0 正常 1 封禁 - Introduce *string `gorm:"column:introduce;type:varchar(255);comment:介绍" json:"introduce"` // 介绍 + UID string `gorm:"column:uid;type:varchar(20);comment:唯一ID" json:"uid"` // 唯一ID + Username string `gorm:"column:username;type:varchar(32);comment:用户名" json:"username"` // 用户名 + Nickname string `gorm:"column:nickname;type:varchar(32);comment:昵称" json:"nickname"` // 昵称 + Email string `gorm:"column:email;type:varchar(32);comment:邮箱" json:"email"` // 邮箱 + Phone string `gorm:"column:phone;type:varchar(32);comment:电话" json:"phone"` // 电话 + Password string `gorm:"column:password;type:varchar(64);comment:密码" json:"-"` // 密码 + Gender string `gorm:"column:gender;type:varchar(32);comment:性别" json:"gender"` // 性别 + Avatar string `gorm:"column:avatar;type:longtext;comment:头像" json:"avatar"` // 头像 + Status int64 `gorm:"column:status;type:tinyint(4);default:0;comment:状态 0 正常 1 封禁" json:"status"` // 状态 0 正常 1 封禁 + Introduce string `gorm:"column:introduce;type:varchar(255);comment:介绍" json:"introduce"` // 介绍 CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);default:0;comment:是否删除 0 未删除 1 已删除" json:"-"` // 是否删除 0 未删除 1 已删除 - Blog *string `gorm:"column:blog;type:varchar(30);comment:博客" json:"blog"` // 博客 - Location *string `gorm:"column:location;type:varchar(50);comment:地址" json:"location"` // 地址 - Company *string `gorm:"column:company;type:varchar(50);comment:公司" json:"company"` // 公司 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + Deleted int64 `gorm:"column:deleted;type:int(11);default:0;comment:是否删除 0 未删除 1 已删除" json:"-"` // 是否删除 0 未删除 1 已删除 + Blog string `gorm:"column:blog;type:varchar(30);comment:博客" json:"blog"` // 博客 + Location string `gorm:"column:location;type:varchar(50);comment:地址" json:"location"` // 地址 + Company string `gorm:"column:company;type:varchar(50);comment:公司" json:"company"` // 公司 + CreatedBy string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 } // TableName ScaAuthUser's table name diff --git a/model/sca_auth_user_device.go b/model/sca_auth_user_device.go index 8e1d5e7..78e30c4 100644 --- a/model/sca_auth_user_device.go +++ b/model/sca_auth_user_device.go @@ -9,24 +9,24 @@ const TableNameScaAuthUserDevice = "sca_auth_user_device" // ScaAuthUserDevice 用户设备信息 type ScaAuthUserDevice struct { ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - UserID *string `gorm:"column:user_id;type:varchar(20);comment:用户ID" json:"user_id"` // 用户ID - IP *string `gorm:"column:ip;type:varchar(20);comment:登录IP" json:"ip"` // 登录IP - Location *string `gorm:"column:location;type:varchar(20);comment:地址" json:"location"` // 地址 + UserID string `gorm:"column:user_id;type:varchar(20);comment:用户ID" json:"user_id"` // 用户ID + IP string `gorm:"column:ip;type:varchar(20);comment:登录IP" json:"ip"` // 登录IP + Location string `gorm:"column:location;type:varchar(20);comment:地址" json:"location"` // 地址 Agent string `gorm:"column:agent;type:varchar(255);comment:设备信息" json:"agent"` // 设备信息 CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);default:0;comment:是否删除" json:"deleted"` // 是否删除 - Browser *string `gorm:"column:browser;type:varchar(20);comment:浏览器" json:"browser"` // 浏览器 - OperatingSystem *string `gorm:"column:operating_system;type:varchar(20);comment:操作系统" json:"operating_system"` // 操作系统 - BrowserVersion *string `gorm:"column:browser_version;type:varchar(20);comment:浏览器版本" json:"browser_version"` // 浏览器版本 - Mobile *bool `gorm:"column:mobile;type:int(11);comment:是否为手机" json:"mobile"` // 是否为手机 - Bot *bool `gorm:"column:bot;type:int(11);comment:是否为机器人" json:"bot"` // 是否为机器人 - Mozilla *string `gorm:"column:mozilla;type:varchar(10);comment:火狐版本" json:"mozilla"` // 火狐版本 - Platform *string `gorm:"column:platform;type:varchar(20);comment:平台" json:"platform"` // 平台 - EngineName *string `gorm:"column:engine_name;type:varchar(20);comment:引擎名称" json:"engine_name"` // 引擎名称 - EngineVersion *string `gorm:"column:engine_version;type:varchar(20);comment:引擎版本" json:"engine_version"` // 引擎版本 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);default:system;comment:创建人" json:"created_by"` // 创建人 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` + Deleted int64 `gorm:"column:deleted;type:int(11);default:0;comment:是否删除" json:"deleted"` // 是否删除 + Browser string `gorm:"column:browser;type:varchar(20);comment:浏览器" json:"browser"` // 浏览器 + OperatingSystem string `gorm:"column:operating_system;type:varchar(20);comment:操作系统" json:"operating_system"` // 操作系统 + BrowserVersion string `gorm:"column:browser_version;type:varchar(20);comment:浏览器版本" json:"browser_version"` // 浏览器版本 + Mobile bool `gorm:"column:mobile;type:int(11);comment:是否为手机" json:"mobile"` // 是否为手机 + Bot bool `gorm:"column:bot;type:int(11);comment:是否为机器人" json:"bot"` // 是否为机器人 + Mozilla string `gorm:"column:mozilla;type:varchar(10);comment:火狐版本" json:"mozilla"` // 火狐版本 + Platform string `gorm:"column:platform;type:varchar(20);comment:平台" json:"platform"` // 平台 + EngineName string `gorm:"column:engine_name;type:varchar(20);comment:引擎名称" json:"engine_name"` // 引擎名称 + EngineVersion string `gorm:"column:engine_version;type:varchar(20);comment:引擎版本" json:"engine_version"` // 引擎版本 + CreatedBy string `gorm:"column:created_by;type:varchar(32);default:system;comment:创建人" json:"created_by"` // 创建人 + UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` } // TableName ScaAuthUserDevice's table name diff --git a/model/sca_auth_user_social.go b/model/sca_auth_user_social.go index 0060305..0a48ebe 100644 --- a/model/sca_auth_user_social.go +++ b/model/sca_auth_user_social.go @@ -9,15 +9,15 @@ const TableNameScaAuthUserSocial = "sca_auth_user_social" // ScaAuthUserSocial 社会用户信息表 type ScaAuthUserSocial struct { ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - UserID *string `gorm:"column:user_id;type:varchar(20);not null;comment:用户ID" json:"user_id"` // 用户ID - Source *string `gorm:"column:source;type:varchar(10);comment:第三方用户来源" json:"source"` // 第三方用户来源 - OpenID *string `gorm:"column:open_id;type:varchar(50);comment:第三方用户的 open id" json:"open_id"` // 第三方用户的 open id - Status *int64 `gorm:"column:status;type:int(11);default:0;comment:状态 0正常 1 封禁" json:"status"` // 状态 0正常 1 封禁 + UserID string `gorm:"column:user_id;type:varchar(20);not null;comment:用户ID" json:"user_id"` // 用户ID + Source string `gorm:"column:source;type:varchar(10);comment:第三方用户来源" json:"source"` // 第三方用户来源 + OpenID string `gorm:"column:open_id;type:varchar(50);comment:第三方用户的 open id" json:"open_id"` // 第三方用户的 open id + Status int64 `gorm:"column:status;type:int(11);default:0;comment:状态 0正常 1 封禁" json:"status"` // 状态 0正常 1 封禁 CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);default:0;comment:是否删除" json:"deleted"` // 是否删除 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);default:system;comment:创建人" json:"created_by"` // 创建人 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` + Deleted int64 `gorm:"column:deleted;type:int(11);default:0;comment:是否删除" json:"deleted"` // 是否删除 + CreatedBy string `gorm:"column:created_by;type:varchar(32);default:system;comment:创建人" json:"created_by"` // 创建人 + UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` } // TableName ScaAuthUserSocial's table name diff --git a/service/impl/comment_reply_service_impl.go b/service/impl/comment_reply_service_impl.go index 7b0fdbc..9897fea 100644 --- a/service/impl/comment_reply_service_impl.go +++ b/service/impl/comment_reply_service_impl.go @@ -200,8 +200,8 @@ func (CommentReplyServiceImpl) GetCommentReplyListService(uid string, topicId st return } for _, userInfo := range userInfos { - userInfoMap[*userInfo.UID] = *userInfo - redis.Set(constant.CommentUserListRedisKey+*userInfo.UID, userInfo, 24*time.Hour) + userInfoMap[userInfo.UID] = *userInfo + redis.Set(constant.CommentUserListRedisKey+userInfo.UID, userInfo, 24*time.Hour) } } }() @@ -279,13 +279,13 @@ func (CommentReplyServiceImpl) GetCommentReplyListService(uid string, topicId st return } commentContent := CommentContent{ - Avatar: *userInfo.Avatar, - NickName: *userInfo.Nickname, + Avatar: userInfo.Avatar, + NickName: userInfo.Nickname, Id: reply.Id, UserId: reply.UserId, TopicId: reply.TopicId, Content: reply.Content, - ReplyUsername: *replyUserInfo.Nickname, + ReplyUsername: replyUserInfo.Nickname, ReplyCount: reply.ReplyCount, Likes: reply.Likes, CreatedTime: reply.CreatedTime, @@ -385,8 +385,8 @@ func (CommentReplyServiceImpl) GetCommentListService(uid string, topicId string, return } for _, userInfo := range userInfos { - userInfoMap[*userInfo.UID] = *userInfo - redis.Set(constant.CommentUserListRedisKey+*userInfo.UID, userInfo, 24*time.Hour) + userInfoMap[userInfo.UID] = *userInfo + redis.Set(constant.CommentUserListRedisKey+userInfo.UID, userInfo, 24*time.Hour) } } }() @@ -473,8 +473,8 @@ func (CommentReplyServiceImpl) GetCommentListService(uid string, topicId string, return } commentContent := CommentContent{ - Avatar: *userInfo.Avatar, - NickName: *userInfo.Nickname, + Avatar: userInfo.Avatar, + NickName: userInfo.Nickname, Id: comment.Id, UserId: comment.UserId, TopicId: comment.TopicId, diff --git a/service/impl/user_service_impl.go b/service/impl/user_service_impl.go index 614e7eb..bf62085 100644 --- a/service/impl/user_service_impl.go +++ b/service/impl/user_service_impl.go @@ -25,10 +25,21 @@ var mu = &sync.Mutex{} // ResponseData 返回数据 type ResponseData struct { - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - ExpiresAt int64 `json:"expires_at"` - UID *string `json:"uid"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + ExpiresAt int64 `json:"expires_at"` + UID *string `json:"uid"` + UserInfo UserInfo `json:"user_info"` +} +type UserInfo struct { + Username string `json:"username,omitempty"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` + Phone string `json:"phone,omitempty"` + Email string `json:"email,omitempty"` + Gender string `json:"gender"` + Status int64 `json:"status"` + CreateAt time.Time `json:"create_at"` } func (res ResponseData) MarshalBinary() ([]byte, error) { @@ -115,13 +126,13 @@ func (UserServiceImpl) RefreshTokenService(refreshToken string) (*ResponseData, // HandelUserLogin 处理用户登录 func (UserServiceImpl) HandelUserLogin(user model.ScaAuthUser, autoLogin bool, c *gin.Context) (*ResponseData, bool) { // 检查 user.UID 是否为 nil - if user.UID == nil { + if user.UID == "" { return nil, false } if !GetUserLoginDevice(user, c) { return nil, false } - accessToken, err := utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: user.UID}) + accessToken, err := utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: &user.UID}) if err != nil { return nil, false } @@ -132,15 +143,25 @@ func (UserServiceImpl) HandelUserLogin(user model.ScaAuthUser, autoLogin bool, c days = time.Minute * 30 } - refreshToken, expiresAt := utils.GenerateRefreshToken(utils.RefreshJWTPayload{UserID: user.UID}, days) + refreshToken, expiresAt := utils.GenerateRefreshToken(utils.RefreshJWTPayload{UserID: &user.UID}, days) data := ResponseData{ AccessToken: accessToken, RefreshToken: refreshToken, ExpiresAt: expiresAt, - UID: user.UID, + UID: &user.UID, + UserInfo: UserInfo{ + Username: user.Username, + Nickname: user.Nickname, + Avatar: user.Avatar, + Phone: user.Phone, + Email: user.Email, + Gender: user.Gender, + Status: user.Status, + CreateAt: *user.CreatedTime, + }, } - err = redis.Set(constant.UserLoginTokenRedisKey+*user.UID, data, days).Err() + err = redis.Set(constant.UserLoginTokenRedisKey+user.UID, data, days).Err() if err != nil { return nil, false } @@ -156,7 +177,7 @@ func (UserServiceImpl) HandelUserLogin(user model.ScaAuthUser, autoLogin bool, c func GetUserLoginDevice(user model.ScaAuthUser, c *gin.Context) bool { // 检查user.UID是否为空 - if user.UID == nil { + if user.UID == "" { global.LOG.Errorln("user.UID is nil") return false } @@ -185,24 +206,24 @@ func GetUserLoginDevice(user model.ScaAuthUser, c *gin.Context) bool { device := model.ScaAuthUserDevice{ UserID: user.UID, - IP: &ip, - Location: &location, + IP: ip, + Location: location, Agent: userAgent, - Browser: &browser, - BrowserVersion: &browserVersion, - OperatingSystem: &os, - Mobile: &mobile, - Bot: &isBot, - Mozilla: &mozilla, - Platform: &platform, - EngineName: &engine, - EngineVersion: &engineVersion, + Browser: browser, + BrowserVersion: browserVersion, + OperatingSystem: os, + Mobile: mobile, + Bot: isBot, + Mozilla: mozilla, + Platform: platform, + EngineName: engine, + EngineVersion: engineVersion, } mu.Lock() defer mu.Unlock() - userDevice, err := userDeviceDao.GetUserDeviceByUIDIPAgent(*user.UID, ip, userAgent) + userDevice, err := userDeviceDao.GetUserDeviceByUIDIPAgent(user.UID, ip, userAgent) if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { err = userDeviceDao.AddUserDevice(&device) if err != nil { diff --git a/utils/generate_avatar.go b/utils/generate_avatar.go index f48116c..51269ab 100644 --- a/utils/generate_avatar.go +++ b/utils/generate_avatar.go @@ -1,9 +1,6 @@ package utils import ( - "encoding/base64" - "errors" - "io" "net/http" "time" ) @@ -14,41 +11,41 @@ var client = &http.Client{ } // GenerateAvatar 用于生成用户头像 -func GenerateAvatar(userId string) (baseImg string, err error) { +func GenerateAvatar(userId string) (baseImg string) { path := "https://api.multiavatar.com/" + userId + ".png" - // 创建请求 - request, err := http.NewRequest("GET", path, nil) - if err != nil { - return "", errors.New("image request error") - } - - // 发送请求并获取响应 - respImg, err := client.Do(request) - if err != nil { - return "", errors.New("failed to fetch image") - } - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - return - } - }(respImg.Body) - - // 读取图片数据 - imgByte, err := io.ReadAll(respImg.Body) - if err != nil { - return "", errors.New("failed to read image data") - } - - // 判断文件类型,生成一个前缀 - mimeType := http.DetectContentType(imgByte) - switch mimeType { - case "image/png": - baseImg = "data:image/png;base64," + base64.StdEncoding.EncodeToString(imgByte) - default: - return "", errors.New("unsupported image type") - } - return baseImg, nil + //// 创建请求 + //request, err := http.NewRequest("GET", path, nil) + //if err != nil { + // return "", errors.New("image request error") + //} + // + //// 发送请求并获取响应 + //respImg, err := client.Do(request) + //if err != nil { + // return "", errors.New("failed to fetch image") + //} + //defer func(Body io.ReadCloser) { + // err := Body.Close() + // if err != nil { + // return + // } + //}(respImg.Body) + // + //// 读取图片数据 + //imgByte, err := io.ReadAll(respImg.Body) + //if err != nil { + // return "", errors.New("failed to read image data") + //} + // + //// 判断文件类型,生成一个前缀 + //mimeType := http.DetectContentType(imgByte) + //switch mimeType { + //case "image/png": + // baseImg = "data:image/png;base64," + base64.StdEncoding.EncodeToString(imgByte) + //default: + // return "", errors.New("unsupported image type") + //} + return path }