mirror of
https://github.com/LLiuHuan/gin-template.git
synced 2025-12-24 13:37:58 +08:00
feat(master): Add login interface, add pdma, format part of the code, and change mysql connection parse Time to True - [添加登录接口,增加pdma,格式化部分代码、mysql连接parseTime改为True]
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -28,6 +28,7 @@ tmp/*
|
||||
# Project runtime log
|
||||
logs/*.log
|
||||
|
||||
docs
|
||||
docs/docs.go
|
||||
docs/swagger.*
|
||||
|
||||
INSTALL.lock
|
||||
BIN
assets/logo.png
Normal file
BIN
assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
@@ -9,23 +9,23 @@ connmaxlifetime = 60
|
||||
host = '127.0.0.1'
|
||||
maxidleconn = 60
|
||||
maxopenconn = 1
|
||||
name = 'gin-template'
|
||||
name = 'gin_template'
|
||||
pass = 'root'
|
||||
port = 3306
|
||||
user = 'root'
|
||||
|
||||
[database.mysql.read]
|
||||
database = 'gin-template'
|
||||
database = 'gin_template'
|
||||
host = '127.0.0.1'
|
||||
name = 'gin-template'
|
||||
name = 'gin_template'
|
||||
pass = 'root'
|
||||
port = 3306
|
||||
user = 'root'
|
||||
|
||||
[database.mysql.write]
|
||||
database = 'gin-template'
|
||||
database = 'gin_template'
|
||||
host = '127.0.0.1'
|
||||
name = 'gin-template'
|
||||
name = 'gin_template'
|
||||
pass = 'root'
|
||||
port = 3306
|
||||
user = 'root'
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package configs
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:32
|
||||
// @description: 常量配置
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:32
|
||||
// @description: 常量配置
|
||||
package configs
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package configs
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:32
|
||||
// @description: 数据库配置
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:32
|
||||
// @description: 数据库配置
|
||||
package configs
|
||||
|
||||
type DataBase struct {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package configs
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:33
|
||||
// @description: 报警配置
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:33
|
||||
// @description: 报警配置
|
||||
package configs
|
||||
|
||||
type Notify struct {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package configs
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:33
|
||||
// @description: redis配置
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:33
|
||||
// @description: redis配置
|
||||
package configs
|
||||
|
||||
type Redis struct {
|
||||
|
||||
1
docs/pdma/.back_gin-template/T20240711100019.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711100019.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711100728.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711100728.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711101116.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711101116.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711102009.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711102009.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711103904.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711103904.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711104038.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711104038.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711104158.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711104158.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711104907.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711104907.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711104934.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711104934.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711110817.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711110817.pdma.json
Normal file
File diff suppressed because one or more lines are too long
1
docs/pdma/.back_gin-template/T20240711110819.pdma.json
Normal file
1
docs/pdma/.back_gin-template/T20240711110819.pdma.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
docs/pdma/.version_gin-template/v1.0.0.json
Normal file
1
docs/pdma/.version_gin-template/v1.0.0.json
Normal file
File diff suppressed because one or more lines are too long
4324
docs/pdma/gin-template.pdma.json
Normal file
4324
docs/pdma/gin-template.pdma.json
Normal file
File diff suppressed because one or more lines are too long
16
go.mod
16
go.mod
@@ -11,21 +11,24 @@ require (
|
||||
github.com/go-playground/locales v0.14.1
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/redis/go-redis/v9 v9.5.3
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/rs/cors/wrapper/gin v0.0.0-20240515105523-1562b1715b35
|
||||
github.com/shirou/gopsutil/v4 v4.24.6
|
||||
github.com/spf13/cast v1.6.0
|
||||
github.com/spf13/viper v1.19.0
|
||||
github.com/sqids/sqids-go v0.4.1
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.3
|
||||
go.uber.org/multierr v1.10.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/text v0.16.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.org/x/tools v0.22.0
|
||||
golang.org/x/tools v0.23.0
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gorm.io/driver/mysql v1.5.7
|
||||
@@ -55,7 +58,6 @@ require (
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
|
||||
github.com/golang-sql/sqlexp v0.1.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
@@ -83,25 +85,23 @@ require (
|
||||
github.com/rs/cors v1.11.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.24.6 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/swaggo/swag v1.16.3 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/net v0.26.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
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
||||
24
go.sum
24
go.sum
@@ -199,6 +199,8 @@ github.com/shirou/gopsutil/v4 v4.24.6 h1:9qqCSYF2pgOU+t+NgJtp7Co5+5mHF/HyKBUckyS
|
||||
github.com/shirou/gopsutil/v4 v4.24.6/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
@@ -260,16 +262,14 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
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/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||
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.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -281,8 +281,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
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=
|
||||
@@ -303,8 +303,8 @@ 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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.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=
|
||||
@@ -326,8 +326,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
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.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package alert
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:40
|
||||
// @description: 告警通知
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:40
|
||||
// @description: 告警通知
|
||||
package alert
|
||||
|
||||
import (
|
||||
|
||||
26
internal/api/admin/func_create.go
Executable file
26
internal/api/admin/func_create.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type createRequest struct{}
|
||||
|
||||
type createResponse struct{}
|
||||
|
||||
// Create 新增管理员
|
||||
//
|
||||
// @Summary 新增管理员
|
||||
// @Description 新增管理员
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body createRequest true "请求信息"
|
||||
// @Success 200 {object} createResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin [post]
|
||||
func (h *handler) Create() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_createadminmenu.go
Executable file
26
internal/api/admin/func_createadminmenu.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type createAdminMenuRequest struct{}
|
||||
|
||||
type createAdminMenuResponse struct{}
|
||||
|
||||
// CreateAdminMenu 提交菜单授权
|
||||
//
|
||||
// @Summary 提交菜单授权
|
||||
// @Description 提交菜单授权
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body createAdminMenuRequest true "请求信息"
|
||||
// @Success 200 {object} createAdminMenuResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/menu [post]
|
||||
func (h *handler) CreateAdminMenu() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_delete.go
Executable file
26
internal/api/admin/func_delete.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type deleteRequest struct{}
|
||||
|
||||
type deleteResponse struct{}
|
||||
|
||||
// Delete 删除管理员
|
||||
//
|
||||
// @Summary 删除管理员
|
||||
// @Description 删除管理员
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body deleteRequest true "请求信息"
|
||||
// @Success 200 {object} deleteResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/{id} [delete]
|
||||
func (h *handler) Delete() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_detail.go
Executable file
26
internal/api/admin/func_detail.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type detailRequest struct{}
|
||||
|
||||
type detailResponse struct{}
|
||||
|
||||
// Detail 个人信息
|
||||
//
|
||||
// @Summary 个人信息
|
||||
// @Description 个人信息
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body detailRequest true "请求信息"
|
||||
// @Success 200 {object} detailResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/info [get]
|
||||
func (h *handler) Detail() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_list.go
Executable file
26
internal/api/admin/func_list.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type listRequest struct{}
|
||||
|
||||
type listResponse struct{}
|
||||
|
||||
// List 管理员列表
|
||||
//
|
||||
// @Summary 管理员列表
|
||||
// @Description 管理员列表
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body listRequest true "请求信息"
|
||||
// @Success 200 {object} listResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin [get]
|
||||
func (h *handler) List() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_listadminmenu.go
Executable file
26
internal/api/admin/func_listadminmenu.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type listAdminMenuRequest struct{}
|
||||
|
||||
type listAdminMenuResponse struct{}
|
||||
|
||||
// ListAdminMenu 菜单授权列表
|
||||
//
|
||||
// @Summary 菜单授权列表
|
||||
// @Description 菜单授权列表
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body listAdminMenuRequest true "请求信息"
|
||||
// @Success 200 {object} listAdminMenuResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/menu/{id} [get]
|
||||
func (h *handler) ListAdminMenu() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
154
internal/api/admin/func_login.go
Executable file
154
internal/api/admin/func_login.go
Executable file
@@ -0,0 +1,154 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/LLiuHuan/gin-template/configs"
|
||||
"github.com/LLiuHuan/gin-template/internal/code"
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/password"
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/validation"
|
||||
"github.com/LLiuHuan/gin-template/internal/proposal"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/redis"
|
||||
"github.com/LLiuHuan/gin-template/internal/services/admin"
|
||||
"github.com/LLiuHuan/gin-template/pkg/errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type loginRequest struct {
|
||||
Username string `form:"username" json:"username" binding:"required"` // 用户名
|
||||
Password string `form:"password" json:"password" binding:"min=4,max=16,required"` // 密码
|
||||
}
|
||||
|
||||
type loginResponse struct {
|
||||
Token string `json:"token"` // 用户身份标识
|
||||
RefreshToken string `json:"refreshToken"` // 刷新token
|
||||
}
|
||||
|
||||
// Login 管理员登录
|
||||
//
|
||||
// @Summary 管理员登录
|
||||
// @Description 管理员登录
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body loginRequest true "请求信息"
|
||||
// @Success 200 {object} loginResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/login [post]
|
||||
//
|
||||
// @Security LoginToken
|
||||
func (h *handler) Login() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(loginRequest)
|
||||
res := new(loginResponse)
|
||||
if err := ctx.ShouldBindJSON(req); err != nil {
|
||||
fmt.Println(err)
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.ParamBindError,
|
||||
code.Text(code.ParamBindError)).
|
||||
WithError(validation.ErrorE(err)),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
searchOneData := new(admin.SearchOneData)
|
||||
searchOneData.Username = req.Username
|
||||
searchOneData.Password = password.GeneratePassword(req.Password)
|
||||
searchOneData.IsUsed = 1
|
||||
|
||||
info, err := h.adminService.Detail(ctx, searchOneData)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.AdminLoginError,
|
||||
code.Text(code.AdminLoginError)).WithError(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if info == nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.AdminLoginError,
|
||||
code.Text(code.AdminLoginError)).WithError(errors.New("未查询出符合条件的用户")),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
token := password.GenerateLoginToken(info.Id)
|
||||
|
||||
// 用户信息
|
||||
sessionUserInfo := &proposal.SessionUserInfo{
|
||||
UserID: info.Id,
|
||||
UserName: info.Username,
|
||||
}
|
||||
|
||||
// 将用户信息记录到 Redis 中
|
||||
err = h.cache.Set(configs.RedisKeyPrefixLoginUser+token, string(sessionUserInfo.Marshal()), configs.LoginSessionTTL, redis.WithTrace(ctx.Trace()))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.AdminLoginError,
|
||||
code.Text(code.AdminLoginError)).WithError(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
searchMenuData := new(admin.SearchMyMenuData)
|
||||
searchMenuData.AdminId = info.Id
|
||||
menu, err := h.adminService.MyMenu(ctx, searchMenuData)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.AdminLoginError,
|
||||
code.Text(code.AdminLoginError)).WithError(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// 菜单栏信息
|
||||
menuJsonInfo, _ := json.Marshal(menu)
|
||||
|
||||
// 将菜单栏信息记录到 Redis 中
|
||||
err = h.cache.Set(configs.RedisKeyPrefixLoginUser+token+":menu", string(menuJsonInfo), configs.LoginSessionTTL, redis.WithTrace(ctx.Trace()))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.AdminLoginError,
|
||||
code.Text(code.AdminLoginError)).WithError(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
searchActionData := new(admin.SearchMyActionData)
|
||||
searchActionData.AdminId = info.Id
|
||||
action, err := h.adminService.MyAction(ctx, searchActionData)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.AdminLoginError,
|
||||
code.Text(code.AdminLoginError)).WithError(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// 可访问接口信息
|
||||
actionJsonInfo, _ := json.Marshal(action)
|
||||
|
||||
// 将可访问接口信息记录到 Redis 中
|
||||
err = h.cache.Set(configs.RedisKeyPrefixLoginUser+token+":action", string(actionJsonInfo), configs.LoginSessionTTL, redis.WithTrace(ctx.Trace()))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(core.Error(
|
||||
http.StatusBadRequest,
|
||||
code.AdminLoginError,
|
||||
code.Text(code.AdminLoginError)).WithError(err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
res.Token = token
|
||||
ctx.Payload(res)
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_logout.go
Executable file
26
internal/api/admin/func_logout.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type logoutRequest struct{}
|
||||
|
||||
type logoutResponse struct{}
|
||||
|
||||
// Logout 管理员登出
|
||||
//
|
||||
// @Summary 管理员登出
|
||||
// @Description 管理员登出
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body logoutRequest true "请求信息"
|
||||
// @Success 200 {object} logoutResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/logout [post]
|
||||
func (h *handler) Logout() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_modifypassword.go
Executable file
26
internal/api/admin/func_modifypassword.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type modifyPasswordRequest struct{}
|
||||
|
||||
type modifyPasswordResponse struct{}
|
||||
|
||||
// ModifyPassword 修改密码
|
||||
//
|
||||
// @Summary 修改密码
|
||||
// @Description 修改密码
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body modifyPasswordRequest true "请求信息"
|
||||
// @Success 200 {object} modifyPasswordResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/modify_password [patch]
|
||||
func (h *handler) ModifyPassword() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_modifypersonalinfo.go
Executable file
26
internal/api/admin/func_modifypersonalinfo.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type modifyPersonalInfoRequest struct{}
|
||||
|
||||
type modifyPersonalInfoResponse struct{}
|
||||
|
||||
// ModifyPersonalInfo 修改个人信息
|
||||
//
|
||||
// @Summary 修改个人信息
|
||||
// @Description 修改个人信息
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body modifyPersonalInfoRequest true "请求信息"
|
||||
// @Success 200 {object} modifyPersonalInfoResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/modify_personal_info [patch]
|
||||
func (h *handler) ModifyPersonalInfo() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_offline.go
Executable file
26
internal/api/admin/func_offline.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type offlineRequest struct{}
|
||||
|
||||
type offlineResponse struct{}
|
||||
|
||||
// Offline 下线管理员
|
||||
//
|
||||
// @Summary 下线管理员
|
||||
// @Description 下线管理员
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body offlineRequest true "请求信息"
|
||||
// @Success 200 {object} offlineResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/offline [patch]
|
||||
func (h *handler) Offline() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_resetpassword.go
Executable file
26
internal/api/admin/func_resetpassword.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type resetPasswordRequest struct{}
|
||||
|
||||
type resetPasswordResponse struct{}
|
||||
|
||||
// ResetPassword 重置密码
|
||||
//
|
||||
// @Summary 重置密码
|
||||
// @Description 重置密码
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body resetPasswordRequest true "请求信息"
|
||||
// @Success 200 {object} resetPasswordResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/reset_password/{id} [patch]
|
||||
func (h *handler) ResetPassword() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/admin/func_updateused.go
Executable file
26
internal/api/admin/func_updateused.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type updateUsedRequest struct{}
|
||||
|
||||
type updateUsedResponse struct{}
|
||||
|
||||
// UpdateUsed 更新管理员为启用/禁用
|
||||
//
|
||||
// @Summary 更新管理员为启用/禁用
|
||||
// @Description 更新管理员为启用/禁用
|
||||
// @Tags API.admin
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body updateUsedRequest true "请求信息"
|
||||
// @Success 200 {object} updateUsedResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/admin/used [patch]
|
||||
func (h *handler) UpdateUsed() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
105
internal/api/admin/handler.go
Normal file
105
internal/api/admin/handler.go
Normal file
@@ -0,0 +1,105 @@
|
||||
// Package admin
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-09 09:47
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/configs"
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/redis"
|
||||
"github.com/LLiuHuan/gin-template/internal/services/admin"
|
||||
"github.com/LLiuHuan/gin-template/pkg/hash"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var _ Handler = (*handler)(nil)
|
||||
|
||||
type Handler interface {
|
||||
i()
|
||||
|
||||
// Login 管理员登录
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/login [post]
|
||||
Login() core.HandlerFunc
|
||||
|
||||
// Logout 管理员登出
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/logout [post]
|
||||
Logout() core.HandlerFunc
|
||||
|
||||
// ModifyPassword 修改密码
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/modify_password [patch]
|
||||
ModifyPassword() core.HandlerFunc
|
||||
|
||||
// Detail 个人信息
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/info [get]
|
||||
Detail() core.HandlerFunc
|
||||
|
||||
// ModifyPersonalInfo 修改个人信息
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/modify_personal_info [patch]
|
||||
ModifyPersonalInfo() core.HandlerFunc
|
||||
|
||||
// Create 新增管理员
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin [post]
|
||||
Create() core.HandlerFunc
|
||||
|
||||
// List 管理员列表
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin [get]
|
||||
List() core.HandlerFunc
|
||||
|
||||
// Delete 删除管理员
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/{id} [delete]
|
||||
Delete() core.HandlerFunc
|
||||
|
||||
// Offline 下线管理员
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/offline [patch]
|
||||
Offline() core.HandlerFunc
|
||||
|
||||
// UpdateUsed 更新管理员为启用/禁用
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/used [patch]
|
||||
UpdateUsed() core.HandlerFunc
|
||||
|
||||
// ResetPassword 重置密码
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/reset_password/{id} [patch]
|
||||
ResetPassword() core.HandlerFunc
|
||||
|
||||
// CreateAdminMenu 提交菜单授权
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/menu [post]
|
||||
CreateAdminMenu() core.HandlerFunc
|
||||
|
||||
// ListAdminMenu 菜单授权列表
|
||||
// @Tags API.admin
|
||||
// @Router /api/v1/admin/menu/{id} [get]
|
||||
ListAdminMenu() core.HandlerFunc
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
logger *zap.Logger
|
||||
cache redis.Repo
|
||||
hashids hash.Hash
|
||||
adminService admin.Service
|
||||
}
|
||||
|
||||
func New(logger *zap.Logger, db database.Repo, cache redis.Repo) Handler {
|
||||
return &handler{
|
||||
logger: logger,
|
||||
cache: cache,
|
||||
hashids: hash.New(configs.Get().HashIds.Alphabet, configs.Get().HashIds.MinLength, configs.Get().HashIds.BlockList),
|
||||
adminService: admin.New(db, cache),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) i() {}
|
||||
@@ -31,15 +31,16 @@ type createResponse struct {
|
||||
}
|
||||
|
||||
// Create 创建任务
|
||||
// @Summary 创建任务
|
||||
// @Description 创建任务
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body createRequest true "请求信息"
|
||||
// @Success 200 {object} createResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron [post]
|
||||
//
|
||||
// @Summary 创建任务
|
||||
// @Description 创建任务
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body createRequest true "请求信息"
|
||||
// @Success 200 {object} createResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron [post]
|
||||
func (h *handler) Create() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(createRequest)
|
||||
|
||||
@@ -33,15 +33,16 @@ type detailResponse struct {
|
||||
}
|
||||
|
||||
// Detail 获取单条任务详情
|
||||
// @Summary 获取单条任务详情
|
||||
// @Description 获取单条任务详情
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body detailRequest true "请求信息"
|
||||
// @Success 200 {object} detailResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/{id} [get]
|
||||
//
|
||||
// @Summary 获取单条任务详情
|
||||
// @Description 获取单条任务详情
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body detailRequest true "请求信息"
|
||||
// @Success 200 {object} detailResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/{id} [get]
|
||||
func (h *handler) Detail() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(detailRequest)
|
||||
|
||||
@@ -19,15 +19,16 @@ type executeResponse struct {
|
||||
}
|
||||
|
||||
// Execute 手动执行任务
|
||||
// @Summary 手动执行任务
|
||||
// @Description 手动执行任务
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body executeRequest true "请求信息"
|
||||
// @Success 200 {object} executeResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/exec/{id} [patch]
|
||||
//
|
||||
// @Summary 手动执行任务
|
||||
// @Description 手动执行任务
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body executeRequest true "请求信息"
|
||||
// @Success 200 {object} executeResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/exec/{id} [patch]
|
||||
func (h *handler) Execute() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(executeRequest)
|
||||
|
||||
@@ -54,15 +54,16 @@ type listResponse struct {
|
||||
}
|
||||
|
||||
// List 任务列表
|
||||
// @Summary 任务列表
|
||||
// @Description 任务列表
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body listRequest true "请求信息"
|
||||
// @Success 200 {object} listResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron [get]
|
||||
//
|
||||
// @Summary 任务列表
|
||||
// @Description 任务列表
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body listRequest true "请求信息"
|
||||
// @Success 200 {object} listResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron [get]
|
||||
func (h *handler) List() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(listRequest)
|
||||
|
||||
@@ -28,19 +28,20 @@ type modifyRequest struct {
|
||||
}
|
||||
|
||||
type modifyResponse struct {
|
||||
Id int32 `json:"id"` // 主键ID
|
||||
Id int `json:"id"` // 主键ID
|
||||
}
|
||||
|
||||
// Modify 编辑任务
|
||||
// @Summary 编辑任务
|
||||
// @Description 编辑任务
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body modifyRequest true "请求信息"
|
||||
// @Success 200 {object} modifyResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/{id} [post]
|
||||
//
|
||||
// @Summary 编辑任务
|
||||
// @Description 编辑任务
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body modifyRequest true "请求信息"
|
||||
// @Success 200 {object} modifyResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/{id} [post]
|
||||
func (h *handler) Modify() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(modifyRequest)
|
||||
@@ -64,7 +65,7 @@ func (h *handler) Modify() core.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
id := int32(ids[0])
|
||||
id := int(ids[0])
|
||||
|
||||
modifyData := new(cron.ModifyCronTaskData)
|
||||
modifyData.Name = req.Name
|
||||
|
||||
@@ -18,15 +18,16 @@ type updateUsedResponse struct {
|
||||
}
|
||||
|
||||
// UpdateUsed 更新任务为启用/禁用
|
||||
// @Summary 更新任务为启用/禁用
|
||||
// @Description 更新任务为启用/禁用
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body updateUsedRequest true "请求信息"
|
||||
// @Success 200 {object} updateUsedResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/used [patch]
|
||||
//
|
||||
// @Summary 更新任务为启用/禁用
|
||||
// @Description 更新任务为启用/禁用
|
||||
// @Tags API.cron
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body updateUsedRequest true "请求信息"
|
||||
// @Success 200 {object} updateUsedResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/cron/used [patch]
|
||||
func (h *handler) UpdateUsed() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(updateUsedRequest)
|
||||
|
||||
@@ -20,15 +20,16 @@ type md5Response struct {
|
||||
}
|
||||
|
||||
// Md5 加密
|
||||
// @Summary 加密
|
||||
// @Description 加密
|
||||
// @Tags Helper
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body md5Request true "请求信息"
|
||||
// @Success 200 {object} md5Response
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /helper/md5/{str} [get]
|
||||
//
|
||||
// @Summary 加密
|
||||
// @Description 加密
|
||||
// @Tags Helper
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body md5Request true "请求信息"
|
||||
// @Success 200 {object} md5Response
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /helper/md5/{str} [get]
|
||||
func (h *handler) Md5() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(md5Request)
|
||||
|
||||
@@ -25,15 +25,16 @@ type signResponse struct {
|
||||
}
|
||||
|
||||
// Sign 签名
|
||||
// @Summary 签名
|
||||
// @Description 签名
|
||||
// @Tags Helper
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body signRequest true "请求信息"
|
||||
// @Success 200 {object} signResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /helper/sign [post]
|
||||
//
|
||||
// @Summary 签名
|
||||
// @Description 签名
|
||||
// @Tags Helper
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body signRequest true "请求信息"
|
||||
// @Success 200 {object} signResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /helper/sign [post]
|
||||
func (h *handler) Sign() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
req := new(signRequest)
|
||||
|
||||
26
internal/api/tool/func_clearcache.go
Executable file
26
internal/api/tool/func_clearcache.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type clearCacheRequest struct{}
|
||||
|
||||
type clearCacheResponse struct{}
|
||||
|
||||
// ClearCache 清空缓存
|
||||
//
|
||||
// @Summary 清空缓存
|
||||
// @Description 清空缓存
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body clearCacheRequest true "请求信息"
|
||||
// @Success 200 {object} clearCacheResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/cache/clear [patch]
|
||||
func (h *handler) ClearCache() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/tool/func_dbs.go
Executable file
26
internal/api/tool/func_dbs.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type dbsRequest struct{}
|
||||
|
||||
type dbsResponse struct{}
|
||||
|
||||
// Dbs 查询 DB
|
||||
//
|
||||
// @Summary 查询 DB
|
||||
// @Description 查询 DB
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body dbsRequest true "请求信息"
|
||||
// @Success 200 {object} dbsResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/data/dbs [get]
|
||||
func (h *handler) Dbs() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/tool/func_hashidsdecode.go
Executable file
26
internal/api/tool/func_hashidsdecode.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type hashIdsDecodeRequest struct{}
|
||||
|
||||
type hashIdsDecodeResponse struct{}
|
||||
|
||||
// HashIdsDecode HashIds 解密
|
||||
//
|
||||
// @Summary HashIds 解密
|
||||
// @Description HashIds 解密
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body hashIdsDecodeRequest true "请求信息"
|
||||
// @Success 200 {object} hashIdsDecodeResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/hashids/decode/{id} [get]
|
||||
func (h *handler) HashIdsDecode() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/tool/func_hashidsencode.go
Executable file
26
internal/api/tool/func_hashidsencode.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type hashIdsEncodeRequest struct{}
|
||||
|
||||
type hashIdsEncodeResponse struct{}
|
||||
|
||||
// HashIdsEncode HashIds 加密
|
||||
//
|
||||
// @Summary HashIds 加密
|
||||
// @Description HashIds 加密
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body hashIdsEncodeRequest true "请求信息"
|
||||
// @Success 200 {object} hashIdsEncodeResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/hashids/encode/{id} [get]
|
||||
func (h *handler) HashIdsEncode() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
123
internal/api/tool/func_projectinfo.go
Executable file
123
internal/api/tool/func_projectinfo.go
Executable file
@@ -0,0 +1,123 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/LLiuHuan/gin-template/configs"
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
"github.com/LLiuHuan/gin-template/pkg/currency"
|
||||
"github.com/LLiuHuan/gin-template/pkg/env"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/cpu"
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"github.com/shirou/gopsutil/v4/host"
|
||||
"github.com/shirou/gopsutil/v4/mem"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
type projectInfoRequest struct{}
|
||||
|
||||
type projectInfoResponse struct {
|
||||
MemTotal string // 内存总量
|
||||
MemUsed string // 内存使用量
|
||||
MemUsedPercent float64 // 内存使用率
|
||||
|
||||
DiskTotal string // 磁盘总量
|
||||
DiskUsed string // 磁盘使用量
|
||||
DiskUsedPercent float64 // 磁盘使用率
|
||||
|
||||
HostOS string // 操作系统
|
||||
HostName string // 主机名
|
||||
|
||||
CpuName string // CPU 名称
|
||||
CpuCores int32 // CPU 核数
|
||||
CpuUsedPercent float64 // CPU 使用率
|
||||
|
||||
GoPath string // GoPath
|
||||
GoVersion string // Go 版本
|
||||
Goroutine int // Goroutine 数量
|
||||
ProjectPath string // 项目路径
|
||||
Env string // 运行环境
|
||||
Host string // 主机地址
|
||||
GoOS string // GoOS
|
||||
GoArch string // GoArch
|
||||
|
||||
ProjectVersion string // 项目版本
|
||||
DatabaseVersion string // 数据库版本
|
||||
RedisVersion string // Redis 版本
|
||||
}
|
||||
|
||||
// ProjectInfo 项目基础信息
|
||||
//
|
||||
// @Summary 项目基础信息
|
||||
// @Description 项目基础信息
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body projectInfoRequest true "请求信息"
|
||||
// @Success 200 {object} projectInfoResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/project/info [get]
|
||||
func (h *handler) ProjectInfo() core.HandlerFunc {
|
||||
type mysqlVersion struct {
|
||||
Ver string
|
||||
}
|
||||
|
||||
databaseVer := new(mysqlVersion)
|
||||
if h.db != nil {
|
||||
h.db.GetDB().Raw("SELECT version() as ver").Scan(databaseVer)
|
||||
}
|
||||
|
||||
redisVer := ""
|
||||
if h.cache != nil {
|
||||
redisVer = h.cache.Version()
|
||||
}
|
||||
return func(ctx core.Context) {
|
||||
memInfo, _ := mem.VirtualMemory()
|
||||
diskInfo, _ := disk.Usage("/")
|
||||
hostInfo, _ := host.Info()
|
||||
cpuInfo, _ := cpu.Info()
|
||||
cpuPercent, _ := cpu.Percent(time.Microsecond, false)
|
||||
|
||||
obj := new(projectInfoResponse)
|
||||
obj.MemTotal = currency.FormatFileSize(cast.ToInt64(memInfo.Total))
|
||||
obj.MemUsed = currency.FormatFileSize(cast.ToInt64(memInfo.Used))
|
||||
obj.MemUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", memInfo.UsedPercent), 64)
|
||||
|
||||
obj.DiskTotal = currency.FormatFileSize(cast.ToInt64(diskInfo.Total))
|
||||
obj.DiskUsed = currency.FormatFileSize(cast.ToInt64(diskInfo.Used))
|
||||
obj.DiskUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", diskInfo.UsedPercent), 64)
|
||||
|
||||
obj.HostOS = fmt.Sprintf("%s(%s) %s", hostInfo.Platform, hostInfo.PlatformFamily, hostInfo.PlatformVersion)
|
||||
obj.HostName = hostInfo.Hostname
|
||||
|
||||
if len(cpuInfo) > 0 {
|
||||
obj.CpuName = cpuInfo[0].ModelName
|
||||
obj.CpuCores = cpuInfo[0].Cores
|
||||
}
|
||||
|
||||
if len(cpuPercent) > 0 {
|
||||
obj.CpuUsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", cpuPercent[0]), 64)
|
||||
}
|
||||
|
||||
obj.GoPath = runtime.GOROOT()
|
||||
obj.GoVersion = runtime.Version()
|
||||
obj.Goroutine = runtime.NumGoroutine()
|
||||
dir, _ := os.Getwd()
|
||||
obj.ProjectPath = strings.Replace(dir, "\\", "/", -1)
|
||||
obj.Host = ctx.Host()
|
||||
obj.Env = env.Active().Value()
|
||||
obj.GoOS = runtime.GOOS
|
||||
obj.GoArch = runtime.GOARCH
|
||||
obj.ProjectVersion = configs.ProjectVersion
|
||||
obj.DatabaseVersion = databaseVer.Ver
|
||||
obj.RedisVersion = redisVer
|
||||
|
||||
ctx.Payload(obj)
|
||||
}
|
||||
}
|
||||
26
internal/api/tool/func_searchcache.go
Executable file
26
internal/api/tool/func_searchcache.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type searchCacheRequest struct{}
|
||||
|
||||
type searchCacheResponse struct{}
|
||||
|
||||
// SearchCache 查询缓存
|
||||
//
|
||||
// @Summary 查询缓存
|
||||
// @Description 查询缓存
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body searchCacheRequest true "请求信息"
|
||||
// @Success 200 {object} searchCacheResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/cache/search [post]
|
||||
func (h *handler) SearchCache() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/tool/func_searchmysql.go
Executable file
26
internal/api/tool/func_searchmysql.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type searchMySQLRequest struct{}
|
||||
|
||||
type searchMySQLResponse struct{}
|
||||
|
||||
// SearchMySQL 执行 SQL 语句
|
||||
//
|
||||
// @Summary 执行 SQL 语句
|
||||
// @Description 执行 SQL 语句
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body searchMySQLRequest true "请求信息"
|
||||
// @Success 200 {object} searchMySQLResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/data/mysql [post]
|
||||
func (h *handler) SearchMySQL() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
26
internal/api/tool/func_tables.go
Executable file
26
internal/api/tool/func_tables.go
Executable file
@@ -0,0 +1,26 @@
|
||||
package tool
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
)
|
||||
|
||||
type tablesRequest struct{}
|
||||
|
||||
type tablesResponse struct{}
|
||||
|
||||
// Tables 查询 Table
|
||||
//
|
||||
// @Summary 查询 Table
|
||||
// @Description 查询 Table
|
||||
// @Tags API.tool
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body tablesRequest true "请求信息"
|
||||
// @Success 200 {object} tablesResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /api/v1/tool/data/tables [post]
|
||||
func (h *handler) Tables() core.HandlerFunc {
|
||||
return func(ctx core.Context) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package code
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:43
|
||||
// @description: 英文错误码
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:43
|
||||
// @description: 英文错误码
|
||||
package code
|
||||
|
||||
var enUSText = map[int]string{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package code
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:43
|
||||
// @description: 中文错误码
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:43
|
||||
// @description: 中文错误码
|
||||
package code
|
||||
|
||||
var zhCNText = map[int]string{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package metrics
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:45
|
||||
// @description: 指标
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 22:45
|
||||
// @description: 指标
|
||||
package metrics
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package core
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 17:28
|
||||
// @description: 跨域请求处理
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 17:28
|
||||
// @description: 跨域请求处理
|
||||
package core
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package core
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 17:31
|
||||
// @description: 恢复panic
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 17:31
|
||||
// @description: 恢复panic
|
||||
package core
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package core
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 17:34
|
||||
// @description: 链路追踪
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 17:34
|
||||
// @description: 链路追踪
|
||||
package core
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package core
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 14:36
|
||||
// @description: 多路复用器
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 14:36
|
||||
// @description: 多路复用器
|
||||
package core
|
||||
|
||||
import (
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/LLiuHuan/gin-template/pkg/env"
|
||||
"github.com/LLiuHuan/gin-template/pkg/errors"
|
||||
|
||||
_ "github.com/LLiuHuan/gin-template/docs"
|
||||
"github.com/gin-contrib/pprof"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
@@ -27,7 +27,6 @@ func GeneratePassword(str string) (password string) {
|
||||
h := hmac.New(sha256.New, []byte(saltPassword))
|
||||
h.Write(mByte)
|
||||
password = hex.EncodeToString(h.Sum(nil))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -41,7 +40,7 @@ func ResetPassword() (password string) {
|
||||
return
|
||||
}
|
||||
|
||||
func GenerateLoginToken(id int32) (token string) {
|
||||
func GenerateLoginToken(id int) (token string) {
|
||||
m := md5.New()
|
||||
m.Write([]byte(fmt.Sprintf("%d%s", id, saltPassword)))
|
||||
token = hex.EncodeToString(m.Sum(nil))
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/LLiuHuan/gin-template/configs"
|
||||
@@ -22,7 +23,6 @@ var trans ut.Translator
|
||||
|
||||
func init() {
|
||||
lang := configs.Get().Project.Local
|
||||
fmt.Println(lang, lang == configs.ZhCN)
|
||||
if lang == configs.ZhCN {
|
||||
trans, _ = ut.New(zh.New()).GetTranslator("zh")
|
||||
if err := zhTranslation.RegisterDefaultTranslations(binding.Validator.Engine().(*validator.Validate), trans); err != nil {
|
||||
@@ -38,13 +38,22 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func Error(err error) (message string) {
|
||||
if validationErrors, ok := err.(validator.ValidationErrors); !ok {
|
||||
func validationError(err error) string {
|
||||
var message string
|
||||
var validationErrors validator.ValidationErrors
|
||||
if !errors.As(err, &validationErrors) {
|
||||
return err.Error()
|
||||
} else {
|
||||
for _, e := range validationErrors {
|
||||
message += e.Translate(trans) + ";"
|
||||
}
|
||||
}
|
||||
for _, e := range validationErrors {
|
||||
message += e.Translate(trans) + ";"
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
func ErrorE(err error) error {
|
||||
return errors.New(validationError(err))
|
||||
}
|
||||
|
||||
func Error(err error) (message string) {
|
||||
return validationError(err)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package proposal
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:40
|
||||
// @description: 告警信息
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:40
|
||||
// @description: 告警信息
|
||||
package proposal
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package proposal
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:41
|
||||
// @description: 指标信息
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:41
|
||||
// @description: 指标信息
|
||||
package proposal
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package proposal
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:41
|
||||
// @description: 用户会话信息
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:41
|
||||
// @description: 用户会话信息
|
||||
package proposal
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
@@ -6,6 +6,7 @@ package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gorm.io/gorm/schema"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -110,6 +111,9 @@ func getDBDriver(mode string, isOpenReadDB int) (*gorm.DB, error) {
|
||||
gormDB, err := gorm.Open(dialector, &gorm.Config{
|
||||
SkipDefaultTransaction: true,
|
||||
PrepareStmt: true,
|
||||
NamingStrategy: schema.NamingStrategy{
|
||||
SingularTable: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -183,7 +187,7 @@ func getDsn(sqlType string, readWrite string) string {
|
||||
if Charset == "" {
|
||||
Charset = "utf8mb4"
|
||||
}
|
||||
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=false&loc=Local", User, Pass, Host, Port, DataBase, Charset)
|
||||
return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local", User, Pass, Host, Port, DataBase, Charset)
|
||||
case "sqlserver", "mssql":
|
||||
return fmt.Sprintf("server=%s;port=%d;database=%s;user id=%s;password=%s;encrypt=disable", Host, Port, DataBase, User, Pass)
|
||||
case "postgresql", "postgre", "postgres":
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Package database
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 10:19
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 10:19
|
||||
package database
|
||||
|
||||
import (
|
||||
@@ -231,8 +232,9 @@ func structHasSpecialField(fieldName string, anyStructPtr interface{}) (bool, st
|
||||
}
|
||||
|
||||
// getColumnNameFromGormTag 从 gorm 标签中获取字段名
|
||||
// @defaultColumn 如果没有 gorm:column 标签为字段重命名,则使用默认字段名
|
||||
// @TagValue 字段中含有的gorm:"column:created_at" 标签值,可能的格式:1. column:created_at 、2. default:null; column:created_at 、3. column:created_at; default:null
|
||||
//
|
||||
// @defaultColumn 如果没有 gorm:column 标签为字段重命名,则使用默认字段名
|
||||
// @TagValue 字段中含有的gorm:"column:created_at" 标签值,可能的格式:1. column:created_at 、2. default:null; column:created_at 、3. column:created_at; default:null
|
||||
func getColumnNameFromGormTag(defaultColumn, TagValue string) (str string) {
|
||||
pos1 := strings.Index(TagValue, "column:")
|
||||
if pos1 == -1 {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package interceptor
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 15:00
|
||||
// @description: 登录拦截器
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 15:00
|
||||
// @description: 登录拦截器
|
||||
package interceptor
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package interceptor
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 15:00
|
||||
// @description: 校验用户权限
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 15:00
|
||||
// @description: 校验用户权限
|
||||
package interceptor
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package interceptor
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 15:00
|
||||
// @description: 校验签名
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 15:00
|
||||
// @description: 校验签名
|
||||
package interceptor
|
||||
|
||||
import (
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/api/admin"
|
||||
"github.com/LLiuHuan/gin-template/internal/api/helper"
|
||||
"github.com/LLiuHuan/gin-template/internal/api/tool"
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
@@ -14,6 +15,7 @@ func setApiV1Router(r *resource) {
|
||||
// helper
|
||||
helperHandler := helper.New(r.logger, r.db, r.cache)
|
||||
toolHandler := tool.New(r.logger, r.db, r.cache)
|
||||
adminHandler := admin.New(r.logger, r.db, r.cache)
|
||||
|
||||
apiRouter := r.mux.Group("/api/v1")
|
||||
{
|
||||
@@ -41,16 +43,12 @@ func setApiV1Router(r *resource) {
|
||||
// }
|
||||
//}
|
||||
}
|
||||
// 需要签名验证,无需登录验证,无需 RBAC 权限验证
|
||||
login := r.mux.Group("/api/v1", r.interceptors.CheckSignature())
|
||||
{
|
||||
login.POST("/login", adminHandler.Login())
|
||||
}
|
||||
|
||||
//// admin
|
||||
//adminHandler := admin.New(r.logger, r.db, r.cache)
|
||||
//
|
||||
//// 需要签名验证,无需登录验证,无需 RBAC 权限验证
|
||||
//login := r.mux.Group("/api", r.interceptors.CheckSignature())
|
||||
//{
|
||||
// login.POST("/login", adminHandler.Login())
|
||||
//}
|
||||
//
|
||||
//// 需要签名验证、登录验证,无需 RBAC 权限验证
|
||||
//notRBAC := r.mux.Group("/api", core.WrapAuthHandler(r.interceptors.CheckLogin), r.interceptors.CheckSignature())
|
||||
//{
|
||||
|
||||
47
internal/services/admin/service.go
Normal file
47
internal/services/admin/service.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Package admin
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-09 09:47
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database/admin"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/redis"
|
||||
)
|
||||
|
||||
var _ Service = (*service)(nil)
|
||||
|
||||
type Service interface {
|
||||
i()
|
||||
|
||||
//Create(ctx core.Context, adminData *CreateAdminData) (id int32, err error)
|
||||
//PageList(ctx core.Context, searchData *SearchData) (listData []*admin.Admin, err error)
|
||||
//PageListCount(ctx core.Context, searchData *SearchData) (total int64, err error)
|
||||
//UpdateUsed(ctx core.Context, id int32, used int32) (err error)
|
||||
//Delete(ctx core.Context, id int32) (err error)
|
||||
Detail(ctx core.Context, searchOneData *SearchOneData) (info *admin.Admin, err error)
|
||||
//ResetPassword(ctx core.Context, id int32) (err error)
|
||||
//ModifyPassword(ctx core.Context, id int32, newPassword string) (err error)
|
||||
//ModifyPersonalInfo(ctx core.Context, id int32, modifyData *ModifyData) (err error)
|
||||
|
||||
//CreateMenu(ctx core.Context, menuData *CreateMenuData) (err error)
|
||||
//ListMenu(ctx core.Context, searchData *SearchListMenuData) (menuData []ListMenuData, err error)
|
||||
MyMenu(ctx core.Context, searchData *SearchMyMenuData) (menuData []ListMyMenuData, err error)
|
||||
MyAction(ctx core.Context, searchData *SearchMyActionData) (actionData []MyActionData, err error)
|
||||
}
|
||||
|
||||
type service struct {
|
||||
db database.Repo
|
||||
cache redis.Repo
|
||||
}
|
||||
|
||||
func New(db database.Repo, cache redis.Repo) Service {
|
||||
return &service{
|
||||
db: db,
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) i() {}
|
||||
57
internal/services/admin/service_detail.go
Normal file
57
internal/services/admin/service_detail.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Package admin
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-09 10:03
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database/admin"
|
||||
)
|
||||
|
||||
type SearchOneData struct {
|
||||
Id int // 用户ID
|
||||
Username string // 用户名
|
||||
Nickname string // 昵称
|
||||
Mobile string // 手机号
|
||||
Password string // 密码
|
||||
IsUsed int32 // 是否启用 1:是 -1:否
|
||||
}
|
||||
|
||||
func (s *service) Detail(ctx core.Context, searchOneData *SearchOneData) (info *admin.Admin, err error) {
|
||||
|
||||
qb := admin.NewQueryBuilder()
|
||||
qb.WhereIsDeleted(database.EqualPredicate, -1)
|
||||
|
||||
if searchOneData.Id != 0 {
|
||||
qb.WhereId(database.EqualPredicate, searchOneData.Id)
|
||||
}
|
||||
|
||||
if searchOneData.Username != "" {
|
||||
qb.WhereUsername(database.EqualPredicate, searchOneData.Username)
|
||||
}
|
||||
|
||||
if searchOneData.Nickname != "" {
|
||||
qb.WhereNickname(database.EqualPredicate, searchOneData.Nickname)
|
||||
}
|
||||
|
||||
if searchOneData.Mobile != "" {
|
||||
qb.WhereMobile(database.EqualPredicate, searchOneData.Mobile)
|
||||
}
|
||||
|
||||
if searchOneData.Password != "" {
|
||||
qb.WherePassword(database.EqualPredicate, searchOneData.Password)
|
||||
}
|
||||
|
||||
if searchOneData.IsUsed != 0 {
|
||||
qb.WhereIsUsed(database.EqualPredicate, searchOneData.IsUsed)
|
||||
}
|
||||
|
||||
info, err = qb.QueryOne(s.db.GetDB().WithContext(ctx.RequestContext()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
73
internal/services/admin/service_myaction.go
Normal file
73
internal/services/admin/service_myaction.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Package admin
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-09 10:00
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database/admin_menu"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database/menu_action"
|
||||
)
|
||||
|
||||
type SearchMyActionData struct {
|
||||
AdminId int `json:"admin_id"` // 管理员ID
|
||||
}
|
||||
|
||||
type MyActionData struct {
|
||||
Id int // 主键
|
||||
MenuId int // 菜单栏ID
|
||||
Method string // 请求方式
|
||||
Api string // 请求地址
|
||||
}
|
||||
|
||||
func (s *service) MyAction(ctx core.Context, searchData *SearchMyActionData) (actionData []MyActionData, err error) {
|
||||
adminMenuQb := admin_menu.NewQueryBuilder()
|
||||
if searchData.AdminId != 0 {
|
||||
adminMenuQb.WhereAdminId(database.EqualPredicate, searchData.AdminId)
|
||||
}
|
||||
|
||||
adminMenuListData, err := adminMenuQb.
|
||||
OrderById(false).
|
||||
QueryAll(s.db.GetDB().WithContext(ctx.RequestContext()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(adminMenuListData) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var menuIds []int
|
||||
for _, v := range adminMenuListData {
|
||||
menuIds = append(menuIds, v.MenuId)
|
||||
}
|
||||
|
||||
actionQb := menu_action.NewQueryBuilder()
|
||||
actionQb.WhereIsDeleted(database.EqualPredicate, -1)
|
||||
actionQb.WhereMenuIdIn(menuIds)
|
||||
actionListData, err := actionQb.QueryAll(s.db.GetDB().WithContext(ctx.RequestContext()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(actionListData) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
actionData = make([]MyActionData, len(actionListData))
|
||||
|
||||
for k, v := range actionListData {
|
||||
data := MyActionData{
|
||||
Id: v.Id,
|
||||
MenuId: v.MenuId,
|
||||
Method: v.Method,
|
||||
Api: v.Api,
|
||||
}
|
||||
|
||||
actionData[k] = data
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Package admin
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-03 15:02
|
||||
package admin
|
||||
|
||||
type SearchMyActionData struct {
|
||||
AdminId int `json:"admin_id"` // 管理员ID
|
||||
}
|
||||
|
||||
type MyActionData struct {
|
||||
Id int // 主键
|
||||
MenuId int // 菜单栏ID
|
||||
Method string // 请求方式
|
||||
Api string // 请求地址
|
||||
}
|
||||
73
internal/services/admin/service_mymenu.go
Normal file
73
internal/services/admin/service_mymenu.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Package admin
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-09 15:07
|
||||
package admin
|
||||
|
||||
import (
|
||||
"github.com/LLiuHuan/gin-template/internal/pkg/core"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database/admin_menu"
|
||||
"github.com/LLiuHuan/gin-template/internal/repository/database/menu"
|
||||
)
|
||||
|
||||
type SearchMyMenuData struct {
|
||||
AdminId int `json:"admin_id"` // 管理员ID
|
||||
}
|
||||
|
||||
type ListMyMenuData struct {
|
||||
Id int `json:"id"` // ID
|
||||
Pid int `json:"pid"` // 父类ID
|
||||
Name string `json:"name"` // 菜单名称
|
||||
Link string `json:"link"` // 链接地址
|
||||
Icon string `json:"icon"` // 图标
|
||||
}
|
||||
|
||||
func (s *service) MyMenu(ctx core.Context, searchData *SearchMyMenuData) (menuData []ListMyMenuData, err error) {
|
||||
adminMenuQb := admin_menu.NewQueryBuilder()
|
||||
if searchData.AdminId != 0 {
|
||||
adminMenuQb.WhereAdminId(database.EqualPredicate, searchData.AdminId)
|
||||
}
|
||||
|
||||
adminMenuListData, err := adminMenuQb.
|
||||
OrderById(false).
|
||||
QueryAll(s.db.GetDB().WithContext(ctx.RequestContext()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(adminMenuListData) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
menuQb := menu.NewQueryBuilder()
|
||||
menuQb.WhereIsDeleted(database.EqualPredicate, -1)
|
||||
menuListData, err := menuQb.
|
||||
OrderBySort(true).
|
||||
QueryAll(s.db.GetDB().WithContext(ctx.RequestContext()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(menuListData) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, menuAllV := range menuListData {
|
||||
for _, v := range adminMenuListData {
|
||||
if menuAllV.Id == v.MenuId {
|
||||
data := ListMyMenuData{
|
||||
Id: menuAllV.Id,
|
||||
Pid: menuAllV.Pid,
|
||||
Name: menuAllV.Name,
|
||||
Link: menuAllV.Link,
|
||||
Icon: menuAllV.Icon,
|
||||
}
|
||||
|
||||
menuData = append(menuData, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -40,15 +40,16 @@ type installRequest struct {
|
||||
type installResponse struct{}
|
||||
|
||||
// Install 安装
|
||||
// @Summary 安装
|
||||
// @Description 安装
|
||||
// @Tags API.install
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body installRequest true "请求信息"
|
||||
// @Success 200 {object} installResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /v1/api/install [post]
|
||||
//
|
||||
// @Summary 安装
|
||||
// @Description 安装
|
||||
// @Tags API.install
|
||||
// @Accept application/x-www-form-urlencoded
|
||||
// @Produce json
|
||||
// @Param Request body installRequest true "请求信息"
|
||||
// @Success 200 {object} installResponse
|
||||
// @Failure 400 {object} code.Failure
|
||||
// @Router /v1/api/install [post]
|
||||
func (h *handler) Install() core.HandlerFunc {
|
||||
installTableList := map[string]map[string]string{
|
||||
"authorized": {
|
||||
|
||||
29
main.go
29
main.go
@@ -1,7 +1,8 @@
|
||||
// Package gin_template
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 18:07
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 18:07
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -25,20 +26,20 @@ func init() {
|
||||
|
||||
}
|
||||
|
||||
// @title swagger 接口文档
|
||||
// @version 2.0
|
||||
// @description
|
||||
// @title swagger 接口文档
|
||||
// @version 2.0
|
||||
// @description
|
||||
|
||||
// @contact.name
|
||||
// @contact.url
|
||||
// @contact.email
|
||||
// @contact.name
|
||||
// @contact.url
|
||||
// @contact.email
|
||||
|
||||
// @license.name MIT
|
||||
// @license.url https://github.com/LLiuHuan/gin-template/blob/master/LICENSE
|
||||
// @license.name MIT
|
||||
// @license.url https://github.com/LLiuHuan/gin-template/blob/master/LICENSE
|
||||
|
||||
// @securityDefinitions.apikey LoginToken
|
||||
// @in header
|
||||
// @name token
|
||||
// @securityDefinitions.apikey LoginToken
|
||||
// @in header
|
||||
// @name token
|
||||
func main() {
|
||||
accessLogger, err := logger.NewJSONLogger(
|
||||
logger.WithDisableConsole(),
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package browser
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:53
|
||||
// @description: 使用浏览器打开指定的 URL
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:53
|
||||
// @description: 使用浏览器打开指定的 URL
|
||||
package browser
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//go:build darwin
|
||||
|
||||
// Package color
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:54
|
||||
// @description: Darwin颜色
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:54
|
||||
// @description: Darwin颜色
|
||||
package color
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//go:build linux
|
||||
|
||||
// Package color
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:54
|
||||
// @description: Linux颜色
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:54
|
||||
// @description: Linux颜色
|
||||
package color
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//go:build windows
|
||||
|
||||
// Package color
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:55
|
||||
// @description: Windows颜色
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:55
|
||||
// @description: Windows颜色
|
||||
package color
|
||||
|
||||
import (
|
||||
|
||||
@@ -6,74 +6,171 @@ package currency
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FormatFileSize 字节的单位转换 保留两位小数
|
||||
func FormatFileSize(fileSize int64) (size string) {
|
||||
if fileSize < 1<<10 {
|
||||
//return strconv.FormatInt(fileSize, 10) + "B"
|
||||
return fmt.Sprintf("%.2f B", float64(fileSize)/float64(1))
|
||||
} else if fileSize < 1<<20 {
|
||||
return fmt.Sprintf("%.2f KB", float64(fileSize)/float64(1<<10))
|
||||
} else if fileSize < 1<<30 {
|
||||
return fmt.Sprintf("%.2f MB", float64(fileSize)/float64(1<<20))
|
||||
} else if fileSize < 1<<40 {
|
||||
return fmt.Sprintf("%.2f GB", float64(fileSize)/float64(1<<30))
|
||||
} else if fileSize < 1<<50 {
|
||||
return fmt.Sprintf("%.2f TB", float64(fileSize)/float64(1<<40))
|
||||
} else if fileSize < 1<<60 {
|
||||
return fmt.Sprintf("%.2f EB", float64(fileSize)/float64(1<<50))
|
||||
} else { //if fileSize < (1000 * 1000 * 1000 * 1000 * 1000 * 1000)
|
||||
return fmt.Sprintf("%.2f ZB", float64(fileSize)/float64(1<<60))
|
||||
// FormatFileSize 字节的单位转换 保留两位小数, 基数是1024
|
||||
func FormatFileSize(fileSize int64) string {
|
||||
units := []struct {
|
||||
threshold int64
|
||||
format string
|
||||
}{
|
||||
{1 << 10, "%.2f B"},
|
||||
{1 << 20, "%.2f KB"},
|
||||
{1 << 30, "%.2f MB"},
|
||||
{1 << 40, "%.2f GB"},
|
||||
{1 << 50, "%.2f TB"},
|
||||
{1 << 60, "%.2f EB"},
|
||||
{math.MaxInt64, "%.2f ZB"},
|
||||
}
|
||||
|
||||
var unit string
|
||||
var value float64
|
||||
|
||||
for _, u := range units {
|
||||
if fileSize < u.threshold {
|
||||
unit = u.format
|
||||
value = float64(fileSize) / float64(u.threshold>>10)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return strings.ReplaceAll(fmt.Sprintf(unit, value), ".00", "")
|
||||
}
|
||||
|
||||
// ReversalFileSize 字节的单位转换 保留两位小数
|
||||
|
||||
func ReversalFileSize(fileSize string) (size float64) {
|
||||
if strings.HasSuffix(fileSize, "KB") {
|
||||
float, err := strconv.ParseFloat(strings.Replace(fileSize, "KB", "", -1), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
units := []struct {
|
||||
suffix string
|
||||
multiplier float64
|
||||
}{
|
||||
{"KB", float64(1 << 10)},
|
||||
{"MB", float64(1 << 20)},
|
||||
{"GB", float64(1 << 30)},
|
||||
{"TB", float64(1 << 40)},
|
||||
{"EB", float64(1 << 50)},
|
||||
{"ZB", float64(1 << 60)},
|
||||
{"B", float64(1)},
|
||||
}
|
||||
|
||||
for _, unit := range units {
|
||||
if strings.HasSuffix(fileSize, unit.suffix) {
|
||||
value, err := strconv.ParseFloat(strings.TrimSpace(strings.TrimSuffix(fileSize, unit.suffix)), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
size = value * unit.multiplier
|
||||
break
|
||||
}
|
||||
size = float * float64(1<<10)
|
||||
} else if strings.HasSuffix(fileSize, "MB") {
|
||||
float, err := strconv.ParseFloat(strings.Replace(fileSize, "MB", "", -1), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
size = float * float64(1<<20)
|
||||
} else if strings.HasSuffix(fileSize, "GB") {
|
||||
float, err := strconv.ParseFloat(strings.Replace(fileSize, "GB", "", -1), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
size = float * float64(1<<30)
|
||||
} else if strings.HasSuffix(fileSize, "TB") {
|
||||
float, err := strconv.ParseFloat(strings.Replace(fileSize, "TB", "", -1), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
size = float * float64(1<<40)
|
||||
} else if strings.HasSuffix(fileSize, "EB") {
|
||||
float, err := strconv.ParseFloat(strings.Replace(fileSize, "EB", "", -1), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
size = float * float64(1<<50)
|
||||
} else if strings.HasSuffix(fileSize, "ZB") {
|
||||
float, err := strconv.ParseFloat(strings.Replace(fileSize, "ZB", "", -1), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
size = float * float64(1<<60)
|
||||
} else {
|
||||
float, err := strconv.ParseFloat(strings.Replace(fileSize, "B", "", -1), 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
size = float * float64(1)
|
||||
}
|
||||
return size / float64(1<<20)
|
||||
}
|
||||
|
||||
// ReversalFileSize 字节的单位转换 保留两位小数
|
||||
//func ReversalFileSize(fileSize string) (size float64) {
|
||||
// if strings.HasSuffix(fileSize, "KB") {
|
||||
// float, err := strconv.ParseFloat(strings.Replace(fileSize, "KB", "", -1), 64)
|
||||
// if err != nil {
|
||||
// return 0
|
||||
// }
|
||||
// size = float * float64(1<<10)
|
||||
// } else if strings.HasSuffix(fileSize, "MB") {
|
||||
// float, err := strconv.ParseFloat(strings.Replace(fileSize, "MB", "", -1), 64)
|
||||
// if err != nil {
|
||||
// return 0
|
||||
// }
|
||||
// size = float * float64(1<<20)
|
||||
// } else if strings.HasSuffix(fileSize, "GB") {
|
||||
// float, err := strconv.ParseFloat(strings.Replace(fileSize, "GB", "", -1), 64)
|
||||
// if err != nil {
|
||||
// return 0
|
||||
// }
|
||||
// size = float * float64(1<<30)
|
||||
// } else if strings.HasSuffix(fileSize, "TB") {
|
||||
// float, err := strconv.ParseFloat(strings.Replace(fileSize, "TB", "", -1), 64)
|
||||
// if err != nil {
|
||||
// return 0
|
||||
// }
|
||||
// size = float * float64(1<<40)
|
||||
// } else if strings.HasSuffix(fileSize, "EB") {
|
||||
// float, err := strconv.ParseFloat(strings.Replace(fileSize, "EB", "", -1), 64)
|
||||
// if err != nil {
|
||||
// return 0
|
||||
// }
|
||||
// size = float * float64(1<<50)
|
||||
// } else if strings.HasSuffix(fileSize, "ZB") {
|
||||
// float, err := strconv.ParseFloat(strings.Replace(fileSize, "ZB", "", -1), 64)
|
||||
// if err != nil {
|
||||
// return 0
|
||||
// }
|
||||
// size = float * float64(1<<60)
|
||||
// } else {
|
||||
// float, err := strconv.ParseFloat(strings.Replace(fileSize, "B", "", -1), 64)
|
||||
// if err != nil {
|
||||
// return 0
|
||||
// }
|
||||
// size = float * float64(1)
|
||||
// }
|
||||
// return size / float64(1<<20)
|
||||
//}
|
||||
|
||||
const (
|
||||
UnitWan = "万"
|
||||
UnitQianWan = "千万"
|
||||
UnitYi = "亿"
|
||||
UnitBaiYi = "百亿"
|
||||
UnitQianYi = "千亿"
|
||||
UnitWanYi = "万亿"
|
||||
)
|
||||
|
||||
func SimplifyNum(num float64, suffix string) string {
|
||||
units := []struct {
|
||||
threshold float64
|
||||
unit string
|
||||
}{
|
||||
{1e12, UnitWanYi},
|
||||
{1e11, UnitQianYi},
|
||||
{1e10, UnitBaiYi},
|
||||
{1e8, UnitYi},
|
||||
{1e7, UnitQianWan},
|
||||
{1e4, UnitWan},
|
||||
}
|
||||
|
||||
num = math.Round(num*100) / 100
|
||||
if num == 0 {
|
||||
return "0"
|
||||
}
|
||||
|
||||
for _, u := range units {
|
||||
if num >= u.threshold {
|
||||
return strings.ReplaceAll(fmt.Sprintf("%.3f %s%s", num/u.threshold, u.unit, suffix), ".000", "")
|
||||
}
|
||||
}
|
||||
|
||||
return strings.ReplaceAll(fmt.Sprintf("%.3f %s", num, suffix), ".000", "")
|
||||
}
|
||||
|
||||
//func SimplifyNum(num float64, suffix string) string {
|
||||
// // 保留两位小数
|
||||
// num = math.Round(num*100) / 100
|
||||
// if num <= 0 {
|
||||
// return "0"
|
||||
// } else if num >= 1000 && num < 1000000 {
|
||||
// return fmt.Sprintf("%.3f 万%s", num/10000, suffix)
|
||||
// } else if num >= 10000000 && num < 100000000 {
|
||||
// return fmt.Sprintf("%.3f 千万%s", num/10000000, suffix)
|
||||
// } else if num >= 100000000 && num < 10000000000 {
|
||||
// return fmt.Sprintf("%.3f 亿%s", num/100000000, suffix)
|
||||
// } else if num >= 10000000000 && num < 100000000000 {
|
||||
// return fmt.Sprintf("%.3f 百亿%s", num/10000000000, suffix)
|
||||
// } else if num >= 100000000000 && num < 1000000000000 {
|
||||
// return fmt.Sprintf("%.3f 千亿%s", num/100000000000, suffix)
|
||||
// } else if num >= 1000000000000 && num < 10000000000000 {
|
||||
// return fmt.Sprintf("%.3f 万亿%s", num/1000000000000, suffix)
|
||||
// } else {
|
||||
// return fmt.Sprintf("%f%s", num, suffix)
|
||||
// }
|
||||
//}
|
||||
|
||||
73
pkg/currency/currency_test.go
Normal file
73
pkg/currency/currency_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
// Package currency
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-09 11:04
|
||||
package currency
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSimplifyNum(t *testing.T) {
|
||||
// 生成一个单元测试
|
||||
if num := SimplifyNum(1, "元"); num != "1 元" {
|
||||
t.Errorf("Expected 1 元, but got %s", num)
|
||||
}
|
||||
if num := SimplifyNum(100, "元"); num != "100 元" {
|
||||
t.Errorf("Expected 100 元, but got %s", num)
|
||||
}
|
||||
if num := SimplifyNum(1000, "元"); num != "1000 元" {
|
||||
t.Errorf("Expected 1000 元, but got %s", num)
|
||||
}
|
||||
if num := SimplifyNum(10000, "元"); num != "1 万元" {
|
||||
t.Errorf("Expected 1 万元, but got %s", num)
|
||||
}
|
||||
if num := SimplifyNum(100000, "元"); num != "10 万元" {
|
||||
t.Errorf("Expected 10 万元, but got %s", num)
|
||||
}
|
||||
if num := SimplifyNum(140312310, "元"); num != " 1.403 亿元" {
|
||||
t.Errorf("Expected 1.403 亿元, but got %s", num)
|
||||
}
|
||||
if num := SimplifyNum(10000000, "元"); num != "1 千万元" {
|
||||
t.Errorf("Expected 1 千万元, but got %s", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatFileSize(t *testing.T) {
|
||||
result := FormatFileSize(1)
|
||||
if result != "1 B" {
|
||||
t.Errorf("Expected 1B, but got %s", result)
|
||||
}
|
||||
|
||||
result = FormatFileSize(1 << 10)
|
||||
if result != "1 KB" {
|
||||
t.Errorf("Expected 1KB, but got %s", result)
|
||||
}
|
||||
|
||||
result = FormatFileSize(1 << 20)
|
||||
if result != "1 MB" {
|
||||
t.Errorf("Expected 1MB, but got %s", result)
|
||||
}
|
||||
|
||||
result = FormatFileSize(1 << 30)
|
||||
if result != "1 GB" {
|
||||
t.Errorf("Expected 1GB, but got %s", result)
|
||||
}
|
||||
|
||||
result = FormatFileSize(1 << 40)
|
||||
if result != "1 TB" {
|
||||
t.Errorf("Expected 1TB, but got %s", result)
|
||||
}
|
||||
|
||||
//result = FormatFileSize(48712831672)
|
||||
//t.Log(result)
|
||||
}
|
||||
|
||||
func TestReversalFileSize(t *testing.T) {
|
||||
result := ReversalFileSize("100 GB")
|
||||
t.Log(result)
|
||||
//if result != 5000 {
|
||||
// t.Errorf("Expected 5000, but got %f", result)
|
||||
//}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package database
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:56
|
||||
// @description: 数据库
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:56
|
||||
// @description: 数据库
|
||||
package database
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package file
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:57
|
||||
// @description: 文件操作
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:57
|
||||
// @description: 文件操作
|
||||
package file
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// Package trace
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:40
|
||||
// @description: 链路追踪
|
||||
//
|
||||
// @program: gin-template
|
||||
// @author: [lliuhuan](https://github.com/lliuhuan)
|
||||
// @create: 2024-07-02 21:40
|
||||
// @description: 链路追踪
|
||||
package trace
|
||||
|
||||
import (
|
||||
|
||||
Reference in New Issue
Block a user