🆕初始化脚本以及一些工具类
This commit is contained in:
parent
a9333df157
commit
7fd186d298
@ -1,13 +1,17 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"github.com/cowardmrx/go_aliyun_oss"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
WireguardClient *wgctrl.Client // wireguard客户端
|
||||
DB *gorm.DB // 数据库客户端
|
||||
Redis *redis.Client // redis客户端
|
||||
WireguardClient *wgctrl.Client // wireguard客户端
|
||||
DB *gorm.DB // 数据库客户端
|
||||
Redis *redis.Client // redis客户端
|
||||
HttpClient *resty.Client // http客户端
|
||||
OSS *go_aliyun_oss.AliOssClient // oss客户端
|
||||
)
|
||||
|
@ -6,4 +6,5 @@ type config struct {
|
||||
Http *http `yaml:"http"`
|
||||
Database *database `yaml:"database"`
|
||||
Redis *redis `yaml:"redis"`
|
||||
File *file `yaml:"file"`
|
||||
}
|
||||
|
10
config/file.go
Normal file
10
config/file.go
Normal file
@ -0,0 +1,10 @@
|
||||
package config
|
||||
|
||||
type file struct {
|
||||
Type string `yaml:"type"`
|
||||
Path string `yaml:"path"`
|
||||
Endpoint string `yaml:"endpoint"`
|
||||
AccessId string `yaml:"accessId"`
|
||||
AccessSecret string `yaml:"accessSecret"`
|
||||
BucketName string `yaml:"bucketName"`
|
||||
}
|
21
constant/admin.go
Normal file
21
constant/admin.go
Normal file
@ -0,0 +1,21 @@
|
||||
package constant
|
||||
|
||||
type UserType int
|
||||
|
||||
const (
|
||||
NormalAdmin UserType = iota
|
||||
SuperAdmin
|
||||
)
|
||||
|
||||
var UserTypeMap = map[UserType]string{
|
||||
NormalAdmin: "普通管理员",
|
||||
SuperAdmin: "超级管理员",
|
||||
}
|
||||
|
||||
func (u UserType) String() string {
|
||||
if v, ok := UserTypeMap[u]; ok {
|
||||
return v
|
||||
}
|
||||
|
||||
return "未知类型"
|
||||
}
|
9
go.mod
9
go.mod
@ -3,9 +3,11 @@ module wireguard-dashboard
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/cowardmrx/go_aliyun_oss v1.0.6 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
@ -13,6 +15,7 @@ require (
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.11.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
@ -35,14 +38,18 @@ require (
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/redis/go-redis/v9 v9.5.1 // indirect
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b // indirect
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
|
53
go.sum
53
go.sum
@ -1,3 +1,6 @@
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible h1:QoRMR0TCctLDqBCMyOu1eXdZyMw3F7uGA9qPn2J4+R8=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.5+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
@ -6,6 +9,8 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/cowardmrx/go_aliyun_oss v1.0.6 h1:KVCCUJe4n/hGzNH1RBuu4qDGa9PfTYJOLsAt3GDZx3s=
|
||||
github.com/cowardmrx/go_aliyun_oss v1.0.6/go.mod h1:hisPCZT3TaXex2fCTXRl/rozLw/dpifyIJtihBlRnkk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
@ -22,6 +27,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
|
||||
github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
|
||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
@ -50,6 +57,9 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
@ -72,6 +82,8 @@ github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNc
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
|
||||
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -86,22 +98,45 @@ 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.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
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/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.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
|
||||
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
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 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -109,10 +144,27 @@ golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
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.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
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/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=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b h1:J1CaxgLerRR5lgx3wnr6L04cJFbWoceSK9JWBdglINo=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b/go.mod h1:tqur9LnfstdR9ep2LaJT4lFUl0EjlHtge+gAjmsHUG4=
|
||||
@ -122,6 +174,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@ -2,6 +2,8 @@ package initialize
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/cowardmrx/go_aliyun_oss"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"golang.zx2c4.com/wireguard/wgctrl"
|
||||
"gopkg.in/yaml.v3"
|
||||
@ -20,10 +22,12 @@ import (
|
||||
// Init
|
||||
// @description: 初始化
|
||||
func Init() {
|
||||
initConfig() // 读取配置文件
|
||||
initWireguard() // 初始化wireguard客户端
|
||||
initDatabase() // 初始化数据库
|
||||
initRedis() // 初始化redis
|
||||
initConfig() // 读取配置文件
|
||||
initWireguard() // 初始化wireguard客户端
|
||||
initDatabase() // 初始化数据库
|
||||
initRedis() // 初始化redis
|
||||
initHttpClient() // 初始化http客户端
|
||||
initOSS() // 初始化oss客户端链接
|
||||
}
|
||||
|
||||
// initConfig
|
||||
@ -98,3 +102,27 @@ func initRedis() {
|
||||
|
||||
client.Redis = c
|
||||
}
|
||||
|
||||
// initHttpClient
|
||||
// @description: 初始化http客户端
|
||||
func initHttpClient() {
|
||||
client.HttpClient = resty.New()
|
||||
}
|
||||
|
||||
// initOSS
|
||||
// @description: 初始化oss客户端
|
||||
func initOSS() {
|
||||
if config.Config.File.Type != "oss" {
|
||||
return
|
||||
}
|
||||
ossConfig := &go_aliyun_oss.AliOssConfig{
|
||||
EndPoint: config.Config.File.Endpoint,
|
||||
AccessKeyId: config.Config.File.AccessId,
|
||||
AccessKeySecret: config.Config.File.AccessSecret,
|
||||
BucketName: config.Config.File.BucketName,
|
||||
OriginalFileName: false,
|
||||
}
|
||||
|
||||
ossClient := ossConfig.CreateOssConnect()
|
||||
client.OSS = ossClient
|
||||
}
|
||||
|
5
main.go
5
main.go
@ -2,15 +2,20 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"log"
|
||||
"net/http"
|
||||
"wireguard-dashboard/config"
|
||||
"wireguard-dashboard/initialize"
|
||||
"wireguard-dashboard/route"
|
||||
"wireguard-dashboard/script"
|
||||
)
|
||||
|
||||
func init() {
|
||||
initialize.Init() // 初始化
|
||||
if err := script.NewScript().Do(); err != nil {
|
||||
zap.S().Errorf("执行脚本错误: %v", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -1,15 +1,18 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Base struct {
|
||||
Id string `json:"id" gorm:"primaryKey;type:varchar(36);not null;comment:'主键'"`
|
||||
CreatedAt datatypes.Time
|
||||
UpdatedAt datatypes.Time
|
||||
CreatedAt DateTime
|
||||
UpdatedAt DateTime
|
||||
}
|
||||
|
||||
func (b *Base) BeforeCreate(*gorm.DB) (err error) {
|
||||
@ -19,3 +22,159 @@ func (b *Base) BeforeCreate(*gorm.DB) (err error) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 默认时间格式
|
||||
const dateTimeFormat = "2006-01-02 15:04:05.000"
|
||||
|
||||
// DateTime 自定义时间类型
|
||||
type DateTime time.Time
|
||||
|
||||
// 可能包含的时间格式
|
||||
var formatMap = map[string]string{
|
||||
"yyyy-mm-dd hh:mm:ss": "2006-01-02 15:04:05",
|
||||
"yyyy-mm-dd hh:mm": "2006-01-02 15:04",
|
||||
"yyyy-mm-dd hh": "2006-01-02 15:04",
|
||||
"yyyy-mm-dd": "2006-01-02",
|
||||
"yyyy-mm": "2006-01",
|
||||
"mm-dd": "01-02",
|
||||
"dd-mm-yy hh:mm:ss": "02-01-06 15:04:05",
|
||||
"yyyy/mm/dd hh:mm:ss": "2006/01/02 15:04:05",
|
||||
"yyyy/mm/dd hh:mm": "2006/01/02 15:04",
|
||||
"yyyy/mm/dd hh": "2006/01/02 15",
|
||||
"yyyy/mm/dd": "2006/01/02",
|
||||
"yyyy/mm": "2006/01",
|
||||
"mm/dd": "01/02",
|
||||
"dd/mm/yy hh:mm:ss": "02/01/06 15:04:05",
|
||||
"yyyy": "2006",
|
||||
"mm": "01",
|
||||
"hh:mm:ss": "15:04:05",
|
||||
"mm:ss": "04:05",
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (dt *DateTime) Scan(value interface{}) error {
|
||||
// mysql 内部日期的格式可能是 2006-01-02 15:04:05 +0800 CST 格式,所以检出的时候还需要进行一次格式化
|
||||
tTime, _ := time.Parse("2006-01-02 15:04:05 +0800 CST", value.(time.Time).String())
|
||||
*dt = DateTime(tTime)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (dt DateTime) Value() (dv driver.Value, err error) {
|
||||
// 0001-01-01 00:00:00 属于空值,遇到空值解析成 null 即可
|
||||
if dt.String() == "0001-01-01 00:00:00.000" {
|
||||
return nil, nil
|
||||
}
|
||||
dv, err = []byte(dt.Format(dateTimeFormat)), nil
|
||||
return
|
||||
}
|
||||
|
||||
// 用于 fmt.Println 和后续验证场景
|
||||
func (dt DateTime) String() string {
|
||||
return dt.Format(dateTimeFormat)
|
||||
}
|
||||
|
||||
// Format 格式化
|
||||
func (dt *DateTime) Format(fm string) string {
|
||||
return time.Time(*dt).Format(fm)
|
||||
}
|
||||
|
||||
// AutoParse 假装是个自动解析时间的函数
|
||||
func (dt DateTime) AutoParse(timeStr string) (t time.Time, err error) {
|
||||
// 循环匹配预设的时间格式
|
||||
for _, v := range formatMap {
|
||||
// 尝试解析,没报错就是解析成功了
|
||||
t, err = time.ParseInLocation(v, timeStr, time.Local)
|
||||
if err == nil {
|
||||
// 错误为空,表示匹配上了
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// After 时间比较
|
||||
func (dt *DateTime) After(now time.Time) bool {
|
||||
return time.Time(*dt).After(now)
|
||||
}
|
||||
|
||||
// Before 时间比较
|
||||
func (dt *DateTime) Before(now time.Time) bool {
|
||||
return time.Time(*dt).Before(now)
|
||||
}
|
||||
|
||||
// IBefore 时间比较
|
||||
func (dt *DateTime) IBefore(now DateTime) bool {
|
||||
return dt.Before(time.Time(now))
|
||||
}
|
||||
|
||||
// SubTime 对比
|
||||
func (dt DateTime) SubTime(t time.Time) time.Duration {
|
||||
return dt.ToTime().Sub(t)
|
||||
}
|
||||
|
||||
// Sub 对比
|
||||
func (dt DateTime) Sub(t DateTime) time.Duration {
|
||||
return dt.ToTime().Sub(t.ToTime())
|
||||
}
|
||||
|
||||
// ToTime 转换为golang的时间类型
|
||||
func (dt DateTime) ToTime() time.Time {
|
||||
return time.Time(dt)
|
||||
}
|
||||
|
||||
// IsNil 是否为空值
|
||||
func (dt DateTime) IsNil() bool {
|
||||
return dt.Format(dateTimeFormat) == "0001-01-01 00:00:00.000"
|
||||
}
|
||||
|
||||
// Unix 实现Unix函数
|
||||
func (dt DateTime) Unix() int64 {
|
||||
return dt.ToTime().Unix()
|
||||
}
|
||||
|
||||
// EndOfCentury 获取本世纪最后时间
|
||||
func (dt DateTime) EndOfCentury() DateTime {
|
||||
yearEnd := time.Now().Local().Year()/100*100 + 99
|
||||
return DateTime(time.Date(yearEnd, 12, 31, 23, 59, 59, 999999999, time.Local))
|
||||
}
|
||||
|
||||
// Add
|
||||
// @description: 添加时间
|
||||
// @receiver dt
|
||||
// @param t
|
||||
func (dt DateTime) Add(d time.Duration) DateTime {
|
||||
return DateTime(dt.ToTime().Add(d))
|
||||
}
|
||||
|
||||
// ======== 序列化 JSON ========
|
||||
|
||||
// MarshalJSON 时间到字符串
|
||||
func (dt DateTime) MarshalJSON() ([]byte, error) {
|
||||
// 过滤掉空数据
|
||||
if dt.IsNil() {
|
||||
return []byte("\"\""), nil
|
||||
}
|
||||
output := fmt.Sprintf(`"%s"`, dt.Format("2006-01-02 15:04:05"))
|
||||
return []byte(output), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON 字符串到时间
|
||||
func (dt *DateTime) UnmarshalJSON(b []byte) (err error) {
|
||||
if len(b) == 2 {
|
||||
*dt = DateTime{}
|
||||
return
|
||||
}
|
||||
// 解析指定的格式
|
||||
var now time.Time
|
||||
if strings.HasPrefix(string(b), "\"") {
|
||||
now, err = dt.AutoParse(string(b)[1 : len(b)-1])
|
||||
} else {
|
||||
now, err = dt.AutoParse(string(b))
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
*dt = DateTime(now)
|
||||
return
|
||||
}
|
||||
|
19
model/entity/user.go
Normal file
19
model/entity/user.go
Normal file
@ -0,0 +1,19 @@
|
||||
package entity
|
||||
|
||||
import "wireguard-dashboard/constant"
|
||||
|
||||
// User
|
||||
// @description: 用户信息
|
||||
type User struct {
|
||||
Base
|
||||
Avatar string `json:"avatar" gorm:"type:varchar(255);not null;comment:'头像'"`
|
||||
Name string `json:"name" gorm:"type:varchar(50);not null;comment:'用户名'"`
|
||||
Account string `json:"account" gorm:"type:varchar(50);not null;comment:'账号'"`
|
||||
Email string `json:"email" gorm:"type:varchar(255);default null;comment:'联系邮箱'"`
|
||||
Password string `json:"password" gorm:"type:varchar(255);not null;comment:'密码'"`
|
||||
IsAdmin constant.UserType `json:"isAdmin" gorm:"type:int(1);not null;comment:'是否为管理员'"`
|
||||
}
|
||||
|
||||
func (*User) TableName() string {
|
||||
return "t_user"
|
||||
}
|
@ -33,6 +33,7 @@ type Client struct {
|
||||
UseServerDns int `json:"useServerDns" gorm:"type:int(1);default 1;comment:'是否使用服务端dns'"`
|
||||
EnableAfterCreation int `json:"enableAfterCreation" gorm:"type:int(1);default 1;comment:'是否创建后启用'"`
|
||||
Keys string `json:"keys" gorm:"type:text;default null;comment:'公钥和密钥的json串'"`
|
||||
UserId string `json:"userId" gorm:"type:char(36);not null;comment:'创建人id'"`
|
||||
}
|
||||
|
||||
func (*Client) TableName() string {
|
||||
|
76
script/db_migrate.go
Normal file
76
script/db_migrate.go
Normal file
@ -0,0 +1,76 @@
|
||||
package script
|
||||
|
||||
import (
|
||||
"go.uber.org/zap"
|
||||
"wireguard-dashboard/client"
|
||||
"wireguard-dashboard/constant"
|
||||
"wireguard-dashboard/model/entity"
|
||||
"wireguard-dashboard/utils"
|
||||
)
|
||||
|
||||
type Script struct{}
|
||||
|
||||
func NewScript() Script {
|
||||
return Script{}
|
||||
}
|
||||
|
||||
func (s Script) Do() error {
|
||||
if err := s.DBMigrate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.CreateSuperAdmin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DBMigrate
|
||||
// @description: 实体migrate
|
||||
// @receiver s
|
||||
// @return error
|
||||
func (s Script) DBMigrate() error {
|
||||
var ent = []any{
|
||||
new(entity.User),
|
||||
new(entity.Server),
|
||||
new(entity.Client),
|
||||
}
|
||||
|
||||
return client.DB.AutoMigrate(ent...)
|
||||
}
|
||||
|
||||
// CreateSuperAdmin
|
||||
// @description: 创建首个超级管理员
|
||||
// @receiver s
|
||||
// @return error
|
||||
func (s Script) CreateSuperAdmin() error {
|
||||
var count int64
|
||||
if err := client.DB.Model(&entity.User{}).Where("is_admin = ?", 1).Count(&count).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 没有超管就创建一个
|
||||
if count <= 0 {
|
||||
avatarPath, err := utils.Avatar().GenerateAvatar()
|
||||
if err != nil {
|
||||
zap.S().Errorf("生成头像失败: %v", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if err = client.DB.Create(&entity.User{
|
||||
Avatar: avatarPath,
|
||||
Name: "超牛管理员",
|
||||
Account: "Admin",
|
||||
Email: "",
|
||||
Password: utils.Password().GenerateHashPassword("admin123"),
|
||||
IsAdmin: constant.SuperAdmin,
|
||||
}).Error; err != nil {
|
||||
zap.S().Errorf("创建管理员失败: %v", err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
34
utils/avatar.go
Normal file
34
utils/avatar.go
Normal file
@ -0,0 +1,34 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"math/rand"
|
||||
"time"
|
||||
"wireguard-dashboard/client"
|
||||
)
|
||||
|
||||
type avatar struct{}
|
||||
|
||||
func Avatar() avatar {
|
||||
return avatar{}
|
||||
}
|
||||
|
||||
func (avatar) GenerateAvatar() (path string, err error) {
|
||||
rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
r := client.HttpClient.R()
|
||||
result, err := r.Get(fmt.Sprintf("https://api.dicebear.com/7.x/croodles/png?seed=%d&scale=100&size=80&clip=true&randomizeIds=true&beard=variant01,variant02,variant03&"+
|
||||
"eyes=variant01,variant02,variant03,variant04,variant05,variant06,variant07,variant08,variant09,variant10,variant11,variant12&mustache=variant01,variant02,variant03&"+
|
||||
"topColor=000000,0fa958,699bf7", rand.Uint32()))
|
||||
if err != nil {
|
||||
zap.S().Errorf("生成头像失败")
|
||||
return "", err
|
||||
}
|
||||
|
||||
filePath, err := FileSystem().UploadFile(result.Body(), ".png")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return filePath, nil
|
||||
}
|
41
utils/file_system.go
Normal file
41
utils/file_system.go
Normal file
@ -0,0 +1,41 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
"wireguard-dashboard/client"
|
||||
"wireguard-dashboard/config"
|
||||
)
|
||||
|
||||
type fileSystem struct{}
|
||||
|
||||
func FileSystem() fileSystem {
|
||||
return fileSystem{}
|
||||
}
|
||||
|
||||
// UploadFile
|
||||
// @description: 上传文件
|
||||
// @receiver fileSystem
|
||||
// @param file
|
||||
// @return filePath
|
||||
// @return err
|
||||
func (fileSystem) UploadFile(file []byte, suffix string) (filePath string, err error) {
|
||||
switch config.Config.File.Type {
|
||||
case "oss":
|
||||
ossObj, err := client.OSS.Put(config.Config.File.Path, file, suffix)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return ossObj.LongPath, nil
|
||||
case "local":
|
||||
filePath = fmt.Sprintf("%v/%d-avatar%s", config.Config.File.Path, time.Now().Unix(), suffix)
|
||||
if err = os.WriteFile(filePath, file, os.FileMode(0777)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return filePath, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
30
utils/password.go
Normal file
30
utils/password.go
Normal file
@ -0,0 +1,30 @@
|
||||
package utils
|
||||
|
||||
import "golang.org/x/crypto/bcrypt"
|
||||
|
||||
type password struct{}
|
||||
|
||||
func Password() password {
|
||||
return password{}
|
||||
}
|
||||
|
||||
// GenerateHashPassword
|
||||
// @description: 生成hash密码
|
||||
// @receiver password
|
||||
// @param pass
|
||||
// @return string
|
||||
func (password) GenerateHashPassword(pass string) string {
|
||||
bytePass := []byte(pass)
|
||||
hPass, _ := bcrypt.GenerateFromPassword(bytePass, bcrypt.DefaultCost)
|
||||
return string(hPass)
|
||||
}
|
||||
|
||||
// ComparePassword
|
||||
// @description: 密码比对
|
||||
// @receiver password
|
||||
// @param dbPass
|
||||
// @param pass
|
||||
// @return bool
|
||||
func (password) ComparePassword(dbPass, pass string) bool {
|
||||
return bcrypt.CompareHashAndPassword([]byte(dbPass), []byte(pass)) == nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user