🔨 refactor code

This commit is contained in:
landaiqing
2024-10-03 02:10:14 +08:00
parent 230921fa3d
commit 16616e3755
17 changed files with 563 additions and 661 deletions

View File

@@ -1,6 +1,6 @@
package enum
var (
Male = ""
Female = ""
Male = "Male"
Female = "Female"
)

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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
}
}

View File

@@ -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 根据手机号查询用户

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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
}