From d0496b34f07e5f95658eca5f5bb20fe1a52887e1 Mon Sep 17 00:00:00 2001 From: landaiqing <3517283258@qq.com> Date: Tue, 6 Aug 2024 00:08:33 +0800 Subject: [PATCH] :sparkles: add go-captcha / add base auth api --- .caches/master.jpg | Bin 0 -> 58719 bytes .caches/thumb.png | Bin 0 -> 3108 bytes api/api.go | 6 +- api/auth_api/auth_api.go | 66 +++++++++++++ api/auth_api/{enter.go => index.go} | 0 api/captcha_api/captcha_api.go | 40 ++++++++ api/captcha_api/index.go | 3 + cmd/gen/gen.go | 16 ++-- common/enum/deleted.go | 6 ++ core/captcha.go | 100 ++++++++++++++++++++ core/gorm.go | 17 ++-- core/logrus.go | 4 +- docs/docs.go | 100 ++++++++++++++++++++ docs/swagger.json | 100 ++++++++++++++++++++ docs/swagger.yaml | 64 +++++++++++++ global/global.go | 12 ++- go.mod | 5 + go.sum | 16 ++++ main.go | 1 + model/sca_auth_permission.gen.go | 30 +++--- model/sca_auth_role.gen.go | 16 ++-- model/sca_auth_role_permission.gen.go | 16 ++-- model/sca_auth_user.gen.go | 40 ++++---- model/sca_auth_user_device.gen.go | 28 +++--- model/sca_auth_user_role.gen.go | 16 ++-- model/sca_auth_user_social.gen.go | 52 +++++----- router/modules/auth_user_router.go | 4 + service/auth_service/auth_service.go | 50 +++++++++- service/auth_service/{enter.go => index.go} | 0 29 files changed, 687 insertions(+), 121 deletions(-) create mode 100644 .caches/master.jpg create mode 100644 .caches/thumb.png rename api/auth_api/{enter.go => index.go} (100%) create mode 100644 api/captcha_api/captcha_api.go create mode 100644 api/captcha_api/index.go create mode 100644 common/enum/deleted.go create mode 100644 core/captcha.go rename service/auth_service/{enter.go => index.go} (100%) diff --git a/.caches/master.jpg b/.caches/master.jpg new file mode 100644 index 0000000000000000000000000000000000000000..891c664beaa76fae4c5309ec5078a6decb55e1cd GIT binary patch literal 58719 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 generate err") + } + + dots, _ := json.Marshal(dotData) + fmt.Println(">>>>> ", string(dots)) + + err = captData.GetMasterImage().SaveToFile("./.caches/master.jpg", option.QualityNone) + if err != nil { + fmt.Println(err) + } + err = captData.GetThumbImage().SaveToFile("./.caches/thumb.png") + if err != nil { + fmt.Println(err) + } +} diff --git a/api/captcha_api/index.go b/api/captcha_api/index.go new file mode 100644 index 0000000..fcaa46d --- /dev/null +++ b/api/captcha_api/index.go @@ -0,0 +1,3 @@ +package main + +type CaptchaAPI struct{} diff --git a/cmd/gen/gen.go b/cmd/gen/gen.go index 2fa6ee3..ee48771 100644 --- a/cmd/gen/gen.go +++ b/cmd/gen/gen.go @@ -99,19 +99,19 @@ func initInfo() (db *gorm.DB, g *gen.Generator, fieldOpts []gen.ModelOpt) { // 将非默认字段名的字段定义为自动时间戳和软删除字段; // 自动时间戳默认字段名为:`updated_at`、`created_at, 表字段数据类型为: INT 或 DATETIME // 软删除默认字段名为:`deleted_at`, 表字段数据类型为: DATETIME - autoUpdateTimeField := gen.FieldGORMTag("update_time", func(tag field.GormTag) field.GormTag { - return tag.Append("autoUpdateTime") - }) - autoCreateTimeField := gen.FieldGORMTag("created_time", func(tag field.GormTag) field.GormTag { - return tag.Append("autoCreateTime") - }) + //autoUpdateTimeField := gen.FieldGORMTag("update_time", func(tag field.GormTag) field.GormTag { + // return tag.Append("autoUpdateTime") + //}) + //autoCreateTimeField := gen.FieldGORMTag("created_time", func(tag field.GormTag) field.GormTag { + // return tag.Append("autoCreateTime") + //}) //softDeleteField := gen.FieldType("deletedAt", "gorm.DeletedAt") // 模型自定义选项组 fieldOpts = []gen.ModelOpt{ // jsonField, - autoCreateTimeField, - autoUpdateTimeField, + //autoCreateTimeField, + //autoUpdateTimeField, //softDeleteField, } diff --git a/common/enum/deleted.go b/common/enum/deleted.go new file mode 100644 index 0000000..0cc0112 --- /dev/null +++ b/common/enum/deleted.go @@ -0,0 +1,6 @@ +package enum + +var ( + UNDELETED int64 = 0 + DELETED int64 = 1 +) diff --git a/core/captcha.go b/core/captcha.go new file mode 100644 index 0000000..291e7a9 --- /dev/null +++ b/core/captcha.go @@ -0,0 +1,100 @@ +package core + +import ( + "github.com/golang/freetype/truetype" + "github.com/wenlng/go-captcha-assets/bindata/chars" + "github.com/wenlng/go-captcha-assets/resources/fonts/fzshengsksjw" + "github.com/wenlng/go-captcha-assets/resources/images" + "github.com/wenlng/go-captcha-assets/resources/tiles" + "github.com/wenlng/go-captcha/v2/base/option" + "github.com/wenlng/go-captcha/v2/click" + "github.com/wenlng/go-captcha/v2/rotate" + "github.com/wenlng/go-captcha/v2/slide" + "log" + "schisandra-cloud-album/global" +) + +// initTextCaptcha 初始化点选验证码 +func initTextCaptcha() { + builder := click.NewBuilder() + + // fonts + fonts, err := fzshengsksjw.GetFont() + if err != nil { + global.LOG.Fatalln(err) + } + + // background images + imgs, err := images.GetImages() + if err != nil { + global.LOG.Fatalln(err) + } + + builder.SetResources( + click.WithChars(chars.GetChineseChars()), + click.WithFonts([]*truetype.Font{fonts}), + click.WithBackgrounds(imgs), + ) + global.TextCaptcha = builder.Make() +} + +// initSlideCaptcha 初始化滑动验证码 +func initsSlideCaptcha() { + builder := slide.NewBuilder( + //slide.WithGenGraphNumber(2), + slide.WithEnableGraphVerticalRandom(true), + ) + + // background images + imgs, err := images.GetImages() + if err != nil { + log.Fatalln(err) + } + + graphs, err := tiles.GetTiles() + if err != nil { + log.Fatalln(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), + ) + + global.SlideCaptcha = builder.Make() +} + +// initRotateCaptcha 初始化旋转验证码 +func initRotateCaptcha() { + builder := rotate.NewBuilder(rotate.WithRangeAnglePos([]option.RangeVal{ + {Min: 20, Max: 330}, + })) + + // background images + imgs, err := images.GetImages() + if err != nil { + log.Fatalln(err) + } + + // set resources + builder.SetResources( + rotate.WithImages(imgs), + ) + + global.RotateCaptcha = builder.Make() +} + +func InitCaptcha() { + initTextCaptcha() +} diff --git a/core/gorm.go b/core/gorm.go index 44928f8..72908b2 100644 --- a/core/gorm.go +++ b/core/gorm.go @@ -26,19 +26,22 @@ func MySQlConnect() *gorm.DB { mysqlLogger = logger.New( log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{ - SlowThreshold: time.Second, //慢sql日志 - LogLevel: logger.Info, //级别 - Colorful: true, //颜色 + SlowThreshold: time.Second, //慢sql日志 + LogLevel: logger.Info, //级别 + Colorful: true, //颜色 + IgnoreRecordNotFoundError: true, //忽略RecordNotFoundError + ParameterizedQueries: true, //格式化SQL语句 }) } else { mysqlLogger = logger.New( log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{ - SlowThreshold: time.Second, //慢sql日志 - LogLevel: logger.Error, //级别 - Colorful: true, //颜色 - + SlowThreshold: time.Second, //慢sql日志 + LogLevel: logger.Error, //级别 + Colorful: true, //颜色 + IgnoreRecordNotFoundError: true, //忽略RecordNotFoundError + ParameterizedQueries: true, //格式化SQL语句 }) } diff --git a/core/logrus.go b/core/logrus.go index 7d6c1ec..60480c2 100644 --- a/core/logrus.go +++ b/core/logrus.go @@ -63,11 +63,11 @@ func InitLogger() *logrus.Logger { } newLog.SetLevel(level) //设置日志级别 global.LOG = newLog - InitDefaultLogger() + initDefaultLogger() return newLog } -func InitDefaultLogger() { +func initDefaultLogger() { //全局日志 logrus.SetOutput(os.Stdout) //设置输出类型 logrus.SetReportCaller(global.CONFIG.Logger.ShowLine) //设置是否显示函数名和行号 diff --git a/docs/docs.go b/docs/docs.go index ef997ed..659cf1e 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -30,6 +30,106 @@ const docTemplate = `{ } } } + }, + "/api/auth/user/delete": { + "delete": { + "tags": [ + "鉴权模块" + ], + "summary": "删除用户", + "parameters": [ + { + "type": "string", + "description": "用户uuid", + "name": "uuid", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/auth/user/query_by_phone": { + "get": { + "tags": [ + "鉴权模块" + ], + "summary": "根据手机号查询用户", + "parameters": [ + { + "type": "string", + "description": "手机号", + "name": "phone", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/auth/user/query_by_username": { + "get": { + "tags": [ + "鉴权模块" + ], + "summary": "根据用户名查询用户", + "parameters": [ + { + "type": "string", + "description": "用户名", + "name": "username", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/auth/user/query_by_uuid": { + "get": { + "tags": [ + "鉴权模块" + ], + "summary": "根据uuid查询用户", + "parameters": [ + { + "type": "string", + "description": "用户uuid", + "name": "uuid", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } } } }` diff --git a/docs/swagger.json b/docs/swagger.json index fc2e332..5aeda8f 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -19,6 +19,106 @@ } } } + }, + "/api/auth/user/delete": { + "delete": { + "tags": [ + "鉴权模块" + ], + "summary": "删除用户", + "parameters": [ + { + "type": "string", + "description": "用户uuid", + "name": "uuid", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/auth/user/query_by_phone": { + "get": { + "tags": [ + "鉴权模块" + ], + "summary": "根据手机号查询用户", + "parameters": [ + { + "type": "string", + "description": "手机号", + "name": "phone", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/auth/user/query_by_username": { + "get": { + "tags": [ + "鉴权模块" + ], + "summary": "根据用户名查询用户", + "parameters": [ + { + "type": "string", + "description": "用户名", + "name": "username", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } + }, + "/api/auth/user/query_by_uuid": { + "get": { + "tags": [ + "鉴权模块" + ], + "summary": "根据uuid查询用户", + "parameters": [ + { + "type": "string", + "description": "用户uuid", + "name": "uuid", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + } + } + } } } } \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml index fee9e38..07df8de 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -11,4 +11,68 @@ paths: summary: 获取所有用户列表 tags: - 鉴权模块 + /api/auth/user/delete: + delete: + parameters: + - description: 用户uuid + in: query + name: uuid + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + summary: 删除用户 + tags: + - 鉴权模块 + /api/auth/user/query_by_phone: + get: + parameters: + - description: 手机号 + in: query + name: phone + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + summary: 根据手机号查询用户 + tags: + - 鉴权模块 + /api/auth/user/query_by_username: + get: + parameters: + - description: 用户名 + in: query + name: username + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + summary: 根据用户名查询用户 + tags: + - 鉴权模块 + /api/auth/user/query_by_uuid: + get: + parameters: + - description: 用户uuid + in: query + name: uuid + required: true + type: string + responses: + "200": + description: OK + schema: + type: string + summary: 根据uuid查询用户 + tags: + - 鉴权模块 swagger: "2.0" diff --git a/global/global.go b/global/global.go index 46cb640..aed262d 100644 --- a/global/global.go +++ b/global/global.go @@ -2,13 +2,19 @@ package global import ( "github.com/sirupsen/logrus" + "github.com/wenlng/go-captcha/v2/click" + "github.com/wenlng/go-captcha/v2/rotate" + "github.com/wenlng/go-captcha/v2/slide" "gorm.io/gorm" "schisandra-cloud-album/config" ) // Config 全局配置文件 var ( - CONFIG *config.Config - DB *gorm.DB - LOG *logrus.Logger + CONFIG *config.Config + DB *gorm.DB + LOG *logrus.Logger + TextCaptcha click.Captcha + SlideCaptcha slide.Captcha + RotateCaptcha rotate.Captcha ) diff --git a/go.mod b/go.mod index 8e4039f..f0cc483 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/cloudwego/iasm v0.2.0 // indirect github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/spec v0.21.0 // indirect @@ -32,6 +33,7 @@ require ( github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/goccy/go-json v0.10.3 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -45,8 +47,11 @@ require ( github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + github.com/wenlng/go-captcha-assets v1.0.1 // indirect + github.com/wenlng/go-captcha/v2 v2.0.0 // indirect golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.25.0 // indirect + golang.org/x/image v0.18.0 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect diff --git a/go.sum b/go.sum index 97bcc73..085b184 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +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-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= @@ -47,6 +49,8 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= 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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -120,6 +124,10 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +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.0 h1:7Z4Zy09SIHgvj9e8ZxP4VhYOwg7IHt8kGlVrE5jP5Z8= +github.com/wenlng/go-captcha/v2 v2.0.0/go.mod h1:5hac1em3uXoyC5ipZ0xFv9umNM/waQvYAQdr0cx/h34= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= @@ -127,17 +135,23 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= +golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ= +golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= 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.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= 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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -157,11 +171,13 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 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.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index f8d4495..b8649c6 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ func main() { core.InitConfig() core.InitLogger() core.InitGorm() + core.InitCaptcha() // 命令行参数绑定 option := cmd.Parse() if cmd.IsStopWeb(&option) { diff --git a/model/sca_auth_permission.gen.go b/model/sca_auth_permission.gen.go index 0ec2be6..b1b9588 100644 --- a/model/sca_auth_permission.gen.go +++ b/model/sca_auth_permission.gen.go @@ -12,21 +12,21 @@ const TableNameScaAuthPermission = "sca_auth_permission" // ScaAuthPermission 权限表 type ScaAuthPermission struct { - ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - PermissionName *string `gorm:"column:permission_name;type:varchar(64);comment:权限名称" json:"permission_name"` // 权限名称 - ParentID *int64 `gorm:"column:parent_id;type:bigint(20);comment:父ID" json:"parent_id"` // 父ID - Type *int64 `gorm:"column:type;type:tinyint(4);comment:类型 0 菜单 1 目录 2 按钮 -1其他" json:"type"` // 类型 0 菜单 1 目录 2 按钮 -1其他 - Path *string `gorm:"column:path;type:varchar(255);comment:路径" json:"path"` // 路径 - Status *int64 `gorm:"column:status;type:tinyint(4);comment:状态 0 启用 1 停用" json:"status"` // 状态 0 启用 1 停用 - Icon *string `gorm:"column:icon;type:varchar(128);comment:图标" json:"icon"` // 图标 - PermissionKey *string `gorm:"column:permission_key;type:varchar(64);comment:权限关键字" json:"permission_key"` // 权限关键字 - Order *int64 `gorm:"column:order;type:int(11);comment:排序" json:"order"` // 排序 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;autoCreateTime;comment:创建时间" json:"created_time"` // 创建时间 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 - UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;autoUpdateTime;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 - Remark *string `gorm:"column:remark;type:varchar(255);comment:备注 描述" json:"remark"` // 备注 描述 + ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID + PermissionName *string `gorm:"column:permission_name;type:varchar(64);comment:权限名称" json:"permission_name"` // 权限名称 + ParentID *int64 `gorm:"column:parent_id;type:bigint(20);comment:父ID" json:"parent_id"` // 父ID + Type *int64 `gorm:"column:type;type:tinyint(4);comment:类型 0 菜单 1 目录 2 按钮 -1其他" json:"type"` // 类型 0 菜单 1 目录 2 按钮 -1其他 + Path *string `gorm:"column:path;type:varchar(255);comment:路径" json:"path"` // 路径 + Status *int64 `gorm:"column:status;type:tinyint(4);comment:状态 0 启用 1 停用" json:"status"` // 状态 0 启用 1 停用 + Icon *string `gorm:"column:icon;type:varchar(128);comment:图标" json:"icon"` // 图标 + PermissionKey *string `gorm:"column:permission_key;type:varchar(64);comment:权限关键字" json:"permission_key"` // 权限关键字 + Order *int64 `gorm:"column:order;type:int(11);comment:排序" json:"order"` // 排序 + CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 + UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 + Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 + Remark *string `gorm:"column:remark;type:varchar(255);comment:备注 描述" json:"remark"` // 备注 描述 } // TableName ScaAuthPermission's table name diff --git a/model/sca_auth_role.gen.go b/model/sca_auth_role.gen.go index 3b5be7c..e5a9dd7 100644 --- a/model/sca_auth_role.gen.go +++ b/model/sca_auth_role.gen.go @@ -12,14 +12,14 @@ const TableNameScaAuthRole = "sca_auth_role" // ScaAuthRole 角色表 type ScaAuthRole struct { - ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - RoleName string `gorm:"column:role_name;type:varchar(32);not null;comment:角色名称" json:"role_name"` // 角色名称 - RoleKey string `gorm:"column:role_key;type:varchar(64);not null;comment:角色关键字" json:"role_key"` // 角色关键字 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;autoCreateTime;comment:创建时间" json:"created_time"` // 创建时间 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 - UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;autoUpdateTime;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除 0 未删除 1已删除" json:"deleted"` // 是否删除 0 未删除 1已删除 + ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID + RoleName string `gorm:"column:role_name;type:varchar(32);not null;comment:角色名称" json:"role_name"` // 角色名称 + RoleKey string `gorm:"column:role_key;type:varchar(64);not null;comment:角色关键字" json:"role_key"` // 角色关键字 + CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 + UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 + Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除 0 未删除 1已删除" json:"deleted"` // 是否删除 0 未删除 1已删除 } // TableName ScaAuthRole's table name diff --git a/model/sca_auth_role_permission.gen.go b/model/sca_auth_role_permission.gen.go index d677ff7..61db414 100644 --- a/model/sca_auth_role_permission.gen.go +++ b/model/sca_auth_role_permission.gen.go @@ -12,14 +12,14 @@ const TableNameScaAuthRolePermission = "sca_auth_role_permission" // ScaAuthRolePermission 角色-权限映射表 type ScaAuthRolePermission struct { - ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - RoleID int64 `gorm:"column:role_id;type:bigint(20);not null;comment:角色ID" json:"role_id"` // 角色ID - PermissionID int64 `gorm:"column:permission_id;type:bigint(20);not null;comment:权限ID" json:"permission_id"` // 权限ID - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;autoCreateTime;comment:创建时间" json:"created_time"` // 创建时间 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 - UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;autoUpdateTime;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 + ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID + RoleID int64 `gorm:"column:role_id;type:bigint(20);not null;comment:角色ID" json:"role_id"` // 角色ID + PermissionID int64 `gorm:"column:permission_id;type:bigint(20);not null;comment:权限ID" json:"permission_id"` // 权限ID + CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 + UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 + Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 } // TableName ScaAuthRolePermission's table name diff --git a/model/sca_auth_user.gen.go b/model/sca_auth_user.gen.go index 14442f7..66e6eb2 100644 --- a/model/sca_auth_user.gen.go +++ b/model/sca_auth_user.gen.go @@ -12,26 +12,26 @@ const TableNameScaAuthUser = "sca_auth_user" // ScaAuthUser 用户表 type ScaAuthUser struct { - ID int64 `gorm:"column:id;type:bigint(255);primaryKey;autoIncrement:true;comment:自增ID" json:"id"` // 自增ID - UUID *string `gorm:"column:uuid;type:varchar(255);comment:唯一ID" json:"uuid"` // 唯一ID - Username *string `gorm:"column:username;type:varchar(32);comment:用户名" json:"username"` // 用户名 - Nickname *string `gorm:"column:nickname;type:varchar(32);comment:昵称" json:"nickname"` // 昵称 - Email *string `gorm:"column:email;type:varchar(32);comment:邮箱" json:"email"` // 邮箱 - Phone *string `gorm:"column:phone;type:varchar(32);comment:电话" json:"phone"` // 电话 - Password *string `gorm:"column:password;type:varchar(64);comment:密码" json:"password"` // 密码 - Gender *string `gorm:"column:gender;type:varchar(32);comment:性别" json:"gender"` // 性别 - Avatar *string `gorm:"column:avatar;type:varchar(255);comment:头像" json:"avatar"` // 头像 - Status *int64 `gorm:"column:status;type:tinyint(4);comment:状态 0 正常 1 封禁" json:"status"` // 状态 0 正常 1 封禁 - Introduce *string `gorm:"column:introduce;type:varchar(255);comment:介绍" json:"introduce"` // 介绍 - ExtJSON *string `gorm:"column:ext_json;type:varchar(255);comment:额外字段" json:"ext_json"` // 额外字段 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;autoCreateTime;comment:创建时间" json:"created_time"` // 创建时间 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 - UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;autoUpdateTime;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除 0 未删除 1 已删除" json:"deleted"` // 是否删除 0 未删除 1 已删除 - Blog *string `gorm:"column:blog;type:varchar(255);comment:博客" json:"blog"` // 博客 - Location *string `gorm:"column:location;type:varchar(255);comment:地址" json:"location"` // 地址 - Company *string `gorm:"column:company;type:varchar(255);comment:公司" json:"company"` // 公司 + ID int64 `gorm:"column:id;type:bigint(255);primaryKey;autoIncrement:true;comment:自增ID" json:"id"` // 自增ID + UUID *string `gorm:"column:uuid;type:varchar(255);comment:唯一ID" json:"uuid"` // 唯一ID + Username *string `gorm:"column:username;type:varchar(32);comment:用户名" json:"username"` // 用户名 + Nickname *string `gorm:"column:nickname;type:varchar(32);comment:昵称" json:"nickname"` // 昵称 + Email *string `gorm:"column:email;type:varchar(32);comment:邮箱" json:"email"` // 邮箱 + Phone *string `gorm:"column:phone;type:varchar(32);comment:电话" json:"phone"` // 电话 + Password *string `gorm:"column:password;type:varchar(64);comment:密码" json:"password"` // 密码 + Gender *string `gorm:"column:gender;type:varchar(32);comment:性别" json:"gender"` // 性别 + Avatar *string `gorm:"column:avatar;type:varchar(255);comment:头像" json:"avatar"` // 头像 + Status *int64 `gorm:"column:status;type:tinyint(4);comment:状态 0 正常 1 封禁" json:"status"` // 状态 0 正常 1 封禁 + Introduce *string `gorm:"column:introduce;type:varchar(255);comment:介绍" json:"introduce"` // 介绍 + ExtJSON *string `gorm:"column:ext_json;type:varchar(255);comment:额外字段" json:"ext_json"` // 额外字段 + CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 + UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 + Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除 0 未删除 1 已删除" json:"deleted"` // 是否删除 0 未删除 1 已删除 + Blog *string `gorm:"column:blog;type:varchar(255);comment:博客" json:"blog"` // 博客 + Location *string `gorm:"column:location;type:varchar(255);comment:地址" json:"location"` // 地址 + Company *string `gorm:"column:company;type:varchar(255);comment:公司" json:"company"` // 公司 } // TableName ScaAuthUser's table name diff --git a/model/sca_auth_user_device.gen.go b/model/sca_auth_user_device.gen.go index bcdf1df..57589a3 100644 --- a/model/sca_auth_user_device.gen.go +++ b/model/sca_auth_user_device.gen.go @@ -12,20 +12,20 @@ const TableNameScaAuthUserDevice = "sca_auth_user_device" // ScaAuthUserDevice 用户设备信息 type ScaAuthUserDevice struct { - ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - UserID *int64 `gorm:"column:user_id;type:bigint(20);comment:用户ID" json:"user_id"` // 用户ID - IP *string `gorm:"column:ip;type:varchar(255);comment:登录IP" json:"ip"` // 登录IP - Location *string `gorm:"column:location;type:varchar(255);comment:地址" json:"location"` // 地址 - Agent *string `gorm:"column:agent;type:varchar(255);comment:设备信息" json:"agent"` // 设备信息 - ExtJSON *string `gorm:"column:ext_json;type:varchar(255);comment:额外字段" json:"ext_json"` // 额外字段 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;autoCreateTime;comment:创建时间" json:"created_time"` // 创建时间 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 - UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;autoUpdateTime;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 - Browser *string `gorm:"column:browser;type:varchar(255);comment:浏览器" json:"browser"` // 浏览器 - OperatingSystem *string `gorm:"column:operating_system;type:varchar(255);comment:操作系统" json:"operating_system"` // 操作系统 - BrowserVersion *string `gorm:"column:browser_version;type:varchar(255);comment:浏览器版本" json:"browser_version"` // 浏览器版本 + ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID + UserID *int64 `gorm:"column:user_id;type:bigint(20);comment:用户ID" json:"user_id"` // 用户ID + IP *string `gorm:"column:ip;type:varchar(255);comment:登录IP" json:"ip"` // 登录IP + Location *string `gorm:"column:location;type:varchar(255);comment:地址" json:"location"` // 地址 + Agent *string `gorm:"column:agent;type:varchar(255);comment:设备信息" json:"agent"` // 设备信息 + ExtJSON *string `gorm:"column:ext_json;type:varchar(255);comment:额外字段" json:"ext_json"` // 额外字段 + CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 + UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 + Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 + Browser *string `gorm:"column:browser;type:varchar(255);comment:浏览器" json:"browser"` // 浏览器 + OperatingSystem *string `gorm:"column:operating_system;type:varchar(255);comment:操作系统" json:"operating_system"` // 操作系统 + BrowserVersion *string `gorm:"column:browser_version;type:varchar(255);comment:浏览器版本" json:"browser_version"` // 浏览器版本 } // TableName ScaAuthUserDevice's table name diff --git a/model/sca_auth_user_role.gen.go b/model/sca_auth_user_role.gen.go index 5453311..066f379 100644 --- a/model/sca_auth_user_role.gen.go +++ b/model/sca_auth_user_role.gen.go @@ -12,14 +12,14 @@ const TableNameScaAuthUserRole = "sca_auth_user_role" // ScaAuthUserRole 用户-角色映射表 type ScaAuthUserRole struct { - ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - UserID int64 `gorm:"column:user_id;type:bigint(20);not null;comment:用户ID" json:"user_id"` // 用户ID - RoleID int64 `gorm:"column:role_id;type:bigint(20);not null;comment:角色ID" json:"role_id"` // 角色ID - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;autoCreateTime;comment:创建时间" json:"created_time"` // 创建时间 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 - UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;autoUpdateTime;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 + ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID + UserID int64 `gorm:"column:user_id;type:bigint(20);not null;comment:用户ID" json:"user_id"` // 用户ID + RoleID int64 `gorm:"column:role_id;type:bigint(20);not null;comment:角色ID" json:"role_id"` // 角色ID + CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 + UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 + Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 } // TableName ScaAuthUserRole's table name diff --git a/model/sca_auth_user_social.gen.go b/model/sca_auth_user_social.gen.go index e09f941..9a1cbeb 100644 --- a/model/sca_auth_user_social.gen.go +++ b/model/sca_auth_user_social.gen.go @@ -12,32 +12,32 @@ const TableNameScaAuthUserSocial = "sca_auth_user_social" // ScaAuthUserSocial 社会用户信息表 type ScaAuthUserSocial struct { - ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID - UserID int64 `gorm:"column:user_id;type:bigint(20);not null;comment:用户ID" json:"user_id"` // 用户ID - UUID *string `gorm:"column:uuid;type:varchar(255);comment:第三方系统的唯一ID" json:"uuid"` // 第三方系统的唯一ID - Source *string `gorm:"column:source;type:varchar(255);comment:第三方用户来源" json:"source"` // 第三方用户来源 - AccessToken *string `gorm:"column:access_token;type:varchar(255);comment:用户的授权令牌" json:"access_token"` // 用户的授权令牌 - ExpireIn *int64 `gorm:"column:expire_in;type:int(11);comment:第三方用户的授权令牌的有效期" json:"expire_in"` // 第三方用户的授权令牌的有效期 - RefreshToken *string `gorm:"column:refresh_token;type:varchar(255);comment:刷新令牌" json:"refresh_token"` // 刷新令牌 - OpenID *string `gorm:"column:open_id;type:varchar(255);comment:第三方用户的 open id" json:"open_id"` // 第三方用户的 open id - UID *string `gorm:"column:uid;type:varchar(255);comment:第三方用户的 ID" json:"uid"` // 第三方用户的 ID - AccessCode *string `gorm:"column:access_code;type:varchar(255);comment:个别平台的授权信息" json:"access_code"` // 个别平台的授权信息 - UnionID *string `gorm:"column:union_id;type:varchar(255);comment:第三方用户的 union id" json:"union_id"` // 第三方用户的 union id - Scope *string `gorm:"column:scope;type:varchar(255);comment:第三方用户授予的权限" json:"scope"` // 第三方用户授予的权限 - TokenType *string `gorm:"column:token_type;type:varchar(255);comment:个别平台的授权信息" json:"token_type"` // 个别平台的授权信息 - IDToken *string `gorm:"column:id_token;type:varchar(255);comment:id token" json:"id_token"` // id token - MacAlgorithm *string `gorm:"column:mac_algorithm;type:varchar(255);comment:小米平台用户的附带属性" json:"mac_algorithm"` // 小米平台用户的附带属性 - MacKey *string `gorm:"column:mac_key;type:varchar(255);comment:小米平台用户的附带属性" json:"mac_key"` // 小米平台用户的附带属性 - Code *string `gorm:"column:code;type:varchar(255);comment:用户的授权code" json:"code"` // 用户的授权code - OauthToken *string `gorm:"column:oauth_token;type:varchar(255);comment:Twitter平台用户的附带属性" json:"oauth_token"` // Twitter平台用户的附带属性 - OauthTokenSecret *string `gorm:"column:oauth_token_secret;type:varchar(255);comment:Twitter平台用户的附带属性" json:"oauth_token_secret"` // Twitter平台用户的附带属性 - Status *string `gorm:"column:status;type:varchar(255);comment:状态 0正常 1 封禁" json:"status"` // 状态 0正常 1 封禁 - ExtJSON *string `gorm:"column:ext_json;type:varchar(255);comment:额外字段" json:"ext_json"` // 额外字段 - CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 - CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;autoCreateTime;comment:创建时间" json:"created_time"` // 创建时间 - UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 - UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;autoUpdateTime;comment:更新时间" json:"update_time"` // 更新时间 - Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 + ID int64 `gorm:"column:id;type:bigint(20);primaryKey;comment:主键ID" json:"id"` // 主键ID + UserID int64 `gorm:"column:user_id;type:bigint(20);not null;comment:用户ID" json:"user_id"` // 用户ID + UUID *string `gorm:"column:uuid;type:varchar(255);comment:第三方系统的唯一ID" json:"uuid"` // 第三方系统的唯一ID + Source *string `gorm:"column:source;type:varchar(255);comment:第三方用户来源" json:"source"` // 第三方用户来源 + AccessToken *string `gorm:"column:access_token;type:varchar(255);comment:用户的授权令牌" json:"access_token"` // 用户的授权令牌 + ExpireIn *int64 `gorm:"column:expire_in;type:int(11);comment:第三方用户的授权令牌的有效期" json:"expire_in"` // 第三方用户的授权令牌的有效期 + RefreshToken *string `gorm:"column:refresh_token;type:varchar(255);comment:刷新令牌" json:"refresh_token"` // 刷新令牌 + OpenID *string `gorm:"column:open_id;type:varchar(255);comment:第三方用户的 open id" json:"open_id"` // 第三方用户的 open id + UID *string `gorm:"column:uid;type:varchar(255);comment:第三方用户的 ID" json:"uid"` // 第三方用户的 ID + AccessCode *string `gorm:"column:access_code;type:varchar(255);comment:个别平台的授权信息" json:"access_code"` // 个别平台的授权信息 + UnionID *string `gorm:"column:union_id;type:varchar(255);comment:第三方用户的 union id" json:"union_id"` // 第三方用户的 union id + Scope *string `gorm:"column:scope;type:varchar(255);comment:第三方用户授予的权限" json:"scope"` // 第三方用户授予的权限 + TokenType *string `gorm:"column:token_type;type:varchar(255);comment:个别平台的授权信息" json:"token_type"` // 个别平台的授权信息 + IDToken *string `gorm:"column:id_token;type:varchar(255);comment:id token" json:"id_token"` // id token + MacAlgorithm *string `gorm:"column:mac_algorithm;type:varchar(255);comment:小米平台用户的附带属性" json:"mac_algorithm"` // 小米平台用户的附带属性 + MacKey *string `gorm:"column:mac_key;type:varchar(255);comment:小米平台用户的附带属性" json:"mac_key"` // 小米平台用户的附带属性 + Code *string `gorm:"column:code;type:varchar(255);comment:用户的授权code" json:"code"` // 用户的授权code + OauthToken *string `gorm:"column:oauth_token;type:varchar(255);comment:Twitter平台用户的附带属性" json:"oauth_token"` // Twitter平台用户的附带属性 + OauthTokenSecret *string `gorm:"column:oauth_token_secret;type:varchar(255);comment:Twitter平台用户的附带属性" json:"oauth_token_secret"` // Twitter平台用户的附带属性 + Status *string `gorm:"column:status;type:varchar(255);comment:状态 0正常 1 封禁" json:"status"` // 状态 0正常 1 封禁 + ExtJSON *string `gorm:"column:ext_json;type:varchar(255);comment:额外字段" json:"ext_json"` // 额外字段 + CreatedBy *string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"` // 创建人 + CreatedTime *time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"` // 创建时间 + UpdateBy *string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"` // 更新人 + UpdateTime *time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"` // 更新时间 + Deleted *int64 `gorm:"column:deleted;type:int(11);comment:是否删除" json:"deleted"` // 是否删除 } // TableName ScaAuthUserSocial's table name diff --git a/router/modules/auth_user_router.go b/router/modules/auth_user_router.go index 0fefbf7..6ad7434 100644 --- a/router/modules/auth_user_router.go +++ b/router/modules/auth_user_router.go @@ -10,4 +10,8 @@ var authApi = api.Api.AuthApi func AuthRouter(router *gin.RouterGroup) { group := router.Group("auth") group.GET("/user/List", authApi.GetUserList) + group.GET("/user/query_by_username", authApi.QueryUserByUsername) + group.GET("/user/query_by_uuid", authApi.QueryUserByUuid) + group.DELETE("/user/delete", authApi.DeleteUser) + group.GET("/user/query_by_phone", authApi.QueryUserByPhone) } diff --git a/service/auth_service/auth_service.go b/service/auth_service/auth_service.go index b82baf4..53724c0 100644 --- a/service/auth_service/auth_service.go +++ b/service/auth_service/auth_service.go @@ -1,12 +1,60 @@ package auth_service import ( + "gorm.io/gorm" + "schisandra-cloud-album/common/enum" "schisandra-cloud-album/global" "schisandra-cloud-album/model" ) +// GetUserList 获取所有用户列表 func (AuthService) GetUserList() []*model.ScaAuthUser { data := make([]*model.ScaAuthUser, 0) - global.DB.Find(&data) + global.DB.Where("deleted = 0 ").Find(&data) return data } + +// QueryUserByName 根据用户名查询用户 +func (AuthService) QueryUserByName(username string) model.ScaAuthUser { + authUser := model.ScaAuthUser{} + global.DB.Where("username = ? and deleted = 0", username).First(&authUser) + return authUser +} + +// QueryUserByUuid 根据用户uuid查询用户 +func (AuthService) QueryUserByUuid(uuid string) model.ScaAuthUser { + authUser := model.ScaAuthUser{} + global.DB.Where("uuid = ? and deleted = 0", uuid).First(&authUser) + return authUser +} + +// AddUser 添加用户 +func (AuthService) AddUser(user model.ScaAuthUser) error { + return global.DB.Create(&user).Error +} + +// UpdateUser 更新用户 +func (AuthService) UpdateUser(user model.ScaAuthUser) *gorm.DB { + authUser := model.ScaAuthUser{} + return global.DB.Model(&authUser).Where("uuid = ?", user.UUID).Updates(user) +} + +// DeleteUser 删除用户 +func (AuthService) DeleteUser(uuid string) error { + authUser := model.ScaAuthUser{} + return global.DB.Model(&authUser).Where("uuid = ?", uuid).Updates(&model.ScaAuthUser{Deleted: &enum.DELETED}).Error +} + +// QueryUserByPhone 根据手机号查询用户 +func (AuthService) QueryUserByPhone(phone string) model.ScaAuthUser { + authUser := model.ScaAuthUser{} + global.DB.Where("phone = ? and deleted = 0", phone).First(&authUser) + return authUser +} + +// QueryUserByEmail 根据邮箱查询用户 +func (AuthService) QueryUserByEmail(email string) model.ScaAuthUser { + authUser := model.ScaAuthUser{} + global.DB.Where("email = ? and deleted = 0", email).First(&authUser) + return authUser +} diff --git a/service/auth_service/enter.go b/service/auth_service/index.go similarity index 100% rename from service/auth_service/enter.go rename to service/auth_service/index.go