✨ code migration
This commit is contained in:
799
.idea/GOHCache.xml
generated
799
.idea/GOHCache.xml
generated
File diff suppressed because it is too large
Load Diff
2
.idea/JavaSceneConfigState.xml
generated
2
.idea/JavaSceneConfigState.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SmartInputSourceJavaSceneConfigState">
|
||||
<option name="customChineseScenes" value="{"capsLockState":false,"code":";FormatText(defaultText);ErrorWithI18n(defaultMsg)","enable":true,"languageType":"CHINESE","name":"自定义中文切换","tip":""}" />
|
||||
<option name="customChineseScenes" value="{"capsLockState":false,"code":";ErrorWithI18n(defaultMsg);FormatText(defaultText)","enable":true,"languageType":"CHINESE","name":"自定义中文切换","tip":""}" />
|
||||
</component>
|
||||
</project>
|
@@ -0,0 +1,44 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha-assets/helper"
|
||||
"github.com/wenlng/go-captcha/v2/click"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// GenerateBasicTextCaptcha generates a basic text captcha and saves it to redis.
|
||||
func GenerateBasicTextCaptcha(capt click.Captcha, redis redis.Client, ctx context.Context) map[string]interface{} {
|
||||
captData, err := capt.Generate()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dotData := captData.GetData()
|
||||
if dotData == nil {
|
||||
return nil
|
||||
}
|
||||
var masterImageBase64, thumbImageBase64 string
|
||||
masterImageBase64 = captData.GetMasterImage().ToBase64()
|
||||
thumbImageBase64 = captData.GetThumbImage().ToBase64()
|
||||
|
||||
dotsByte, err := json.Marshal(dotData)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
key := helper.StringToMD5(string(dotsByte))
|
||||
err = redis.Set(ctx, constant.UserCaptchaPrefix+key, dotsByte, time.Minute).Err()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"key": key,
|
||||
"image": masterImageBase64,
|
||||
"thumb": thumbImageBase64,
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha-assets/helper"
|
||||
"github.com/wenlng/go-captcha/v2/click"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// GenerateClickShapeCaptcha generate click shape captcha
|
||||
func GenerateClickShapeCaptcha(click click.Captcha, redis redis.Client, ctx context.Context) map[string]interface{} {
|
||||
captData, err := click.Generate()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
dotData := captData.GetData()
|
||||
if dotData == nil {
|
||||
return nil
|
||||
}
|
||||
var masterImageBase64, thumbImageBase64 string
|
||||
masterImageBase64 = captData.GetMasterImage().ToBase64()
|
||||
thumbImageBase64 = captData.GetThumbImage().ToBase64()
|
||||
|
||||
dotsByte, err := json.Marshal(dotData)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
key := helper.StringToMD5(string(dotsByte))
|
||||
err = redis.Set(ctx, constant.UserCaptchaPrefix+key, dotsByte, time.Minute).Err()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"key": key,
|
||||
"image": masterImageBase64,
|
||||
"thumb": thumbImageBase64,
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha-assets/helper"
|
||||
"github.com/wenlng/go-captcha/v2/rotate"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// GenerateRotateCaptcha generate rotate captcha
|
||||
func GenerateRotateCaptcha(captcha rotate.Captcha, redis *redis.Client, ctx context.Context) (map[string]interface{}, error) {
|
||||
captchaData, err := captcha.Generate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockData := captchaData.GetData()
|
||||
if blockData == nil {
|
||||
return nil, errors.New("captcha data is nil")
|
||||
}
|
||||
masterImageBase64 := captchaData.GetMasterImage().ToBase64()
|
||||
thumbImageBase64 := captchaData.GetThumbImage().ToBase64()
|
||||
dotsByte, err := json.Marshal(blockData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := helper.StringToMD5(string(dotsByte))
|
||||
err = redis.Set(ctx, constant.UserCaptchaPrefix+key, dotsByte, time.Minute).Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"key": key,
|
||||
"image": masterImageBase64,
|
||||
"thumb": thumbImageBase64,
|
||||
}, nil
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha-assets/helper"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// GenerateSlideBasicCaptcha generate slide basic captcha
|
||||
func GenerateSlideBasicCaptcha(slide slide.Captcha, redis *redis.Client, ctx context.Context) (map[string]interface{}, error) {
|
||||
captData, err := slide.Generate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockData := captData.GetData()
|
||||
if blockData == nil {
|
||||
return nil, errors.New("block data is nil")
|
||||
}
|
||||
var masterImageBase64, tileImageBase64 string
|
||||
masterImageBase64 = captData.GetMasterImage().ToBase64()
|
||||
|
||||
tileImageBase64 = captData.GetTileImage().ToBase64()
|
||||
|
||||
dotsByte, err := json.Marshal(blockData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := helper.StringToMD5(string(dotsByte))
|
||||
err = redis.Set(ctx, constant.UserCaptchaPrefix+key, dotsByte, time.Minute).Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"key": key,
|
||||
"image": masterImageBase64,
|
||||
"thumb": tileImageBase64,
|
||||
"thumb_width": blockData.Width,
|
||||
"thumb_height": blockData.Height,
|
||||
"thumb_x": blockData.TileX,
|
||||
"thumb_y": blockData.TileY,
|
||||
}, nil
|
||||
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
package generate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha-assets/helper"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// GenerateSlideRegionCaptcha generate slide region captcha
|
||||
func GenerateSlideRegionCaptcha(slide slide.Captcha, redis redis.Client, ctx context.Context) map[string]interface{} {
|
||||
captData, err := slide.Generate()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
blockData := captData.GetData()
|
||||
if blockData == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var masterImageBase64, tileImageBase64 string
|
||||
masterImageBase64 = captData.GetMasterImage().ToBase64()
|
||||
tileImageBase64 = captData.GetTileImage().ToBase64()
|
||||
|
||||
blockByte, err := json.Marshal(blockData)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
key := helper.StringToMD5(string(blockByte))
|
||||
err = redis.Set(ctx, constant.UserCaptchaPrefix+key, blockByte, time.Minute).Err()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"code": 0,
|
||||
"key": key,
|
||||
"image": masterImageBase64,
|
||||
"tile": tileImageBase64,
|
||||
"tile_width": blockData.Width,
|
||||
"tile_height": blockData.Height,
|
||||
"tile_x": blockData.TileX,
|
||||
"tile_y": blockData.TileY,
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package verify
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha/v2/click"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
)
|
||||
|
||||
// VerifyBasicTextCaptcha verify basic text captcha
|
||||
func VerifyBasicTextCaptcha(dots string, key string, redis *redis.Client, ctx context.Context) bool {
|
||||
cacheDataByte, err := redis.Get(ctx, constant.UserCaptchaPrefix+key).Bytes()
|
||||
if len(cacheDataByte) == 0 || err != nil {
|
||||
return false
|
||||
}
|
||||
src := strings.Split(dots, ",")
|
||||
|
||||
var dct map[int]*click.Dot
|
||||
if err := json.Unmarshal(cacheDataByte, &dct); err != nil {
|
||||
|
||||
return false
|
||||
}
|
||||
chkRet := false
|
||||
if (len(dct) * 2) == len(src) {
|
||||
for i := 0; i < len(dct); i++ {
|
||||
dot := dct[i]
|
||||
j := i * 2
|
||||
k := i*2 + 1
|
||||
sx, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[j]), 64)
|
||||
sy, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[k]), 64)
|
||||
|
||||
chkRet = click.CheckPoint(int64(sx), int64(sy), int64(dot.X), int64(dot.Y), int64(dot.Width), int64(dot.Height), 0)
|
||||
if !chkRet {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if chkRet {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
8
app/core/api/common/constant/oauth_type.go
Normal file
8
app/core/api/common/constant/oauth_type.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package constant
|
||||
|
||||
const (
|
||||
OAuthSourceWechat = "wechat"
|
||||
OAuthSourceQQ = "qq"
|
||||
OAuthSourceGithub = "github"
|
||||
OAuthSourceGitee = "gitee"
|
||||
)
|
@@ -1,9 +1,26 @@
|
||||
package constant
|
||||
|
||||
// 用户相关的redis key
|
||||
const (
|
||||
UserClientPrefix string = "user:client:"
|
||||
UserSessionPrefix string = "user:session:"
|
||||
UserCaptchaPrefix string = "user:captcha:"
|
||||
UserTokenPrefix string = "user:token:"
|
||||
UserSmsRedisPrefix string = "user:sms:"
|
||||
UserQrcodePrefix = "user:qrcode:"
|
||||
)
|
||||
|
||||
// 评论相关的redis key
|
||||
const (
|
||||
CommentSubmitCaptchaPrefix = "comment:submit:captcha:"
|
||||
CommentOfflineMessagePrefix = "comment:offline:message:"
|
||||
CommentLikeLockPrefix = "comment:like:lock:"
|
||||
CommentDislikeLockPrefix = "comment:dislike:lock:"
|
||||
CommentLikeListPrefix = "comment:like:list:"
|
||||
CommentUserListPrefix = "comment:user:list:"
|
||||
)
|
||||
|
||||
// 系统相关的redis key
|
||||
const (
|
||||
SystemApiNonceRedisKey = "system:controller:nonce:"
|
||||
)
|
||||
|
20
app/core/api/common/utils/gen_validate_code.go
Normal file
20
app/core/api/common/utils/gen_validate_code.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GenValidateCode(width int) string {
|
||||
numeric := [10]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
r := len(numeric)
|
||||
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
var sb strings.Builder
|
||||
for i := 0; i < width; i++ {
|
||||
fmt.Fprintf(&sb, "%d", numeric[rand.Intn(r)])
|
||||
}
|
||||
return sb.String()
|
||||
}
|
@@ -42,6 +42,29 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// OAuth请求参数
|
||||
type (
|
||||
// OAuth请求参数
|
||||
OAuthRequest {
|
||||
state string `form:"state"`
|
||||
}
|
||||
// OAuth回调请求参数
|
||||
OAuthCallbackRequest {
|
||||
Code string `form:"code"`
|
||||
}
|
||||
OAuthWechatRequest {
|
||||
client_id string `form:"client_id"`
|
||||
}
|
||||
)
|
||||
|
||||
type (
|
||||
SmsSendRequest {
|
||||
Phone string `json:"phone"`
|
||||
Angle int64 `json:"angle"`
|
||||
Key string `json:"key"`
|
||||
}
|
||||
)
|
||||
|
||||
// 统一响应参数
|
||||
type (
|
||||
Response {
|
||||
@@ -54,7 +77,7 @@ type (
|
||||
// 用户服务
|
||||
@server (
|
||||
group: user // 微服务分组
|
||||
prefix: /api/auth/user // 微服务前缀
|
||||
prefix: /api/user // 微服务前缀
|
||||
timeout: 10s // 超时时间
|
||||
maxBytes: 1048576 // 最大请求大小
|
||||
signature: true // 是否开启签名验证
|
||||
@@ -69,14 +92,17 @@ service core {
|
||||
|
||||
// 手机号登录
|
||||
@handler phoneLogin
|
||||
post /phone_login (PhoneLoginRequest) returns (Response)
|
||||
post /phone/login (PhoneLoginRequest) returns (Response)
|
||||
|
||||
// 重置密码
|
||||
@handler resetPassword
|
||||
post /reset_password (ResetPasswordRequest) returns (Response)
|
||||
post /reset/password (ResetPasswordRequest) returns (Response)
|
||||
|
||||
@handler refreshToken
|
||||
post /token/refresh returns (Response)
|
||||
|
||||
@handler getUserDevice
|
||||
get /device
|
||||
}
|
||||
|
||||
// 客户端服务
|
||||
@@ -92,6 +118,95 @@ service core {
|
||||
)
|
||||
service core {
|
||||
@handler generateClientId
|
||||
get /generate_client_id returns (Response)
|
||||
get /generate returns (Response)
|
||||
}
|
||||
|
||||
@server (
|
||||
group: websocket // 微服务分组
|
||||
prefix: /api/ws // 微服务前缀
|
||||
timeout: 10s // 超时时间
|
||||
Recover: true // 是否开启自动恢复
|
||||
)
|
||||
service core {
|
||||
@handler qrcodeWebsocket
|
||||
get /qrcode
|
||||
|
||||
@handler messageWebsocket
|
||||
get /message
|
||||
}
|
||||
|
||||
@server (
|
||||
group: oauth // 微服务分组
|
||||
prefix: /api/oauth // 微服务前缀
|
||||
timeout: 10s // 超时时间
|
||||
maxBytes: 1048576 // 最大请求大小
|
||||
signature: false // 是否开启签名验证
|
||||
middleware: SecurityHeadersMiddleware // 注册中间件
|
||||
MaxConns: true // 是否开启最大连接数限制
|
||||
Recover: true // 是否开启自动恢复
|
||||
)
|
||||
service core {
|
||||
@handler getGiteeOauthUrl
|
||||
get /gitee/url returns (Response)
|
||||
|
||||
@handler getGithubOauthUrl
|
||||
get /github/url (OAuthRequest) returns (Response)
|
||||
|
||||
@handler getQqOauthUrl
|
||||
get /qq/url (OAuthRequest) returns (Response)
|
||||
|
||||
@handler giteeCallback
|
||||
get /gitee/callback (OAuthCallbackRequest)
|
||||
|
||||
@handler githubCallback
|
||||
get /github/callback (OAuthCallbackRequest)
|
||||
|
||||
@handler qqCallback
|
||||
get /qq/callback (OAuthCallbackRequest)
|
||||
|
||||
@handler wechatCallback
|
||||
get /wechat/callback
|
||||
|
||||
@handler getWechatQrcode
|
||||
get /wechat/qrcode (OAuthWechatRequest) returns (Response)
|
||||
}
|
||||
|
||||
@server (
|
||||
group: sms // 微服务分组
|
||||
prefix: /api/sms // 微服务前缀
|
||||
timeout: 10s // 超时时间
|
||||
maxBytes: 1048576 // 最大请求大小
|
||||
signature: false // 是否开启签名验证
|
||||
middleware: SecurityHeadersMiddleware // 注册中间件
|
||||
MaxConns: true // 是否开启最大连接数限制
|
||||
Recover: true // 是否开启自动恢复
|
||||
)
|
||||
service core {
|
||||
@handler sendSmsByAliyun
|
||||
post /ali/send (SmsSendRequest) returns (Response)
|
||||
|
||||
@handler sendSmsBySmsbao
|
||||
post /smsbao/send (SmsSendRequest) returns (Response)
|
||||
|
||||
@handler sendSmsByTest
|
||||
post /test/send (SmsSendRequest) returns (Response)
|
||||
}
|
||||
|
||||
@server (
|
||||
group: captcha // 微服务分组
|
||||
prefix: /api/captcha // 微服务前缀
|
||||
timeout: 10s // 超时时间
|
||||
maxBytes: 1048576 // 最大请求大小
|
||||
signature: false // 是否开启签名验证
|
||||
middleware: SecurityHeadersMiddleware // 注册中间件
|
||||
MaxConns: true // 是否开启最大连接数限制
|
||||
Recover: true // 是否开启自动恢复
|
||||
)
|
||||
service core {
|
||||
@handler generateRotateCaptcha
|
||||
get /rotate/generate returns (Response)
|
||||
|
||||
@handler generateSlideBasicCaptcha
|
||||
get /slide/generate returns (Response)
|
||||
}
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/middleware"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/config"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/handler"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/websocket"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/idgenerator"
|
||||
)
|
||||
@@ -30,6 +31,8 @@ func main() {
|
||||
handler.RegisterHandlers(server, ctx)
|
||||
// init id generator
|
||||
idgenerator.NewIDGenerator()
|
||||
// init websocket handler
|
||||
websocket.InitializeWebSocketHandler(ctx)
|
||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||
server.Start()
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ Name: main
|
||||
Host: 0.0.0.0
|
||||
Port: 80
|
||||
Web:
|
||||
Addr: localhost:8080
|
||||
URL: http://localhost:5173
|
||||
Middlewares:
|
||||
Log: true
|
||||
Mysql:
|
||||
@@ -20,3 +20,55 @@ Mongo:
|
||||
Password: LDQ20020618xxx
|
||||
Database: schisandra-cloud-album
|
||||
AuthSource: admin
|
||||
Wechat:
|
||||
# 微信公众号APPID
|
||||
AppID: wx55251c2f83b9fc25
|
||||
# 微信公众号APPSECRET
|
||||
AppSecret: d511800cd53d248afe1260bb8aeed230
|
||||
# 微信公众号Token
|
||||
Token: LDQ20020618xxx
|
||||
# 微信公众号EncodingAESKey
|
||||
AESKey:
|
||||
OAuth:
|
||||
# Github配置
|
||||
Github:
|
||||
# Github客户端ID
|
||||
ClientID: Ov23limqLtbVhBngctSl
|
||||
# Github客户端密钥
|
||||
ClientSecret: 84a5be0317b8f4c6b55039a0eb23ea4606676e66
|
||||
# Github回调地址
|
||||
RedirectURI: https://landaiqing.cn/api/oauth/github/callback
|
||||
# Gitee配置
|
||||
Gitee:
|
||||
# Gitee客户端ID
|
||||
ClientID: bd2ff03b5f644242d862832b8cc749015d0a7c8f163fbd5ab67886d436fb198b
|
||||
# Gitee客户端密钥
|
||||
ClientSecret: 3994b463aa962c878a58a1255f59a92e050e205e9204cffe48a25ad17a758f97
|
||||
# Gitee回调地址
|
||||
RedirectURI: https://landaiqing.cn/api/oauth/gitee/callback
|
||||
# QQ配置
|
||||
QQ:
|
||||
# QQ客户端ID
|
||||
ClientID: '102296211'
|
||||
# QQ客户端密钥
|
||||
ClientSecret: ukOo10SggRxHVVIr
|
||||
# QQ回调地址
|
||||
RedirectURI: https://landaiqing.cn/api/oauth/qq/callback
|
||||
# 短信配置
|
||||
SMS:
|
||||
Ali:
|
||||
# 阿里云API地址
|
||||
Host: http://dysmsapi.aliyuncs.com
|
||||
# 阿里云AccessKeyId
|
||||
AccessKeyId: LTAI5tDy2edL9LhW43rnus69
|
||||
# 阿里云AccessKeySecret
|
||||
AccessKeySecret: YWp44dcFrBICrjZgqvJBE7ZHArZfIP
|
||||
# 短信模板ID
|
||||
TemplateCode: SMS_154950909
|
||||
# 短信签名
|
||||
Signature: 阿里云短信测试
|
||||
SMSBao:
|
||||
# 短信宝用户账号
|
||||
Username: landaiqing
|
||||
# 短信宝用户密码
|
||||
Password: $LDQ20020618xxx$
|
@@ -4,6 +4,9 @@ import "github.com/zeromicro/go-zero/rest"
|
||||
|
||||
type Config struct {
|
||||
rest.RestConf
|
||||
Web struct {
|
||||
URL string
|
||||
}
|
||||
Auth struct {
|
||||
AccessSecret string
|
||||
AccessExpire int64
|
||||
@@ -23,4 +26,40 @@ type Config struct {
|
||||
AuthSource string
|
||||
Database string
|
||||
}
|
||||
Wechat struct {
|
||||
AppID string
|
||||
AppSecret string
|
||||
Token string
|
||||
AESKey string
|
||||
}
|
||||
OAuth struct {
|
||||
Github struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
RedirectURI string
|
||||
}
|
||||
QQ struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
RedirectURI string
|
||||
}
|
||||
Gitee struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
RedirectURI string
|
||||
}
|
||||
}
|
||||
SMS struct {
|
||||
Ali struct {
|
||||
Host string
|
||||
AccessKeyId string
|
||||
AccessKeySecret string
|
||||
Signature string
|
||||
TemplateCode string
|
||||
}
|
||||
SMSBao struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,21 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/captcha"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func GenerateRotateCaptchaHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := captcha.NewGenerateRotateCaptchaLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GenerateRotateCaptcha()
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/captcha"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func GenerateSlideBasicCaptchaHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := captcha.NewGenerateSlideBasicCaptchaLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GenerateSlideBasicCaptcha()
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func GetGiteeOauthUrlHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := oauth.NewGetGiteeOauthUrlLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetGiteeOauthUrl()
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func GetGithubOauthUrlHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.OAuthRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := oauth.NewGetGithubOauthUrlLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetGithubOauthUrl(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func GetQqOauthUrlHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.OAuthRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := oauth.NewGetQqOauthUrlLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetQqOauthUrl(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func GetWechatQrcodeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.OAuthWechatRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := oauth.NewGetWechatQrcodeLogic(r.Context(), svcCtx)
|
||||
resp, err := l.GetWechatQrcode(r, &req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func GiteeCallbackHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.OAuthCallbackRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := oauth.NewGiteeCallbackLogic(r.Context(), svcCtx)
|
||||
err := l.GiteeCallback(w, r, &req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func GithubCallbackHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.OAuthCallbackRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := oauth.NewGithubCallbackLogic(r.Context(), svcCtx)
|
||||
err := l.GithubCallback(w, r, &req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
29
app/core/api/internal/handler/oauth/qq_callback_handler.go
Normal file
29
app/core/api/internal/handler/oauth/qq_callback_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func QqCallbackHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.OAuthCallbackRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := oauth.NewQqCallbackLogic(r.Context(), svcCtx)
|
||||
err := l.QqCallback(w, r, &req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/oauth"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func WechatCallbackHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := oauth.NewWechatCallbackLogic(r.Context(), svcCtx)
|
||||
err := l.WechatCallback(w, r)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,8 +7,12 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
captcha "schisandra-album-cloud-microservices/app/core/api/internal/handler/captcha"
|
||||
client "schisandra-album-cloud-microservices/app/core/api/internal/handler/client"
|
||||
oauth "schisandra-album-cloud-microservices/app/core/api/internal/handler/oauth"
|
||||
sms "schisandra-album-cloud-microservices/app/core/api/internal/handler/sms"
|
||||
user "schisandra-album-cloud-microservices/app/core/api/internal/handler/user"
|
||||
websocket "schisandra-album-cloud-microservices/app/core/api/internal/handler/websocket"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
@@ -21,7 +25,28 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/generate_client_id",
|
||||
Path: "/rotate/generate",
|
||||
Handler: captcha.GenerateRotateCaptchaHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/slide/generate",
|
||||
Handler: captcha.GenerateSlideBasicCaptchaHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/captcha"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/generate",
|
||||
Handler: client.GenerateClientIdHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
@@ -35,6 +60,88 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/gitee/callback",
|
||||
Handler: oauth.GiteeCallbackHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/gitee/url",
|
||||
Handler: oauth.GetGiteeOauthUrlHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/github/callback",
|
||||
Handler: oauth.GithubCallbackHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/github/url",
|
||||
Handler: oauth.GetGithubOauthUrlHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/qq/callback",
|
||||
Handler: oauth.QqCallbackHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/qq/url",
|
||||
Handler: oauth.GetQqOauthUrlHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/wechat/callback",
|
||||
Handler: oauth.WechatCallbackHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/wechat/qrcode",
|
||||
Handler: oauth.GetWechatQrcodeHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/oauth"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/ali/send",
|
||||
Handler: sms.SendSmsByAliyunHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/smsbao/send",
|
||||
Handler: sms.SendSmsBySmsbaoHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/test/send",
|
||||
Handler: sms.SendSmsByTestHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/api/sms"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.SecurityHeadersMiddleware},
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/device",
|
||||
Handler: user.GetUserDeviceHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/login",
|
||||
@@ -42,12 +149,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/phone_login",
|
||||
Path: "/phone/login",
|
||||
Handler: user.PhoneLoginHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodPost,
|
||||
Path: "/reset_password",
|
||||
Path: "/reset/password",
|
||||
Handler: user.ResetPasswordHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
@@ -58,8 +165,25 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
}...,
|
||||
),
|
||||
rest.WithSignature(serverCtx.Config.Signature),
|
||||
rest.WithPrefix("/api/auth/user"),
|
||||
rest.WithPrefix("/api/user"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
rest.WithMaxBytes(1048576),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/message",
|
||||
Handler: websocket.MessageWebsocketHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/qrcode",
|
||||
Handler: websocket.QrcodeWebsocketHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
rest.WithPrefix("/api/ws"),
|
||||
rest.WithTimeout(10000*time.Millisecond),
|
||||
)
|
||||
}
|
||||
|
@@ -0,0 +1,28 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/sms"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func SendSmsByAliyunHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.SmsSendRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := sms.NewSendSmsByAliyunLogic(r.Context(), svcCtx)
|
||||
resp, err := l.SendSmsByAliyun(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/sms"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func SendSmsBySmsbaoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.SmsSendRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := sms.NewSendSmsBySmsbaoLogic(r.Context(), svcCtx)
|
||||
resp, err := l.SendSmsBySmsbao(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/sms"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
)
|
||||
|
||||
func SendSmsByTestHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.SmsSendRequest
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := sms.NewSendSmsByTestLogic(r.Context(), svcCtx)
|
||||
resp, err := l.SendSmsByTest(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/user"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func GetUserDeviceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := user.NewGetUserDeviceLogic(r.Context(), svcCtx)
|
||||
err := l.GetUserDevice(r)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/websocket"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func MessageWebsocketHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := websocket.NewMessageWebsocketLogic(r.Context(), svcCtx)
|
||||
err := l.MessageWebsocket(w, r)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/websocket"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
func QrcodeWebsocketHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := websocket.NewQrcodeWebsocketLogic(r.Context(), svcCtx)
|
||||
err := l.QrcodeWebsocket(w, r)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/captcha/generate"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GenerateRotateCaptchaLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGenerateRotateCaptchaLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GenerateRotateCaptchaLogic {
|
||||
return &GenerateRotateCaptchaLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GenerateRotateCaptchaLogic) GenerateRotateCaptcha() (resp *types.Response, err error) {
|
||||
captcha, err := generate.GenerateRotateCaptcha(l.svcCtx.RotateCaptcha, l.svcCtx.RedisClient, l.ctx)
|
||||
if err != nil {
|
||||
return response.Error(), err
|
||||
}
|
||||
return response.SuccessWithData(captcha), nil
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/captcha/generate"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GenerateSlideBasicCaptchaLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGenerateSlideBasicCaptchaLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GenerateSlideBasicCaptchaLogic {
|
||||
return &GenerateSlideBasicCaptchaLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GenerateSlideBasicCaptchaLogic) GenerateSlideBasicCaptcha() (resp *types.Response, err error) {
|
||||
captcha, err := generate.GenerateSlideBasicCaptcha(l.svcCtx.SlideCaptcha, l.svcCtx.RedisClient, l.ctx)
|
||||
if err != nil {
|
||||
return response.Error(), err
|
||||
}
|
||||
return response.SuccessWithData(captcha), nil
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetGiteeOauthUrlLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetGiteeOauthUrlLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetGiteeOauthUrlLogic {
|
||||
return &GetGiteeOauthUrlLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetGiteeOauthUrlLogic) GetGiteeOauthUrl() (resp *types.Response, err error) {
|
||||
clientID := l.svcCtx.Config.OAuth.Gitee.ClientID
|
||||
redirectURI := l.svcCtx.Config.OAuth.Gitee.RedirectURI
|
||||
url := "https://gitee.com/oauth/authorize?client_id=" + clientID + "&redirect_uri=" + redirectURI + "&response_type=code"
|
||||
return response.SuccessWithData(url), nil
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetGithubOauthUrlLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetGithubOauthUrlLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetGithubOauthUrlLogic {
|
||||
return &GetGithubOauthUrlLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetGithubOauthUrlLogic) GetGithubOauthUrl(req *types.OAuthRequest) (resp *types.Response, err error) {
|
||||
clientId := l.svcCtx.Config.OAuth.Github.ClientID
|
||||
redirectUrl := l.svcCtx.Config.OAuth.Github.RedirectURI
|
||||
url := "https://github.com/login/oauth/authorize?client_id=" + clientId + "&redirect_uri=" + redirectUrl + "&state=" + req.State
|
||||
return response.SuccessWithData(url), nil
|
||||
}
|
32
app/core/api/internal/logic/oauth/get_qq_oauth_url_logic.go
Normal file
32
app/core/api/internal/logic/oauth/get_qq_oauth_url_logic.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetQqOauthUrlLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetQqOauthUrlLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetQqOauthUrlLogic {
|
||||
return &GetQqOauthUrlLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetQqOauthUrlLogic) GetQqOauthUrl(req *types.OAuthRequest) (resp *types.Response, err error) {
|
||||
clientId := l.svcCtx.Config.OAuth.QQ.ClientID
|
||||
redirectURI := l.svcCtx.Config.OAuth.QQ.RedirectURI
|
||||
url := "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectURI + "&state=" + req.State
|
||||
return response.SuccessWithData(url), nil
|
||||
}
|
64
app/core/api/internal/logic/oauth/get_wechat_qrcode_logic.go
Normal file
64
app/core/api/internal/logic/oauth/get_wechat_qrcode_logic.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/basicService/qrCode/response"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
response2 "schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetWechatQrcodeLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetWechatQrcodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWechatQrcodeLogic {
|
||||
return &GetWechatQrcodeLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetWechatQrcodeLogic) GetWechatQrcode(r *http.Request, req *types.OAuthWechatRequest) (resp *types.Response, err error) {
|
||||
ip := utils.GetClientIP(r) // 使用工具函数获取客户端IP
|
||||
key := constant.UserQrcodePrefix + ip
|
||||
|
||||
// 从Redis获取二维码数据
|
||||
qrcode := l.svcCtx.RedisClient.Get(l.ctx, key).Val()
|
||||
if qrcode != "" {
|
||||
data := new(response.ResponseQRCodeCreate)
|
||||
if err = json.Unmarshal([]byte(qrcode), data); err != nil {
|
||||
return response2.Error(), err
|
||||
}
|
||||
return response2.SuccessWithData(data.Url), nil
|
||||
}
|
||||
|
||||
// 生成临时二维码
|
||||
data, err := l.svcCtx.WechatPublic.QRCode.Temporary(l.ctx, req.Client_id, 7*24*3600)
|
||||
if err != nil {
|
||||
return response2.Error(), err
|
||||
}
|
||||
|
||||
// 序列化数据并存储到Redis
|
||||
serializedData, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return response2.Error(), err
|
||||
}
|
||||
if err = l.svcCtx.RedisClient.Set(l.ctx, key, serializedData, time.Hour*24*7).Err(); err != nil {
|
||||
return response2.Error(), err
|
||||
}
|
||||
|
||||
return response2.SuccessWithData(data.Url), nil
|
||||
}
|
257
app/core/api/internal/logic/oauth/gitee_callback_logic.go
Normal file
257
app/core/api/internal/logic/oauth/gitee_callback_logic.go
Normal file
@@ -0,0 +1,257 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/yitter/idgenerator-go/idgen"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/user"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuser"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthusersocial"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GiteeCallbackLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
type GiteeUser struct {
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
Bio string `json:"bio"`
|
||||
Blog string `json:"blog"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Email string `json:"email"`
|
||||
EventsURL string `json:"events_url"`
|
||||
Followers int `json:"followers"`
|
||||
FollowersURL string `json:"followers_url"`
|
||||
Following int `json:"following"`
|
||||
FollowingURL string `json:"following_url"`
|
||||
GistsURL string `json:"gists_url"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
ID int `json:"id"`
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
OrganizationsURL string `json:"organizations_url"`
|
||||
PublicGists int `json:"public_gists"`
|
||||
PublicRepos int `json:"public_repos"`
|
||||
ReceivedEventsURL string `json:"received_events_url"`
|
||||
Remark string `json:"remark"`
|
||||
ReposURL string `json:"repos_url"`
|
||||
Stared int `json:"stared"`
|
||||
StarredURL string `json:"starred_url"`
|
||||
SubscriptionsURL string `json:"subscriptions_url"`
|
||||
Type string `json:"type"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
URL string `json:"url"`
|
||||
Watched int `json:"watched"`
|
||||
Weibo interface{} `json:"weibo"`
|
||||
}
|
||||
type Token struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
|
||||
var Script = `
|
||||
<script>
|
||||
window.opener.postMessage('%s', '%s');
|
||||
window.close();
|
||||
</script>
|
||||
`
|
||||
|
||||
func NewGiteeCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GiteeCallbackLogic {
|
||||
return &GiteeCallbackLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GiteeCallbackLogic) GiteeCallback(w http.ResponseWriter, r *http.Request, req *types.OAuthCallbackRequest) error {
|
||||
// 获取 token
|
||||
tokenAuthUrl := l.GetGiteeTokenAuthUrl(req.Code)
|
||||
token, err := l.GetGiteeToken(tokenAuthUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if token == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
userInfo, err := l.GetGiteeUserInfo(token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var giteeUser GiteeUser
|
||||
marshal, err := json.Marshal(userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = json.Unmarshal(marshal, &giteeUser); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx, err := l.svcCtx.MySQLClient.Tx(l.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Id := strconv.Itoa(giteeUser.ID)
|
||||
|
||||
socialUser, err := l.svcCtx.MySQLClient.ScaAuthUserSocial.Query().
|
||||
Where(scaauthusersocial.OpenID(Id),
|
||||
scaauthusersocial.Source(constant.OAuthSourceGitee),
|
||||
scaauthusersocial.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
|
||||
if err != nil && !ent.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if ent.IsNotFound(err) {
|
||||
// 创建用户
|
||||
uid := idgen.NextId()
|
||||
uidStr := strconv.FormatInt(uid, 10)
|
||||
|
||||
addUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Create().
|
||||
SetUID(uidStr).
|
||||
SetAvatar(giteeUser.AvatarURL).
|
||||
SetUsername(giteeUser.Login).
|
||||
SetNickname(giteeUser.Name).
|
||||
SetBlog(giteeUser.Blog).
|
||||
SetEmail(giteeUser.Email).
|
||||
SetDeleted(constant.NotDeleted).
|
||||
SetGender(constant.Male).
|
||||
Save(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if err = l.svcCtx.MySQLClient.ScaAuthUserSocial.Create().
|
||||
SetUserID(uidStr).
|
||||
SetOpenID(Id).
|
||||
SetSource(constant.OAuthSourceGitee).
|
||||
Exec(l.ctx); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if res, err := l.svcCtx.CasbinEnforcer.AddRoleForUser(uidStr, constant.User); !res || err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if result := HandleOauthLoginResponse(addUser, l.svcCtx, r, w, l.ctx); !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
} else {
|
||||
sacAuthUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Query().
|
||||
Where(scaauthuser.UID(socialUser.UserID), scaauthuser.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if result := HandleOauthLoginResponse(sacAuthUser, l.svcCtx, r, w, l.ctx); !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleOauthLoginResponse 处理登录响应
|
||||
func HandleOauthLoginResponse(scaAuthUser *ent.ScaAuthUser, svcCtx *svc.ServiceContext, r *http.Request, w http.ResponseWriter, ctx context.Context) bool {
|
||||
data, result := user.HandleUserLogin(scaAuthUser, svcCtx, true, r, w, ctx)
|
||||
if !result {
|
||||
return false
|
||||
}
|
||||
responseData := response.SuccessWithData(data)
|
||||
formattedScript := fmt.Sprintf(Script, responseData, svcCtx.Config.Web.URL)
|
||||
|
||||
// 设置响应状态码和内容类型
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
|
||||
// 写入响应内容
|
||||
if _, writeErr := w.Write([]byte(formattedScript)); writeErr != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// GetGiteeTokenAuthUrl 获取Gitee token
|
||||
func (l *GiteeCallbackLogic) GetGiteeTokenAuthUrl(code string) string {
|
||||
clientId := l.svcCtx.Config.OAuth.Gitee.ClientID
|
||||
clientSecret := l.svcCtx.Config.OAuth.Gitee.ClientSecret
|
||||
redirectURI := l.svcCtx.Config.OAuth.Gitee.RedirectURI
|
||||
return fmt.Sprintf(
|
||||
"https://gitee.com/oauth/token?grant_type=authorization_code&code=%s&client_id=%s&redirect_uri=%s&client_secret=%s",
|
||||
code, clientId, redirectURI, clientSecret,
|
||||
)
|
||||
}
|
||||
|
||||
// GetGiteeToken 获取 token
|
||||
func (l *GiteeCallbackLogic) GetGiteeToken(url string) (*Token, error) {
|
||||
|
||||
// 形成请求
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodPost, url, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json")
|
||||
|
||||
// 发送请求并获得响应
|
||||
var httpClient = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = httpClient.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应体解析为 token,并返回
|
||||
var token Token
|
||||
if err = json.NewDecoder(res.Body).Decode(&token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// GetGiteeUserInfo 获取用户信息
|
||||
func (l *GiteeCallbackLogic) GetGiteeUserInfo(token *Token) (map[string]interface{}, error) {
|
||||
|
||||
// 形成请求
|
||||
var userInfoUrl = "https://gitee.com/api/v5/user" // github用户信息获取接口
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, userInfoUrl, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", token.AccessToken))
|
||||
// 发送请求并获取响应
|
||||
var client = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = client.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应的数据写入 userInfo 中,并返回
|
||||
var userInfo = make(map[string]interface{})
|
||||
if err = json.NewDecoder(res.Body).Decode(&userInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
236
app/core/api/internal/logic/oauth/github_callback_logic.go
Normal file
236
app/core/api/internal/logic/oauth/github_callback_logic.go
Normal file
@@ -0,0 +1,236 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/yitter/idgenerator-go/idgen"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuser"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthusersocial"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GithubCallbackLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
type GitHubUser struct {
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
Bio interface{} `json:"bio"`
|
||||
Blog string `json:"blog"`
|
||||
Company interface{} `json:"company"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
Email string `json:"email"`
|
||||
EventsURL string `json:"events_url"`
|
||||
Followers int `json:"followers"`
|
||||
FollowersURL string `json:"followers_url"`
|
||||
Following int `json:"following"`
|
||||
FollowingURL string `json:"following_url"`
|
||||
GistsURL string `json:"gists_url"`
|
||||
GravatarID string `json:"gravatar_id"`
|
||||
Hireable interface{} `json:"hireable"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
ID int `json:"id"`
|
||||
Location interface{} `json:"location"`
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
NodeID string `json:"node_id"`
|
||||
NotificationEmail interface{} `json:"notification_email"`
|
||||
OrganizationsURL string `json:"organizations_url"`
|
||||
PublicGists int `json:"public_gists"`
|
||||
PublicRepos int `json:"public_repos"`
|
||||
ReceivedEventsURL string `json:"received_events_url"`
|
||||
ReposURL string `json:"repos_url"`
|
||||
SiteAdmin bool `json:"site_admin"`
|
||||
StarredURL string `json:"starred_url"`
|
||||
SubscriptionsURL string `json:"subscriptions_url"`
|
||||
TwitterUsername interface{} `json:"twitter_username"`
|
||||
Type string `json:"type"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func NewGithubCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GithubCallbackLogic {
|
||||
return &GithubCallbackLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GithubCallbackLogic) GithubCallback(w http.ResponseWriter, r *http.Request, req *types.OAuthCallbackRequest) error {
|
||||
|
||||
// 获取 token
|
||||
tokenAuthUrl := l.GetTokenAuthUrl(req.Code)
|
||||
token, err := l.GetToken(tokenAuthUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if token == nil {
|
||||
|
||||
return errors.New("failed to get token")
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
userInfo, err := l.GetUserInfo(token)
|
||||
if err != nil {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if userInfo == nil {
|
||||
return errors.New("failed to get user info")
|
||||
}
|
||||
|
||||
// 处理用户信息
|
||||
userInfoBytes, err := json.Marshal(userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var gitHubUser GitHubUser
|
||||
err = json.Unmarshal(userInfoBytes, &gitHubUser)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx, err := l.svcCtx.MySQLClient.Tx(l.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Id := strconv.Itoa(gitHubUser.ID)
|
||||
socialUser, err := l.svcCtx.MySQLClient.ScaAuthUserSocial.Query().
|
||||
Where(scaauthusersocial.OpenID(Id),
|
||||
scaauthusersocial.Source(constant.OAuthSourceGithub),
|
||||
scaauthusersocial.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
|
||||
if err != nil && !ent.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if ent.IsNotFound(err) {
|
||||
// 创建用户
|
||||
uid := idgen.NextId()
|
||||
uidStr := strconv.FormatInt(uid, 10)
|
||||
|
||||
addUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Create().
|
||||
SetUID(uidStr).
|
||||
SetAvatar(gitHubUser.AvatarURL).
|
||||
SetUsername(gitHubUser.Login).
|
||||
SetNickname(gitHubUser.Name).
|
||||
SetBlog(gitHubUser.Blog).
|
||||
SetEmail(gitHubUser.Email).
|
||||
SetDeleted(constant.NotDeleted).
|
||||
SetGender(constant.Male).
|
||||
Save(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if err = l.svcCtx.MySQLClient.ScaAuthUserSocial.Create().
|
||||
SetUserID(uidStr).
|
||||
SetOpenID(Id).
|
||||
SetSource(constant.OAuthSourceGithub).
|
||||
Exec(l.ctx); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if res, err := l.svcCtx.CasbinEnforcer.AddRoleForUser(uidStr, constant.User); !res || err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if result := HandleOauthLoginResponse(addUser, l.svcCtx, r, w, l.ctx); !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
} else {
|
||||
sacAuthUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Query().
|
||||
Where(scaauthuser.UID(socialUser.UserID), scaauthuser.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if result := HandleOauthLoginResponse(sacAuthUser, l.svcCtx, r, w, l.ctx); !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTokenAuthUrl 通过code获取token认证url
|
||||
func (l *GithubCallbackLogic) GetTokenAuthUrl(code string) string {
|
||||
clientId := l.svcCtx.Config.OAuth.Github.ClientID
|
||||
clientSecret := l.svcCtx.Config.OAuth.Github.ClientSecret
|
||||
return fmt.Sprintf(
|
||||
"https://github.com/login/oauth/access_token?client_id=%s&client_secret=%s&code=%s",
|
||||
clientId, clientSecret, code,
|
||||
)
|
||||
}
|
||||
|
||||
// GetToken 获取 token
|
||||
func (l *GithubCallbackLogic) GetToken(url string) (*Token, error) {
|
||||
|
||||
// 形成请求
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, url, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json")
|
||||
|
||||
// 发送请求并获得响应
|
||||
var httpClient = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = httpClient.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应体解析为 token,并返回
|
||||
var token Token
|
||||
if err = json.NewDecoder(res.Body).Decode(&token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// GetUserInfo 获取用户信息
|
||||
func (l *GithubCallbackLogic) GetUserInfo(token *Token) (map[string]interface{}, error) {
|
||||
|
||||
// 形成请求
|
||||
var userInfoUrl = "https://api.github.com/user" // github用户信息获取接口
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, userInfoUrl, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("accept", "application/json")
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", token.AccessToken))
|
||||
|
||||
// 发送请求并获取响应
|
||||
var client = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = client.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应的数据写入 userInfo 中,并返回
|
||||
var userInfo = make(map[string]interface{})
|
||||
if err = json.NewDecoder(res.Body).Decode(&userInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
252
app/core/api/internal/logic/oauth/qq_callback_logic.go
Normal file
252
app/core/api/internal/logic/oauth/qq_callback_logic.go
Normal file
@@ -0,0 +1,252 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/yitter/idgenerator-go/idgen"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuser"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthusersocial"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type QqCallbackLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
type AuthQQme struct {
|
||||
ClientID string `json:"client_id"`
|
||||
OpenID string `json:"openid"`
|
||||
}
|
||||
type QQToken struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpireIn string `json:"expire_in"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
type QQUserInfo struct {
|
||||
City string `json:"city"`
|
||||
Figureurl string `json:"figureurl"`
|
||||
Figureurl1 string `json:"figureurl_1"`
|
||||
Figureurl2 string `json:"figureurl_2"`
|
||||
FigureurlQq string `json:"figureurl_qq"`
|
||||
FigureurlQq1 string `json:"figureurl_qq_1"`
|
||||
FigureurlQq2 string `json:"figureurl_qq_2"`
|
||||
Gender string `json:"gender"`
|
||||
GenderType int `json:"gender_type"`
|
||||
IsLost int `json:"is_lost"`
|
||||
IsYellowVip string `json:"is_yellow_vip"`
|
||||
IsYellowYearVip string `json:"is_yellow_year_vip"`
|
||||
Level string `json:"level"`
|
||||
Msg string `json:"msg"`
|
||||
Nickname string `json:"nickname"`
|
||||
Province string `json:"province"`
|
||||
Ret int `json:"ret"`
|
||||
Vip string `json:"vip"`
|
||||
Year string `json:"year"`
|
||||
YellowVipLevel string `json:"yellow_vip_level"`
|
||||
}
|
||||
|
||||
func NewQqCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QqCallbackLogic {
|
||||
return &QqCallbackLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *QqCallbackLogic) QqCallback(w http.ResponseWriter, r *http.Request, req *types.OAuthCallbackRequest) error {
|
||||
|
||||
tokenAuthUrl := l.GetQQTokenAuthUrl(req.Code)
|
||||
token, err := l.GetQQToken(tokenAuthUrl)
|
||||
if err != nil {
|
||||
|
||||
return err
|
||||
}
|
||||
if token == nil {
|
||||
return errors.New("get qq token failed")
|
||||
}
|
||||
|
||||
// 通过 token 获取 openid
|
||||
authQQme, err := l.GetQQUserOpenID(token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 通过 token 和 openid 获取用户信息
|
||||
userInfo, err := l.GetQQUserUserInfo(token, authQQme.OpenID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 处理用户信息
|
||||
userInfoBytes, err := json.Marshal(userInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var qqUserInfo QQUserInfo
|
||||
err = json.Unmarshal(userInfoBytes, &qqUserInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx, err := l.svcCtx.MySQLClient.Tx(l.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
socialUser, err := l.svcCtx.MySQLClient.ScaAuthUserSocial.Query().
|
||||
Where(scaauthusersocial.OpenID(authQQme.OpenID),
|
||||
scaauthusersocial.Source(constant.OAuthSourceQQ),
|
||||
scaauthusersocial.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
|
||||
if err != nil && !ent.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if ent.IsNotFound(err) {
|
||||
// 创建用户
|
||||
uid := idgen.NextId()
|
||||
uidStr := strconv.FormatInt(uid, 10)
|
||||
|
||||
addUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Create().
|
||||
SetUID(uidStr).
|
||||
SetAvatar(qqUserInfo.FigureurlQq1).
|
||||
SetUsername(authQQme.OpenID).
|
||||
SetNickname(qqUserInfo.Nickname).
|
||||
SetDeleted(constant.NotDeleted).
|
||||
SetGender(constant.Male).
|
||||
Save(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if err = l.svcCtx.MySQLClient.ScaAuthUserSocial.Create().
|
||||
SetUserID(uidStr).
|
||||
SetOpenID(authQQme.OpenID).
|
||||
SetSource(constant.OAuthSourceQQ).
|
||||
Exec(l.ctx); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if res, err := l.svcCtx.CasbinEnforcer.AddRoleForUser(uidStr, constant.User); !res || err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if result := HandleOauthLoginResponse(addUser, l.svcCtx, r, w, l.ctx); !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
} else {
|
||||
sacAuthUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Query().
|
||||
Where(scaauthuser.UID(socialUser.UserID), scaauthuser.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if result := HandleOauthLoginResponse(sacAuthUser, l.svcCtx, r, w, l.ctx); !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetQQTokenAuthUrl 通过code获取token认证url
|
||||
func (l *QqCallbackLogic) GetQQTokenAuthUrl(code string) string {
|
||||
clientId := l.svcCtx.Config.OAuth.QQ.ClientID
|
||||
clientSecret := l.svcCtx.Config.OAuth.QQ.ClientSecret
|
||||
redirectURI := l.svcCtx.Config.OAuth.QQ.RedirectURI
|
||||
return fmt.Sprintf(
|
||||
"https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s&fmt=json",
|
||||
clientId, clientSecret, code, redirectURI,
|
||||
)
|
||||
}
|
||||
|
||||
// GetQQToken 获取 token
|
||||
func (l *QqCallbackLogic) GetQQToken(url string) (*QQToken, error) {
|
||||
|
||||
// 形成请求
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, url, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 发送请求并获得响应
|
||||
var httpClient = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = httpClient.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 将响应体解析为 token,并返回
|
||||
var token QQToken
|
||||
if err = json.NewDecoder(res.Body).Decode(&token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// GetQQUserOpenID 获取用户 openid
|
||||
func (l *QqCallbackLogic) GetQQUserOpenID(token *QQToken) (*AuthQQme, error) {
|
||||
|
||||
// 形成请求
|
||||
var userInfoUrl = "https://graph.qq.com/oauth2.0/me?access_token=" + token.AccessToken + "&fmt=json"
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, userInfoUrl, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 发送请求并获取响应
|
||||
var client = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = client.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应体解析为 AuthQQme,并返回
|
||||
var authQQme AuthQQme
|
||||
if err = json.NewDecoder(res.Body).Decode(&authQQme); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &authQQme, nil
|
||||
}
|
||||
|
||||
// GetQQUserUserInfo 获取用户信息
|
||||
func (l *QqCallbackLogic) GetQQUserUserInfo(token *QQToken, openId string) (map[string]interface{}, error) {
|
||||
|
||||
clientId := l.svcCtx.Config.OAuth.QQ.ClientID
|
||||
// 形成请求
|
||||
var userInfoUrl = "https://graph.qq.com/user/get_user_info?access_token=" + token.AccessToken + "&oauth_consumer_key=" + clientId + "&openid=" + openId
|
||||
var req *http.Request
|
||||
var err error
|
||||
if req, err = http.NewRequest(http.MethodGet, userInfoUrl, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 发送请求并获取响应
|
||||
var client = http.Client{}
|
||||
var res *http.Response
|
||||
if res, err = client.Do(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 将响应的数据写入 userInfo 中,并返回
|
||||
var userInfo = make(map[string]interface{})
|
||||
if err = json.NewDecoder(res.Body).Decode(&userInfo); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
201
app/core/api/internal/logic/oauth/wechat_callback_logic.go
Normal file
201
app/core/api/internal/logic/oauth/wechat_callback_logic.go
Normal file
@@ -0,0 +1,201 @@
|
||||
package oauth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ArtisanCloud/PowerLibs/v3/http/helper"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/contract"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/messages"
|
||||
models2 "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount/server/handlers/models"
|
||||
"github.com/yitter/idgenerator-go/idgen"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/i18n"
|
||||
randomname "schisandra-album-cloud-microservices/app/core/api/common/random_name"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/user"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/logic/websocket"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuser"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthusersocial"
|
||||
)
|
||||
|
||||
type WechatCallbackLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewWechatCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WechatCallbackLogic {
|
||||
return &WechatCallbackLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *WechatCallbackLogic) WechatCallback(w http.ResponseWriter, r *http.Request) error {
|
||||
_, err := l.svcCtx.WechatPublic.Server.VerifyURL(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rs, err := l.svcCtx.WechatPublic.Server.Notify(r, func(event contract.EventInterface) interface{} {
|
||||
switch event.GetMsgType() {
|
||||
case models2.CALLBACK_MSG_TYPE_EVENT:
|
||||
switch event.GetEvent() {
|
||||
case models.CALLBACK_EVENT_SUBSCRIBE:
|
||||
msg := models.EventSubscribe{}
|
||||
err = event.ReadMessage(&msg)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return "error"
|
||||
}
|
||||
key := strings.TrimPrefix(msg.EventKey, "qrscene_")
|
||||
err = l.HandlerWechatLogin(msg.FromUserName, key, w, r)
|
||||
if err != nil {
|
||||
return messages.NewText(i18n.FormatText(l.ctx, "login.loginFailed", "登录失败"))
|
||||
}
|
||||
return messages.NewText(i18n.FormatText(l.ctx, "login.loginSuccess", "登录成功"))
|
||||
|
||||
case models.CALLBACK_EVENT_UNSUBSCRIBE:
|
||||
msg := models.EventUnSubscribe{}
|
||||
err := event.ReadMessage(&msg)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return "error"
|
||||
}
|
||||
return messages.NewText("ok")
|
||||
|
||||
case models.CALLBACK_EVENT_SCAN:
|
||||
msg := models.EventScan{}
|
||||
err = event.ReadMessage(&msg)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return "error"
|
||||
}
|
||||
err = l.HandlerWechatLogin(msg.FromUserName, msg.EventKey, w, r)
|
||||
if err != nil {
|
||||
return messages.NewText(i18n.FormatText(l.ctx, "login.loginFailed", "登录失败"))
|
||||
}
|
||||
return messages.NewText(i18n.FormatText(l.ctx, "login.loginSuccess", "登录成功"))
|
||||
|
||||
}
|
||||
|
||||
case models2.CALLBACK_MSG_TYPE_TEXT:
|
||||
msg := models.MessageText{}
|
||||
err := event.ReadMessage(&msg)
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
return "error"
|
||||
}
|
||||
}
|
||||
return messages.NewText("ok")
|
||||
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = helper.HttpResponseSend(rs, w)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandlerWechatLogin 处理微信登录
|
||||
func (l *WechatCallbackLogic) HandlerWechatLogin(openId string, clientId string, w http.ResponseWriter, r *http.Request) error {
|
||||
if openId == "" {
|
||||
return errors.New("openId is empty")
|
||||
}
|
||||
socialUser, err := l.svcCtx.MySQLClient.ScaAuthUserSocial.Query().
|
||||
Where(scaauthusersocial.OpenID(openId),
|
||||
scaauthusersocial.Source(constant.OAuthSourceWechat),
|
||||
scaauthusersocial.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
|
||||
if err != nil && !ent.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
tx, err := l.svcCtx.MySQLClient.Tx(l.ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ent.IsNotFound(err) {
|
||||
// 创建用户
|
||||
uid := idgen.NextId()
|
||||
uidStr := strconv.FormatInt(uid, 10)
|
||||
avatar := utils.GenerateAvatar(uidStr)
|
||||
name := randomname.GenerateName()
|
||||
|
||||
addUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Create().
|
||||
SetUID(uidStr).
|
||||
SetAvatar(avatar).
|
||||
SetUsername(openId).
|
||||
SetNickname(name).
|
||||
SetDeleted(constant.NotDeleted).
|
||||
SetGender(constant.Male).
|
||||
Save(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if err = l.svcCtx.MySQLClient.ScaAuthUserSocial.Create().
|
||||
SetUserID(uidStr).
|
||||
SetOpenID(openId).
|
||||
SetSource(constant.OAuthSourceWechat).
|
||||
Exec(l.ctx); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
if res, err := l.svcCtx.CasbinEnforcer.AddRoleForUser(uidStr, constant.User); !res || err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
data, result := user.HandleUserLogin(addUser, l.svcCtx, true, r, w, l.ctx)
|
||||
if !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
marshal, fault := json.Marshal(data)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
err = websocket.QrcodeWebSocketHandler.SendMessageToClient(clientId, marshal)
|
||||
if err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
} else {
|
||||
sacAuthUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Query().
|
||||
Where(scaauthuser.UID(socialUser.UserID), scaauthuser.Deleted(constant.NotDeleted)).
|
||||
First(l.ctx)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
|
||||
data, result := user.HandleUserLogin(sacAuthUser, l.svcCtx, true, r, w, l.ctx)
|
||||
if !result {
|
||||
return tx.Rollback()
|
||||
}
|
||||
marshal, fault := json.Marshal(data)
|
||||
if fault != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
err = websocket.QrcodeWebSocketHandler.SendMessageToClient(clientId, marshal)
|
||||
if err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return tx.Rollback()
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
73
app/core/api/internal/logic/sms/send_sms_by_aliyun_logic.go
Normal file
73
app/core/api/internal/logic/sms/send_sms_by_aliyun_logic.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
gosms "github.com/pkg6/go-sms"
|
||||
"github.com/pkg6/go-sms/gateways"
|
||||
"github.com/pkg6/go-sms/gateways/aliyun"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/captcha/verify"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SendSmsByAliyunLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSendSmsByAliyunLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendSmsByAliyunLogic {
|
||||
return &SendSmsByAliyunLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SendSmsByAliyunLogic) SendSmsByAliyun(req *types.SmsSendRequest) (resp *types.Response, err error) {
|
||||
|
||||
checkRotateData := verify.VerifyRotateCaptcha(l.ctx, l.svcCtx.RedisClient, req.Angle, req.Key)
|
||||
if !checkRotateData {
|
||||
return response.ErrorWithI18n(l.ctx, "captcha.verificationFailure", "验证码错误"), nil
|
||||
}
|
||||
isPhone := utils.IsPhone(req.Phone)
|
||||
if !isPhone {
|
||||
return response.ErrorWithI18n(l.ctx, "login.phoneFormatError", "手机号格式错误"), nil
|
||||
}
|
||||
val := l.svcCtx.RedisClient.Get(l.ctx, constant.UserSmsRedisPrefix+req.Phone).Val()
|
||||
if val != "" {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendTooFrequently", "验证码发送过于频繁,请稍后再试"), nil
|
||||
}
|
||||
sms := gosms.NewParser(gateways.Gateways{
|
||||
ALiYun: aliyun.ALiYun{
|
||||
Host: l.svcCtx.Config.SMS.Ali.Host,
|
||||
AccessKeyId: l.svcCtx.Config.SMS.Ali.AccessKeyId,
|
||||
AccessKeySecret: l.svcCtx.Config.SMS.Ali.AccessKeySecret,
|
||||
},
|
||||
})
|
||||
code := utils.GenValidateCode(6)
|
||||
wrong := l.svcCtx.RedisClient.Set(l.ctx, constant.UserSmsRedisPrefix+req.Phone, code, time.Minute).Err()
|
||||
if wrong != nil {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendFailed", "验证码发送失败"), wrong
|
||||
}
|
||||
_, err = sms.Send(req.Phone, gosms.MapStringAny{
|
||||
"content": "您的验证码是:****。请不要把验证码泄露给其他人。",
|
||||
"template": l.svcCtx.Config.SMS.Ali.TemplateCode,
|
||||
"signName": l.svcCtx.Config.SMS.Ali.Signature,
|
||||
"data": gosms.MapStrings{
|
||||
"code": code,
|
||||
},
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendFailed", "验证码发送失败"), err
|
||||
}
|
||||
return response.Success(), nil
|
||||
}
|
66
app/core/api/internal/logic/sms/send_sms_by_smsbao_logic.go
Normal file
66
app/core/api/internal/logic/sms/send_sms_by_smsbao_logic.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
gosms "github.com/pkg6/go-sms"
|
||||
"github.com/pkg6/go-sms/gateways"
|
||||
"github.com/pkg6/go-sms/gateways/smsbao"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/captcha/verify"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SendSmsBySmsbaoLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSendSmsBySmsbaoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendSmsBySmsbaoLogic {
|
||||
return &SendSmsBySmsbaoLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SendSmsBySmsbaoLogic) SendSmsBySmsbao(req *types.SmsSendRequest) (resp *types.Response, err error) {
|
||||
checkRotateData := verify.VerifyRotateCaptcha(l.ctx, l.svcCtx.RedisClient, req.Angle, req.Key)
|
||||
if !checkRotateData {
|
||||
return response.ErrorWithI18n(l.ctx, "captcha.verificationFailure", "验证码错误"), nil
|
||||
}
|
||||
isPhone := utils.IsPhone(req.Phone)
|
||||
if !isPhone {
|
||||
return response.ErrorWithI18n(l.ctx, "login.phoneFormatError", "手机号格式错误"), nil
|
||||
}
|
||||
val := l.svcCtx.RedisClient.Get(l.ctx, constant.UserSmsRedisPrefix+req.Phone).Val()
|
||||
if val != "" {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendTooFrequently", "验证码发送过于频繁,请稍后再试"), nil
|
||||
}
|
||||
sms := gosms.NewParser(gateways.Gateways{
|
||||
SmsBao: smsbao.SmsBao{
|
||||
User: l.svcCtx.Config.SMS.SMSBao.Username,
|
||||
Password: l.svcCtx.Config.SMS.SMSBao.Password,
|
||||
},
|
||||
})
|
||||
code := utils.GenValidateCode(6)
|
||||
wrong := l.svcCtx.RedisClient.Set(l.ctx, constant.UserSmsRedisPrefix+req.Phone, code, time.Minute).Err()
|
||||
if wrong != nil {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendFailed", "验证码发送失败"), wrong
|
||||
}
|
||||
_, err = sms.Send(req.Phone, gosms.MapStringAny{
|
||||
"content": "您的验证码是:" + code + "。请不要把验证码泄露给其他人。",
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendFailed", "验证码发送失败"), err
|
||||
}
|
||||
return response.Success(), nil
|
||||
}
|
50
app/core/api/internal/logic/sms/send_sms_by_test_logic.go
Normal file
50
app/core/api/internal/logic/sms/send_sms_by_test_logic.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/captcha/verify"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/response"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type SendSmsByTestLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewSendSmsByTestLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendSmsByTestLogic {
|
||||
return &SendSmsByTestLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SendSmsByTestLogic) SendSmsByTest(req *types.SmsSendRequest) (resp *types.Response, err error) {
|
||||
checkRotateData := verify.VerifyRotateCaptcha(l.ctx, l.svcCtx.RedisClient, req.Angle, req.Key)
|
||||
if !checkRotateData {
|
||||
return response.ErrorWithI18n(l.ctx, "captcha.verificationFailure", "验证码错误"), nil
|
||||
}
|
||||
isPhone := utils.IsPhone(req.Phone)
|
||||
if !isPhone {
|
||||
return response.ErrorWithI18n(l.ctx, "login.phoneFormatError", "手机号格式错误"), nil
|
||||
}
|
||||
val := l.svcCtx.RedisClient.Get(l.ctx, constant.UserSmsRedisPrefix+req.Phone).Val()
|
||||
if val != "" {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendTooFrequently", "验证码发送过于频繁,请稍后再试"), nil
|
||||
}
|
||||
code := utils.GenValidateCode(6)
|
||||
wrong := l.svcCtx.RedisClient.Set(l.ctx, constant.UserSmsRedisPrefix+req.Phone, code, time.Minute).Err()
|
||||
if wrong != nil {
|
||||
return response.ErrorWithI18n(l.ctx, "sms.smsSendFailed", "验证码发送失败"), wrong
|
||||
}
|
||||
return response.Success(), nil
|
||||
}
|
@@ -5,8 +5,6 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"github.com/mssola/useragent"
|
||||
"github.com/zeromicro/go-zero/core/logc"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
@@ -19,7 +17,6 @@ import (
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuser"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuserdevice"
|
||||
)
|
||||
|
||||
type AccountLoginLogic struct {
|
||||
@@ -116,87 +113,14 @@ func HandleUserLogin(user *ent.ScaAuthUser, svcCtx *svc.ServiceContext, autoLogi
|
||||
return nil, false
|
||||
}
|
||||
session.Values[constant.SESSION_KEY] = sessionData
|
||||
if err = session.Save(r, w); err != nil {
|
||||
logc.Error(ctx, err)
|
||||
err = session.Save(r, w)
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
// 记录用户登录设备
|
||||
if !getUserLoginDevice(user.UID, r, svcCtx.Ip2Region, svcCtx.MySQLClient, ctx) {
|
||||
if !GetUserLoginDevice(user.UID, r, svcCtx.Ip2Region, svcCtx.MySQLClient, ctx) {
|
||||
return nil, false
|
||||
}
|
||||
return &data, true
|
||||
|
||||
}
|
||||
|
||||
// getUserLoginDevice 获取用户登录设备
|
||||
func getUserLoginDevice(userId string, r *http.Request, ip2location *xdb.Searcher, entClient *ent.Client, ctx context.Context) bool {
|
||||
userAgent := r.Header.Get("User-Agent")
|
||||
if userAgent == "" {
|
||||
return false
|
||||
}
|
||||
ip := utils.GetClientIP(r)
|
||||
location, err := ip2location.SearchByStr(ip)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
location = utils.RemoveZeroAndAdjust(location)
|
||||
|
||||
ua := useragent.New(userAgent)
|
||||
isBot := ua.Bot()
|
||||
browser, browserVersion := ua.Browser()
|
||||
os := ua.OS()
|
||||
mobile := ua.Mobile()
|
||||
mozilla := ua.Mozilla()
|
||||
platform := ua.Platform()
|
||||
engine, engineVersion := ua.Engine()
|
||||
|
||||
device, err := entClient.ScaAuthUserDevice.Query().
|
||||
Where(scaauthuserdevice.UserID(userId), scaauthuserdevice.IP(ip), scaauthuserdevice.Agent(userAgent)).
|
||||
Only(ctx)
|
||||
|
||||
// 如果有错误,表示设备不存在,执行插入
|
||||
if ent.IsNotFound(err) {
|
||||
// 创建新的设备记录
|
||||
err = entClient.ScaAuthUserDevice.Create().
|
||||
SetBot(isBot).
|
||||
SetAgent(userAgent).
|
||||
SetBrowser(browser).
|
||||
SetBrowserVersion(browserVersion).
|
||||
SetEngineName(engine).
|
||||
SetEngineVersion(engineVersion).
|
||||
SetIP(ip).
|
||||
SetLocation(location).
|
||||
SetOperatingSystem(os).
|
||||
SetMobile(mobile).
|
||||
SetMozilla(mozilla).
|
||||
SetPlatform(platform).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else if err == nil {
|
||||
// 如果设备存在,执行更新
|
||||
err = device.Update().
|
||||
SetBot(isBot).
|
||||
SetAgent(userAgent).
|
||||
SetBrowser(browser).
|
||||
SetBrowserVersion(browserVersion).
|
||||
SetEngineName(engine).
|
||||
SetEngineVersion(engineVersion).
|
||||
SetIP(ip).
|
||||
SetLocation(location).
|
||||
SetOperatingSystem(os).
|
||||
SetMobile(mobile).
|
||||
SetMozilla(mozilla).
|
||||
SetPlatform(platform).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
logc.Error(ctx, err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
133
app/core/api/internal/logic/user/get_user_device_logic.go
Normal file
133
app/core/api/internal/logic/user/get_user_device_logic.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"github.com/mssola/useragent"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/types"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent/scaauthuserdevice"
|
||||
)
|
||||
|
||||
type GetUserDeviceLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewGetUserDeviceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserDeviceLogic {
|
||||
return &GetUserDeviceLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetUserDeviceLogic) GetUserDevice(r *http.Request) error {
|
||||
session, err := l.svcCtx.Session.Get(r, constant.SESSION_KEY)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sessionData, ok := session.Values[constant.SESSION_KEY]
|
||||
if !ok {
|
||||
return errors.New("User not found or device not found")
|
||||
}
|
||||
var data types.SessionData
|
||||
err = json.Unmarshal(sessionData.([]byte), &data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res := GetUserLoginDevice(data.UID, r, l.svcCtx.Ip2Region, l.svcCtx.MySQLClient, l.ctx)
|
||||
if !res {
|
||||
return errors.New("User not found or device not found")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserLoginDevice 获取用户登录设备
|
||||
func GetUserLoginDevice(userId string, r *http.Request, ip2location *xdb.Searcher, entClient *ent.Client, ctx context.Context) bool {
|
||||
userAgent := r.Header.Get("User-Agent")
|
||||
if userAgent == "" {
|
||||
return false
|
||||
}
|
||||
ip := utils.GetClientIP(r)
|
||||
location, err := ip2location.SearchByStr(ip)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return false
|
||||
}
|
||||
location = utils.RemoveZeroAndAdjust(location)
|
||||
|
||||
ua := useragent.New(userAgent)
|
||||
isBot := ua.Bot()
|
||||
browser, browserVersion := ua.Browser()
|
||||
os := ua.OS()
|
||||
mobile := ua.Mobile()
|
||||
mozilla := ua.Mozilla()
|
||||
platform := ua.Platform()
|
||||
engine, engineVersion := ua.Engine()
|
||||
|
||||
device, err := entClient.ScaAuthUserDevice.Query().
|
||||
Where(scaauthuserdevice.UserID(userId), scaauthuserdevice.IP(ip), scaauthuserdevice.Agent(userAgent)).
|
||||
Only(ctx)
|
||||
|
||||
// 如果有错误,表示设备不存在,执行插入
|
||||
if ent.IsNotFound(err) {
|
||||
// 创建新的设备记录
|
||||
err = entClient.ScaAuthUserDevice.Create().
|
||||
SetUserID(userId).
|
||||
SetBot(isBot).
|
||||
SetAgent(userAgent).
|
||||
SetBrowser(browser).
|
||||
SetBrowserVersion(browserVersion).
|
||||
SetEngineName(engine).
|
||||
SetEngineVersion(engineVersion).
|
||||
SetIP(ip).
|
||||
SetLocation(location).
|
||||
SetOperatingSystem(os).
|
||||
SetMobile(mobile).
|
||||
SetMozilla(mozilla).
|
||||
SetPlatform(platform).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else if err == nil {
|
||||
// 如果设备存在,执行更新
|
||||
err = device.Update().
|
||||
SetUserID(userId).
|
||||
SetBot(isBot).
|
||||
SetAgent(userAgent).
|
||||
SetBrowser(browser).
|
||||
SetBrowserVersion(browserVersion).
|
||||
SetEngineName(engine).
|
||||
SetEngineVersion(engineVersion).
|
||||
SetIP(ip).
|
||||
SetLocation(location).
|
||||
SetOperatingSystem(os).
|
||||
SetMobile(mobile).
|
||||
SetMozilla(mozilla).
|
||||
SetPlatform(platform).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
logx.Error(err)
|
||||
return false
|
||||
}
|
||||
}
|
@@ -43,7 +43,7 @@ func (l *PhoneLoginLogic) PhoneLogin(r *http.Request, w http.ResponseWriter, req
|
||||
if req.Captcha != code {
|
||||
return response.ErrorWithI18n(l.ctx, "login.captchaError", "验证码错误"), nil
|
||||
}
|
||||
user, err := l.svcCtx.MySQLClient.ScaAuthUser.Query().Where(scaauthuser.Phone(req.Phone), scaauthuser.Deleted(0)).Only(l.ctx)
|
||||
user, err := l.svcCtx.MySQLClient.ScaAuthUser.Query().Where(scaauthuser.Phone(req.Phone), scaauthuser.Deleted(0)).First(l.ctx)
|
||||
tx, wrong := l.svcCtx.MySQLClient.Tx(l.ctx)
|
||||
if wrong != nil {
|
||||
return response.ErrorWithI18n(l.ctx, "login.loginFailed", "登录失败"), err
|
||||
@@ -54,7 +54,7 @@ func (l *PhoneLoginLogic) PhoneLogin(r *http.Request, w http.ResponseWriter, req
|
||||
avatar := utils.GenerateAvatar(uidStr)
|
||||
name := randomname.GenerateName()
|
||||
|
||||
addUser, wrong := l.svcCtx.MySQLClient.ScaAuthUser.Create().
|
||||
addUser, fault := l.svcCtx.MySQLClient.ScaAuthUser.Create().
|
||||
SetUID(uidStr).
|
||||
SetPhone(req.Phone).
|
||||
SetAvatar(avatar).
|
||||
@@ -62,7 +62,12 @@ func (l *PhoneLoginLogic) PhoneLogin(r *http.Request, w http.ResponseWriter, req
|
||||
SetDeleted(constant.NotDeleted).
|
||||
SetGender(constant.Male).
|
||||
Save(l.ctx)
|
||||
if wrong != nil {
|
||||
if fault != nil {
|
||||
err = tx.Rollback()
|
||||
return response.ErrorWithI18n(l.ctx, "login.registerError", "注册失败"), err
|
||||
}
|
||||
_, err = l.svcCtx.CasbinEnforcer.AddRoleForUser(uidStr, constant.User)
|
||||
if err != nil {
|
||||
err = tx.Rollback()
|
||||
return response.ErrorWithI18n(l.ctx, "login.registerError", "注册失败"), err
|
||||
}
|
||||
@@ -72,15 +77,21 @@ func (l *PhoneLoginLogic) PhoneLogin(r *http.Request, w http.ResponseWriter, req
|
||||
return response.ErrorWithI18n(l.ctx, "login.registerError", "注册失败"), err
|
||||
}
|
||||
err = tx.Commit()
|
||||
return response.SuccessWithData(data), err
|
||||
} else if err != nil {
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
return response.SuccessWithData(data), nil
|
||||
} else if err == nil {
|
||||
data, result := HandleUserLogin(user, l.svcCtx, req.AutoLogin, r, w, l.ctx)
|
||||
if !result {
|
||||
err = tx.Rollback()
|
||||
return response.ErrorWithI18n(l.ctx, "login.loginFailed", "登录失败"), err
|
||||
}
|
||||
err = tx.Commit()
|
||||
return response.SuccessWithData(data), err
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
return response.SuccessWithData(data), nil
|
||||
} else {
|
||||
return response.ErrorWithI18n(l.ctx, "login.loginFailed", "登录失败"), nil
|
||||
}
|
||||
|
193
app/core/api/internal/logic/websocket/message_websocket_logic.go
Normal file
193
app/core/api/internal/logic/websocket/message_websocket_logic.go
Normal file
@@ -0,0 +1,193 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/lxzan/gws"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/jwt"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
type MessageWebsocketLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewMessageWebsocketLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MessageWebsocketLogic {
|
||||
return &MessageWebsocketLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
type MessageWebSocket struct {
|
||||
redis *redis.Client
|
||||
ctx context.Context
|
||||
gws.BuiltinEventHandler
|
||||
sessions *gws.ConcurrentMap[string, *gws.Conn] // 使用内置的ConcurrentMap存储连接, 可以减少锁冲突
|
||||
}
|
||||
|
||||
var MessageWebSocketHandler *MessageWebSocket
|
||||
|
||||
// InitializeWebSocketHandler 初始化WebSocketHandler
|
||||
func InitializeWebSocketHandler(svcCtx *svc.ServiceContext) {
|
||||
MessageWebSocketHandler = NewMessageWebSocket(svcCtx)
|
||||
}
|
||||
func (l *MessageWebsocketLogic) MessageWebsocket(w http.ResponseWriter, r *http.Request) error {
|
||||
upgrader := gws.NewUpgrader(MessageWebSocketHandler, &gws.ServerOption{
|
||||
HandshakeTimeout: 5 * time.Second, // 握手超时时间
|
||||
ReadBufferSize: 1024, // 读缓冲区大小
|
||||
ParallelEnabled: true, // 开启并行消息处理
|
||||
Recovery: gws.Recovery, // 开启异常恢复
|
||||
CheckUtf8Enabled: false, // 关闭UTF8校验
|
||||
PermessageDeflate: gws.PermessageDeflate{
|
||||
Enabled: true, // 开启压缩
|
||||
},
|
||||
Authorize: func(r *http.Request, session gws.SessionStorage) bool {
|
||||
var clientId = r.URL.Query().Get("user_id")
|
||||
if clientId == "" {
|
||||
return false
|
||||
}
|
||||
token := r.URL.Query().Get("token")
|
||||
if token == "" {
|
||||
return false
|
||||
}
|
||||
accessToken, res := jwt.ParseAccessToken(l.svcCtx.Config.Auth.AccessSecret, token)
|
||||
if !res || accessToken.UserID != clientId {
|
||||
return false
|
||||
}
|
||||
session.Store("user_id", clientId)
|
||||
return true
|
||||
},
|
||||
})
|
||||
socket, err := upgrader.Upgrade(w, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
socket.ReadLoop() // 此处阻塞会使请求上下文不能顺利被GC
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewMessageWebSocket 创建WebSocket实例
|
||||
func NewMessageWebSocket(svcCtx *svc.ServiceContext) *MessageWebSocket {
|
||||
return &MessageWebSocket{
|
||||
redis: svcCtx.RedisClient,
|
||||
ctx: context.Background(),
|
||||
sessions: gws.NewConcurrentMap[string, *gws.Conn](64, 128),
|
||||
}
|
||||
}
|
||||
|
||||
// OnOpen 连接建立
|
||||
func (c *MessageWebSocket) OnOpen(socket *gws.Conn) {
|
||||
clientId := MustLoad[string](socket.Session(), "user_id")
|
||||
c.sessions.Store(clientId, socket)
|
||||
// 订阅该用户的频道
|
||||
go c.subscribeUserChannel(clientId, c.redis)
|
||||
fmt.Printf("websocket client %s connected\n", clientId)
|
||||
}
|
||||
|
||||
// OnClose 关闭连接
|
||||
func (c *MessageWebSocket) OnClose(socket *gws.Conn, err error) {
|
||||
name := MustLoad[string](socket.Session(), "user_id")
|
||||
sharding := c.sessions.GetSharding(name)
|
||||
c.sessions.Delete(name)
|
||||
sharding.Lock()
|
||||
defer sharding.Unlock()
|
||||
fmt.Printf("websocket closed, name=%s, msg=%s\n", name, err.Error())
|
||||
}
|
||||
|
||||
// OnPing 处理客户端的Ping消息
|
||||
func (c *MessageWebSocket) OnPing(socket *gws.Conn, payload []byte) {
|
||||
_ = socket.SetDeadline(time.Now().Add(PingInterval + HeartbeatWaitTimeout))
|
||||
_ = socket.WritePong(payload)
|
||||
}
|
||||
|
||||
// OnPong 处理客户端的Pong消息
|
||||
func (c *MessageWebSocket) OnPong(_ *gws.Conn, _ []byte) {}
|
||||
|
||||
// OnMessage 接受消息
|
||||
func (c *MessageWebSocket) OnMessage(socket *gws.Conn, message *gws.Message) {
|
||||
defer message.Close()
|
||||
clientId := MustLoad[string](socket.Session(), "user_id")
|
||||
if conn, ok := c.sessions.Load(clientId); ok {
|
||||
_ = conn.WriteMessage(gws.OpcodeText, message.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
// SendMessageToClient 向指定客户端发送消息
|
||||
func (c *MessageWebSocket) SendMessageToClient(clientId string, message []byte) error {
|
||||
conn, ok := c.sessions.Load(clientId)
|
||||
if ok {
|
||||
return conn.WriteMessage(gws.OpcodeText, message)
|
||||
}
|
||||
return fmt.Errorf("client %s not found", clientId)
|
||||
}
|
||||
|
||||
// SendMessageToUser 发送消息到指定用户的 Redis 频道
|
||||
func (c *MessageWebSocket) SendMessageToUser(clientId string, message []byte, redis *redis.Client, ctx context.Context) error {
|
||||
if _, ok := c.sessions.Load(clientId); ok {
|
||||
return redis.Publish(ctx, clientId, message).Err()
|
||||
} else {
|
||||
return redis.LPush(ctx, constant.CommentOfflineMessagePrefix+clientId, message).Err()
|
||||
}
|
||||
}
|
||||
|
||||
// 订阅用户频道
|
||||
func (c *MessageWebSocket) subscribeUserChannel(clientId string, redis *redis.Client) {
|
||||
conn, ok := c.sessions.Load(clientId)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取离线消息
|
||||
messages, err := redis.LRange(c.ctx, constant.CommentOfflineMessagePrefix+clientId, 0, -1).Result()
|
||||
if err != nil {
|
||||
fmt.Printf("Error loading offline messages for user %s: %v\n", clientId, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 逐条发送离线消息
|
||||
for _, msg := range messages {
|
||||
if writeErr := conn.WriteMessage(gws.OpcodeText, []byte(msg)); writeErr != nil {
|
||||
fmt.Printf("Error writing offline message to user %s: %v\n", clientId, writeErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 清空离线消息列表
|
||||
if delErr := redis.Del(c.ctx, constant.CommentOfflineMessagePrefix+clientId); delErr.Err() != nil {
|
||||
fmt.Printf("Error clearing offline messages for user %s: %v\n", clientId, delErr.Err())
|
||||
return
|
||||
}
|
||||
|
||||
pubsub := redis.Subscribe(c.ctx, clientId)
|
||||
defer func() {
|
||||
if closeErr := pubsub.Close(); closeErr != nil {
|
||||
fmt.Printf("Error closing pubsub for user %s: %v\n", clientId, closeErr)
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
msg, waitErr := pubsub.ReceiveMessage(context.Background())
|
||||
if waitErr != nil {
|
||||
fmt.Printf("Error receiving message for user %s: %v\n", clientId, err)
|
||||
return
|
||||
}
|
||||
|
||||
if writeErr := conn.WriteMessage(gws.OpcodeText, []byte(msg.Payload)); writeErr != nil {
|
||||
fmt.Printf("Error writing message to user %s: %v\n", clientId, writeErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
134
app/core/api/internal/logic/websocket/qrcode_websocket_logic.go
Normal file
134
app/core/api/internal/logic/websocket/qrcode_websocket_logic.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/lxzan/gws"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/constant"
|
||||
"schisandra-album-cloud-microservices/app/core/api/common/utils"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
|
||||
)
|
||||
|
||||
type QrcodeWebsocketLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewQrcodeWebsocketLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QrcodeWebsocketLogic {
|
||||
return &QrcodeWebsocketLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
PingInterval = 5 * time.Second // 客户端心跳间隔
|
||||
HeartbeatWaitTimeout = 10 * time.Second // 心跳等待超时时间
|
||||
)
|
||||
|
||||
type QrcodeWebSocket struct {
|
||||
gws.BuiltinEventHandler
|
||||
sessions *gws.ConcurrentMap[string, *gws.Conn] // 使用内置的ConcurrentMap存储连接, 可以减少锁冲突
|
||||
}
|
||||
|
||||
var QrcodeWebSocketHandler = NewWebSocket()
|
||||
|
||||
func (l *QrcodeWebsocketLogic) QrcodeWebsocket(w http.ResponseWriter, r *http.Request) error {
|
||||
upgrader := gws.NewUpgrader(QrcodeWebSocketHandler, &gws.ServerOption{
|
||||
HandshakeTimeout: 5 * time.Second, // 握手超时时间
|
||||
ReadBufferSize: 1024, // 读缓冲区大小
|
||||
ParallelEnabled: true, // 开启并行消息处理
|
||||
Recovery: gws.Recovery, // 开启异常恢复
|
||||
CheckUtf8Enabled: false, // 关闭UTF8校验
|
||||
PermessageDeflate: gws.PermessageDeflate{
|
||||
Enabled: true, // 开启压缩
|
||||
},
|
||||
Authorize: func(r *http.Request, session gws.SessionStorage) bool {
|
||||
var clientId = r.URL.Query().Get("client_id")
|
||||
if clientId == "" {
|
||||
return false
|
||||
}
|
||||
ip := utils.GetClientIP(r)
|
||||
exists := l.svcCtx.RedisClient.Get(l.ctx, constant.UserClientPrefix+ip).Val()
|
||||
if clientId != exists {
|
||||
return false
|
||||
}
|
||||
session.Store("client_id", clientId)
|
||||
return true
|
||||
},
|
||||
})
|
||||
socket, err := upgrader.Upgrade(w, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
socket.ReadLoop() // 此处阻塞会使请求上下文不能顺利被GC
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustLoad 从session中加载数据
|
||||
func MustLoad[T any](session gws.SessionStorage, key string) (v T) {
|
||||
if value, exist := session.Load(key); exist {
|
||||
v = value.(T)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// NewWebSocket 创建WebSocket实例
|
||||
func NewWebSocket() *QrcodeWebSocket {
|
||||
return &QrcodeWebSocket{
|
||||
sessions: gws.NewConcurrentMap[string, *gws.Conn](64, 128),
|
||||
}
|
||||
}
|
||||
|
||||
// OnOpen 连接建立
|
||||
func (c *QrcodeWebSocket) OnOpen(socket *gws.Conn) {
|
||||
clientId := MustLoad[string](socket.Session(), "client_id")
|
||||
c.sessions.Store(clientId, socket)
|
||||
fmt.Printf("websocket client %s connected\n", clientId)
|
||||
}
|
||||
|
||||
// OnClose 关闭连接
|
||||
func (c *QrcodeWebSocket) OnClose(socket *gws.Conn, err error) {
|
||||
name := MustLoad[string](socket.Session(), "client_id")
|
||||
sharding := c.sessions.GetSharding(name)
|
||||
c.sessions.Delete(name)
|
||||
sharding.Lock()
|
||||
defer sharding.Unlock()
|
||||
fmt.Printf("websocket closed, name=%s, err=%s\n", name, err.Error())
|
||||
}
|
||||
|
||||
// OnPing 处理客户端的Ping消息
|
||||
func (c *QrcodeWebSocket) OnPing(socket *gws.Conn, payload []byte) {
|
||||
_ = socket.SetDeadline(time.Now().Add(PingInterval + HeartbeatWaitTimeout))
|
||||
_ = socket.WritePong(payload)
|
||||
}
|
||||
|
||||
// OnPong 处理客户端的Pong消息
|
||||
func (c *QrcodeWebSocket) OnPong(_ *gws.Conn, _ []byte) {}
|
||||
|
||||
// OnMessage 接受消息
|
||||
func (c *QrcodeWebSocket) OnMessage(socket *gws.Conn, message *gws.Message) {
|
||||
defer message.Close()
|
||||
clientId := MustLoad[string](socket.Session(), "client_id")
|
||||
if conn, ok := c.sessions.Load(clientId); ok {
|
||||
_ = conn.WriteMessage(gws.OpcodeText, message.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
// SendMessageToClient 向指定客户端发送消息
|
||||
func (c *QrcodeWebSocket) SendMessageToClient(clientId string, message []byte) error {
|
||||
conn, ok := c.sessions.Load(clientId)
|
||||
if ok {
|
||||
return conn.WriteMessage(gws.OpcodeText, message)
|
||||
}
|
||||
return fmt.Errorf("client %s not found", clientId)
|
||||
}
|
@@ -1,16 +1,21 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount"
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
"github.com/rbcervilla/redisstore/v9"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/wenlng/go-captcha/v2/rotate"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
sensitive "github.com/zmexing/go-sensitive-word"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
"go.mongodb.org/mongo-driver/v2/mongo"
|
||||
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/config"
|
||||
"schisandra-album-cloud-microservices/app/core/api/internal/middleware"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/captcha"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/casbinx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/ip2region"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mongodb"
|
||||
@@ -18,6 +23,8 @@ import (
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/ent"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/redis_session"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/redisx"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/sensitivex"
|
||||
"schisandra-album-cloud-microservices/app/core/api/repository/wechat_public"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
@@ -29,6 +36,10 @@ type ServiceContext struct {
|
||||
Session *redisstore.RedisStore
|
||||
Ip2Region *xdb.Searcher
|
||||
CasbinEnforcer *casbin.CachedEnforcer
|
||||
WechatPublic *officialAccount.OfficialAccount
|
||||
Sensitive *sensitive.Manager
|
||||
RotateCaptcha rotate.Captcha
|
||||
SlideCaptcha slide.Captcha
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@@ -41,5 +52,9 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
Session: redis_session.NewRedisSession(c.Redis.Host, c.Redis.Pass),
|
||||
Ip2Region: ip2region.NewIP2Region(),
|
||||
CasbinEnforcer: casbinx.NewCasbin(c.Mysql.DataSource),
|
||||
WechatPublic: wechat_public.NewWechatPublic(c.Wechat.AppID, c.Wechat.AppSecret, c.Wechat.Token, c.Wechat.AESKey, c.Redis.Host, c.Redis.Pass, c.Redis.DB),
|
||||
Sensitive: sensitivex.NewSensitive(),
|
||||
RotateCaptcha: captcha.NewRotateCaptcha(),
|
||||
SlideCaptcha: captcha.NewSlideCaptcha(),
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,18 @@ type LoginResponse struct {
|
||||
Status int8 `json:"status"`
|
||||
}
|
||||
|
||||
type OAuthCallbackRequest struct {
|
||||
Code string `form:"code"`
|
||||
}
|
||||
|
||||
type OAuthRequest struct {
|
||||
State string `form:"state"`
|
||||
}
|
||||
|
||||
type OAuthWechatRequest struct {
|
||||
Client_id string `form:"client_id"`
|
||||
}
|
||||
|
||||
type PhoneLoginRequest struct {
|
||||
Phone string `json:"phone"`
|
||||
Captcha string `json:"captcha"`
|
||||
@@ -38,3 +50,9 @@ type Response struct {
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data,optional"`
|
||||
}
|
||||
|
||||
type SmsSendRequest struct {
|
||||
Phone string `json:"phone"`
|
||||
Angle int64 `json:"angle"`
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
38
app/core/api/repository/captcha/click_shape_captcha.go
Normal file
38
app/core/api/repository/captcha/click_shape_captcha.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"github.com/wenlng/go-captcha-assets/resources/images"
|
||||
"github.com/wenlng/go-captcha-assets/resources/shapes"
|
||||
"github.com/wenlng/go-captcha/v2/base/option"
|
||||
"github.com/wenlng/go-captcha/v2/click"
|
||||
)
|
||||
|
||||
// NewClickShapeCaptcha 初始化点击形状验证码
|
||||
func NewClickShapeCaptcha() click.Captcha {
|
||||
builder := click.NewBuilder(
|
||||
click.WithRangeLen(option.RangeVal{Min: 3, Max: 6}),
|
||||
click.WithRangeVerifyLen(option.RangeVal{Min: 2, Max: 3}),
|
||||
click.WithRangeThumbBgDistort(1),
|
||||
click.WithIsThumbNonDeformAbility(true),
|
||||
)
|
||||
|
||||
// shape
|
||||
// click.WithUseShapeOriginalColor(false) -> Random rewriting of graphic colors
|
||||
shapeMaps, err := shapes.GetShapes()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// background images
|
||||
imgs, err := images.GetImages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// set resources
|
||||
builder.SetResources(
|
||||
click.WithShapes(shapeMaps),
|
||||
click.WithBackgrounds(imgs),
|
||||
)
|
||||
return builder.MakeWithShape()
|
||||
}
|
26
app/core/api/repository/captcha/rotate_captcha.go
Normal file
26
app/core/api/repository/captcha/rotate_captcha.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"github.com/wenlng/go-captcha-assets/resources/images"
|
||||
"github.com/wenlng/go-captcha/v2/base/option"
|
||||
"github.com/wenlng/go-captcha/v2/rotate"
|
||||
)
|
||||
|
||||
// NewRotateCaptcha 初始化旋转验证码
|
||||
func NewRotateCaptcha() rotate.Captcha {
|
||||
builder := rotate.NewBuilder(rotate.WithRangeAnglePos([]option.RangeVal{
|
||||
{Min: 20, Max: 330},
|
||||
}))
|
||||
|
||||
// background images
|
||||
imgs, err := images.GetImages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// set resources
|
||||
builder.SetResources(
|
||||
rotate.WithImages(imgs),
|
||||
)
|
||||
return builder.Make()
|
||||
}
|
44
app/core/api/repository/captcha/slide_captcha.go
Normal file
44
app/core/api/repository/captcha/slide_captcha.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"github.com/wenlng/go-captcha-assets/resources/images"
|
||||
"github.com/wenlng/go-captcha-assets/resources/tiles"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
)
|
||||
|
||||
// NewSlideCaptcha 初始化滑动验证码
|
||||
func NewSlideCaptcha() slide.Captcha {
|
||||
builder := slide.NewBuilder(
|
||||
// slide.WithGenGraphNumber(2),
|
||||
slide.WithEnableGraphVerticalRandom(true),
|
||||
)
|
||||
|
||||
// background images
|
||||
imgs, err := images.GetImages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
graphs, err := tiles.GetTiles()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var newGraphs = make([]*slide.GraphImage, 0, len(graphs))
|
||||
for i := 0; i < len(graphs); i++ {
|
||||
graph := graphs[i]
|
||||
newGraphs = append(newGraphs, &slide.GraphImage{
|
||||
OverlayImage: graph.OverlayImage,
|
||||
MaskImage: graph.MaskImage,
|
||||
ShadowImage: graph.ShadowImage,
|
||||
})
|
||||
}
|
||||
|
||||
// set resources
|
||||
builder.SetResources(
|
||||
slide.WithGraphImages(newGraphs),
|
||||
slide.WithBackgrounds(imgs),
|
||||
)
|
||||
|
||||
return builder.Make()
|
||||
}
|
43
app/core/api/repository/captcha/slide_region_captcha.go
Normal file
43
app/core/api/repository/captcha/slide_region_captcha.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"github.com/wenlng/go-captcha-assets/resources/images"
|
||||
"github.com/wenlng/go-captcha-assets/resources/tiles"
|
||||
"github.com/wenlng/go-captcha/v2/slide"
|
||||
)
|
||||
|
||||
// NewSlideRegionCaptcha 初始化滑动区域验证码
|
||||
func NewSlideRegionCaptcha() slide.Captcha {
|
||||
builder := slide.NewBuilder(
|
||||
slide.WithGenGraphNumber(2),
|
||||
slide.WithEnableGraphVerticalRandom(true),
|
||||
)
|
||||
|
||||
// background image
|
||||
imgs, err := images.GetImages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
graphs, err := tiles.GetTiles()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var newGraphs = make([]*slide.GraphImage, 0, len(graphs))
|
||||
for i := 0; i < len(graphs); i++ {
|
||||
graph := graphs[i]
|
||||
newGraphs = append(newGraphs, &slide.GraphImage{
|
||||
OverlayImage: graph.OverlayImage,
|
||||
MaskImage: graph.MaskImage,
|
||||
ShadowImage: graph.ShadowImage,
|
||||
})
|
||||
}
|
||||
|
||||
// set resources
|
||||
builder.SetResources(
|
||||
slide.WithGraphImages(newGraphs),
|
||||
slide.WithBackgrounds(imgs),
|
||||
)
|
||||
|
||||
return builder.MakeWithRegion()
|
||||
}
|
97
app/core/api/repository/captcha/text_captcha.go
Normal file
97
app/core/api/repository/captcha/text_captcha.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/wenlng/go-captcha-assets/resources/fonts/fzshengsksjw"
|
||||
"github.com/wenlng/go-captcha-assets/resources/images"
|
||||
"github.com/wenlng/go-captcha-assets/sourcedata/chars"
|
||||
"github.com/wenlng/go-captcha/v2/base/option"
|
||||
"github.com/wenlng/go-captcha/v2/click"
|
||||
)
|
||||
|
||||
// NewTextCaptcha 初始化点选验证码
|
||||
func NewTextCaptcha() click.Captcha {
|
||||
builder := click.NewBuilder(
|
||||
click.WithRangeLen(option.RangeVal{Min: 4, Max: 6}),
|
||||
click.WithRangeVerifyLen(option.RangeVal{Min: 2, Max: 4}),
|
||||
click.WithRangeThumbColors([]string{
|
||||
"#1f55c4",
|
||||
"#780592",
|
||||
"#2f6b00",
|
||||
"#910000",
|
||||
"#864401",
|
||||
"#675901",
|
||||
"#016e5c",
|
||||
}),
|
||||
click.WithRangeColors([]string{
|
||||
"#fde98e",
|
||||
"#60c1ff",
|
||||
"#fcb08e",
|
||||
"#fb88ff",
|
||||
"#b4fed4",
|
||||
"#cbfaa9",
|
||||
"#78d6f8",
|
||||
}),
|
||||
)
|
||||
|
||||
// fonts
|
||||
fonts, err := fzshengsksjw.GetFont()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// background images
|
||||
imgs, err := images.GetImages()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// thumb images
|
||||
// thumbImages, err := thumbs.GetThumbs()
|
||||
// if err != nil {
|
||||
// log.Fatalln(err)
|
||||
// }
|
||||
|
||||
// set resources
|
||||
builder.SetResources(
|
||||
click.WithChars(chars.GetChineseChars()),
|
||||
// click.WithChars([]string{
|
||||
// "1A",
|
||||
// "5E",
|
||||
// "3d",
|
||||
// "0p",
|
||||
// "78",
|
||||
// "DL",
|
||||
// "CB",
|
||||
// "9M",
|
||||
// }),
|
||||
// click.WithChars(chars.GetAlphaChars()),
|
||||
click.WithFonts([]*truetype.Font{fonts}),
|
||||
click.WithBackgrounds(imgs),
|
||||
// click.WithThumbBackgrounds(thumbImages),
|
||||
)
|
||||
// global.TextCaptcha = builder.Make()
|
||||
|
||||
// ============================
|
||||
|
||||
builder.Clear()
|
||||
builder.SetOptions(
|
||||
click.WithRangeLen(option.RangeVal{Min: 4, Max: 6}),
|
||||
click.WithRangeVerifyLen(option.RangeVal{Min: 2, Max: 4}),
|
||||
click.WithRangeThumbColors([]string{
|
||||
"#4a85fb",
|
||||
"#d93ffb",
|
||||
"#56be01",
|
||||
"#ee2b2b",
|
||||
"#cd6904",
|
||||
"#b49b03",
|
||||
"#01ad90",
|
||||
}),
|
||||
)
|
||||
builder.SetResources(
|
||||
click.WithChars(chars.GetChineseChars()),
|
||||
click.WithFonts([]*truetype.Font{fonts}),
|
||||
click.WithBackgrounds(imgs),
|
||||
)
|
||||
return builder.Make()
|
||||
}
|
@@ -31,8 +31,8 @@ var (
|
||||
ScaAuthRoleColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true, Comment: "主键ID", SchemaType: map[string]string{"mysql": "bigint(20)"}},
|
||||
{Name: "created_at", Type: field.TypeTime, Comment: "创建时间"},
|
||||
{Name: "updated_at", Type: field.TypeTime, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Nullable: true, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "updated_at", Type: field.TypeTime, Nullable: true, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "role_name", Type: field.TypeString, Size: 32, Comment: "角色名称"},
|
||||
{Name: "role_key", Type: field.TypeString, Size: 64, Comment: "角色关键字"},
|
||||
}
|
||||
@@ -47,8 +47,8 @@ var (
|
||||
ScaAuthUserColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true, Comment: "自增ID", SchemaType: map[string]string{"mysql": "bigint(20)"}},
|
||||
{Name: "created_at", Type: field.TypeTime, Comment: "创建时间"},
|
||||
{Name: "updated_at", Type: field.TypeTime, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Nullable: true, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "updated_at", Type: field.TypeTime, Nullable: true, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "uid", Type: field.TypeString, Unique: true, Size: 20, Comment: "唯一ID"},
|
||||
{Name: "username", Type: field.TypeString, Nullable: true, Size: 32, Comment: "用户名"},
|
||||
{Name: "nickname", Type: field.TypeString, Nullable: true, Size: 32, Comment: "昵称"},
|
||||
@@ -56,7 +56,7 @@ var (
|
||||
{Name: "phone", Type: field.TypeString, Nullable: true, Size: 32, Comment: "电话"},
|
||||
{Name: "password", Type: field.TypeString, Nullable: true, Size: 64, Comment: "密码"},
|
||||
{Name: "gender", Type: field.TypeInt8, Nullable: true, Comment: "性别"},
|
||||
{Name: "avatar", Type: field.TypeString, Nullable: true, Comment: "头像"},
|
||||
{Name: "avatar", Type: field.TypeString, Nullable: true, Size: 2147483647, Comment: "头像"},
|
||||
{Name: "status", Type: field.TypeInt8, Nullable: true, Comment: "状态 0 正常 1 封禁", Default: 0},
|
||||
{Name: "introduce", Type: field.TypeString, Nullable: true, Size: 255, Comment: "介绍"},
|
||||
{Name: "blog", Type: field.TypeString, Nullable: true, Size: 30, Comment: "博客"},
|
||||
@@ -91,8 +91,8 @@ var (
|
||||
ScaAuthUserDeviceColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true, Comment: "主键ID", SchemaType: map[string]string{"mysql": "bigint(20)"}},
|
||||
{Name: "created_at", Type: field.TypeTime, Comment: "创建时间"},
|
||||
{Name: "updated_at", Type: field.TypeTime, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Nullable: true, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "updated_at", Type: field.TypeTime, Nullable: true, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "user_id", Type: field.TypeString, Size: 20, Comment: "用户ID"},
|
||||
{Name: "ip", Type: field.TypeString, Size: 20, Comment: "登录IP"},
|
||||
{Name: "location", Type: field.TypeString, Size: 20, Comment: "地址"},
|
||||
@@ -125,8 +125,8 @@ var (
|
||||
ScaAuthUserSocialColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true, Comment: "主键ID", SchemaType: map[string]string{"mysql": "bigint(20)"}},
|
||||
{Name: "created_at", Type: field.TypeTime, Comment: "创建时间"},
|
||||
{Name: "updated_at", Type: field.TypeTime, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Nullable: true, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "updated_at", Type: field.TypeTime, Nullable: true, Comment: "更新时间"},
|
||||
{Name: "deleted", Type: field.TypeInt8, Comment: "是否删除 0 未删除 1 已删除", Default: 0},
|
||||
{Name: "user_id", Type: field.TypeString, Size: 20, Comment: "用户ID"},
|
||||
{Name: "open_id", Type: field.TypeString, Size: 50, Comment: "第三方用户的 open id"},
|
||||
{Name: "source", Type: field.TypeString, Size: 10, Comment: "第三方用户来源"},
|
||||
|
@@ -1016,9 +1016,22 @@ func (m *ScaAuthRoleMutation) OldUpdatedAt(ctx context.Context) (v time.Time, er
|
||||
return oldValue.UpdatedAt, nil
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (m *ScaAuthRoleMutation) ClearUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
m.clearedFields[scaauthrole.FieldUpdatedAt] = struct{}{}
|
||||
}
|
||||
|
||||
// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
|
||||
func (m *ScaAuthRoleMutation) UpdatedAtCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthrole.FieldUpdatedAt]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetUpdatedAt resets all changes to the "updated_at" field.
|
||||
func (m *ScaAuthRoleMutation) ResetUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
delete(m.clearedFields, scaauthrole.FieldUpdatedAt)
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
@@ -1071,24 +1084,10 @@ func (m *ScaAuthRoleMutation) AddedDeleted() (r int8, exists bool) {
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (m *ScaAuthRoleMutation) ClearDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
m.clearedFields[scaauthrole.FieldDeleted] = struct{}{}
|
||||
}
|
||||
|
||||
// DeletedCleared returns if the "deleted" field was cleared in this mutation.
|
||||
func (m *ScaAuthRoleMutation) DeletedCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthrole.FieldDeleted]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetDeleted resets all changes to the "deleted" field.
|
||||
func (m *ScaAuthRoleMutation) ResetDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
delete(m.clearedFields, scaauthrole.FieldDeleted)
|
||||
}
|
||||
|
||||
// SetRoleName sets the "role_name" field.
|
||||
@@ -1339,8 +1338,8 @@ func (m *ScaAuthRoleMutation) AddField(name string, value ent.Value) error {
|
||||
// mutation.
|
||||
func (m *ScaAuthRoleMutation) ClearedFields() []string {
|
||||
var fields []string
|
||||
if m.FieldCleared(scaauthrole.FieldDeleted) {
|
||||
fields = append(fields, scaauthrole.FieldDeleted)
|
||||
if m.FieldCleared(scaauthrole.FieldUpdatedAt) {
|
||||
fields = append(fields, scaauthrole.FieldUpdatedAt)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
@@ -1356,8 +1355,8 @@ func (m *ScaAuthRoleMutation) FieldCleared(name string) bool {
|
||||
// error if the field is not defined in the schema.
|
||||
func (m *ScaAuthRoleMutation) ClearField(name string) error {
|
||||
switch name {
|
||||
case scaauthrole.FieldDeleted:
|
||||
m.ClearDeleted()
|
||||
case scaauthrole.FieldUpdatedAt:
|
||||
m.ClearUpdatedAt()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown ScaAuthRole nullable field %s", name)
|
||||
@@ -1636,9 +1635,22 @@ func (m *ScaAuthUserMutation) OldUpdatedAt(ctx context.Context) (v time.Time, er
|
||||
return oldValue.UpdatedAt, nil
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (m *ScaAuthUserMutation) ClearUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
m.clearedFields[scaauthuser.FieldUpdatedAt] = struct{}{}
|
||||
}
|
||||
|
||||
// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
|
||||
func (m *ScaAuthUserMutation) UpdatedAtCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthuser.FieldUpdatedAt]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetUpdatedAt resets all changes to the "updated_at" field.
|
||||
func (m *ScaAuthUserMutation) ResetUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
delete(m.clearedFields, scaauthuser.FieldUpdatedAt)
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
@@ -1691,24 +1703,10 @@ func (m *ScaAuthUserMutation) AddedDeleted() (r int8, exists bool) {
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (m *ScaAuthUserMutation) ClearDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
m.clearedFields[scaauthuser.FieldDeleted] = struct{}{}
|
||||
}
|
||||
|
||||
// DeletedCleared returns if the "deleted" field was cleared in this mutation.
|
||||
func (m *ScaAuthUserMutation) DeletedCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthuser.FieldDeleted]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetDeleted resets all changes to the "deleted" field.
|
||||
func (m *ScaAuthUserMutation) ResetDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
delete(m.clearedFields, scaauthuser.FieldDeleted)
|
||||
}
|
||||
|
||||
// SetUID sets the "uid" field.
|
||||
@@ -2731,8 +2729,8 @@ func (m *ScaAuthUserMutation) AddField(name string, value ent.Value) error {
|
||||
// mutation.
|
||||
func (m *ScaAuthUserMutation) ClearedFields() []string {
|
||||
var fields []string
|
||||
if m.FieldCleared(scaauthuser.FieldDeleted) {
|
||||
fields = append(fields, scaauthuser.FieldDeleted)
|
||||
if m.FieldCleared(scaauthuser.FieldUpdatedAt) {
|
||||
fields = append(fields, scaauthuser.FieldUpdatedAt)
|
||||
}
|
||||
if m.FieldCleared(scaauthuser.FieldUsername) {
|
||||
fields = append(fields, scaauthuser.FieldUsername)
|
||||
@@ -2784,8 +2782,8 @@ func (m *ScaAuthUserMutation) FieldCleared(name string) bool {
|
||||
// error if the field is not defined in the schema.
|
||||
func (m *ScaAuthUserMutation) ClearField(name string) error {
|
||||
switch name {
|
||||
case scaauthuser.FieldDeleted:
|
||||
m.ClearDeleted()
|
||||
case scaauthuser.FieldUpdatedAt:
|
||||
m.ClearUpdatedAt()
|
||||
return nil
|
||||
case scaauthuser.FieldUsername:
|
||||
m.ClearUsername()
|
||||
@@ -3131,9 +3129,22 @@ func (m *ScaAuthUserDeviceMutation) OldUpdatedAt(ctx context.Context) (v time.Ti
|
||||
return oldValue.UpdatedAt, nil
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (m *ScaAuthUserDeviceMutation) ClearUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
m.clearedFields[scaauthuserdevice.FieldUpdatedAt] = struct{}{}
|
||||
}
|
||||
|
||||
// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
|
||||
func (m *ScaAuthUserDeviceMutation) UpdatedAtCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthuserdevice.FieldUpdatedAt]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetUpdatedAt resets all changes to the "updated_at" field.
|
||||
func (m *ScaAuthUserDeviceMutation) ResetUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
delete(m.clearedFields, scaauthuserdevice.FieldUpdatedAt)
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
@@ -3186,24 +3197,10 @@ func (m *ScaAuthUserDeviceMutation) AddedDeleted() (r int8, exists bool) {
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (m *ScaAuthUserDeviceMutation) ClearDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
m.clearedFields[scaauthuserdevice.FieldDeleted] = struct{}{}
|
||||
}
|
||||
|
||||
// DeletedCleared returns if the "deleted" field was cleared in this mutation.
|
||||
func (m *ScaAuthUserDeviceMutation) DeletedCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthuserdevice.FieldDeleted]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetDeleted resets all changes to the "deleted" field.
|
||||
func (m *ScaAuthUserDeviceMutation) ResetDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
delete(m.clearedFields, scaauthuserdevice.FieldDeleted)
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
@@ -4004,8 +4001,8 @@ func (m *ScaAuthUserDeviceMutation) AddField(name string, value ent.Value) error
|
||||
// mutation.
|
||||
func (m *ScaAuthUserDeviceMutation) ClearedFields() []string {
|
||||
var fields []string
|
||||
if m.FieldCleared(scaauthuserdevice.FieldDeleted) {
|
||||
fields = append(fields, scaauthuserdevice.FieldDeleted)
|
||||
if m.FieldCleared(scaauthuserdevice.FieldUpdatedAt) {
|
||||
fields = append(fields, scaauthuserdevice.FieldUpdatedAt)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
@@ -4021,8 +4018,8 @@ func (m *ScaAuthUserDeviceMutation) FieldCleared(name string) bool {
|
||||
// error if the field is not defined in the schema.
|
||||
func (m *ScaAuthUserDeviceMutation) ClearField(name string) error {
|
||||
switch name {
|
||||
case scaauthuserdevice.FieldDeleted:
|
||||
m.ClearDeleted()
|
||||
case scaauthuserdevice.FieldUpdatedAt:
|
||||
m.ClearUpdatedAt()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown ScaAuthUserDevice nullable field %s", name)
|
||||
@@ -4324,9 +4321,22 @@ func (m *ScaAuthUserSocialMutation) OldUpdatedAt(ctx context.Context) (v time.Ti
|
||||
return oldValue.UpdatedAt, nil
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (m *ScaAuthUserSocialMutation) ClearUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
m.clearedFields[scaauthusersocial.FieldUpdatedAt] = struct{}{}
|
||||
}
|
||||
|
||||
// UpdatedAtCleared returns if the "updated_at" field was cleared in this mutation.
|
||||
func (m *ScaAuthUserSocialMutation) UpdatedAtCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthusersocial.FieldUpdatedAt]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetUpdatedAt resets all changes to the "updated_at" field.
|
||||
func (m *ScaAuthUserSocialMutation) ResetUpdatedAt() {
|
||||
m.updated_at = nil
|
||||
delete(m.clearedFields, scaauthusersocial.FieldUpdatedAt)
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
@@ -4379,24 +4389,10 @@ func (m *ScaAuthUserSocialMutation) AddedDeleted() (r int8, exists bool) {
|
||||
return *v, true
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (m *ScaAuthUserSocialMutation) ClearDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
m.clearedFields[scaauthusersocial.FieldDeleted] = struct{}{}
|
||||
}
|
||||
|
||||
// DeletedCleared returns if the "deleted" field was cleared in this mutation.
|
||||
func (m *ScaAuthUserSocialMutation) DeletedCleared() bool {
|
||||
_, ok := m.clearedFields[scaauthusersocial.FieldDeleted]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ResetDeleted resets all changes to the "deleted" field.
|
||||
func (m *ScaAuthUserSocialMutation) ResetDeleted() {
|
||||
m.deleted = nil
|
||||
m.adddeleted = nil
|
||||
delete(m.clearedFields, scaauthusersocial.FieldDeleted)
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
@@ -4779,8 +4775,8 @@ func (m *ScaAuthUserSocialMutation) AddField(name string, value ent.Value) error
|
||||
// mutation.
|
||||
func (m *ScaAuthUserSocialMutation) ClearedFields() []string {
|
||||
var fields []string
|
||||
if m.FieldCleared(scaauthusersocial.FieldDeleted) {
|
||||
fields = append(fields, scaauthusersocial.FieldDeleted)
|
||||
if m.FieldCleared(scaauthusersocial.FieldUpdatedAt) {
|
||||
fields = append(fields, scaauthusersocial.FieldUpdatedAt)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
@@ -4796,8 +4792,8 @@ func (m *ScaAuthUserSocialMutation) FieldCleared(name string) bool {
|
||||
// error if the field is not defined in the schema.
|
||||
func (m *ScaAuthUserSocialMutation) ClearField(name string) error {
|
||||
switch name {
|
||||
case scaauthusersocial.FieldDeleted:
|
||||
m.ClearDeleted()
|
||||
case scaauthusersocial.FieldUpdatedAt:
|
||||
m.ClearUpdatedAt()
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unknown ScaAuthUserSocial nullable field %s", name)
|
||||
|
@@ -57,8 +57,6 @@ func init() {
|
||||
scaauthrole.DefaultCreatedAt = scaauthroleDescCreatedAt.Default.(func() time.Time)
|
||||
// scaauthroleDescUpdatedAt is the schema descriptor for updated_at field.
|
||||
scaauthroleDescUpdatedAt := scaauthroleMixinFields0[1].Descriptor()
|
||||
// scaauthrole.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||
scaauthrole.DefaultUpdatedAt = scaauthroleDescUpdatedAt.Default.(func() time.Time)
|
||||
// scaauthrole.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||
scaauthrole.UpdateDefaultUpdatedAt = scaauthroleDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||
// scaauthroleDescDeleted is the schema descriptor for deleted field.
|
||||
@@ -86,8 +84,6 @@ func init() {
|
||||
scaauthuser.DefaultCreatedAt = scaauthuserDescCreatedAt.Default.(func() time.Time)
|
||||
// scaauthuserDescUpdatedAt is the schema descriptor for updated_at field.
|
||||
scaauthuserDescUpdatedAt := scaauthuserMixinFields0[1].Descriptor()
|
||||
// scaauthuser.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||
scaauthuser.DefaultUpdatedAt = scaauthuserDescUpdatedAt.Default.(func() time.Time)
|
||||
// scaauthuser.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||
scaauthuser.UpdateDefaultUpdatedAt = scaauthuserDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||
// scaauthuserDescDeleted is the schema descriptor for deleted field.
|
||||
@@ -151,8 +147,6 @@ func init() {
|
||||
scaauthuserdevice.DefaultCreatedAt = scaauthuserdeviceDescCreatedAt.Default.(func() time.Time)
|
||||
// scaauthuserdeviceDescUpdatedAt is the schema descriptor for updated_at field.
|
||||
scaauthuserdeviceDescUpdatedAt := scaauthuserdeviceMixinFields0[1].Descriptor()
|
||||
// scaauthuserdevice.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||
scaauthuserdevice.DefaultUpdatedAt = scaauthuserdeviceDescUpdatedAt.Default.(func() time.Time)
|
||||
// scaauthuserdevice.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||
scaauthuserdevice.UpdateDefaultUpdatedAt = scaauthuserdeviceDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||
// scaauthuserdeviceDescDeleted is the schema descriptor for deleted field.
|
||||
@@ -216,8 +210,6 @@ func init() {
|
||||
scaauthusersocial.DefaultCreatedAt = scaauthusersocialDescCreatedAt.Default.(func() time.Time)
|
||||
// scaauthusersocialDescUpdatedAt is the schema descriptor for updated_at field.
|
||||
scaauthusersocialDescUpdatedAt := scaauthusersocialMixinFields0[1].Descriptor()
|
||||
// scaauthusersocial.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||
scaauthusersocial.DefaultUpdatedAt = scaauthusersocialDescUpdatedAt.Default.(func() time.Time)
|
||||
// scaauthusersocial.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||
scaauthusersocial.UpdateDefaultUpdatedAt = scaauthusersocialDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||
// scaauthusersocialDescDeleted is the schema descriptor for deleted field.
|
||||
|
@@ -50,8 +50,6 @@ func ValidColumn(column string) bool {
|
||||
var (
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||
DefaultUpdatedAt func() time.Time
|
||||
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||
UpdateDefaultUpdatedAt func() time.Time
|
||||
// DefaultDeleted holds the default value on creation for the "deleted" field.
|
||||
|
@@ -159,6 +159,16 @@ func UpdatedAtLTE(v time.Time) predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
|
||||
func UpdatedAtIsNil() predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldIsNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
|
||||
func UpdatedAtNotNil() predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldNotNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// DeletedEQ applies the EQ predicate on the "deleted" field.
|
||||
func DeletedEQ(v int8) predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldEQ(FieldDeleted, v))
|
||||
@@ -199,16 +209,6 @@ func DeletedLTE(v int8) predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldLTE(FieldDeleted, v))
|
||||
}
|
||||
|
||||
// DeletedIsNil applies the IsNil predicate on the "deleted" field.
|
||||
func DeletedIsNil() predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldIsNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// DeletedNotNil applies the NotNil predicate on the "deleted" field.
|
||||
func DeletedNotNil() predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldNotNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// RoleNameEQ applies the EQ predicate on the "role_name" field.
|
||||
func RoleNameEQ(v string) predicate.ScaAuthRole {
|
||||
return predicate.ScaAuthRole(sql.FieldEQ(FieldRoleName, v))
|
||||
|
@@ -119,10 +119,6 @@ func (sarc *ScaAuthRoleCreate) defaults() {
|
||||
v := scaauthrole.DefaultCreatedAt()
|
||||
sarc.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := sarc.mutation.UpdatedAt(); !ok {
|
||||
v := scaauthrole.DefaultUpdatedAt()
|
||||
sarc.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
if _, ok := sarc.mutation.Deleted(); !ok {
|
||||
v := scaauthrole.DefaultDeleted
|
||||
sarc.mutation.SetDeleted(v)
|
||||
@@ -134,8 +130,8 @@ func (sarc *ScaAuthRoleCreate) check() error {
|
||||
if _, ok := sarc.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "ScaAuthRole.created_at"`)}
|
||||
}
|
||||
if _, ok := sarc.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "ScaAuthRole.updated_at"`)}
|
||||
if _, ok := sarc.mutation.Deleted(); !ok {
|
||||
return &ValidationError{Name: "deleted", err: errors.New(`ent: missing required field "ScaAuthRole.deleted"`)}
|
||||
}
|
||||
if v, ok := sarc.mutation.Deleted(); ok {
|
||||
if err := scaauthrole.DeletedValidator(v); err != nil {
|
||||
|
@@ -34,6 +34,12 @@ func (saru *ScaAuthRoleUpdate) SetUpdatedAt(t time.Time) *ScaAuthRoleUpdate {
|
||||
return saru
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (saru *ScaAuthRoleUpdate) ClearUpdatedAt() *ScaAuthRoleUpdate {
|
||||
saru.mutation.ClearUpdatedAt()
|
||||
return saru
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (saru *ScaAuthRoleUpdate) SetDeleted(i int8) *ScaAuthRoleUpdate {
|
||||
saru.mutation.ResetDeleted()
|
||||
@@ -55,12 +61,6 @@ func (saru *ScaAuthRoleUpdate) AddDeleted(i int8) *ScaAuthRoleUpdate {
|
||||
return saru
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (saru *ScaAuthRoleUpdate) ClearDeleted() *ScaAuthRoleUpdate {
|
||||
saru.mutation.ClearDeleted()
|
||||
return saru
|
||||
}
|
||||
|
||||
// SetRoleName sets the "role_name" field.
|
||||
func (saru *ScaAuthRoleUpdate) SetRoleName(s string) *ScaAuthRoleUpdate {
|
||||
saru.mutation.SetRoleName(s)
|
||||
@@ -124,7 +124,7 @@ func (saru *ScaAuthRoleUpdate) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (saru *ScaAuthRoleUpdate) defaults() {
|
||||
if _, ok := saru.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := saru.mutation.UpdatedAt(); !ok && !saru.mutation.UpdatedAtCleared() {
|
||||
v := scaauthrole.UpdateDefaultUpdatedAt()
|
||||
saru.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -165,15 +165,15 @@ func (saru *ScaAuthRoleUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if value, ok := saru.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthrole.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if saru.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthrole.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := saru.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthrole.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := saru.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthrole.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if saru.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthrole.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := saru.mutation.RoleName(); ok {
|
||||
_spec.SetField(scaauthrole.FieldRoleName, field.TypeString, value)
|
||||
}
|
||||
@@ -206,6 +206,12 @@ func (saruo *ScaAuthRoleUpdateOne) SetUpdatedAt(t time.Time) *ScaAuthRoleUpdateO
|
||||
return saruo
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (saruo *ScaAuthRoleUpdateOne) ClearUpdatedAt() *ScaAuthRoleUpdateOne {
|
||||
saruo.mutation.ClearUpdatedAt()
|
||||
return saruo
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (saruo *ScaAuthRoleUpdateOne) SetDeleted(i int8) *ScaAuthRoleUpdateOne {
|
||||
saruo.mutation.ResetDeleted()
|
||||
@@ -227,12 +233,6 @@ func (saruo *ScaAuthRoleUpdateOne) AddDeleted(i int8) *ScaAuthRoleUpdateOne {
|
||||
return saruo
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (saruo *ScaAuthRoleUpdateOne) ClearDeleted() *ScaAuthRoleUpdateOne {
|
||||
saruo.mutation.ClearDeleted()
|
||||
return saruo
|
||||
}
|
||||
|
||||
// SetRoleName sets the "role_name" field.
|
||||
func (saruo *ScaAuthRoleUpdateOne) SetRoleName(s string) *ScaAuthRoleUpdateOne {
|
||||
saruo.mutation.SetRoleName(s)
|
||||
@@ -309,7 +309,7 @@ func (saruo *ScaAuthRoleUpdateOne) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (saruo *ScaAuthRoleUpdateOne) defaults() {
|
||||
if _, ok := saruo.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := saruo.mutation.UpdatedAt(); !ok && !saruo.mutation.UpdatedAtCleared() {
|
||||
v := scaauthrole.UpdateDefaultUpdatedAt()
|
||||
saruo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -367,15 +367,15 @@ func (saruo *ScaAuthRoleUpdateOne) sqlSave(ctx context.Context) (_node *ScaAuthR
|
||||
if value, ok := saruo.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthrole.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if saruo.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthrole.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := saruo.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthrole.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := saruo.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthrole.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if saruo.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthrole.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := saruo.mutation.RoleName(); ok {
|
||||
_spec.SetField(scaauthrole.FieldRoleName, field.TypeString, value)
|
||||
}
|
||||
|
@@ -83,8 +83,6 @@ func ValidColumn(column string) bool {
|
||||
var (
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||
DefaultUpdatedAt func() time.Time
|
||||
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||
UpdateDefaultUpdatedAt func() time.Time
|
||||
// DefaultDeleted holds the default value on creation for the "deleted" field.
|
||||
|
@@ -214,6 +214,16 @@ func UpdatedAtLTE(v time.Time) predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
|
||||
func UpdatedAtIsNil() predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldIsNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
|
||||
func UpdatedAtNotNil() predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldNotNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// DeletedEQ applies the EQ predicate on the "deleted" field.
|
||||
func DeletedEQ(v int8) predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldEQ(FieldDeleted, v))
|
||||
@@ -254,16 +264,6 @@ func DeletedLTE(v int8) predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldLTE(FieldDeleted, v))
|
||||
}
|
||||
|
||||
// DeletedIsNil applies the IsNil predicate on the "deleted" field.
|
||||
func DeletedIsNil() predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldIsNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// DeletedNotNil applies the NotNil predicate on the "deleted" field.
|
||||
func DeletedNotNil() predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldNotNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// UIDEQ applies the EQ predicate on the "uid" field.
|
||||
func UIDEQ(v string) predicate.ScaAuthUser {
|
||||
return predicate.ScaAuthUser(sql.FieldEQ(FieldUID, v))
|
||||
|
@@ -281,10 +281,6 @@ func (sauc *ScaAuthUserCreate) defaults() {
|
||||
v := scaauthuser.DefaultCreatedAt()
|
||||
sauc.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := sauc.mutation.UpdatedAt(); !ok {
|
||||
v := scaauthuser.DefaultUpdatedAt()
|
||||
sauc.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
if _, ok := sauc.mutation.Deleted(); !ok {
|
||||
v := scaauthuser.DefaultDeleted
|
||||
sauc.mutation.SetDeleted(v)
|
||||
@@ -300,8 +296,8 @@ func (sauc *ScaAuthUserCreate) check() error {
|
||||
if _, ok := sauc.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "ScaAuthUser.created_at"`)}
|
||||
}
|
||||
if _, ok := sauc.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "ScaAuthUser.updated_at"`)}
|
||||
if _, ok := sauc.mutation.Deleted(); !ok {
|
||||
return &ValidationError{Name: "deleted", err: errors.New(`ent: missing required field "ScaAuthUser.deleted"`)}
|
||||
}
|
||||
if v, ok := sauc.mutation.Deleted(); ok {
|
||||
if err := scaauthuser.DeletedValidator(v); err != nil {
|
||||
|
@@ -34,6 +34,12 @@ func (sauu *ScaAuthUserUpdate) SetUpdatedAt(t time.Time) *ScaAuthUserUpdate {
|
||||
return sauu
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (sauu *ScaAuthUserUpdate) ClearUpdatedAt() *ScaAuthUserUpdate {
|
||||
sauu.mutation.ClearUpdatedAt()
|
||||
return sauu
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (sauu *ScaAuthUserUpdate) SetDeleted(i int8) *ScaAuthUserUpdate {
|
||||
sauu.mutation.ResetDeleted()
|
||||
@@ -55,12 +61,6 @@ func (sauu *ScaAuthUserUpdate) AddDeleted(i int8) *ScaAuthUserUpdate {
|
||||
return sauu
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (sauu *ScaAuthUserUpdate) ClearDeleted() *ScaAuthUserUpdate {
|
||||
sauu.mutation.ClearDeleted()
|
||||
return sauu
|
||||
}
|
||||
|
||||
// SetUID sets the "uid" field.
|
||||
func (sauu *ScaAuthUserUpdate) SetUID(s string) *ScaAuthUserUpdate {
|
||||
sauu.mutation.SetUID(s)
|
||||
@@ -364,7 +364,7 @@ func (sauu *ScaAuthUserUpdate) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (sauu *ScaAuthUserUpdate) defaults() {
|
||||
if _, ok := sauu.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := sauu.mutation.UpdatedAt(); !ok && !sauu.mutation.UpdatedAtCleared() {
|
||||
v := scaauthuser.UpdateDefaultUpdatedAt()
|
||||
sauu.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -445,15 +445,15 @@ func (sauu *ScaAuthUserUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if value, ok := sauu.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthuser.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if sauu.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthuser.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := sauu.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthuser.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := sauu.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthuser.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if sauu.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthuser.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := sauu.mutation.UID(); ok {
|
||||
_spec.SetField(scaauthuser.FieldUID, field.TypeString, value)
|
||||
}
|
||||
@@ -561,6 +561,12 @@ func (sauuo *ScaAuthUserUpdateOne) SetUpdatedAt(t time.Time) *ScaAuthUserUpdateO
|
||||
return sauuo
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (sauuo *ScaAuthUserUpdateOne) ClearUpdatedAt() *ScaAuthUserUpdateOne {
|
||||
sauuo.mutation.ClearUpdatedAt()
|
||||
return sauuo
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (sauuo *ScaAuthUserUpdateOne) SetDeleted(i int8) *ScaAuthUserUpdateOne {
|
||||
sauuo.mutation.ResetDeleted()
|
||||
@@ -582,12 +588,6 @@ func (sauuo *ScaAuthUserUpdateOne) AddDeleted(i int8) *ScaAuthUserUpdateOne {
|
||||
return sauuo
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (sauuo *ScaAuthUserUpdateOne) ClearDeleted() *ScaAuthUserUpdateOne {
|
||||
sauuo.mutation.ClearDeleted()
|
||||
return sauuo
|
||||
}
|
||||
|
||||
// SetUID sets the "uid" field.
|
||||
func (sauuo *ScaAuthUserUpdateOne) SetUID(s string) *ScaAuthUserUpdateOne {
|
||||
sauuo.mutation.SetUID(s)
|
||||
@@ -904,7 +904,7 @@ func (sauuo *ScaAuthUserUpdateOne) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (sauuo *ScaAuthUserUpdateOne) defaults() {
|
||||
if _, ok := sauuo.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := sauuo.mutation.UpdatedAt(); !ok && !sauuo.mutation.UpdatedAtCleared() {
|
||||
v := scaauthuser.UpdateDefaultUpdatedAt()
|
||||
sauuo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -1002,15 +1002,15 @@ func (sauuo *ScaAuthUserUpdateOne) sqlSave(ctx context.Context) (_node *ScaAuthU
|
||||
if value, ok := sauuo.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthuser.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if sauuo.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthuser.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := sauuo.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthuser.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := sauuo.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthuser.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if sauuo.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthuser.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := sauuo.mutation.UID(); ok {
|
||||
_spec.SetField(scaauthuser.FieldUID, field.TypeString, value)
|
||||
}
|
||||
|
@@ -83,8 +83,6 @@ func ValidColumn(column string) bool {
|
||||
var (
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||
DefaultUpdatedAt func() time.Time
|
||||
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||
UpdateDefaultUpdatedAt func() time.Time
|
||||
// DefaultDeleted holds the default value on creation for the "deleted" field.
|
||||
|
@@ -214,6 +214,16 @@ func UpdatedAtLTE(v time.Time) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
|
||||
func UpdatedAtIsNil() predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldIsNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
|
||||
func UpdatedAtNotNil() predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldNotNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// DeletedEQ applies the EQ predicate on the "deleted" field.
|
||||
func DeletedEQ(v int8) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldEQ(FieldDeleted, v))
|
||||
@@ -254,16 +264,6 @@ func DeletedLTE(v int8) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldLTE(FieldDeleted, v))
|
||||
}
|
||||
|
||||
// DeletedIsNil applies the IsNil predicate on the "deleted" field.
|
||||
func DeletedIsNil() predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldIsNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// DeletedNotNil applies the NotNil predicate on the "deleted" field.
|
||||
func DeletedNotNil() predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldNotNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// UserIDEQ applies the EQ predicate on the "user_id" field.
|
||||
func UserIDEQ(v string) predicate.ScaAuthUserDevice {
|
||||
return predicate.ScaAuthUserDevice(sql.FieldEQ(FieldUserID, v))
|
||||
|
@@ -185,10 +185,6 @@ func (saudc *ScaAuthUserDeviceCreate) defaults() {
|
||||
v := scaauthuserdevice.DefaultCreatedAt()
|
||||
saudc.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := saudc.mutation.UpdatedAt(); !ok {
|
||||
v := scaauthuserdevice.DefaultUpdatedAt()
|
||||
saudc.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
if _, ok := saudc.mutation.Deleted(); !ok {
|
||||
v := scaauthuserdevice.DefaultDeleted
|
||||
saudc.mutation.SetDeleted(v)
|
||||
@@ -200,8 +196,8 @@ func (saudc *ScaAuthUserDeviceCreate) check() error {
|
||||
if _, ok := saudc.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "ScaAuthUserDevice.created_at"`)}
|
||||
}
|
||||
if _, ok := saudc.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "ScaAuthUserDevice.updated_at"`)}
|
||||
if _, ok := saudc.mutation.Deleted(); !ok {
|
||||
return &ValidationError{Name: "deleted", err: errors.New(`ent: missing required field "ScaAuthUserDevice.deleted"`)}
|
||||
}
|
||||
if v, ok := saudc.mutation.Deleted(); ok {
|
||||
if err := scaauthuserdevice.DeletedValidator(v); err != nil {
|
||||
|
@@ -34,6 +34,12 @@ func (saudu *ScaAuthUserDeviceUpdate) SetUpdatedAt(t time.Time) *ScaAuthUserDevi
|
||||
return saudu
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) ClearUpdatedAt() *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.ClearUpdatedAt()
|
||||
return saudu
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetDeleted(i int8) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.ResetDeleted()
|
||||
@@ -55,12 +61,6 @@ func (saudu *ScaAuthUserDeviceUpdate) AddDeleted(i int8) *ScaAuthUserDeviceUpdat
|
||||
return saudu
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) ClearDeleted() *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.ClearDeleted()
|
||||
return saudu
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) SetUserID(s string) *ScaAuthUserDeviceUpdate {
|
||||
saudu.mutation.SetUserID(s)
|
||||
@@ -278,7 +278,7 @@ func (saudu *ScaAuthUserDeviceUpdate) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (saudu *ScaAuthUserDeviceUpdate) defaults() {
|
||||
if _, ok := saudu.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := saudu.mutation.UpdatedAt(); !ok && !saudu.mutation.UpdatedAtCleared() {
|
||||
v := scaauthuserdevice.UpdateDefaultUpdatedAt()
|
||||
saudu.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -364,15 +364,15 @@ func (saudu *ScaAuthUserDeviceUpdate) sqlSave(ctx context.Context) (n int, err e
|
||||
if value, ok := saudu.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if saudu.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthuserdevice.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := saudu.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := saudu.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthuserdevice.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if saudu.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthuserdevice.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := saudu.mutation.UserID(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldUserID, field.TypeString, value)
|
||||
}
|
||||
@@ -438,6 +438,12 @@ func (sauduo *ScaAuthUserDeviceUpdateOne) SetUpdatedAt(t time.Time) *ScaAuthUser
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) ClearUpdatedAt() *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.ClearUpdatedAt()
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetDeleted(i int8) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.ResetDeleted()
|
||||
@@ -459,12 +465,6 @@ func (sauduo *ScaAuthUserDeviceUpdateOne) AddDeleted(i int8) *ScaAuthUserDeviceU
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) ClearDeleted() *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.ClearDeleted()
|
||||
return sauduo
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) SetUserID(s string) *ScaAuthUserDeviceUpdateOne {
|
||||
sauduo.mutation.SetUserID(s)
|
||||
@@ -695,7 +695,7 @@ func (sauduo *ScaAuthUserDeviceUpdateOne) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (sauduo *ScaAuthUserDeviceUpdateOne) defaults() {
|
||||
if _, ok := sauduo.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := sauduo.mutation.UpdatedAt(); !ok && !sauduo.mutation.UpdatedAtCleared() {
|
||||
v := scaauthuserdevice.UpdateDefaultUpdatedAt()
|
||||
sauduo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -798,15 +798,15 @@ func (sauduo *ScaAuthUserDeviceUpdateOne) sqlSave(ctx context.Context) (_node *S
|
||||
if value, ok := sauduo.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if sauduo.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthuserdevice.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := sauduo.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := sauduo.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthuserdevice.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if sauduo.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthuserdevice.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := sauduo.mutation.UserID(); ok {
|
||||
_spec.SetField(scaauthuserdevice.FieldUserID, field.TypeString, value)
|
||||
}
|
||||
|
@@ -56,8 +56,6 @@ func ValidColumn(column string) bool {
|
||||
var (
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||
DefaultUpdatedAt func() time.Time
|
||||
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||
UpdateDefaultUpdatedAt func() time.Time
|
||||
// DefaultDeleted holds the default value on creation for the "deleted" field.
|
||||
|
@@ -169,6 +169,16 @@ func UpdatedAtLTE(v time.Time) predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
|
||||
func UpdatedAtIsNil() predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldIsNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
|
||||
func UpdatedAtNotNil() predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldNotNull(FieldUpdatedAt))
|
||||
}
|
||||
|
||||
// DeletedEQ applies the EQ predicate on the "deleted" field.
|
||||
func DeletedEQ(v int8) predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldEQ(FieldDeleted, v))
|
||||
@@ -209,16 +219,6 @@ func DeletedLTE(v int8) predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldLTE(FieldDeleted, v))
|
||||
}
|
||||
|
||||
// DeletedIsNil applies the IsNil predicate on the "deleted" field.
|
||||
func DeletedIsNil() predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldIsNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// DeletedNotNil applies the NotNil predicate on the "deleted" field.
|
||||
func DeletedNotNil() predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldNotNull(FieldDeleted))
|
||||
}
|
||||
|
||||
// UserIDEQ applies the EQ predicate on the "user_id" field.
|
||||
func UserIDEQ(v string) predicate.ScaAuthUserSocial {
|
||||
return predicate.ScaAuthUserSocial(sql.FieldEQ(FieldUserID, v))
|
||||
|
@@ -139,10 +139,6 @@ func (sausc *ScaAuthUserSocialCreate) defaults() {
|
||||
v := scaauthusersocial.DefaultCreatedAt()
|
||||
sausc.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := sausc.mutation.UpdatedAt(); !ok {
|
||||
v := scaauthusersocial.DefaultUpdatedAt()
|
||||
sausc.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
if _, ok := sausc.mutation.Deleted(); !ok {
|
||||
v := scaauthusersocial.DefaultDeleted
|
||||
sausc.mutation.SetDeleted(v)
|
||||
@@ -158,8 +154,8 @@ func (sausc *ScaAuthUserSocialCreate) check() error {
|
||||
if _, ok := sausc.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "ScaAuthUserSocial.created_at"`)}
|
||||
}
|
||||
if _, ok := sausc.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "ScaAuthUserSocial.updated_at"`)}
|
||||
if _, ok := sausc.mutation.Deleted(); !ok {
|
||||
return &ValidationError{Name: "deleted", err: errors.New(`ent: missing required field "ScaAuthUserSocial.deleted"`)}
|
||||
}
|
||||
if v, ok := sausc.mutation.Deleted(); ok {
|
||||
if err := scaauthusersocial.DeletedValidator(v); err != nil {
|
||||
|
@@ -34,6 +34,12 @@ func (sausu *ScaAuthUserSocialUpdate) SetUpdatedAt(t time.Time) *ScaAuthUserSoci
|
||||
return sausu
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (sausu *ScaAuthUserSocialUpdate) ClearUpdatedAt() *ScaAuthUserSocialUpdate {
|
||||
sausu.mutation.ClearUpdatedAt()
|
||||
return sausu
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (sausu *ScaAuthUserSocialUpdate) SetDeleted(i int8) *ScaAuthUserSocialUpdate {
|
||||
sausu.mutation.ResetDeleted()
|
||||
@@ -55,12 +61,6 @@ func (sausu *ScaAuthUserSocialUpdate) AddDeleted(i int8) *ScaAuthUserSocialUpdat
|
||||
return sausu
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (sausu *ScaAuthUserSocialUpdate) ClearDeleted() *ScaAuthUserSocialUpdate {
|
||||
sausu.mutation.ClearDeleted()
|
||||
return sausu
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (sausu *ScaAuthUserSocialUpdate) SetUserID(s string) *ScaAuthUserSocialUpdate {
|
||||
sausu.mutation.SetUserID(s)
|
||||
@@ -159,7 +159,7 @@ func (sausu *ScaAuthUserSocialUpdate) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (sausu *ScaAuthUserSocialUpdate) defaults() {
|
||||
if _, ok := sausu.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := sausu.mutation.UpdatedAt(); !ok && !sausu.mutation.UpdatedAtCleared() {
|
||||
v := scaauthusersocial.UpdateDefaultUpdatedAt()
|
||||
sausu.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -205,15 +205,15 @@ func (sausu *ScaAuthUserSocialUpdate) sqlSave(ctx context.Context) (n int, err e
|
||||
if value, ok := sausu.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthusersocial.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if sausu.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthusersocial.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := sausu.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthusersocial.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := sausu.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthusersocial.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if sausu.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthusersocial.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := sausu.mutation.UserID(); ok {
|
||||
_spec.SetField(scaauthusersocial.FieldUserID, field.TypeString, value)
|
||||
}
|
||||
@@ -255,6 +255,12 @@ func (sausuo *ScaAuthUserSocialUpdateOne) SetUpdatedAt(t time.Time) *ScaAuthUser
|
||||
return sausuo
|
||||
}
|
||||
|
||||
// ClearUpdatedAt clears the value of the "updated_at" field.
|
||||
func (sausuo *ScaAuthUserSocialUpdateOne) ClearUpdatedAt() *ScaAuthUserSocialUpdateOne {
|
||||
sausuo.mutation.ClearUpdatedAt()
|
||||
return sausuo
|
||||
}
|
||||
|
||||
// SetDeleted sets the "deleted" field.
|
||||
func (sausuo *ScaAuthUserSocialUpdateOne) SetDeleted(i int8) *ScaAuthUserSocialUpdateOne {
|
||||
sausuo.mutation.ResetDeleted()
|
||||
@@ -276,12 +282,6 @@ func (sausuo *ScaAuthUserSocialUpdateOne) AddDeleted(i int8) *ScaAuthUserSocialU
|
||||
return sausuo
|
||||
}
|
||||
|
||||
// ClearDeleted clears the value of the "deleted" field.
|
||||
func (sausuo *ScaAuthUserSocialUpdateOne) ClearDeleted() *ScaAuthUserSocialUpdateOne {
|
||||
sausuo.mutation.ClearDeleted()
|
||||
return sausuo
|
||||
}
|
||||
|
||||
// SetUserID sets the "user_id" field.
|
||||
func (sausuo *ScaAuthUserSocialUpdateOne) SetUserID(s string) *ScaAuthUserSocialUpdateOne {
|
||||
sausuo.mutation.SetUserID(s)
|
||||
@@ -393,7 +393,7 @@ func (sausuo *ScaAuthUserSocialUpdateOne) ExecX(ctx context.Context) {
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (sausuo *ScaAuthUserSocialUpdateOne) defaults() {
|
||||
if _, ok := sausuo.mutation.UpdatedAt(); !ok {
|
||||
if _, ok := sausuo.mutation.UpdatedAt(); !ok && !sausuo.mutation.UpdatedAtCleared() {
|
||||
v := scaauthusersocial.UpdateDefaultUpdatedAt()
|
||||
sausuo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
@@ -456,15 +456,15 @@ func (sausuo *ScaAuthUserSocialUpdateOne) sqlSave(ctx context.Context) (_node *S
|
||||
if value, ok := sausuo.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(scaauthusersocial.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if sausuo.mutation.UpdatedAtCleared() {
|
||||
_spec.ClearField(scaauthusersocial.FieldUpdatedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := sausuo.mutation.Deleted(); ok {
|
||||
_spec.SetField(scaauthusersocial.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if value, ok := sausuo.mutation.AddedDeleted(); ok {
|
||||
_spec.AddField(scaauthusersocial.FieldDeleted, field.TypeInt8, value)
|
||||
}
|
||||
if sausuo.mutation.DeletedCleared() {
|
||||
_spec.ClearField(scaauthusersocial.FieldDeleted, field.TypeInt8)
|
||||
}
|
||||
if value, ok := sausuo.mutation.UserID(); ok {
|
||||
_spec.SetField(scaauthusersocial.FieldUserID, field.TypeString, value)
|
||||
}
|
||||
|
@@ -26,8 +26,6 @@ func NewMySQL(url string) *ent.Client {
|
||||
drv := entsql.OpenDB("mysql", db)
|
||||
client := ent.NewClient(ent.Driver(drv), ent.Debug())
|
||||
|
||||
defer client.Close()
|
||||
|
||||
if err = client.Schema.Create(context.Background()); err != nil {
|
||||
log.Panicf("failed creating model resources: %v", err)
|
||||
}
|
||||
|
@@ -19,13 +19,12 @@ func (DefaultMixin) Fields() []ent.Field {
|
||||
Default(time.Now).
|
||||
Comment("创建时间"),
|
||||
field.Time("updated_at").
|
||||
Default(time.Now).
|
||||
Comment("更新时间").
|
||||
Optional().
|
||||
UpdateDefault(time.Now),
|
||||
field.Int8("deleted").
|
||||
Default(0).
|
||||
Max(1).
|
||||
Optional().
|
||||
Comment("是否删除 0 未删除 1 已删除"),
|
||||
}
|
||||
}
|
||||
|
@@ -59,7 +59,7 @@ func (ScaAuthUser) Fields() []ent.Field {
|
||||
field.Int8("gender").
|
||||
Optional().
|
||||
Comment("性别"),
|
||||
field.String("avatar").
|
||||
field.Text("avatar").
|
||||
Optional().
|
||||
Comment("头像"),
|
||||
field.Int8("status").
|
||||
|
34
app/core/api/repository/sensitivex/inti.go
Normal file
34
app/core/api/repository/sensitivex/inti.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package sensitivex
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
sensitive "github.com/zmexing/go-sensitive-word"
|
||||
)
|
||||
|
||||
func NewSensitive() *sensitive.Manager {
|
||||
filter, err := sensitive.NewFilter(
|
||||
sensitive.StoreOption{Type: sensitive.StoreMemory},
|
||||
sensitive.FilterOption{Type: sensitive.FilterDfa},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// 加载敏感词库
|
||||
err = filter.Store.LoadDictPath(
|
||||
filepath.Join(cwd, "resources/sensitive/", "反动词库.txt"),
|
||||
filepath.Join(cwd, "resources/sensitive/", "暴恐词库.txt"),
|
||||
filepath.Join(cwd, "resources/sensitive/", "色情词库.txt"),
|
||||
filepath.Join(cwd, "resources/sensitive/", "贪腐词库.txt"),
|
||||
filepath.Join(cwd, "resources/sensitive/", "民生词库.txt"),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return filter
|
||||
}
|
34
app/core/api/repository/wechat_public/init.go
Normal file
34
app/core/api/repository/wechat_public/init.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package wechat_public
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel"
|
||||
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount"
|
||||
)
|
||||
|
||||
// NewWechatPublic 微信公众号实例化
|
||||
func NewWechatPublic(appId, appSecret, token, aesKey, addr, pass string, db int) *officialAccount.OfficialAccount {
|
||||
OfficialAccountApp, err := officialAccount.NewOfficialAccount(&officialAccount.UserConfig{
|
||||
AppID: appId,
|
||||
Secret: appSecret,
|
||||
Token: token,
|
||||
AESKey: aesKey,
|
||||
Log: officialAccount.Log{
|
||||
Level: "error",
|
||||
Stdout: true,
|
||||
},
|
||||
ResponseType: os.Getenv("response_type"),
|
||||
HttpDebug: true,
|
||||
Debug: true,
|
||||
Cache: kernel.NewRedisClient(&kernel.UniversalOptions{
|
||||
Addrs: []string{addr},
|
||||
Password: pass,
|
||||
DB: db,
|
||||
}),
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return OfficialAccountApp
|
||||
}
|
@@ -12,4 +12,10 @@ userNotRegistered = "user not registered!"
|
||||
registerError = "register error!"
|
||||
passwordNotMatch = "password not match!"
|
||||
passwordFormatError = "password format error!"
|
||||
resetPasswordError = "reset password error!"
|
||||
resetPasswordError = "reset password error!"
|
||||
loginSuccess = "login success!"
|
||||
|
||||
[sms]
|
||||
smsSendTooFrequently = "sms send too frequently!"
|
||||
smsSendFailed = "sms send failed!"
|
||||
smsSendSuccess = "sms send success!"
|
@@ -12,4 +12,10 @@ userNotRegistered = "用户未注册!"
|
||||
registerError = "注册失败!"
|
||||
passwordNotMatch = "两次输入的密码不一致!"
|
||||
passwordFormatError = "密码格式错误!"
|
||||
resetPasswordError = "重置密码失败!"
|
||||
resetPasswordError = "重置密码失败!"
|
||||
loginSuccess = "登录成功!"
|
||||
|
||||
[sms]
|
||||
smsSendTooFrequently = "验证码发送过于频繁,请稍后再试!"
|
||||
smsSendFailed = "短信发送失败!"
|
||||
smsSendSuccess = "短信发送成功!"
|
||||
|
50
go.mod
50
go.mod
@@ -21,7 +21,7 @@ require (
|
||||
github.com/yitter/idgenerator-go v1.3.1
|
||||
github.com/zeromicro/go-zero v1.7.3
|
||||
go.mongodb.org/mongo-driver/v2 v2.0.0-beta2
|
||||
golang.org/x/crypto v0.28.0
|
||||
golang.org/x/crypto v0.29.0
|
||||
golang.org/x/text v0.20.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
)
|
||||
@@ -29,66 +29,98 @@ require (
|
||||
require (
|
||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.2.6 // indirect
|
||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 // indirect
|
||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.2.55 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
|
||||
github.com/casbin/govaluate v1.2.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/cloudflare/circl v1.5.0 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dolthub/maphash v0.1.0 // indirect
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.20.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/securecookie v1.1.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/imroc/req/v3 v3.48.0 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lxzan/gws v1.8.8 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 // indirect
|
||||
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pkg6/go-requests v0.2.2 // indirect
|
||||
github.com/pkg6/go-sms v0.1.2 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.48.1 // indirect
|
||||
github.com/refraction-networking/utls v1.6.7 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/wenlng/go-captcha-assets v1.0.1 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
github.com/zmexing/go-sensitive-word v1.3.0 // indirect
|
||||
go.opentelemetry.io/otel v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.32.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
|
||||
golang.org/x/image v0.22.0 // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/net v0.31.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/tools v0.27.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
92
go.sum
92
go.sum
@@ -4,12 +4,20 @@ entgo.io/ent v0.14.1 h1:fUERL506Pqr92EPHJqr8EYxbPioflJo6PudkrEA8a/s=
|
||||
entgo.io/ent v0.14.1/go.mod h1:MH6XLG0KXpkcDQhKiHfANZSzR55TJyPL5IGNpI8wpco=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.2.6 h1:xNDXBJ1VNYAEgs4UG/lSygzU66/XG3mTA7mm/qE//NY=
|
||||
github.com/ArtisanCloud/PowerLibs/v3 v3.2.6/go.mod h1:xFGsskCnzAu+6rFEJbGVAlwhrwZPXAny6m7j71S/B5k=
|
||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 h1:P+erNlErr+X2v7Et+yTWaTfIRhw+HfpAPdvNIEwk9Gw=
|
||||
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7/go.mod h1:VZQNCvcK/rldF3QaExiSl1gJEAkyc5/I8RLOd3WFZq4=
|
||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.2.55 h1:NKyw6PPEeomEieDMoEXvtL0RkFP6oFepJ1Jsn/6zE9w=
|
||||
github.com/ArtisanCloud/PowerWeChat/v3 v3.2.55/go.mod h1:D2cB1wtwC1YgzYT1Ni8NWS5wJCm5n1T18TybXkFlwvo=
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -32,15 +40,23 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenmingyong0423/go-mongox/v2 v2.0.0-beta1 h1:nYXdDoLswF1+2yVPLXpwBcfBXJvn5C37DzHuopDA9WE=
|
||||
github.com/chenmingyong0423/go-mongox/v2 v2.0.0-beta1/go.mod h1:ZcRdmUMTLaq8wOQ2r1EKAvCeEw3RxLSWswIcbAJLFG0=
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
|
||||
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dolthub/maphash v0.1.0 h1:bsQ7JsF4FkkWyrP3oCnFJgrCUAFbFf3kOl4L/QxPDyQ=
|
||||
github.com/dolthub/maphash v0.1.0/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4=
|
||||
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE=
|
||||
github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
@@ -58,6 +74,10 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx
|
||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
@@ -76,6 +96,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs=
|
||||
github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
@@ -86,12 +108,21 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc=
|
||||
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
|
||||
github.com/imroc/req/v3 v3.48.0 h1:IYuMGetuwLzOOTzDCquDqs912WNwpsPK0TBXWPIvoqg=
|
||||
github.com/imroc/req/v3 v3.48.0/go.mod h1:weam9gmyb00QnOtu6HXSnk44dNFkIUQb5QdMx13FeUU=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
@@ -105,6 +136,8 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20240510055607-89e20ab7b6c6 h1:YeIGErDiB/fhmNsJy0cfjoT8XnRNT9hb19xZ4MvWQDU=
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20240510055607-89e20ab7b6c6/go.mod h1:C5LA5UO2ZXJrLaPLYtE1wUJMiyd/nwWaCO5cw/2pSHs=
|
||||
github.com/lxzan/gws v1.8.8 h1:st193ZG8qN8sSw8/g/UituFhs7etmKzS7jUqhijg5wM=
|
||||
github.com/lxzan/gws v1.8.8/go.mod h1:FcGeRMB7HwGuTvMLR24ku0Zx0p6RXqeKASeMc4VYgi4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@@ -124,12 +157,22 @@ github.com/nicksnyder/go-i18n/v2 v2.4.1 h1:zwzjtX4uYyiaU02K5Ia3zSkpJZrByARkRB4V3
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.1/go.mod h1:++Pl70FR6Cki7hdzZRnEEqdc2dJt+SAGotyFg/SvZMk=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
||||
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1 h1:jOJ5Pg2w1oeB6PeDurIYf6k9PQ+aTITr/6lP/L/zp6c=
|
||||
github.com/orcaman/concurrent-map/v2 v2.0.1/go.mod h1:9Eq3TG2oBe5FirmYWQfYO5iH1q0Jv47PLaNK++uCdOM=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg6/go-requests v0.2.2 h1:wL0aFmyybM/Wuqj8xQa3sNL5ioAL97hQZ78TJovltbM=
|
||||
github.com/pkg6/go-requests v0.2.2/go.mod h1:/rcVm8Itd2djtxDVxjRnHURChV86TB4ooZnP+IBZBmg=
|
||||
github.com/pkg6/go-sms v0.1.2 h1:HZQlBkRVF9xQHhyCMB3kXY/kltfvuNgMTKuN/DoSg7w=
|
||||
github.com/pkg6/go-sms v0.1.2/go.mod h1:PwFBEssnkYXw+mfSmQ+6fwgXgrcUB9NK5dLUglx+ZW4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
@@ -142,10 +185,16 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA=
|
||||
github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
|
||||
github.com/rbcervilla/redisstore/v9 v9.0.0 h1:wOPbBaydbdxzi1gTafDftCI/Z7vnsXw0QDPCuhiMG0g=
|
||||
github.com/rbcervilla/redisstore/v9 v9.0.0/go.mod h1:q/acLpoKkTZzIsBYt0R4THDnf8W/BH6GjQYvxDSSfdI=
|
||||
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
||||
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
@@ -163,6 +212,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
@@ -170,6 +220,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/wenlng/go-captcha-assets v1.0.1 h1:AdjRFMKmadPRWRTv0XEYfjDvcaayZ2yExITDvlK/7bk=
|
||||
github.com/wenlng/go-captcha-assets v1.0.1/go.mod h1:yQqc7rRbxgLCg+tWtVp+7Y317D1wIZDan/yIwt8wSac=
|
||||
github.com/wenlng/go-captcha/v2 v2.0.1 h1:N6XSHymJ7e9Z/LyWWTWLMAkAXtW27ZROZpvNrqPhSnA=
|
||||
github.com/wenlng/go-captcha/v2 v2.0.1/go.mod h1:5hac1em3uXoyC5ipZ0xFv9umNM/waQvYAQdr0cx/h34=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
@@ -178,6 +230,7 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yitter/idgenerator-go v1.3.1 h1:GjVi2BupiDb1IXaXqrkOJE4p6qKdj3NaM3GdAjWok14=
|
||||
github.com/yitter/idgenerator-go v1.3.1/go.mod h1:VVjbqFjGUsIkaXVkXEdmx1LiXUL3K1NvyxWPJBPbBpE=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
|
||||
@@ -187,10 +240,14 @@ github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA=
|
||||
github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zeromicro/go-zero v1.7.3 h1:yDUQF2DXDhUHc77/NZF6mzsoRPMBfldjPmG2O/ZSzss=
|
||||
github.com/zeromicro/go-zero v1.7.3/go.mod h1:9JIW3gHBGuc9LzvjZnNwINIq9QdiKu3AigajLtkJamQ=
|
||||
github.com/zmexing/go-sensitive-word v1.3.0 h1:dB9S9kNklksOODGLLAov0RaVCwC2w9Kwxz6NZMdM6rk=
|
||||
github.com/zmexing/go-sensitive-word v1.3.0/go.mod h1:wkNIpkq1iPOe3l7l83zvnnV5mm20jfj2x8V8kjOTsUM=
|
||||
go.mongodb.org/mongo-driver/v2 v2.0.0-beta2 h1:PRtbRKwblE8ZfI8qOhofcjn9y8CmKZI7trS5vDMeJX0=
|
||||
go.mongodb.org/mongo-driver/v2 v2.0.0-beta2/go.mod h1:UGLb3ZgEzaY0cCbJpH9UFt9B6gEXiTPzsnJS38nBeoU=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
|
||||
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8=
|
||||
@@ -205,37 +262,63 @@ go.opentelemetry.io/otel/exporters/zipkin v1.24.0 h1:3evrL5poBuh1KF51D9gO/S+N/1m
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0/go.mod h1:0EHgD8R0+8yRhUYJOGR8Hfg2dpiJQxDOszd5smVO9wM=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
|
||||
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
|
||||
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
|
||||
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
|
||||
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
|
||||
golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g=
|
||||
golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -244,25 +327,34 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
|
||||
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
|
||||
|
Reference in New Issue
Block a user