🎨 update / add nsq
This commit is contained in:
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/wenlng/go-captcha/v2/rotate"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
"log"
|
||||
"schisandra-cloud-album/api/captcha_api/dto"
|
||||
"schisandra-cloud-album/common/constant"
|
||||
"schisandra-cloud-album/common/redis"
|
||||
"schisandra-cloud-album/common/result"
|
||||
@@ -72,7 +71,7 @@ func (CaptchaAPI) GenerateRotateCaptcha(c *gin.Context) {
|
||||
// @Success 200 {string} json
|
||||
// @Router /api/captcha/rotate/check [post]
|
||||
func (CaptchaAPI) CheckRotateData(c *gin.Context) {
|
||||
var rotateRequest dto.RotateCaptchaRequest
|
||||
var rotateRequest RotateCaptchaRequest
|
||||
if err := c.ShouldBindJSON(&rotateRequest); err != nil {
|
||||
result.FailWithNull(c)
|
||||
return
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package dto
|
||||
package captcha_api
|
||||
|
||||
type RotateCaptchaRequest struct {
|
||||
Angle int `json:"angle" binding:"required"`
|
@@ -1,16 +1,7 @@
|
||||
package comment_api
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"github.com/acmestack/gorm-plus/gplus"
|
||||
"io"
|
||||
"regexp"
|
||||
"schisandra-cloud-album/api/comment_api/dto"
|
||||
"schisandra-cloud-album/global"
|
||||
"schisandra-cloud-album/model"
|
||||
"schisandra-cloud-album/service"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@@ -61,166 +52,3 @@ type CommentResponse struct {
|
||||
Current int `json:"current"`
|
||||
Comments []CommentContent `json:"comments"`
|
||||
}
|
||||
|
||||
// base64ToBytes 将base64字符串转换为字节数组
|
||||
func base64ToBytes(base64Str string) ([]byte, error) {
|
||||
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64Str))
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to decode base64 string")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// processImages 处理图片,将 base64 字符串转换为字节数组
|
||||
func processImages(images []string) ([][]byte, error) {
|
||||
var imagesData [][]byte
|
||||
dataChan := make(chan []byte, len(images)) // 创建一个带缓冲的 channel
|
||||
re := regexp.MustCompile(`^data:image/\w+;base64,`)
|
||||
|
||||
for _, img := range images {
|
||||
wg.Add(1) // 增加 WaitGroup 的计数
|
||||
go func(img string) {
|
||||
defer wg.Done() // 函数结束时减少计数
|
||||
|
||||
imgWithoutPrefix := re.ReplaceAllString(img, "")
|
||||
data, err := base64ToBytes(imgWithoutPrefix)
|
||||
if err != nil {
|
||||
return // 出错时直接返回
|
||||
}
|
||||
dataChan <- data // 将结果发送到 channel
|
||||
}(img)
|
||||
}
|
||||
|
||||
wg.Wait() // 等待所有 goroutine 完成
|
||||
close(dataChan) // 关闭 channel
|
||||
|
||||
for data := range dataChan { // 收集所有结果
|
||||
imagesData = append(imagesData, data)
|
||||
}
|
||||
|
||||
return imagesData, nil
|
||||
}
|
||||
|
||||
// getMimeType 获取 MIME 类型
|
||||
func getMimeType(data []byte) string {
|
||||
if len(data) < 4 {
|
||||
return "application/octet-stream" // 默认类型
|
||||
}
|
||||
|
||||
// 判断 JPEG
|
||||
if data[0] == 0xFF && data[1] == 0xD8 {
|
||||
return "image/jpeg"
|
||||
}
|
||||
|
||||
// 判断 PNG
|
||||
if len(data) >= 8 && data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47 &&
|
||||
data[4] == 0x0D && data[5] == 0x0A && data[6] == 0x1A && data[7] == 0x0A {
|
||||
return "image/png"
|
||||
}
|
||||
|
||||
// 判断 GIF
|
||||
if len(data) >= 6 && data[0] == 'G' && data[1] == 'I' && data[2] == 'F' {
|
||||
return "image/gif"
|
||||
}
|
||||
// 判断 WEBP
|
||||
if len(data) >= 12 && data[0] == 0x52 && data[1] == 0x49 && data[2] == 0x46 && data[3] == 0x46 &&
|
||||
data[8] == 0x57 && data[9] == 0x45 && data[10] == 0x42 && data[11] == 0x50 {
|
||||
return "image/webp"
|
||||
}
|
||||
// 判断svg
|
||||
if len(data) >= 4 && data[0] == '<' && data[1] == '?' && data[2] == 'x' && data[3] == 'm' {
|
||||
return "image/svg+xml"
|
||||
}
|
||||
// 判断JPG
|
||||
if len(data) >= 3 && data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF {
|
||||
return "image/jpeg"
|
||||
}
|
||||
|
||||
return "application/octet-stream" // 默认类型
|
||||
}
|
||||
|
||||
// 点赞
|
||||
var likeChannel = make(chan dto.CommentLikeRequest, 100)
|
||||
var cancelLikeChannel = make(chan dto.CommentLikeRequest, 100) // 取消点赞
|
||||
|
||||
func init() {
|
||||
go likeConsumer() // 启动消费者
|
||||
go cancelLikeConsumer() // 启动消费者
|
||||
}
|
||||
func likeConsumer() {
|
||||
for likeRequest := range likeChannel {
|
||||
processLike(likeRequest) // 处理点赞
|
||||
}
|
||||
}
|
||||
func cancelLikeConsumer() {
|
||||
for cancelLikeRequest := range cancelLikeChannel {
|
||||
processCancelLike(cancelLikeRequest) // 处理取消点赞
|
||||
}
|
||||
}
|
||||
|
||||
func processLike(likeRequest dto.CommentLikeRequest) {
|
||||
mx.Lock()
|
||||
defer mx.Unlock()
|
||||
|
||||
likes := model.ScaCommentLikes{
|
||||
CommentId: likeRequest.CommentId,
|
||||
UserId: likeRequest.UserID,
|
||||
TopicId: likeRequest.TopicId,
|
||||
}
|
||||
|
||||
tx := global.DB.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
res := global.DB.Create(&likes) // 假设这是插入数据库的方法
|
||||
if res.Error != nil {
|
||||
tx.Rollback()
|
||||
global.LOG.Errorln(res.Error)
|
||||
return
|
||||
}
|
||||
|
||||
// 异步更新点赞计数
|
||||
go func() {
|
||||
if err := commentReplyService.UpdateCommentLikesCount(likeRequest.CommentId, likeRequest.TopicId); err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
}
|
||||
}()
|
||||
|
||||
tx.Commit()
|
||||
}
|
||||
func processCancelLike(cancelLikeRequest dto.CommentLikeRequest) {
|
||||
mx.Lock()
|
||||
defer mx.Unlock()
|
||||
|
||||
tx := global.DB.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
query, u := gplus.NewQuery[model.ScaCommentLikes]()
|
||||
query.Eq(&u.CommentId, cancelLikeRequest.CommentId).
|
||||
Eq(&u.UserId, cancelLikeRequest.UserID).
|
||||
Eq(&u.TopicId, cancelLikeRequest.TopicId)
|
||||
|
||||
res := gplus.Delete[model.ScaCommentLikes](query)
|
||||
if res.Error != nil {
|
||||
tx.Rollback()
|
||||
return // 返回错误而非打印
|
||||
}
|
||||
|
||||
// 异步更新点赞计数
|
||||
go func() {
|
||||
if err := commentReplyService.DecrementCommentLikesCount(cancelLikeRequest.CommentId, cancelLikeRequest.TopicId); err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
}
|
||||
}()
|
||||
|
||||
tx.Commit()
|
||||
return
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/mssola/useragent"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"schisandra-cloud-album/api/comment_api/dto"
|
||||
"schisandra-cloud-album/common/enum"
|
||||
"schisandra-cloud-album/common/result"
|
||||
"schisandra-cloud-album/global"
|
||||
@@ -25,10 +24,10 @@ import (
|
||||
// @Tags 评论
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param comment_request body dto.CommentRequest true "评论请求"
|
||||
// @Param comment_request body CommentRequest true "评论请求"
|
||||
// @Router /auth/comment/submit [post]
|
||||
func (CommentAPI) CommentSubmit(c *gin.Context) {
|
||||
commentRequest := dto.CommentRequest{}
|
||||
commentRequest := CommentRequest{}
|
||||
if err := c.ShouldBindJSON(&commentRequest); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -146,10 +145,10 @@ func (CommentAPI) CommentSubmit(c *gin.Context) {
|
||||
// @Tags 评论
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param reply_comment_request body dto.ReplyCommentRequest true "回复评论请求"
|
||||
// @Param reply_comment_request body ReplyCommentRequest true "回复评论请求"
|
||||
// @Router /auth/reply/submit [post]
|
||||
func (CommentAPI) ReplySubmit(c *gin.Context) {
|
||||
replyCommentRequest := dto.ReplyCommentRequest{}
|
||||
replyCommentRequest := ReplyCommentRequest{}
|
||||
if err := c.ShouldBindJSON(&replyCommentRequest); err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
@@ -273,10 +272,10 @@ func (CommentAPI) ReplySubmit(c *gin.Context) {
|
||||
// @Tags 评论
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param reply_reply_request body dto.ReplyReplyRequest true "回复回复请求"
|
||||
// @Param reply_reply_request body ReplyReplyRequest true "回复回复请求"
|
||||
// @Router /auth/reply/reply/submit [post]
|
||||
func (CommentAPI) ReplyReplySubmit(c *gin.Context) {
|
||||
replyReplyRequest := dto.ReplyReplyRequest{}
|
||||
replyReplyRequest := ReplyReplyRequest{}
|
||||
if err := c.ShouldBindJSON(&replyReplyRequest); err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
@@ -398,10 +397,10 @@ func (CommentAPI) ReplyReplySubmit(c *gin.Context) {
|
||||
// @Tags 评论
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param comment_list_request body dto.CommentListRequest true "评论列表请求"
|
||||
// @Param comment_list_request body CommentListRequest true "评论列表请求"
|
||||
// @Router /auth/comment/list [post]
|
||||
func (CommentAPI) CommentList(c *gin.Context) {
|
||||
commentListRequest := dto.CommentListRequest{}
|
||||
commentListRequest := CommentListRequest{}
|
||||
err := c.ShouldBindJSON(&commentListRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
@@ -573,10 +572,10 @@ func (CommentAPI) CommentList(c *gin.Context) {
|
||||
// @Tags 评论
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param reply_list_request body dto.ReplyListRequest true "回复列表请求"
|
||||
// @Param reply_list_request body ReplyListRequest true "回复列表请求"
|
||||
// @Router /auth/reply/list [post]
|
||||
func (CommentAPI) ReplyList(c *gin.Context) {
|
||||
replyListRequest := dto.ReplyListRequest{}
|
||||
replyListRequest := ReplyListRequest{}
|
||||
err := c.ShouldBindJSON(&replyListRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
@@ -754,10 +753,10 @@ func (CommentAPI) ReplyList(c *gin.Context) {
|
||||
// @Tags 评论
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param comment_like_request body dto.CommentLikeRequest true "点赞请求"
|
||||
// @Param comment_like_request body CommentLikeRequest true "点赞请求"
|
||||
// @Router /auth/comment/like [post]
|
||||
func (CommentAPI) CommentLikes(c *gin.Context) {
|
||||
likeRequest := dto.CommentLikeRequest{}
|
||||
likeRequest := CommentLikeRequest{}
|
||||
err := c.ShouldBindJSON(&likeRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
@@ -765,7 +764,7 @@ func (CommentAPI) CommentLikes(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 将点赞请求发送到 channel 中
|
||||
likeChannel <- dto.CommentLikeRequest{
|
||||
likeChannel <- CommentLikeRequest{
|
||||
CommentId: likeRequest.CommentId,
|
||||
UserID: likeRequest.UserID,
|
||||
TopicId: likeRequest.TopicId,
|
||||
@@ -780,16 +779,16 @@ func (CommentAPI) CommentLikes(c *gin.Context) {
|
||||
// @Tags 评论
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param comment_like_request body dto.CommentLikeRequest true "取消点赞请求"
|
||||
// @Param comment_like_request body CommentLikeRequest true "取消点赞请求"
|
||||
// @Router /auth/comment/cancel_like [post]
|
||||
func (CommentAPI) CancelCommentLikes(c *gin.Context) {
|
||||
likeRequest := dto.CommentLikeRequest{}
|
||||
likeRequest := CommentLikeRequest{}
|
||||
if err := c.ShouldBindJSON(&likeRequest); err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
}
|
||||
// 将取消点赞请求发送到 channel
|
||||
cancelLikeChannel <- dto.CommentLikeRequest{
|
||||
cancelLikeChannel <- CommentLikeRequest{
|
||||
CommentId: likeRequest.CommentId,
|
||||
UserID: likeRequest.UserID,
|
||||
TopicId: likeRequest.TopicId,
|
||||
|
175
api/comment_api/handler.go
Normal file
175
api/comment_api/handler.go
Normal file
@@ -0,0 +1,175 @@
|
||||
package comment_api
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"github.com/acmestack/gorm-plus/gplus"
|
||||
"io"
|
||||
"regexp"
|
||||
"schisandra-cloud-album/global"
|
||||
"schisandra-cloud-album/model"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// base64ToBytes 将base64字符串转换为字节数组
|
||||
func base64ToBytes(base64Str string) ([]byte, error) {
|
||||
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64Str))
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to decode base64 string")
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// processImages 处理图片,将 base64 字符串转换为字节数组
|
||||
func processImages(images []string) ([][]byte, error) {
|
||||
var imagesData [][]byte
|
||||
dataChan := make(chan []byte, len(images)) // 创建一个带缓冲的 channel
|
||||
re := regexp.MustCompile(`^data:image/\w+;base64,`)
|
||||
|
||||
for _, img := range images {
|
||||
wg.Add(1) // 增加 WaitGroup 的计数
|
||||
go func(img string) {
|
||||
defer wg.Done() // 函数结束时减少计数
|
||||
|
||||
imgWithoutPrefix := re.ReplaceAllString(img, "")
|
||||
data, err := base64ToBytes(imgWithoutPrefix)
|
||||
if err != nil {
|
||||
return // 出错时直接返回
|
||||
}
|
||||
dataChan <- data // 将结果发送到 channel
|
||||
}(img)
|
||||
}
|
||||
|
||||
wg.Wait() // 等待所有 goroutine 完成
|
||||
close(dataChan) // 关闭 channel
|
||||
|
||||
for data := range dataChan { // 收集所有结果
|
||||
imagesData = append(imagesData, data)
|
||||
}
|
||||
|
||||
return imagesData, nil
|
||||
}
|
||||
|
||||
// getMimeType 获取 MIME 类型
|
||||
func getMimeType(data []byte) string {
|
||||
if len(data) < 4 {
|
||||
return "application/octet-stream" // 默认类型
|
||||
}
|
||||
|
||||
// 判断 JPEG
|
||||
if data[0] == 0xFF && data[1] == 0xD8 {
|
||||
return "image/jpeg"
|
||||
}
|
||||
|
||||
// 判断 PNG
|
||||
if len(data) >= 8 && data[0] == 0x89 && data[1] == 0x50 && data[2] == 0x4E && data[3] == 0x47 &&
|
||||
data[4] == 0x0D && data[5] == 0x0A && data[6] == 0x1A && data[7] == 0x0A {
|
||||
return "image/png"
|
||||
}
|
||||
|
||||
// 判断 GIF
|
||||
if len(data) >= 6 && data[0] == 'G' && data[1] == 'I' && data[2] == 'F' {
|
||||
return "image/gif"
|
||||
}
|
||||
// 判断 WEBP
|
||||
if len(data) >= 12 && data[0] == 0x52 && data[1] == 0x49 && data[2] == 0x46 && data[3] == 0x46 &&
|
||||
data[8] == 0x57 && data[9] == 0x45 && data[10] == 0x42 && data[11] == 0x50 {
|
||||
return "image/webp"
|
||||
}
|
||||
// 判断svg
|
||||
if len(data) >= 4 && data[0] == '<' && data[1] == '?' && data[2] == 'x' && data[3] == 'm' {
|
||||
return "image/svg+xml"
|
||||
}
|
||||
// 判断JPG
|
||||
if len(data) >= 3 && data[0] == 0xFF && data[1] == 0xD8 && data[2] == 0xFF {
|
||||
return "image/jpeg"
|
||||
}
|
||||
|
||||
return "application/octet-stream" // 默认类型
|
||||
}
|
||||
|
||||
// 点赞
|
||||
var likeChannel = make(chan CommentLikeRequest, 100)
|
||||
var cancelLikeChannel = make(chan CommentLikeRequest, 100) // 取消点赞
|
||||
|
||||
func init() {
|
||||
go likeConsumer() // 启动消费者
|
||||
go cancelLikeConsumer() // 启动消费者
|
||||
}
|
||||
func likeConsumer() {
|
||||
for likeRequest := range likeChannel {
|
||||
processLike(likeRequest) // 处理点赞
|
||||
}
|
||||
}
|
||||
func cancelLikeConsumer() {
|
||||
for cancelLikeRequest := range cancelLikeChannel {
|
||||
processCancelLike(cancelLikeRequest) // 处理取消点赞
|
||||
}
|
||||
}
|
||||
|
||||
func processLike(likeRequest CommentLikeRequest) {
|
||||
mx.Lock()
|
||||
defer mx.Unlock()
|
||||
|
||||
likes := model.ScaCommentLikes{
|
||||
CommentId: likeRequest.CommentId,
|
||||
UserId: likeRequest.UserID,
|
||||
TopicId: likeRequest.TopicId,
|
||||
}
|
||||
|
||||
tx := global.DB.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
res := global.DB.Create(&likes) // 假设这是插入数据库的方法
|
||||
if res.Error != nil {
|
||||
tx.Rollback()
|
||||
global.LOG.Errorln(res.Error)
|
||||
return
|
||||
}
|
||||
|
||||
// 异步更新点赞计数
|
||||
go func() {
|
||||
if err := commentReplyService.UpdateCommentLikesCount(likeRequest.CommentId, likeRequest.TopicId); err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
}
|
||||
}()
|
||||
|
||||
tx.Commit()
|
||||
}
|
||||
func processCancelLike(cancelLikeRequest CommentLikeRequest) {
|
||||
mx.Lock()
|
||||
defer mx.Unlock()
|
||||
|
||||
tx := global.DB.Begin()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
}()
|
||||
|
||||
query, u := gplus.NewQuery[model.ScaCommentLikes]()
|
||||
query.Eq(&u.CommentId, cancelLikeRequest.CommentId).
|
||||
Eq(&u.UserId, cancelLikeRequest.UserID).
|
||||
Eq(&u.TopicId, cancelLikeRequest.TopicId)
|
||||
|
||||
res := gplus.Delete[model.ScaCommentLikes](query)
|
||||
if res.Error != nil {
|
||||
tx.Rollback()
|
||||
return // 返回错误而非打印
|
||||
}
|
||||
|
||||
// 异步更新点赞计数
|
||||
go func() {
|
||||
if err := commentReplyService.DecrementCommentLikesCount(cancelLikeRequest.CommentId, cancelLikeRequest.TopicId); err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
}
|
||||
}()
|
||||
|
||||
tx.Commit()
|
||||
return
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package dto
|
||||
package comment_api
|
||||
|
||||
type CommentRequest struct {
|
||||
Content string `json:"content" binding:"required"`
|
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/mssola/useragent"
|
||||
"gorm.io/gorm"
|
||||
"net/http"
|
||||
"schisandra-cloud-album/api/user_api/dto"
|
||||
"schisandra-cloud-album/common/constant"
|
||||
"schisandra-cloud-album/common/redis"
|
||||
"schisandra-cloud-album/common/result"
|
||||
@@ -95,13 +94,13 @@ func HandelUserLogin(userId string, c *gin.Context) (bool, result.Response) {
|
||||
case expiresAt = <-expiresAtChan:
|
||||
}
|
||||
|
||||
data := dto.ResponseData{
|
||||
data := ResponseData{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
ExpiresAt: expiresAt,
|
||||
UID: &userId,
|
||||
}
|
||||
wrong := utils.SetSession(c, "user", data)
|
||||
wrong := utils.SetSession(c, constant.SessionKey, data)
|
||||
if wrong != nil {
|
||||
return false, result.Response{}
|
||||
}
|
||||
|
19
api/oauth_api/request_param.go
Normal file
19
api/oauth_api/request_param.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package oauth_api
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// ResponseData 返回数据
|
||||
type ResponseData struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
ExpiresAt int64 `json:"expires_at"`
|
||||
UID *string `json:"uid"`
|
||||
}
|
||||
|
||||
func (res ResponseData) MarshalBinary() ([]byte, error) {
|
||||
return json.Marshal(res)
|
||||
}
|
||||
|
||||
func (res ResponseData) UnmarshalBinary(data []byte) error {
|
||||
return json.Unmarshal(data, &res)
|
||||
}
|
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yitter/idgenerator-go/idgen"
|
||||
"gorm.io/gorm"
|
||||
"schisandra-cloud-album/api/user_api/dto"
|
||||
"schisandra-cloud-album/api/websocket_api"
|
||||
"schisandra-cloud-album/common/constant"
|
||||
"schisandra-cloud-album/common/enum"
|
||||
@@ -291,7 +290,7 @@ func handelUserLogin(userId string, clientId string, c *gin.Context) bool {
|
||||
return
|
||||
}
|
||||
refreshToken, expiresAt := utils.GenerateRefreshToken(utils.RefreshJWTPayload{UserID: &userId}, time.Hour*24*7)
|
||||
data := dto.ResponseData{
|
||||
data := ResponseData{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
ExpiresAt: expiresAt,
|
||||
@@ -313,8 +312,8 @@ func handelUserLogin(userId string, clientId string, c *gin.Context) bool {
|
||||
resultChan <- false
|
||||
return
|
||||
}
|
||||
gob.Register(dto.ResponseData{})
|
||||
wrong := utils.SetSession(c, "user", data)
|
||||
gob.Register(ResponseData{})
|
||||
wrong := utils.SetSession(c, constant.SessionKey, data)
|
||||
if wrong != nil {
|
||||
resultChan <- false
|
||||
return
|
||||
|
@@ -3,7 +3,6 @@ package permission_api
|
||||
import (
|
||||
ginI18n "github.com/gin-contrib/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
"schisandra-cloud-album/api/permission_api/dto"
|
||||
"schisandra-cloud-album/common/result"
|
||||
"schisandra-cloud-album/global"
|
||||
"schisandra-cloud-album/service"
|
||||
@@ -17,16 +16,16 @@ var permissionService = service.Service.PermissionService
|
||||
// @Tags 权限管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param permissions body dto.AddPermissionRequestDto true "权限列表"
|
||||
// @Param permissions body AddPermissionRequest true "权限列表"
|
||||
// @Router /api/auth/permission/add [post]
|
||||
func (PermissionAPI) AddPermissions(c *gin.Context) {
|
||||
addPermissionRequestDto := dto.AddPermissionRequestDto{}
|
||||
err := c.ShouldBind(&addPermissionRequestDto.Permissions)
|
||||
addPermissionRequest := AddPermissionRequest{}
|
||||
err := c.ShouldBind(&addPermissionRequest.Permissions)
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
return
|
||||
}
|
||||
err = permissionService.CreatePermissions(addPermissionRequestDto.Permissions)
|
||||
err = permissionService.CreatePermissions(addPermissionRequest.Permissions)
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "CreatedFailed"), c)
|
||||
@@ -42,12 +41,12 @@ func (PermissionAPI) AddPermissions(c *gin.Context) {
|
||||
// @Tags 权限管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param permissions body dto.AddPermissionToRoleRequestDto true "权限列表"
|
||||
// @Param permissions body AddPermissionToRoleRequest true "权限列表"
|
||||
// @Router /api/auth/permission/assign [post]
|
||||
func (PermissionAPI) AssignPermissionsToRole(c *gin.Context) {
|
||||
permissionToRoleRequestDto := dto.AddPermissionToRoleRequestDto{}
|
||||
permissionToRoleRequest := AddPermissionToRoleRequest{}
|
||||
|
||||
err := c.ShouldBind(&permissionToRoleRequestDto)
|
||||
err := c.ShouldBind(&permissionToRoleRequest)
|
||||
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
@@ -55,7 +54,7 @@ func (PermissionAPI) AssignPermissionsToRole(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
policy, err := global.Casbin.AddPolicy(permissionToRoleRequestDto.RoleKey, permissionToRoleRequestDto.Permission, permissionToRoleRequestDto.Method)
|
||||
policy, err := global.Casbin.AddPolicy(permissionToRoleRequest.RoleKey, permissionToRoleRequest.Permission, permissionToRoleRequest.Method)
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "AssignFailed"), c)
|
||||
@@ -71,7 +70,7 @@ func (PermissionAPI) AssignPermissionsToRole(c *gin.Context) {
|
||||
|
||||
// GetUserPermissions 获取用户角色权限
|
||||
func (PermissionAPI) GetUserPermissions(c *gin.Context) {
|
||||
getPermissionRequest := dto.GetPermissionRequest{}
|
||||
getPermissionRequest := GetPermissionRequest{}
|
||||
err := c.ShouldBindJSON(&getPermissionRequest)
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
@@ -1,16 +1,14 @@
|
||||
package dto
|
||||
package permission_api
|
||||
|
||||
import (
|
||||
"schisandra-cloud-album/model"
|
||||
)
|
||||
import "schisandra-cloud-album/model"
|
||||
|
||||
// AddPermissionRequestDto 添加权限请求dto
|
||||
type AddPermissionRequestDto struct {
|
||||
// AddPermissionToRoleRequest 添加权限请求
|
||||
type AddPermissionRequest struct {
|
||||
Permissions []model.ScaAuthPermission `form:"permissions[]" json:"permissions"`
|
||||
}
|
||||
|
||||
// AddPermissionToRoleRequestDto 添加权限到角色请求dto
|
||||
type AddPermissionToRoleRequestDto struct {
|
||||
// AddPermissionToRoleRequest 添加权限到角色请求
|
||||
type AddPermissionToRoleRequest struct {
|
||||
RoleKey string `json:"role_key"`
|
||||
Permission string `json:"permission"`
|
||||
Method string `json:"method"`
|
@@ -1,11 +1,11 @@
|
||||
package dto
|
||||
package role_api
|
||||
|
||||
type RoleRequestDto struct {
|
||||
type RoleRequest struct {
|
||||
RoleName string `json:"role_name" binding:"required"`
|
||||
RoleKey string `json:"role_key" binding:"required"`
|
||||
}
|
||||
|
||||
type AddRoleToUserRequestDto struct {
|
||||
type AddRoleToUserRequest struct {
|
||||
Uid string `json:"uid" binding:"required"`
|
||||
RoleKey string `json:"role_key" binding:"required"`
|
||||
}
|
@@ -3,7 +3,6 @@ package role_api
|
||||
import (
|
||||
ginI18n "github.com/gin-contrib/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
"schisandra-cloud-album/api/role_api/dto"
|
||||
"schisandra-cloud-album/common/result"
|
||||
"schisandra-cloud-album/global"
|
||||
"schisandra-cloud-album/model"
|
||||
@@ -18,18 +17,18 @@ var roleService = service.Service.RoleService
|
||||
// @Tags 角色
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param roleRequestDto body dto.RoleRequestDto true "角色信息"
|
||||
// @Param roleRequestDto body RoleRequest true "角色信息"
|
||||
// @Router /api/auth/role/create [post]
|
||||
func (RoleAPI) CreateRole(c *gin.Context) {
|
||||
roleRequestDto := dto.RoleRequestDto{}
|
||||
err := c.ShouldBindJSON(&roleRequestDto)
|
||||
roleRequest := RoleRequest{}
|
||||
err := c.ShouldBindJSON(&roleRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "CreatedFailed"), c)
|
||||
return
|
||||
}
|
||||
role := model.ScaAuthRole{
|
||||
RoleName: roleRequestDto.RoleName,
|
||||
RoleKey: roleRequestDto.RoleKey,
|
||||
RoleName: roleRequest.RoleName,
|
||||
RoleKey: roleRequest.RoleKey,
|
||||
}
|
||||
err = roleService.AddRole(role)
|
||||
if err != nil {
|
||||
@@ -46,16 +45,16 @@ func (RoleAPI) CreateRole(c *gin.Context) {
|
||||
// @Tags 角色
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param addRoleToUserRequestDto body dto.AddRoleToUserRequestDto true "给指定用户添加角色"
|
||||
// @Param addRoleToUserRequestDto body AddRoleToUserRequest true "给指定用户添加角色"
|
||||
// @Router /api/auth/role/add_role_to_user [post]
|
||||
func (RoleAPI) AddRoleToUser(c *gin.Context) {
|
||||
addRoleToUserRequestDto := dto.AddRoleToUserRequestDto{}
|
||||
err := c.ShouldBindJSON(&addRoleToUserRequestDto)
|
||||
addRoleToUserRequest := AddRoleToUserRequest{}
|
||||
err := c.ShouldBindJSON(&addRoleToUserRequest)
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
return
|
||||
}
|
||||
user, err := global.Casbin.AddRoleForUser(addRoleToUserRequestDto.Uid, addRoleToUserRequestDto.RoleKey)
|
||||
user, err := global.Casbin.AddRoleForUser(addRoleToUserRequest.Uid, addRoleToUserRequest.RoleKey)
|
||||
if err != nil {
|
||||
global.LOG.Error(err)
|
||||
return
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package dto
|
||||
package sms_api
|
||||
|
||||
type SmsRequest struct {
|
||||
Phone string `json:"phone" binding:"required"`
|
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/pkg6/go-sms/gateways"
|
||||
"github.com/pkg6/go-sms/gateways/aliyun"
|
||||
"github.com/pkg6/go-sms/gateways/smsbao"
|
||||
"schisandra-cloud-album/api/sms_api/dto"
|
||||
"schisandra-cloud-album/common/constant"
|
||||
"schisandra-cloud-album/common/redis"
|
||||
"schisandra-cloud-album/common/result"
|
||||
@@ -24,7 +23,7 @@ import (
|
||||
// @Param phone query string true "手机号"
|
||||
// @Router /api/sms/ali/send [get]
|
||||
func (SmsAPI) SendMessageByAli(c *gin.Context) {
|
||||
smsRequest := dto.SmsRequest{}
|
||||
smsRequest := SmsRequest{}
|
||||
err := c.ShouldBindJSON(&smsRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaSendFailed"), c)
|
||||
@@ -83,7 +82,7 @@ func (SmsAPI) SendMessageByAli(c *gin.Context) {
|
||||
// @Param phone query string true "手机号"
|
||||
// @Router /api/sms/smsbao/send [post]
|
||||
func (SmsAPI) SendMessageBySmsBao(c *gin.Context) {
|
||||
smsRequest := dto.SmsRequest{}
|
||||
smsRequest := SmsRequest{}
|
||||
err := c.ShouldBindJSON(&smsRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaSendFailed"), c)
|
||||
@@ -135,7 +134,7 @@ func (SmsAPI) SendMessageBySmsBao(c *gin.Context) {
|
||||
// @Param phone query string true "手机号"
|
||||
// @Router /api/sms/test/send [post]
|
||||
func (SmsAPI) SendMessageTest(c *gin.Context) {
|
||||
smsRequest := dto.SmsRequest{}
|
||||
smsRequest := SmsRequest{}
|
||||
err := c.ShouldBindJSON(&smsRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaSendFailed"), c)
|
||||
|
134
api/user_api/handler.go
Normal file
134
api/user_api/handler.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package user_api
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
ginI18n "github.com/gin-contrib/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/mssola/useragent"
|
||||
"gorm.io/gorm"
|
||||
"schisandra-cloud-album/common/constant"
|
||||
"schisandra-cloud-album/common/redis"
|
||||
"schisandra-cloud-album/common/result"
|
||||
"schisandra-cloud-album/global"
|
||||
"schisandra-cloud-album/model"
|
||||
"schisandra-cloud-album/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
// getUserLoginDevice 获取用户登录设备
|
||||
func getUserLoginDevice(user model.ScaAuthUser, c *gin.Context) bool {
|
||||
|
||||
// 检查user.UID是否为空
|
||||
if user.UID == nil {
|
||||
global.LOG.Errorln("user.UID is nil")
|
||||
return false
|
||||
}
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
if userAgent == "" {
|
||||
global.LOG.Errorln("user-agent is empty")
|
||||
return false
|
||||
}
|
||||
ua := useragent.New(userAgent)
|
||||
|
||||
ip := utils.GetClientIP(c)
|
||||
location, err := global.IP2Location.SearchByStr(ip)
|
||||
if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
}
|
||||
location = utils.RemoveZeroAndAdjust(location)
|
||||
|
||||
isBot := ua.Bot()
|
||||
browser, browserVersion := ua.Browser()
|
||||
os := ua.OS()
|
||||
mobile := ua.Mobile()
|
||||
mozilla := ua.Mozilla()
|
||||
platform := ua.Platform()
|
||||
engine, engineVersion := ua.Engine()
|
||||
|
||||
device := model.ScaAuthUserDevice{
|
||||
UserID: user.UID,
|
||||
IP: &ip,
|
||||
Location: &location,
|
||||
Agent: userAgent,
|
||||
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 := userDeviceService.GetUserDeviceByUIDIPAgent(*user.UID, ip, userAgent)
|
||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
err = userDeviceService.AddUserDevice(&device)
|
||||
if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
}
|
||||
} else if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
} else {
|
||||
err := userDeviceService.UpdateUserDevice(userDevice.ID, &device)
|
||||
if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// handelUserLogin 处理用户登录
|
||||
func handelUserLogin(user model.ScaAuthUser, autoLogin bool, c *gin.Context) {
|
||||
// 检查 user.UID 是否为 nil
|
||||
if user.UID == nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
}
|
||||
if !getUserLoginDevice(user, c) {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
accessToken, err := utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: user.UID})
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
|
||||
var days time.Duration
|
||||
if autoLogin {
|
||||
days = 7 * 24 * time.Hour
|
||||
} else {
|
||||
days = time.Minute * 30
|
||||
}
|
||||
|
||||
refreshToken, expiresAt := utils.GenerateRefreshToken(utils.RefreshJWTPayload{UserID: user.UID}, days)
|
||||
data := ResponseData{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
ExpiresAt: expiresAt,
|
||||
UID: user.UID,
|
||||
}
|
||||
|
||||
err = redis.Set(constant.UserLoginTokenRedisKey+*user.UID, data, days).Err()
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
gob.Register(ResponseData{})
|
||||
err = utils.SetSession(c, constant.SessionKey, data)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
result.OkWithData(data, c)
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package dto
|
||||
package user_api
|
||||
|
||||
import "encoding/json"
|
||||
|
@@ -1,15 +1,11 @@
|
||||
package user_api
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
ginI18n "github.com/gin-contrib/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/mssola/useragent"
|
||||
"github.com/yitter/idgenerator-go/idgen"
|
||||
"gorm.io/gorm"
|
||||
"reflect"
|
||||
"schisandra-cloud-album/api/user_api/dto"
|
||||
"schisandra-cloud-album/common/constant"
|
||||
"schisandra-cloud-album/common/enum"
|
||||
"schisandra-cloud-album/common/randomname"
|
||||
@@ -107,11 +103,11 @@ func (UserAPI) QueryUserByPhone(c *gin.Context) {
|
||||
// AccountLogin 账号登录
|
||||
// @Summary 账号登录
|
||||
// @Tags 用户模块
|
||||
// @Param user body dto.AccountLoginRequest true "用户信息"
|
||||
// @Param user body AccountLoginRequest true "用户信息"
|
||||
// @Success 200 {string} json
|
||||
// @Router /api/user/login [post]
|
||||
func (UserAPI) AccountLogin(c *gin.Context) {
|
||||
accountLoginRequest := dto.AccountLoginRequest{}
|
||||
accountLoginRequest := AccountLoginRequest{}
|
||||
err := c.ShouldBindJSON(&accountLoginRequest)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
@@ -152,11 +148,11 @@ func (UserAPI) AccountLogin(c *gin.Context) {
|
||||
// PhoneLogin 手机号登录/注册
|
||||
// @Summary 手机号登录/注册
|
||||
// @Tags 用户模块
|
||||
// @Param user body dto.PhoneLoginRequest true "用户信息"
|
||||
// @Param user body PhoneLoginRequest true "用户信息"
|
||||
// @Success 200 {string} json
|
||||
// @Router /api/user/phone_login [post]
|
||||
func (UserAPI) PhoneLogin(c *gin.Context) {
|
||||
request := dto.PhoneLoginRequest{}
|
||||
request := PhoneLoginRequest{}
|
||||
err := c.ShouldBind(&request)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
@@ -265,7 +261,7 @@ func (UserAPI) PhoneLogin(c *gin.Context) {
|
||||
// @Success 200 {string} json
|
||||
// @Router /api/token/refresh [post]
|
||||
func (UserAPI) RefreshHandler(c *gin.Context) {
|
||||
request := dto.RefreshTokenRequest{}
|
||||
request := RefreshTokenRequest{}
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
@@ -289,7 +285,7 @@ func (UserAPI) RefreshHandler(c *gin.Context) {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginExpired"), c)
|
||||
return
|
||||
}
|
||||
data := dto.ResponseData{
|
||||
data := ResponseData{
|
||||
AccessToken: accessTokenString,
|
||||
RefreshToken: refreshToken,
|
||||
UID: parseRefreshToken.UserID,
|
||||
@@ -301,60 +297,14 @@ func (UserAPI) RefreshHandler(c *gin.Context) {
|
||||
result.OkWithData(data, c)
|
||||
}
|
||||
|
||||
// handelUserLogin 处理用户登录
|
||||
func handelUserLogin(user model.ScaAuthUser, autoLogin bool, c *gin.Context) {
|
||||
// 检查 user.UID 是否为 nil
|
||||
if user.UID == nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
}
|
||||
if !getUserLoginDevice(user, c) {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
accessToken, err := utils.GenerateAccessToken(utils.AccessJWTPayload{UserID: user.UID})
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
|
||||
var days time.Duration
|
||||
if autoLogin {
|
||||
days = 7 * 24 * time.Hour
|
||||
} else {
|
||||
days = time.Minute * 30
|
||||
}
|
||||
|
||||
refreshToken, expiresAt := utils.GenerateRefreshToken(utils.RefreshJWTPayload{UserID: user.UID}, days)
|
||||
data := dto.ResponseData{
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
ExpiresAt: expiresAt,
|
||||
UID: user.UID,
|
||||
}
|
||||
|
||||
err = redis.Set(constant.UserLoginTokenRedisKey+*user.UID, data, days).Err()
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
gob.Register(dto.ResponseData{})
|
||||
err = utils.SetSession(c, "user", data)
|
||||
if err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
|
||||
return
|
||||
}
|
||||
result.OkWithData(data, c)
|
||||
}
|
||||
|
||||
// ResetPassword 重置密码
|
||||
// @Summary 重置密码
|
||||
// @Tags 用户模块
|
||||
// @Param user body dto.ResetPasswordRequest true "用户信息"
|
||||
// @Param user body ResetPasswordRequest true "用户信息"
|
||||
// @Success 200 {string} json
|
||||
// @Router /api/user/reset_password [post]
|
||||
func (UserAPI) ResetPassword(c *gin.Context) {
|
||||
var resetPasswordRequest dto.ResetPasswordRequest
|
||||
var resetPasswordRequest ResetPasswordRequest
|
||||
if err := c.ShouldBindJSON(&resetPasswordRequest); err != nil {
|
||||
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
|
||||
return
|
||||
@@ -432,77 +382,6 @@ func (UserAPI) ResetPassword(c *gin.Context) {
|
||||
result.OkWithMessage(ginI18n.MustGetMessage(c, "ResetPasswordSuccess"), c)
|
||||
}
|
||||
|
||||
// getUserLoginDevice 获取用户登录设备
|
||||
func getUserLoginDevice(user model.ScaAuthUser, c *gin.Context) bool {
|
||||
|
||||
// 检查user.UID是否为空
|
||||
if user.UID == nil {
|
||||
global.LOG.Errorln("user.UID is nil")
|
||||
return false
|
||||
}
|
||||
userAgent := c.GetHeader("User-Agent")
|
||||
if userAgent == "" {
|
||||
global.LOG.Errorln("user-agent is empty")
|
||||
return false
|
||||
}
|
||||
ua := useragent.New(userAgent)
|
||||
|
||||
ip := utils.GetClientIP(c)
|
||||
location, err := global.IP2Location.SearchByStr(ip)
|
||||
if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
}
|
||||
location = utils.RemoveZeroAndAdjust(location)
|
||||
|
||||
isBot := ua.Bot()
|
||||
browser, browserVersion := ua.Browser()
|
||||
os := ua.OS()
|
||||
mobile := ua.Mobile()
|
||||
mozilla := ua.Mozilla()
|
||||
platform := ua.Platform()
|
||||
engine, engineVersion := ua.Engine()
|
||||
|
||||
device := model.ScaAuthUserDevice{
|
||||
UserID: user.UID,
|
||||
IP: &ip,
|
||||
Location: &location,
|
||||
Agent: userAgent,
|
||||
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 := userDeviceService.GetUserDeviceByUIDIPAgent(*user.UID, ip, userAgent)
|
||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
err = userDeviceService.AddUserDevice(&device)
|
||||
if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
}
|
||||
} else if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
} else {
|
||||
err := userDeviceService.UpdateUserDevice(userDevice.ID, &device)
|
||||
if err != nil {
|
||||
global.LOG.Errorln(err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Logout 退出登录
|
||||
// @Summary 退出登录
|
||||
// @Tags 用户模块
|
||||
|
Reference in New Issue
Block a user