🔨 refactor code
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
package enum
|
package enum
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Male = "男"
|
Male = "Male"
|
||||||
Female = "女"
|
Female = "Female"
|
||||||
)
|
)
|
||||||
|
@@ -135,120 +135,103 @@ func GetGiteeUserInfo(token *Token) (map[string]interface{}, error) {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Router /controller/oauth/gitee/callback [get]
|
// @Router /controller/oauth/gitee/callback [get]
|
||||||
func (OAuthController) GiteeCallback(c *gin.Context) {
|
func (OAuthController) GiteeCallback(c *gin.Context) {
|
||||||
var err error
|
|
||||||
// 获取 code
|
// 获取 code
|
||||||
var code = c.Query("code")
|
code := c.Query("code")
|
||||||
if code == "" {
|
if code == "" {
|
||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步获取 token
|
// 获取 token
|
||||||
var tokenChan = make(chan *Token)
|
tokenAuthUrl := GetGiteeTokenAuthUrl(code)
|
||||||
var errChan = make(chan error)
|
token, err := GetGiteeToken(tokenAuthUrl)
|
||||||
go func() {
|
if err != nil {
|
||||||
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:
|
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
case userInfo := <-userInfoChan:
|
}
|
||||||
userInfoBytes, err := json.Marshal(userInfo)
|
if token == nil {
|
||||||
if err != nil {
|
global.LOG.Error(errors.New("failed to get token"))
|
||||||
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)
|
|
||||||
}
|
|
||||||
return
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -141,124 +141,111 @@ func GetUserInfo(token *Token) (map[string]interface{}, error) {
|
|||||||
// @Success 200 {string} string "登录成功"
|
// @Success 200 {string} string "登录成功"
|
||||||
// @Router /controller/oauth/github/callback [get]
|
// @Router /controller/oauth/github/callback [get]
|
||||||
func (OAuthController) Callback(c *gin.Context) {
|
func (OAuthController) Callback(c *gin.Context) {
|
||||||
var err error
|
|
||||||
// 获取 code
|
// 获取 code
|
||||||
var code = c.Query("code")
|
code := c.Query("code")
|
||||||
if code == "" {
|
if code == "" {
|
||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用channel来接收异步操作的结果
|
// 获取 token
|
||||||
tokenChan := make(chan *Token)
|
tokenAuthUrl := GetTokenAuthUrl(code)
|
||||||
userInfoChan := make(chan map[string]interface{})
|
token, err := GetToken(tokenAuthUrl)
|
||||||
errChan := make(chan error)
|
if err != nil {
|
||||||
|
|
||||||
// 异步获取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:
|
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
case userInfo := <-userInfoChan:
|
}
|
||||||
if userInfo == nil {
|
if token == nil {
|
||||||
global.LOG.Error(<-errChan)
|
global.LOG.Error(errors.New("failed to get token"))
|
||||||
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)
|
|
||||||
}
|
|
||||||
return
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@ import (
|
|||||||
"schisandra-cloud-album/global"
|
"schisandra-cloud-album/global"
|
||||||
"schisandra-cloud-album/service/impl"
|
"schisandra-cloud-album/service/impl"
|
||||||
"schisandra-cloud-album/utils"
|
"schisandra-cloud-album/utils"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,12 +32,73 @@ var script = `
|
|||||||
`
|
`
|
||||||
|
|
||||||
func HandleLoginResponse(c *gin.Context, uid string) {
|
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
|
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 {
|
if err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
@@ -46,78 +108,3 @@ func HandleLoginResponse(c *gin.Context, uid string) {
|
|||||||
c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(formattedScript))
|
c.Data(http.StatusOK, "text/html; charset=utf-8", []byte(formattedScript))
|
||||||
return
|
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
|
|
||||||
}
|
|
||||||
|
@@ -166,72 +166,40 @@ func GetQQUserUserInfo(token *QQToken, openId string) (map[string]interface{}, e
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Router /controller/oauth/qq/callback [get]
|
// @Router /controller/oauth/qq/callback [get]
|
||||||
func (OAuthController) QQCallback(c *gin.Context) {
|
func (OAuthController) QQCallback(c *gin.Context) {
|
||||||
var err error
|
|
||||||
// 获取 code
|
// 获取 code
|
||||||
var code = c.Query("code")
|
code := c.Query("code")
|
||||||
if code == "" {
|
if code == "" {
|
||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通过 code, 获取 token
|
// 通过 code 获取 token
|
||||||
var tokenAuthUrl = GetQQTokenAuthUrl(code)
|
tokenAuthUrl := GetQQTokenAuthUrl(code)
|
||||||
tokenChan := make(chan *QQToken)
|
token, err := GetQQToken(tokenAuthUrl)
|
||||||
errChan := make(chan error)
|
if err != nil {
|
||||||
go func() {
|
global.LOG.Error(err)
|
||||||
token, err := GetQQToken(tokenAuthUrl)
|
return
|
||||||
if err != nil {
|
}
|
||||||
errChan <- err
|
if token == nil {
|
||||||
return
|
global.LOG.Error(errors.New("failed to get token"))
|
||||||
}
|
return
|
||||||
tokenChan <- token
|
}
|
||||||
}()
|
|
||||||
var token *QQToken
|
// 通过 token 获取 openid
|
||||||
select {
|
authQQme, err := GetQQUserOpenID(token)
|
||||||
case token = <-tokenChan:
|
if err != nil {
|
||||||
case err = <-errChan:
|
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通过 token,获取 openid
|
// 通过 token 和 openid 获取用户信息
|
||||||
openIDChan := make(chan *AuthQQme)
|
userInfo, err := GetQQUserUserInfo(token, authQQme.OpenID)
|
||||||
errChan = make(chan error)
|
if err != nil {
|
||||||
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:
|
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理用户信息
|
||||||
userInfoBytes, err := json.Marshal(userInfo)
|
userInfoBytes, err := json.Marshal(userInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
@@ -244,6 +212,7 @@ func (OAuthController) QQCallback(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查询用户社交信息
|
||||||
userSocial, err := userSocialService.QueryUserSocialByOpenIDService(authQQme.OpenID, enum.OAuthSourceQQ)
|
userSocial, err := userSocialService.QueryUserSocialByOpenIDService(authQQme.OpenID, enum.OAuthSourceQQ)
|
||||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
db := global.DB
|
db := global.DB
|
||||||
@@ -257,27 +226,29 @@ func (OAuthController) QQCallback(c *gin.Context) {
|
|||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// 第一次登录,创建用户
|
// 第一次登录,创建用户
|
||||||
uid := idgen.NextId()
|
uid := idgen.NextId()
|
||||||
uidStr := strconv.FormatInt(uid, 10)
|
uidStr := strconv.FormatInt(uid, 10)
|
||||||
user := model.ScaAuthUser{
|
user := model.ScaAuthUser{
|
||||||
UID: &uidStr,
|
UID: uidStr,
|
||||||
Username: &authQQme.OpenID,
|
Username: authQQme.OpenID,
|
||||||
Nickname: &qqUserInfo.Nickname,
|
Nickname: qqUserInfo.Nickname,
|
||||||
Avatar: &qqUserInfo.FigureurlQq1,
|
Avatar: qqUserInfo.FigureurlQq1,
|
||||||
Gender: &qqUserInfo.Gender,
|
Gender: qqUserInfo.Gender,
|
||||||
}
|
}
|
||||||
addUser, err := userService.AddUserService(user)
|
addUser, wrong := userService.AddUserService(user)
|
||||||
if err != nil {
|
if wrong != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(wrong)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
qq := enum.OAuthSourceQQ
|
qq := enum.OAuthSourceQQ
|
||||||
userSocial = model.ScaAuthUserSocial{
|
userSocial = model.ScaAuthUserSocial{
|
||||||
UserID: &uidStr,
|
UserID: uidStr,
|
||||||
OpenID: &authQQme.OpenID,
|
OpenID: authQQme.OpenID,
|
||||||
Source: &qq,
|
Source: qq,
|
||||||
}
|
}
|
||||||
err = userSocialService.AddUserSocialService(userSocial)
|
err = userSocialService.AddUserSocialService(userSocial)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -285,20 +256,22 @@ func (OAuthController) QQCallback(c *gin.Context) {
|
|||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = global.Casbin.AddRoleForUser(uidStr, enum.User)
|
_, err = global.Casbin.AddRoleForUser(uidStr, enum.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := tx.Commit().Error; err != nil {
|
|
||||||
|
if err = tx.Commit().Error; err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
HandleLoginResponse(c, *addUser.UID)
|
HandleLoginResponse(c, addUser.UID)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
HandleLoginResponse(c, *userSocial.UserID)
|
HandleLoginResponse(c, userSocial.UserID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,27 @@
|
|||||||
package oauth_controller
|
package oauth_controller
|
||||||
|
|
||||||
import "encoding/json"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// ResponseData 返回数据
|
// ResponseData 返回数据
|
||||||
type ResponseData struct {
|
type ResponseData struct {
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
RefreshToken string `json:"refresh_token"`
|
RefreshToken string `json:"refresh_token"`
|
||||||
ExpiresAt int64 `json:"expires_at"`
|
ExpiresAt int64 `json:"expires_at"`
|
||||||
UID *string `json:"uid"`
|
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) {
|
func (res ResponseData) MarshalBinary() ([]byte, error) {
|
||||||
|
@@ -169,6 +169,7 @@ func wechatLoginHandler(openId string, clientId string, c *gin.Context) bool {
|
|||||||
if openId == "" {
|
if openId == "" {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
authUserSocial, err := userSocialService.QueryUserSocialByOpenIDService(openId, enum.OAuthSourceWechat)
|
authUserSocial, err := userSocialService.QueryUserSocialByOpenIDService(openId, enum.OAuthSourceWechat)
|
||||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
tx := global.DB.Begin()
|
tx := global.DB.Begin()
|
||||||
@@ -180,107 +181,63 @@ func wechatLoginHandler(openId string, clientId string, c *gin.Context) bool {
|
|||||||
|
|
||||||
uid := idgen.NextId()
|
uid := idgen.NextId()
|
||||||
uidStr := strconv.FormatInt(uid, 10)
|
uidStr := strconv.FormatInt(uid, 10)
|
||||||
avatar, err := utils.GenerateAvatar(uidStr)
|
avatar := utils.GenerateAvatar(uidStr)
|
||||||
name := randomname.GenerateName()
|
name := randomname.GenerateName()
|
||||||
if err != nil {
|
|
||||||
global.LOG.Errorln(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
createUser := model.ScaAuthUser{
|
createUser := model.ScaAuthUser{
|
||||||
UID: &uidStr,
|
UID: uidStr,
|
||||||
Username: &openId,
|
Username: openId,
|
||||||
Avatar: &avatar,
|
Avatar: avatar,
|
||||||
Nickname: &name,
|
Nickname: name,
|
||||||
Gender: &enum.Male,
|
Gender: enum.Male,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步添加用户
|
// 添加用户
|
||||||
addUserChan := make(chan *model.ScaAuthUser, 1)
|
addUser, worn := userService.AddUserService(createUser)
|
||||||
errChan := make(chan error, 1)
|
if worn != nil {
|
||||||
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:
|
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(worn)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
wechat := enum.OAuthSourceWechat
|
wechat := enum.OAuthSourceWechat
|
||||||
userSocial := model.ScaAuthUserSocial{
|
userSocial := model.ScaAuthUserSocial{
|
||||||
UserID: &uidStr,
|
UserID: uidStr,
|
||||||
OpenID: &openId,
|
OpenID: openId,
|
||||||
Source: &wechat,
|
Source: wechat,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步添加用户社交信息
|
// 添加用户社交信息
|
||||||
wrongChan := make(chan error, 1)
|
if wrong := userSocialService.AddUserSocialService(userSocial); wrong != nil {
|
||||||
go func() {
|
tx.Rollback()
|
||||||
wrong := userSocialService.AddUserSocialService(userSocial)
|
global.LOG.Error(wrong)
|
||||||
wrongChan <- wrong
|
return false
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case wrong := <-wrongChan:
|
|
||||||
if wrong != nil {
|
|
||||||
tx.Rollback()
|
|
||||||
global.LOG.Error(wrong)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步添加角色
|
// 添加角色
|
||||||
roleErrChan := make(chan error, 1)
|
if _, err = global.Casbin.AddRoleForUser(uidStr, enum.User); err != nil {
|
||||||
go func() {
|
tx.Rollback()
|
||||||
_, err := global.Casbin.AddRoleForUser(uidStr, enum.User)
|
global.LOG.Error(err)
|
||||||
roleErrChan <- err
|
return false
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case err := <-roleErrChan:
|
|
||||||
if err != nil {
|
|
||||||
tx.Rollback()
|
|
||||||
global.LOG.Error(err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 异步处理用户登录
|
// 处理用户登录
|
||||||
resChan := make(chan bool, 1)
|
if res := handelUserLogin(addUser.UID, clientId, c); !res {
|
||||||
go func() {
|
tx.Rollback()
|
||||||
res := handelUserLogin(*addUser.UID, clientId, c)
|
return false
|
||||||
resChan <- res
|
|
||||||
}()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case res := <-resChan:
|
|
||||||
if !res {
|
|
||||||
tx.Rollback()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
res := handelUserLogin(*authUserSocial.UserID, clientId, c)
|
res := handelUserLogin(authUserSocial.UserID, clientId, c)
|
||||||
if !res {
|
return res
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handelUserLogin 处理用户登录
|
// handelUserLogin 处理用户登录
|
||||||
func handelUserLogin(userId string, clientId string, c *gin.Context) bool {
|
func handelUserLogin(userId string, clientId string, c *gin.Context) bool {
|
||||||
|
|
||||||
|
user := userService.QueryUserByUuidService(&userId)
|
||||||
resultChan := make(chan bool, 1)
|
resultChan := make(chan bool, 1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -295,6 +252,16 @@ func handelUserLogin(userId string, clientId string, c *gin.Context) bool {
|
|||||||
RefreshToken: refreshToken,
|
RefreshToken: refreshToken,
|
||||||
ExpiresAt: expiresAt,
|
ExpiresAt: expiresAt,
|
||||||
UID: &userId,
|
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()
|
fail := redis.Set(constant.UserLoginTokenRedisKey+userId, data, time.Hour*24*7).Err()
|
||||||
if fail != nil {
|
if fail != nil {
|
||||||
|
@@ -139,7 +139,7 @@ func (UserController) AccountLogin(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.Verify(*user.Password, password) {
|
if !utils.Verify(user.Password, password) {
|
||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "PasswordError"), c)
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "PasswordError"), c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -171,101 +171,66 @@ func (UserController) PhoneLogin(c *gin.Context) {
|
|||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "PhoneErrorFormat"), c)
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "PhoneErrorFormat"), c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 获取验证码
|
||||||
|
code := redis.Get(constant.UserLoginSmsRedisKey + phone).Val()
|
||||||
|
if code == "" {
|
||||||
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaExpired"), c)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
userChan := make(chan model.ScaAuthUser)
|
if captcha != code {
|
||||||
go func() {
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaError"), c)
|
||||||
user := userService.QueryUserByPhoneService(phone)
|
return
|
||||||
userChan <- user
|
}
|
||||||
|
tx := global.DB.Begin()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
// 查询用户
|
||||||
user := <-userChan
|
user := userService.QueryUserByPhoneService(phone)
|
||||||
close(userChan)
|
|
||||||
|
|
||||||
if user.ID == 0 {
|
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()
|
uid := idgen.NextId()
|
||||||
uidStr := strconv.FormatInt(uid, 10)
|
uidStr := strconv.FormatInt(uid, 10)
|
||||||
|
avatar := utils.GenerateAvatar(uidStr)
|
||||||
avatar, err := utils.GenerateAvatar(uidStr)
|
|
||||||
if err != nil {
|
|
||||||
global.LOG.Errorln(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
name := randomname.GenerateName()
|
name := randomname.GenerateName()
|
||||||
createUser := model.ScaAuthUser{
|
createUser := model.ScaAuthUser{
|
||||||
UID: &uidStr,
|
UID: uidStr,
|
||||||
Phone: &phone,
|
Phone: phone,
|
||||||
Avatar: &avatar,
|
Avatar: avatar,
|
||||||
Nickname: &name,
|
Nickname: name,
|
||||||
Gender: &enum.Male,
|
Gender: enum.Male,
|
||||||
}
|
}
|
||||||
|
|
||||||
errChan := make(chan error)
|
addUser, w := userService.AddUserService(createUser)
|
||||||
go func() {
|
if w != nil {
|
||||||
err = global.DB.Transaction(func(tx *gorm.DB) error {
|
tx.Rollback()
|
||||||
addUser, w := userService.AddUserService(createUser)
|
return
|
||||||
if w != nil {
|
}
|
||||||
return w
|
_, err = global.Casbin.AddRoleForUser(uidStr, enum.User)
|
||||||
}
|
|
||||||
_, 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)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "RegisterUserError"), c)
|
tx.Rollback()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
data, res := userService.HandelUserLogin(*addUser, autoLogin, c)
|
||||||
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)
|
|
||||||
if !res {
|
if !res {
|
||||||
|
tx.Rollback()
|
||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||||
return
|
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)
|
result.OkWithData(data, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,7 +325,7 @@ func (UserController) ResetPassword(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := userService.UpdateUserService(phone, encrypt); err != nil {
|
if err = userService.UpdateUserService(phone, encrypt); err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ResetPasswordError"), c)
|
result.FailWithMessage(ginI18n.MustGetMessage(c, "ResetPasswordError"), c)
|
||||||
return
|
return
|
||||||
@@ -430,36 +395,44 @@ func (UserController) GetUserLoginDevice(c *gin.Context) {
|
|||||||
platform := ua.Platform()
|
platform := ua.Platform()
|
||||||
engine, engineVersion := ua.Engine()
|
engine, engineVersion := ua.Engine()
|
||||||
device := model.ScaAuthUserDevice{
|
device := model.ScaAuthUserDevice{
|
||||||
UserID: &userId,
|
UserID: userId,
|
||||||
IP: &ip,
|
IP: ip,
|
||||||
Location: &location,
|
Location: location,
|
||||||
Agent: userAgent,
|
Agent: userAgent,
|
||||||
Browser: &browser,
|
Browser: browser,
|
||||||
BrowserVersion: &browserVersion,
|
BrowserVersion: browserVersion,
|
||||||
OperatingSystem: &os,
|
OperatingSystem: os,
|
||||||
Mobile: &mobile,
|
Mobile: mobile,
|
||||||
Bot: &isBot,
|
Bot: isBot,
|
||||||
Mozilla: &mozilla,
|
Mozilla: mozilla,
|
||||||
Platform: &platform,
|
Platform: platform,
|
||||||
EngineName: &engine,
|
EngineName: engine,
|
||||||
EngineVersion: &engineVersion,
|
EngineVersion: engineVersion,
|
||||||
}
|
}
|
||||||
mu.Lock()
|
tx := global.DB.Begin()
|
||||||
defer mu.Unlock()
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
}()
|
||||||
userDevice, err := userDeviceService.GetUserDeviceByUIDIPAgentService(userId, ip, userAgent)
|
userDevice, err := userDeviceService.GetUserDeviceByUIDIPAgentService(userId, ip, userAgent)
|
||||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
err = userDeviceService.AddUserDeviceService(&device)
|
err = userDeviceService.AddUserDeviceService(&device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
global.LOG.Errorln(err)
|
global.LOG.Errorln(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
tx.Commit()
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
err := userDeviceService.UpdateUserDeviceService(userDevice.ID, &device)
|
err = userDeviceService.UpdateUserDeviceService(userDevice.ID, &device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
global.LOG.Errorln(err)
|
global.LOG.Errorln(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
tx.Commit()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -59,13 +59,13 @@ func (UserDaoImpl) AddUser(user model.ScaAuthUser) (*model.ScaAuthUser, error) {
|
|||||||
|
|
||||||
// UpdateUser 更新用户
|
// UpdateUser 更新用户
|
||||||
func (UserDaoImpl) UpdateUser(phone string, password string) error {
|
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 删除用户
|
// DeleteUser 删除用户
|
||||||
func (UserDaoImpl) DeleteUser(uuid string) error {
|
func (UserDaoImpl) DeleteUser(uuid string) error {
|
||||||
authUser := model.ScaAuthUser{}
|
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 根据手机号查询用户
|
// QueryUserByPhone 根据手机号查询用户
|
||||||
|
@@ -10,21 +10,21 @@ const TableNameScaAuthPermission = "sca_auth_permission"
|
|||||||
// ScaAuthPermission 权限表
|
// ScaAuthPermission 权限表
|
||||||
type ScaAuthPermission struct {
|
type ScaAuthPermission struct {
|
||||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID
|
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"` // 权限名称
|
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
|
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其他
|
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"` // 路径
|
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 停用
|
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"` // 请求方式
|
Method string `gorm:"column:method;type:varchar(20);comment:请求方式" json:"method"` // 请求方式
|
||||||
Icon *string `gorm:"column:icon;type:varchar(128);comment:图标" json:"icon"` // 图标
|
Icon string `gorm:"column:icon;type:varchar(128);comment:图标" json:"icon"` // 图标
|
||||||
PermissionKey *string `gorm:"column:permission_key;type:varchar(64);comment:权限关键字" json:"permission_key"` // 权限关键字
|
PermissionKey string `gorm:"column:permission_key;type:varchar(64);comment:权限关键字" json:"permission_key"` // 权限关键字
|
||||||
Order *int64 `gorm:"column:order;type:int(11);comment:排序" json:"order"` // 排序
|
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"` // 创建时间
|
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"` // 更新时间
|
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"` // 是否删除
|
Deleted int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除
|
||||||
Remark *string `gorm:"column:remark;type:varchar(255);comment:备注 描述" json:"remark"` // 备注 描述
|
Remark string `gorm:"column:remark;type:varchar(255);comment:备注 描述" json:"remark"` // 备注 描述
|
||||||
CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人
|
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"`
|
UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName ScaAuthPermission's table name
|
// TableName ScaAuthPermission's table name
|
||||||
|
@@ -14,9 +14,9 @@ type ScaAuthRole struct {
|
|||||||
RoleKey string `gorm:"column:role_key;type:varchar(64);not null;comment:角色关键字" json:"role_key"` // 角色关键字
|
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"` // 创建时间
|
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"` // 更新时间
|
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已删除
|
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"` // 创建人
|
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"`
|
UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName ScaAuthRole's table name
|
// TableName ScaAuthRole's table name
|
||||||
|
@@ -10,24 +10,24 @@ const TableNameScaAuthUser = "sca_auth_user"
|
|||||||
// ScaAuthUser 用户表
|
// ScaAuthUser 用户表
|
||||||
type ScaAuthUser struct {
|
type ScaAuthUser struct {
|
||||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;autoIncrement:true;comment:自增ID" json:"-"` // 自增ID
|
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
|
UID string `gorm:"column:uid;type:varchar(20);comment:唯一ID" json:"uid"` // 唯一ID
|
||||||
Username *string `gorm:"column:username;type:varchar(32);comment:用户名" json:"username"` // 用户名
|
Username string `gorm:"column:username;type:varchar(32);comment:用户名" json:"username"` // 用户名
|
||||||
Nickname *string `gorm:"column:nickname;type:varchar(32);comment:昵称" json:"nickname"` // 昵称
|
Nickname string `gorm:"column:nickname;type:varchar(32);comment:昵称" json:"nickname"` // 昵称
|
||||||
Email *string `gorm:"column:email;type:varchar(32);comment:邮箱" json:"email"` // 邮箱
|
Email string `gorm:"column:email;type:varchar(32);comment:邮箱" json:"email"` // 邮箱
|
||||||
Phone *string `gorm:"column:phone;type:varchar(32);comment:电话" json:"phone"` // 电话
|
Phone string `gorm:"column:phone;type:varchar(32);comment:电话" json:"phone"` // 电话
|
||||||
Password *string `gorm:"column:password;type:varchar(64);comment:密码" json:"-"` // 密码
|
Password string `gorm:"column:password;type:varchar(64);comment:密码" json:"-"` // 密码
|
||||||
Gender *string `gorm:"column:gender;type:varchar(32);comment:性别" json:"gender"` // 性别
|
Gender string `gorm:"column:gender;type:varchar(32);comment:性别" json:"gender"` // 性别
|
||||||
Avatar *string `gorm:"column:avatar;type:longtext;comment:头像" json:"avatar"` // 头像
|
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 封禁
|
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"` // 介绍
|
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"` // 创建时间
|
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"` // 更新时间
|
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 已删除
|
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"` // 博客
|
Blog string `gorm:"column:blog;type:varchar(30);comment:博客" json:"blog"` // 博客
|
||||||
Location *string `gorm:"column:location;type:varchar(50);comment:地址" json:"location"` // 地址
|
Location string `gorm:"column:location;type:varchar(50);comment:地址" json:"location"` // 地址
|
||||||
Company *string `gorm:"column:company;type:varchar(50);comment:公司" json:"company"` // 公司
|
Company string `gorm:"column:company;type:varchar(50);comment:公司" json:"company"` // 公司
|
||||||
CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人
|
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"` // 更新人
|
UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName ScaAuthUser's table name
|
// TableName ScaAuthUser's table name
|
||||||
|
@@ -9,24 +9,24 @@ const TableNameScaAuthUserDevice = "sca_auth_user_device"
|
|||||||
// ScaAuthUserDevice 用户设备信息
|
// ScaAuthUserDevice 用户设备信息
|
||||||
type ScaAuthUserDevice struct {
|
type ScaAuthUserDevice struct {
|
||||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID
|
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
|
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
|
IP string `gorm:"column:ip;type:varchar(20);comment:登录IP" json:"ip"` // 登录IP
|
||||||
Location *string `gorm:"column:location;type:varchar(20);comment:地址" json:"location"` // 地址
|
Location string `gorm:"column:location;type:varchar(20);comment:地址" json:"location"` // 地址
|
||||||
Agent string `gorm:"column:agent;type:varchar(255);comment:设备信息" json:"agent"` // 设备信息
|
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"` // 创建时间
|
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"` // 更新时间
|
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"` // 是否删除
|
Deleted int64 `gorm:"column:deleted;type:int(11);default:0;comment:是否删除" json:"deleted"` // 是否删除
|
||||||
Browser *string `gorm:"column:browser;type:varchar(20);comment:浏览器" json:"browser"` // 浏览器
|
Browser string `gorm:"column:browser;type:varchar(20);comment:浏览器" json:"browser"` // 浏览器
|
||||||
OperatingSystem *string `gorm:"column:operating_system;type:varchar(20);comment:操作系统" json:"operating_system"` // 操作系统
|
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"` // 浏览器版本
|
BrowserVersion string `gorm:"column:browser_version;type:varchar(20);comment:浏览器版本" json:"browser_version"` // 浏览器版本
|
||||||
Mobile *bool `gorm:"column:mobile;type:int(11);comment:是否为手机" json:"mobile"` // 是否为手机
|
Mobile bool `gorm:"column:mobile;type:int(11);comment:是否为手机" json:"mobile"` // 是否为手机
|
||||||
Bot *bool `gorm:"column:bot;type:int(11);comment:是否为机器人" json:"bot"` // 是否为机器人
|
Bot bool `gorm:"column:bot;type:int(11);comment:是否为机器人" json:"bot"` // 是否为机器人
|
||||||
Mozilla *string `gorm:"column:mozilla;type:varchar(10);comment:火狐版本" json:"mozilla"` // 火狐版本
|
Mozilla string `gorm:"column:mozilla;type:varchar(10);comment:火狐版本" json:"mozilla"` // 火狐版本
|
||||||
Platform *string `gorm:"column:platform;type:varchar(20);comment:平台" json:"platform"` // 平台
|
Platform string `gorm:"column:platform;type:varchar(20);comment:平台" json:"platform"` // 平台
|
||||||
EngineName *string `gorm:"column:engine_name;type:varchar(20);comment:引擎名称" json:"engine_name"` // 引擎名称
|
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"` // 引擎版本
|
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"` // 创建人
|
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"`
|
UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName ScaAuthUserDevice's table name
|
// TableName ScaAuthUserDevice's table name
|
||||||
|
@@ -9,15 +9,15 @@ const TableNameScaAuthUserSocial = "sca_auth_user_social"
|
|||||||
// ScaAuthUserSocial 社会用户信息表
|
// ScaAuthUserSocial 社会用户信息表
|
||||||
type ScaAuthUserSocial struct {
|
type ScaAuthUserSocial struct {
|
||||||
ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID
|
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
|
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"` // 第三方用户来源
|
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
|
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 封禁
|
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"` // 创建时间
|
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"` // 更新时间
|
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"` // 是否删除
|
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"` // 创建人
|
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"`
|
UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TableName ScaAuthUserSocial's table name
|
// TableName ScaAuthUserSocial's table name
|
||||||
|
@@ -200,8 +200,8 @@ func (CommentReplyServiceImpl) GetCommentReplyListService(uid string, topicId st
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, userInfo := range userInfos {
|
for _, userInfo := range userInfos {
|
||||||
userInfoMap[*userInfo.UID] = *userInfo
|
userInfoMap[userInfo.UID] = *userInfo
|
||||||
redis.Set(constant.CommentUserListRedisKey+*userInfo.UID, userInfo, 24*time.Hour)
|
redis.Set(constant.CommentUserListRedisKey+userInfo.UID, userInfo, 24*time.Hour)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -279,13 +279,13 @@ func (CommentReplyServiceImpl) GetCommentReplyListService(uid string, topicId st
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
commentContent := CommentContent{
|
commentContent := CommentContent{
|
||||||
Avatar: *userInfo.Avatar,
|
Avatar: userInfo.Avatar,
|
||||||
NickName: *userInfo.Nickname,
|
NickName: userInfo.Nickname,
|
||||||
Id: reply.Id,
|
Id: reply.Id,
|
||||||
UserId: reply.UserId,
|
UserId: reply.UserId,
|
||||||
TopicId: reply.TopicId,
|
TopicId: reply.TopicId,
|
||||||
Content: reply.Content,
|
Content: reply.Content,
|
||||||
ReplyUsername: *replyUserInfo.Nickname,
|
ReplyUsername: replyUserInfo.Nickname,
|
||||||
ReplyCount: reply.ReplyCount,
|
ReplyCount: reply.ReplyCount,
|
||||||
Likes: reply.Likes,
|
Likes: reply.Likes,
|
||||||
CreatedTime: reply.CreatedTime,
|
CreatedTime: reply.CreatedTime,
|
||||||
@@ -385,8 +385,8 @@ func (CommentReplyServiceImpl) GetCommentListService(uid string, topicId string,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, userInfo := range userInfos {
|
for _, userInfo := range userInfos {
|
||||||
userInfoMap[*userInfo.UID] = *userInfo
|
userInfoMap[userInfo.UID] = *userInfo
|
||||||
redis.Set(constant.CommentUserListRedisKey+*userInfo.UID, userInfo, 24*time.Hour)
|
redis.Set(constant.CommentUserListRedisKey+userInfo.UID, userInfo, 24*time.Hour)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -473,8 +473,8 @@ func (CommentReplyServiceImpl) GetCommentListService(uid string, topicId string,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
commentContent := CommentContent{
|
commentContent := CommentContent{
|
||||||
Avatar: *userInfo.Avatar,
|
Avatar: userInfo.Avatar,
|
||||||
NickName: *userInfo.Nickname,
|
NickName: userInfo.Nickname,
|
||||||
Id: comment.Id,
|
Id: comment.Id,
|
||||||
UserId: comment.UserId,
|
UserId: comment.UserId,
|
||||||
TopicId: comment.TopicId,
|
TopicId: comment.TopicId,
|
||||||
|
@@ -25,10 +25,21 @@ var mu = &sync.Mutex{}
|
|||||||
|
|
||||||
// ResponseData 返回数据
|
// ResponseData 返回数据
|
||||||
type ResponseData struct {
|
type ResponseData struct {
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
RefreshToken string `json:"refresh_token"`
|
RefreshToken string `json:"refresh_token"`
|
||||||
ExpiresAt int64 `json:"expires_at"`
|
ExpiresAt int64 `json:"expires_at"`
|
||||||
UID *string `json:"uid"`
|
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) {
|
func (res ResponseData) MarshalBinary() ([]byte, error) {
|
||||||
@@ -115,13 +126,13 @@ func (UserServiceImpl) RefreshTokenService(refreshToken string) (*ResponseData,
|
|||||||
// HandelUserLogin 处理用户登录
|
// HandelUserLogin 处理用户登录
|
||||||
func (UserServiceImpl) HandelUserLogin(user model.ScaAuthUser, autoLogin bool, c *gin.Context) (*ResponseData, bool) {
|
func (UserServiceImpl) HandelUserLogin(user model.ScaAuthUser, autoLogin bool, c *gin.Context) (*ResponseData, bool) {
|
||||||
// 检查 user.UID 是否为 nil
|
// 检查 user.UID 是否为 nil
|
||||||
if user.UID == nil {
|
if user.UID == "" {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
if !GetUserLoginDevice(user, c) {
|
if !GetUserLoginDevice(user, c) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
accessToken, err := utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: user.UID})
|
accessToken, err := utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: &user.UID})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
@@ -132,15 +143,25 @@ func (UserServiceImpl) HandelUserLogin(user model.ScaAuthUser, autoLogin bool, c
|
|||||||
days = time.Minute * 30
|
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{
|
data := ResponseData{
|
||||||
AccessToken: accessToken,
|
AccessToken: accessToken,
|
||||||
RefreshToken: refreshToken,
|
RefreshToken: refreshToken,
|
||||||
ExpiresAt: expiresAt,
|
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 {
|
if err != nil {
|
||||||
return nil, false
|
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 {
|
func GetUserLoginDevice(user model.ScaAuthUser, c *gin.Context) bool {
|
||||||
|
|
||||||
// 检查user.UID是否为空
|
// 检查user.UID是否为空
|
||||||
if user.UID == nil {
|
if user.UID == "" {
|
||||||
global.LOG.Errorln("user.UID is nil")
|
global.LOG.Errorln("user.UID is nil")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -185,24 +206,24 @@ func GetUserLoginDevice(user model.ScaAuthUser, c *gin.Context) bool {
|
|||||||
|
|
||||||
device := model.ScaAuthUserDevice{
|
device := model.ScaAuthUserDevice{
|
||||||
UserID: user.UID,
|
UserID: user.UID,
|
||||||
IP: &ip,
|
IP: ip,
|
||||||
Location: &location,
|
Location: location,
|
||||||
Agent: userAgent,
|
Agent: userAgent,
|
||||||
Browser: &browser,
|
Browser: browser,
|
||||||
BrowserVersion: &browserVersion,
|
BrowserVersion: browserVersion,
|
||||||
OperatingSystem: &os,
|
OperatingSystem: os,
|
||||||
Mobile: &mobile,
|
Mobile: mobile,
|
||||||
Bot: &isBot,
|
Bot: isBot,
|
||||||
Mozilla: &mozilla,
|
Mozilla: mozilla,
|
||||||
Platform: &platform,
|
Platform: platform,
|
||||||
EngineName: &engine,
|
EngineName: engine,
|
||||||
EngineVersion: &engineVersion,
|
EngineVersion: engineVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
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) {
|
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
err = userDeviceDao.AddUserDevice(&device)
|
err = userDeviceDao.AddUserDevice(&device)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -14,41 +11,41 @@ var client = &http.Client{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenerateAvatar 用于生成用户头像
|
// GenerateAvatar 用于生成用户头像
|
||||||
func GenerateAvatar(userId string) (baseImg string, err error) {
|
func GenerateAvatar(userId string) (baseImg string) {
|
||||||
|
|
||||||
path := "https://api.multiavatar.com/" + userId + ".png"
|
path := "https://api.multiavatar.com/" + userId + ".png"
|
||||||
|
|
||||||
// 创建请求
|
//// 创建请求
|
||||||
request, err := http.NewRequest("GET", path, nil)
|
//request, err := http.NewRequest("GET", path, nil)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return "", errors.New("image request error")
|
// return "", errors.New("image request error")
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// 发送请求并获取响应
|
//// 发送请求并获取响应
|
||||||
respImg, err := client.Do(request)
|
//respImg, err := client.Do(request)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return "", errors.New("failed to fetch image")
|
// return "", errors.New("failed to fetch image")
|
||||||
}
|
//}
|
||||||
defer func(Body io.ReadCloser) {
|
//defer func(Body io.ReadCloser) {
|
||||||
err := Body.Close()
|
// err := Body.Close()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
}(respImg.Body)
|
//}(respImg.Body)
|
||||||
|
//
|
||||||
// 读取图片数据
|
//// 读取图片数据
|
||||||
imgByte, err := io.ReadAll(respImg.Body)
|
//imgByte, err := io.ReadAll(respImg.Body)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return "", errors.New("failed to read image data")
|
// return "", errors.New("failed to read image data")
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// 判断文件类型,生成一个前缀
|
//// 判断文件类型,生成一个前缀
|
||||||
mimeType := http.DetectContentType(imgByte)
|
//mimeType := http.DetectContentType(imgByte)
|
||||||
switch mimeType {
|
//switch mimeType {
|
||||||
case "image/png":
|
//case "image/png":
|
||||||
baseImg = "data:image/png;base64," + base64.StdEncoding.EncodeToString(imgByte)
|
// baseImg = "data:image/png;base64," + base64.StdEncoding.EncodeToString(imgByte)
|
||||||
default:
|
//default:
|
||||||
return "", errors.New("unsupported image type")
|
// return "", errors.New("unsupported image type")
|
||||||
}
|
//}
|
||||||
return baseImg, nil
|
return path
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user