From ee1cbf16853b58d69586f89236d9bf9589a2bd30 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 6 Aug 2022 23:50:25 +0800 Subject: [PATCH 01/41] Init Gin Repo --- .gitignore | 6 ++++ go.mod | 26 +++++++++++++++++ go.sum | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 22 ++++++++++++++ 4 files changed, 140 insertions(+) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae6798b --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Goland Setting +.idea/ + +# Binary file +go_build_* +ddlBackend \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0f9d3dd --- /dev/null +++ b/go.mod @@ -0,0 +1,26 @@ +module ddlBackend + +go 1.18 + +require github.com/gin-gonic/gin v1.8.1 + +require ( + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.10.0 // indirect + github.com/goccy/go-json v0.9.7 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/ugorji/go/codec v1.2.7 // indirect + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect + golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect + golang.org/x/text v0.3.6 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f99c8fe --- /dev/null +++ b/go.sum @@ -0,0 +1,86 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= +github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= +github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= +github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..a899d47 --- /dev/null +++ b/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + "github.com/gin-gonic/gin" +) + +func main() { + route := gin.Default() + + route.GET("/ping", func(context *gin.Context) { + context.JSONP(200, gin.H{ + "message": "pong", + }) + }) + + err := route.Run() + if err != nil { + fmt.Println(err.Error()) + return + } +} -- Gitee From f41a01d65f263c57908e0f801888377c285dcbba Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sun, 7 Aug 2022 15:56:38 +0800 Subject: [PATCH 02/41] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BA=86DDL=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E6=A8=A1=E5=9E=8B=20=E6=B7=BB=E5=8A=A0=E4=BA=86?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 25 +++++++++++++++++++++++++ go.mod | 5 +++++ go.sum | 13 +++++++++++++ log/log.go | 12 ++++++++++++ main.go | 20 +++++++++++--------- models/ddl_notice.go | 20 ++++++++++++++++++++ 6 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 database/database.go create mode 100644 log/log.go create mode 100644 models/ddl_notice.go diff --git a/database/database.go b/database/database.go new file mode 100644 index 0000000..93c7b9c --- /dev/null +++ b/database/database.go @@ -0,0 +1,25 @@ +package database + +import ( + "ddlBackend/models" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +// Database 数据库指针 +var Database *gorm.DB + +// OpenDatabase 打开数据库函数 +func OpenDatabase() (err error) { + Database, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) + if err != nil { + return err + } + + // 创建记录DDL事件的表 + if !Database.Migrator().HasTable(&models.DDLNotice{}) { + err = Database.Migrator().CreateTable(&models.DDLNotice{}) + } + + return err +} diff --git a/go.mod b/go.mod index 0f9d3dd..c96f642 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,12 @@ require ( github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/goccy/go-json v0.9.7 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-sqlite3 v1.14.14 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect @@ -23,4 +26,6 @@ require ( golang.org/x/text v0.3.6 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect + gorm.io/driver/sqlite v1.3.6 // indirect + gorm.io/gorm v1.23.8 // indirect ) diff --git a/go.sum b/go.sum index f99c8fe..5edf219 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,11 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -34,6 +39,9 @@ github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= +github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= @@ -84,3 +92,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ= +gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE= +gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE= +gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= diff --git a/log/log.go b/log/log.go new file mode 100644 index 0000000..10d7f0a --- /dev/null +++ b/log/log.go @@ -0,0 +1,12 @@ +package log + +import ( + "fmt" + "time" +) + +// DDLLog 日志记录函数 +func DDLLog(message string) { + now := time.Now() + fmt.Printf("%v %s\n", now, message) +} diff --git a/main.go b/main.go index a899d47..acf7f4d 100644 --- a/main.go +++ b/main.go @@ -1,22 +1,24 @@ package main import ( - "fmt" + "ddlBackend/database" + "ddlBackend/log" "github.com/gin-gonic/gin" ) func main() { - route := gin.Default() + // 打开数据库 + err := database.OpenDatabase() + if err != nil { + log.DDLLog(err.Error()) + return + } - route.GET("/ping", func(context *gin.Context) { - context.JSONP(200, gin.H{ - "message": "pong", - }) - }) + route := gin.Default() - err := route.Run() + err = route.Run() if err != nil { - fmt.Println(err.Error()) + log.DDLLog(err.Error()) return } } diff --git a/models/ddl_notice.go b/models/ddl_notice.go new file mode 100644 index 0000000..40f9214 --- /dev/null +++ b/models/ddl_notice.go @@ -0,0 +1,20 @@ +package models + +import ( + "gorm.io/gorm" + "time" +) + +// DDLNotice DDL事件模型 +type DDLNotice struct { + // gorm约定 + gorm.Model + // Title DDL事件的标题 + Title string + // Detail DDL事件的详情 + Detail string + // DDLTime DDL时间 + DDLTime time.Time + // NoticeType DDL的分类 + NoticeType int +} -- Gitee From dd8c58bdfca6c23162454869a029a3b594fde8b4 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sun, 7 Aug 2022 17:37:51 +0800 Subject: [PATCH 03/41] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BA=86DDL=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E7=B1=BB=E5=9E=8B=E5=B8=B8=E9=87=8F=20=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E4=BA=86/ddlNotices=E7=9B=B8=E5=85=B3=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +++- handlers/ddl_handlers.go | 65 ++++++++++++++++++++++++++++++++++++++++ main.go | 4 +++ models/ddl_notice.go | 13 ++++---- models/ddl_type.go | 22 ++++++++++++++ 5 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 handlers/ddl_handlers.go create mode 100644 models/ddl_type.go diff --git a/.gitignore b/.gitignore index ae6798b..ba444bf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ # Binary file go_build_* -ddlBackend \ No newline at end of file +ddlBackend + +# Database File +*.db \ No newline at end of file diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go new file mode 100644 index 0000000..6dacc7b --- /dev/null +++ b/handlers/ddl_handlers.go @@ -0,0 +1,65 @@ +package handlers + +import ( + "ddlBackend/database" + "ddlBackend/log" + "ddlBackend/models" + "github.com/gin-gonic/gin" + "net/http" + "strconv" +) + +// CreateDDLHandler 创建DDL事件处理函数 +func CreateDDLHandler(context *gin.Context) { + var ddlNotice models.DDLNotice + + err := context.ShouldBindJSON(&ddlNotice) + if err != nil { + // 绑定json数据失败 + // 返回 400 错误请求 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + result := database.Database.Create(&ddlNotice) + if result.Error != nil { + // 在数据库中创建失败 + // 返回 500 服务器错误 + log.DDLLog(result.Error.Error()) + context.JSONP(http.StatusInternalServerError, gin.H{ + "error": result.Error.Error(), + }) + } + + context.JSON(http.StatusCreated, ddlNotice) + return +} + +// ReadDDLHandler 读取DDL事件处理函数 +func ReadDDLHandler(context *gin.Context) { + start := context.DefaultQuery("start", "0") + step := context.DefaultQuery("step", "20") + noticeType := context.DefaultQuery("noticeType", "0") + + // 将过滤器参数从字符串转换为数字 + var err error + var startNum, stepNum int + startNum, err = strconv.Atoi(start) + stepNum, err = strconv.Atoi(step) + if err != nil { + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var ddlNotices []models.DDLNotice + database.Database.Table("ddl_notices").Order("ddl_time DESC").Where("notice_type = ?", noticeType).Offset(startNum).Limit(stepNum).Find(&ddlNotices) + + context.JSON(http.StatusOK, ddlNotices) + return +} diff --git a/main.go b/main.go index acf7f4d..7ac4fc1 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "ddlBackend/database" + "ddlBackend/handlers" "ddlBackend/log" "github.com/gin-gonic/gin" ) @@ -16,6 +17,9 @@ func main() { route := gin.Default() + route.GET("/ddlNotices", handlers.ReadDDLHandler) + route.POST("/ddlNotices", handlers.CreateDDLHandler) + err = route.Run() if err != nil { log.DDLLog(err.Error()) diff --git a/models/ddl_notice.go b/models/ddl_notice.go index 40f9214..4fd941d 100644 --- a/models/ddl_notice.go +++ b/models/ddl_notice.go @@ -1,20 +1,19 @@ package models import ( - "gorm.io/gorm" "time" ) // DDLNotice DDL事件模型 type DDLNotice struct { - // gorm约定 - gorm.Model + // 数据库事件编号 + ID uint `gorm:"primaryKey" json:"id"` // Title DDL事件的标题 - Title string + Title string `json:"title"` // Detail DDL事件的详情 - Detail string + Detail string `json:"detail"` // DDLTime DDL时间 - DDLTime time.Time + DDLTime time.Time `json:"ddl_time"` // NoticeType DDL的分类 - NoticeType int + NoticeType int `json:"notice_type"` } diff --git a/models/ddl_type.go b/models/ddl_type.go new file mode 100644 index 0000000..ca48f6e --- /dev/null +++ b/models/ddl_type.go @@ -0,0 +1,22 @@ +package models + +const ( + // DDL DDL事件 + DDL = iota + // ALL 全部活动类型 + ALL + // OTHER 其他类型活动 + OTHER + // POLITICS 思想政治类活动 + POLITICS + // LITERAL 文体类活动 + LITERAL + // VOLUNTEER 志愿类活动 + VOLUNTEER + // LECTURE 讲座类活动 + LECTURE + // CONTEST 竞赛类活动 + CONTEST + // SELECTION 评优类活动 + SELECTION +) -- Gitee From 208982110bb0e6a6f05fa5e508178b2d72ff04b2 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sun, 7 Aug 2022 18:13:50 +0800 Subject: [PATCH 04/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E7=8F=AD?= =?UTF-8?q?=E7=BA=A7url=E4=B8=8B=E7=9A=84=E5=A4=84=E7=90=86=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 71 ++++++++++++++++++++++++++++++++++ main.go | 3 ++ models/ddl_notice.go | 2 + 3 files changed, 76 insertions(+) create mode 100644 handlers/ddl_class_handlers.go diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go new file mode 100644 index 0000000..26925df --- /dev/null +++ b/handlers/ddl_class_handlers.go @@ -0,0 +1,71 @@ +package handlers + +import ( + "ddlBackend/database" + "ddlBackend/log" + "ddlBackend/models" + "github.com/gin-gonic/gin" + "net/http" + "strconv" +) + +// CreateClassDDLHandler 班级url下创建DDL事件处理函数 +func CreateClassDDLHandler(context *gin.Context) { + className := context.Param("class") + + var ddlNotice models.DDLNotice + err := context.ShouldBindJSON(&ddlNotice) + if err != nil { + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + if className != ddlNotice.ClassName { + context.JSON(http.StatusBadRequest, gin.H{ + "error": "the url and the body are not the same", + }) + return + } + + result := database.Database.Table("ddl_notices").Create(&ddlNotice) + if result.Error != nil { + log.DDLLog(result.Error.Error()) + context.JSON(http.StatusInternalServerError, gin.H{ + "error": result.Error.Error(), + }) + return + } + + context.JSON(http.StatusCreated, ddlNotice) + return +} + +// ReadClassDDLHandler 班级url下读取DDL事件处理函数 +func ReadClassDDLHandler(context *gin.Context) { + className := context.Query("class") + + start := context.DefaultQuery("start", "0") + step := context.DefaultQuery("step", "20") + noticeType := context.DefaultQuery("noticeType", "0") + + // 将过滤器参数从字符串转换为数字 + var err error + var startNum, stepNum int + startNum, err = strconv.Atoi(start) + stepNum, err = strconv.Atoi(step) + if err != nil { + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var ddlNotices []models.DDLNotice + database.Database.Table("ddl_notices").Order("ddl_time DESC").Offset(startNum).Limit(stepNum).Where("class_name = ? AND notice_type = ?", className, noticeType).Find(&ddlNotices) + context.JSON(http.StatusOK, ddlNotices) + return +} diff --git a/main.go b/main.go index 7ac4fc1..eebf5f5 100644 --- a/main.go +++ b/main.go @@ -20,6 +20,9 @@ func main() { route.GET("/ddlNotices", handlers.ReadDDLHandler) route.POST("/ddlNotices", handlers.CreateDDLHandler) + route.GET("/ddlNotices/:class", handlers.ReadClassDDLHandler) + route.POST("/ddlNotices/:class", handlers.CreateClassDDLHandler) + err = route.Run() if err != nil { log.DDLLog(err.Error()) diff --git a/models/ddl_notice.go b/models/ddl_notice.go index 4fd941d..f827d0f 100644 --- a/models/ddl_notice.go +++ b/models/ddl_notice.go @@ -16,4 +16,6 @@ type DDLNotice struct { DDLTime time.Time `json:"ddl_time"` // NoticeType DDL的分类 NoticeType int `json:"notice_type"` + // ClassName 班级名称 + ClassName string `json:"class_name"` } -- Gitee From 1346a0b098336d6c1279508846435fd4216b4e3e Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 8 Aug 2022 11:04:42 +0800 Subject: [PATCH 05/41] =?UTF-8?q?=E5=B0=86DDL=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E6=8C=89=E7=85=A7=E7=8F=AD=E7=BA=A7=E6=8B=86=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 28 +++++++++++++++++++++---- handlers/ddl_class_handlers.go | 37 ++++++++++++++++++++++++++++++++-- handlers/ddl_handlers.go | 25 +++++++++++++++++++++-- 3 files changed, 82 insertions(+), 8 deletions(-) diff --git a/database/database.go b/database/database.go index 93c7b9c..1e2d953 100644 --- a/database/database.go +++ b/database/database.go @@ -2,10 +2,15 @@ package database import ( "ddlBackend/models" + "errors" + "fmt" "gorm.io/driver/sqlite" "gorm.io/gorm" ) +// DDLTables DDL表列表 +var DDLTables = [7]string{"dddd", "304", "305", "306", "307", "308", "309"} + // Database 数据库指针 var Database *gorm.DB @@ -16,10 +21,25 @@ func OpenDatabase() (err error) { return err } - // 创建记录DDL事件的表 - if !Database.Migrator().HasTable(&models.DDLNotice{}) { - err = Database.Migrator().CreateTable(&models.DDLNotice{}) + // 创建ddl相关的表 + for _, value := range DDLTables { + if !Database.Migrator().HasTable(value) { + err = Database.Table(value).AutoMigrate(&models.DDLNotice{}) + if err != nil { + return err + } + } } - return err + return nil +} + +// GetDDLTable 获取指定班级的DDL事件表 +func GetDDLTable(className string) (*gorm.DB, error) { + for _, value := range DDLTables { + if className == value { + return Database.Table(className).Order("ddl_time DESC"), nil + } + } + return nil, errors.New(fmt.Sprintf("The table named %s not exists", className)) } diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index 26925df..f8e60f2 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -5,6 +5,7 @@ import ( "ddlBackend/log" "ddlBackend/models" "github.com/gin-gonic/gin" + "gorm.io/gorm" "net/http" "strconv" ) @@ -16,6 +17,8 @@ func CreateClassDDLHandler(context *gin.Context) { var ddlNotice models.DDLNotice err := context.ShouldBindJSON(&ddlNotice) if err != nil { + // 请求体绑定失败 + // 返回 400 错误请求 log.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), @@ -24,14 +27,30 @@ func CreateClassDDLHandler(context *gin.Context) { } if className != ddlNotice.ClassName { + // 请求url和请求体中班级不符 + // 返回 400 错误请求 context.JSON(http.StatusBadRequest, gin.H{ "error": "the url and the body are not the same", }) return } - result := database.Database.Table("ddl_notices").Create(&ddlNotice) + var db *gorm.DB + db, err = database.GetDDLTable(className) + if err != nil { + // 无法获取对应班级的数据库 + // 返回 400 错误请求 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + result := db.Create(&ddlNotice) if result.Error != nil { + // 在数据库中创建失败 + // 返回 500 服务器错误 log.DDLLog(result.Error.Error()) context.JSON(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), @@ -57,6 +76,8 @@ func ReadClassDDLHandler(context *gin.Context) { startNum, err = strconv.Atoi(start) stepNum, err = strconv.Atoi(step) if err != nil { + // 请求参数转换失败 + // 返回 400 错误请求 log.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), @@ -65,7 +86,19 @@ func ReadClassDDLHandler(context *gin.Context) { } var ddlNotices []models.DDLNotice - database.Database.Table("ddl_notices").Order("ddl_time DESC").Offset(startNum).Limit(stepNum).Where("class_name = ? AND notice_type = ?", className, noticeType).Find(&ddlNotices) + var db *gorm.DB + db, err = database.GetDDLTable(className) + if err != nil { + // 无法获取对应班级的数据库 + // 返回 400 错误请求 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + db.Where("notice_type = ?", noticeType).Offset(startNum).Limit(stepNum).Find(&ddlNotices) context.JSON(http.StatusOK, ddlNotices) return } diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go index 6dacc7b..75cd15d 100644 --- a/handlers/ddl_handlers.go +++ b/handlers/ddl_handlers.go @@ -5,6 +5,7 @@ import ( "ddlBackend/log" "ddlBackend/models" "github.com/gin-gonic/gin" + "gorm.io/gorm" "net/http" "strconv" ) @@ -24,7 +25,19 @@ func CreateDDLHandler(context *gin.Context) { return } - result := database.Database.Create(&ddlNotice) + var db *gorm.DB + db, err = database.GetDDLTable(ddlNotice.ClassName) + if err != nil { + // 获取对应班级数据库失败 + // 返回 400 错误请求 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + result := db.Create(&ddlNotice) if result.Error != nil { // 在数据库中创建失败 // 返回 500 服务器错误 @@ -32,6 +45,7 @@ func CreateDDLHandler(context *gin.Context) { context.JSONP(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), }) + return } context.JSON(http.StatusCreated, ddlNotice) @@ -50,6 +64,8 @@ func ReadDDLHandler(context *gin.Context) { startNum, err = strconv.Atoi(start) stepNum, err = strconv.Atoi(step) if err != nil { + // 请求参数转换失败 + // 返回 400 错误请求 log.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), @@ -58,7 +74,12 @@ func ReadDDLHandler(context *gin.Context) { } var ddlNotices []models.DDLNotice - database.Database.Table("ddl_notices").Order("ddl_time DESC").Where("notice_type = ?", noticeType).Offset(startNum).Limit(stepNum).Find(&ddlNotices) + for _, value := range database.DDLTables { + db, _ := database.GetDDLTable(value) + var list []models.DDLNotice + db.Where("notice_type = ?", noticeType).Offset(startNum).Limit(stepNum).Find(&list) + ddlNotices = append(ddlNotices, list...) + } context.JSON(http.StatusOK, ddlNotices) return -- Gitee From 5777abcb267627c8435ec0a5ca7c3883f5d3eca2 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 8 Aug 2022 13:49:17 +0800 Subject: [PATCH 06/41] =?UTF-8?q?=E7=8F=AD=E7=BA=A7=E7=BC=96=E5=8F=B7url?= =?UTF-8?q?=E4=B8=8B=E7=9A=84=E8=AF=B7=E6=B1=82=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 2 +- handlers/ddl_class_id_handlers.go | 165 ++++++++++++++++++++++++++++++ main.go | 4 + 3 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 handlers/ddl_class_id_handlers.go diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index f8e60f2..5966c5f 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -64,7 +64,7 @@ func CreateClassDDLHandler(context *gin.Context) { // ReadClassDDLHandler 班级url下读取DDL事件处理函数 func ReadClassDDLHandler(context *gin.Context) { - className := context.Query("class") + className := context.Param("class") start := context.DefaultQuery("start", "0") step := context.DefaultQuery("step", "20") diff --git a/handlers/ddl_class_id_handlers.go b/handlers/ddl_class_id_handlers.go new file mode 100644 index 0000000..b9319d6 --- /dev/null +++ b/handlers/ddl_class_id_handlers.go @@ -0,0 +1,165 @@ +package handlers + +import ( + "ddlBackend/database" + "ddlBackend/log" + "ddlBackend/models" + "fmt" + "github.com/gin-gonic/gin" + "gorm.io/gorm" + "net/http" + "strconv" +) + +func ReadClassIDDDLHandler(context *gin.Context) { + className := context.Param("class") + id := context.Param("id") + + var db *gorm.DB + var err error + db, err = database.GetDDLTable(className) + if err != nil { + // 获取指定班级的数据库失败 + // 返回 400 错误请求 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var idNum int + idNum, err = strconv.Atoi(id) + if err != nil { + // 转换id字符串失败 + // 返回 400 请求错误 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var ddlNotice models.DDLNotice + result := db.Where("id = ?", idNum).Find(&ddlNotice) + if result.Error != nil { + context.JSON(http.StatusNotFound, gin.H{ + "error": result.Error.Error(), + }) + } else { + context.JSON(http.StatusOK, ddlNotice) + } + return +} + +func UpdateClassIDDDLHandler(context *gin.Context) { + className := context.Param("class") + id := context.Param("id") + + var db *gorm.DB + var err error + db, err = database.GetDDLTable(className) + if err != nil { + // 获取指定班级的数据库失败 + // 返回 400 错误请求 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var idNum int + idNum, err = strconv.Atoi(id) + if err != nil { + // 转换id字符串失败 + // 返回 400 请求错误 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var ddlNotice models.DDLNotice + result := db.Where("id = ?", idNum).Find(&ddlNotice) + + if result.Error != nil { + // 读取指定的事件失败 + // 返回 404 未找到错误 + context.JSON(http.StatusNotFound, gin.H{ + "err": result.Error.Error(), + }) + return + } + + err = context.ShouldBindJSON(&ddlNotice) + if err != nil { + // 绑定请求体失败 + // 返回 400 请求错误 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + if ddlNotice.ID != uint(idNum) { + // 请求体中的ID和url中的ID不符 + // 返回 400 请求错误 + context.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("the id %d in the url and %d in the body are not the same", ddlNotice.ID, idNum), + }) + return + } + + db.Save(&ddlNotice) + context.JSON(http.StatusNoContent, gin.H{}) + return +} + +func DeleteClassIDDDLHandler(context *gin.Context) { + className := context.Param("class") + id := context.Param("id") + + var db *gorm.DB + var err error + db, err = database.GetDDLTable(className) + if err != nil { + // 获取指定班级的数据库失败 + // 返回 400 错误请求 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var idNum int + idNum, err = strconv.Atoi(id) + if err != nil { + // 转换id字符串失败 + // 返回 400 请求错误 + log.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var ddlNotice models.DDLNotice + result := db.Where("id = ?", idNum).Find(&ddlNotice) + + if result.Error != nil { + // 读取指定的事件失败 + // 返回 404 未找到错误 + context.JSON(http.StatusNotFound, gin.H{ + "err": result.Error.Error(), + }) + return + } + + db.Delete(&ddlNotice) + context.JSON(http.StatusNoContent, gin.H{}) + return +} diff --git a/main.go b/main.go index eebf5f5..c7c3b70 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,10 @@ func main() { route.GET("/ddlNotices/:class", handlers.ReadClassDDLHandler) route.POST("/ddlNotices/:class", handlers.CreateClassDDLHandler) + route.GET("/ddlNotices/:class/:id", handlers.ReadClassIDDDLHandler) + route.PUT("/ddlNotices/:class/:id", handlers.UpdateClassIDDDLHandler) + route.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) + err = route.Run() if err != nil { log.DDLLog(err.Error()) -- Gitee From 7d586c4554a0ccaa31776b099872b1ecdf8d7f07 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 8 Aug 2022 15:03:18 +0800 Subject: [PATCH 07/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 ++++- config/config.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 12 ++++++++++-- 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 config/config.go diff --git a/.gitignore b/.gitignore index ba444bf..6e61bdf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,7 @@ go_build_* ddlBackend # Database File -*.db \ No newline at end of file +*.db + +# Setting File +config.json \ No newline at end of file diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..71a2d28 --- /dev/null +++ b/config/config.go @@ -0,0 +1,51 @@ +package config + +import ( + "bufio" + "ddlBackend/log" + "encoding/json" + "os" +) + +type Config struct { + AppPort string `json:"app_port"` +} + +var DefaultSetting = Config{ + AppPort: ":8080", +} + +// Setting 配置文件对象 +var Setting Config + +// ReadConfig 读取配置文件 +func ReadConfig() error { + file, err := os.Open("config.json") + // 函数执行完成后关闭文件 + defer func(file *os.File) { + err := file.Close() + if err != nil { + // 关闭文件中错误 + log.DDLLog(err.Error()) + } + }(file) + + if err != nil { + // 读取配置文件错误 + // 采用默认配置 + Setting = DefaultSetting + return err + } + + reader := bufio.NewReader(file) + decoder := json.NewDecoder(reader) + err = decoder.Decode(&Setting) + if err != nil { + // 解析json失败 + // 采用默认配置 + Setting = DefaultSetting + return err + } + + return nil +} diff --git a/main.go b/main.go index c7c3b70..0c8eba5 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "ddlBackend/config" "ddlBackend/database" "ddlBackend/handlers" "ddlBackend/log" @@ -8,8 +9,15 @@ import ( ) func main() { + // 读取配置文件 + err := config.ReadConfig() + if err != nil { + log.DDLLog(err.Error()) + log.DDLLog("Read config file failed, using default setting") + } + // 打开数据库 - err := database.OpenDatabase() + err = database.OpenDatabase() if err != nil { log.DDLLog(err.Error()) return @@ -27,7 +35,7 @@ func main() { route.PUT("/ddlNotices/:class/:id", handlers.UpdateClassIDDDLHandler) route.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) - err = route.Run() + err = route.Run(config.Setting.AppPort) if err != nil { log.DDLLog(err.Error()) return -- Gitee From 18d51010620df6756844e3ec6720a1d837823b12 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 8 Aug 2022 15:19:05 +0800 Subject: [PATCH 08/41] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=BA=86=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E7=BB=93=E6=9E=84=20=E5=B0=86log=E5=92=8Cconfig?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=88=B0tool=E7=9B=AE=E5=BD=95=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 12 ++++++------ handlers/ddl_class_id_handlers.go | 16 ++++++++-------- handlers/ddl_handlers.go | 10 +++++----- main.go | 15 +++++++-------- {config => tool}/config.go | 5 ++--- {log => tool}/log.go | 2 +- 6 files changed, 29 insertions(+), 31 deletions(-) rename {config => tool}/config.go (92%) rename {log => tool}/log.go (91%) diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index 5966c5f..d265677 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -2,8 +2,8 @@ package handlers import ( "ddlBackend/database" - "ddlBackend/log" "ddlBackend/models" + "ddlBackend/tool" "github.com/gin-gonic/gin" "gorm.io/gorm" "net/http" @@ -19,7 +19,7 @@ func CreateClassDDLHandler(context *gin.Context) { if err != nil { // 请求体绑定失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -40,7 +40,7 @@ func CreateClassDDLHandler(context *gin.Context) { if err != nil { // 无法获取对应班级的数据库 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -51,7 +51,7 @@ func CreateClassDDLHandler(context *gin.Context) { if result.Error != nil { // 在数据库中创建失败 // 返回 500 服务器错误 - log.DDLLog(result.Error.Error()) + tool.DDLLog(result.Error.Error()) context.JSON(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), }) @@ -78,7 +78,7 @@ func ReadClassDDLHandler(context *gin.Context) { if err != nil { // 请求参数转换失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -91,7 +91,7 @@ func ReadClassDDLHandler(context *gin.Context) { if err != nil { // 无法获取对应班级的数据库 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) diff --git a/handlers/ddl_class_id_handlers.go b/handlers/ddl_class_id_handlers.go index b9319d6..7800e25 100644 --- a/handlers/ddl_class_id_handlers.go +++ b/handlers/ddl_class_id_handlers.go @@ -2,8 +2,8 @@ package handlers import ( "ddlBackend/database" - "ddlBackend/log" "ddlBackend/models" + "ddlBackend/tool" "fmt" "github.com/gin-gonic/gin" "gorm.io/gorm" @@ -21,7 +21,7 @@ func ReadClassIDDDLHandler(context *gin.Context) { if err != nil { // 获取指定班级的数据库失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -33,7 +33,7 @@ func ReadClassIDDDLHandler(context *gin.Context) { if err != nil { // 转换id字符串失败 // 返回 400 请求错误 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -62,7 +62,7 @@ func UpdateClassIDDDLHandler(context *gin.Context) { if err != nil { // 获取指定班级的数据库失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -74,7 +74,7 @@ func UpdateClassIDDDLHandler(context *gin.Context) { if err != nil { // 转换id字符串失败 // 返回 400 请求错误 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -97,7 +97,7 @@ func UpdateClassIDDDLHandler(context *gin.Context) { if err != nil { // 绑定请求体失败 // 返回 400 请求错误 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -128,7 +128,7 @@ func DeleteClassIDDDLHandler(context *gin.Context) { if err != nil { // 获取指定班级的数据库失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -140,7 +140,7 @@ func DeleteClassIDDDLHandler(context *gin.Context) { if err != nil { // 转换id字符串失败 // 返回 400 请求错误 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go index 75cd15d..d85b229 100644 --- a/handlers/ddl_handlers.go +++ b/handlers/ddl_handlers.go @@ -2,8 +2,8 @@ package handlers import ( "ddlBackend/database" - "ddlBackend/log" "ddlBackend/models" + "ddlBackend/tool" "github.com/gin-gonic/gin" "gorm.io/gorm" "net/http" @@ -18,7 +18,7 @@ func CreateDDLHandler(context *gin.Context) { if err != nil { // 绑定json数据失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -30,7 +30,7 @@ func CreateDDLHandler(context *gin.Context) { if err != nil { // 获取对应班级数据库失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -41,7 +41,7 @@ func CreateDDLHandler(context *gin.Context) { if result.Error != nil { // 在数据库中创建失败 // 返回 500 服务器错误 - log.DDLLog(result.Error.Error()) + tool.DDLLog(result.Error.Error()) context.JSONP(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), }) @@ -66,7 +66,7 @@ func ReadDDLHandler(context *gin.Context) { if err != nil { // 请求参数转换失败 // 返回 400 错误请求 - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) diff --git a/main.go b/main.go index 0c8eba5..38bf528 100644 --- a/main.go +++ b/main.go @@ -1,25 +1,24 @@ package main import ( - "ddlBackend/config" "ddlBackend/database" "ddlBackend/handlers" - "ddlBackend/log" + "ddlBackend/tool" "github.com/gin-gonic/gin" ) func main() { // 读取配置文件 - err := config.ReadConfig() + err := tool.ReadConfig() if err != nil { - log.DDLLog(err.Error()) - log.DDLLog("Read config file failed, using default setting") + tool.DDLLog(err.Error()) + tool.DDLLog("Read config file failed, using default setting") } // 打开数据库 err = database.OpenDatabase() if err != nil { - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) return } @@ -35,9 +34,9 @@ func main() { route.PUT("/ddlNotices/:class/:id", handlers.UpdateClassIDDDLHandler) route.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) - err = route.Run(config.Setting.AppPort) + err = route.Run(tool.Setting.AppPort) if err != nil { - log.DDLLog(err.Error()) + tool.DDLLog(err.Error()) return } } diff --git a/config/config.go b/tool/config.go similarity index 92% rename from config/config.go rename to tool/config.go index 71a2d28..060c355 100644 --- a/config/config.go +++ b/tool/config.go @@ -1,8 +1,7 @@ -package config +package tool import ( "bufio" - "ddlBackend/log" "encoding/json" "os" ) @@ -26,7 +25,7 @@ func ReadConfig() error { err := file.Close() if err != nil { // 关闭文件中错误 - log.DDLLog(err.Error()) + DDLLog(err.Error()) } }(file) diff --git a/log/log.go b/tool/log.go similarity index 91% rename from log/log.go rename to tool/log.go index 10d7f0a..4ec0fa6 100644 --- a/log/log.go +++ b/tool/log.go @@ -1,4 +1,4 @@ -package log +package tool import ( "fmt" -- Gitee From 404eb9834e337aa4c8406f57211f2049c3d3f503 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 8 Aug 2022 17:31:13 +0800 Subject: [PATCH 09/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86jwt=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Middleware/jwt_middleware.go | 48 ++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ models/jwt_claims.go | 11 +++++++++ tool/config.go | 6 +++-- tool/jwt.go | 47 +++++++++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 Middleware/jwt_middleware.go create mode 100644 models/jwt_claims.go create mode 100644 tool/jwt.go diff --git a/Middleware/jwt_middleware.go b/Middleware/jwt_middleware.go new file mode 100644 index 0000000..8456c80 --- /dev/null +++ b/Middleware/jwt_middleware.go @@ -0,0 +1,48 @@ +package Middleware + +import ( + "ddlBackend/tool" + "github.com/gin-gonic/gin" + "net/http" + "strings" + "time" +) + +// JWTAuthMiddleware JWT验证中间件 +func JWTAuthMiddleware() gin.HandlerFunc { + return func(context *gin.Context) { + // Authorization 的header由"Bearer " + token组成 + bearerLength := len("Bearer ") + + authHeader := context.GetHeader("Authorization") + + if len(authHeader) < bearerLength { + // 如果令牌的长度不够 + context.JSON(http.StatusUnauthorized, gin.H{ + "error": "The authorization header is incorrect", + }) + context.Abort() + return + } + + token := strings.TrimSpace(authHeader[bearerLength:]) + claims, err := tool.ParseJWTToken(token) + if err != nil { + // 解析令牌中遇到错误 + context.JSON(http.StatusUnauthorized, gin.H{ + "error": err.Error(), + }) + context.Abort() + } else if time.Now().Unix() > claims.ExpiresAt { + // 令牌过期 + context.JSON(http.StatusUnauthorized, gin.H{ + "error": "The token has been expired", + }) + context.Abort() + } else { + // 没有问题就把信息记录在context中 + context.Set("Claims", *claims) + } + return + } +} diff --git a/go.mod b/go.mod index c96f642..6da1942 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require github.com/gin-gonic/gin v1.8.1 require ( + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect diff --git a/go.sum b/go.sum index 5edf219..3196667 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= diff --git a/models/jwt_claims.go b/models/jwt_claims.go new file mode 100644 index 0000000..d6aa4e8 --- /dev/null +++ b/models/jwt_claims.go @@ -0,0 +1,11 @@ +package models + +import "github.com/dgrijalva/jwt-go" + +// JWTClaims JWT实体信息 +type JWTClaims struct { + Username string `json:"username"` + Classname string `json:"classname"` + Permission uint `json:"permission"` + jwt.StandardClaims +} diff --git a/tool/config.go b/tool/config.go index 060c355..060f62b 100644 --- a/tool/config.go +++ b/tool/config.go @@ -7,11 +7,13 @@ import ( ) type Config struct { - AppPort string `json:"app_port"` + AppPort string `json:"app_port"` + JWTSecret string `json:"jwt_secret"` } var DefaultSetting = Config{ - AppPort: ":8080", + AppPort: ":8080", + JWTSecret: "MakeBuptGreatAgain", } // Setting 配置文件对象 diff --git a/tool/jwt.go b/tool/jwt.go new file mode 100644 index 0000000..5f1b81c --- /dev/null +++ b/tool/jwt.go @@ -0,0 +1,47 @@ +package tool + +import ( + "ddlBackend/models" + "github.com/dgrijalva/jwt-go" + "time" +) + +// GenerateJWTToken 生成JWT令牌 +func GenerateJWTToken(info models.UserInformation) (string, error) { + // 设置token的有效时间为24小时 + expireTime := time.Now().Add(24 * time.Hour) + + // 设置token中的信息 + claims := models.JWTClaims{ + Username: info.Username, + Classname: info.Classname, + Permission: info.Permission, + StandardClaims: jwt.StandardClaims{ + // token失效时间 + ExpiresAt: expireTime.Unix(), + // token签发人 + Issuer: "SquidWard", + }, + } + + tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + return tokenClaims.SignedString(Setting.JWTSecret) +} + +// ParseJWTToken 解析令牌并返回其中的信息 +func ParseJWTToken(token string) (*models.JWTClaims, error) { + tokenClaims, err := jwt.ParseWithClaims(token, &models.JWTClaims{}, func(token *jwt.Token) (interface{}, error) { + return Setting.JWTSecret, nil + }) + + if tokenClaims != nil { + // 尝试判断令牌中的信息是否正确 + claims, ok := tokenClaims.Claims.(*models.JWTClaims) + // 如果信息正确且令牌有效 + if ok && tokenClaims.Valid { + return claims, nil + } + } + + return nil, err +} -- Gitee From fbafe8fb394360604a34789b95497c94f7a6911b Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 8 Aug 2022 18:03:09 +0800 Subject: [PATCH 10/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 8 ++++++++ models/user_information.go | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 models/user_information.go diff --git a/database/database.go b/database/database.go index 1e2d953..27c1576 100644 --- a/database/database.go +++ b/database/database.go @@ -31,6 +31,14 @@ func OpenDatabase() (err error) { } } + // 创建用户表 + if !Database.Migrator().HasTable(&models.UserInformation{}) { + err = Database.AutoMigrate(&models.UserInformation{}) + if err != nil { + return err + } + } + return nil } diff --git a/models/user_information.go b/models/user_information.go new file mode 100644 index 0000000..5d2a0e8 --- /dev/null +++ b/models/user_information.go @@ -0,0 +1,17 @@ +package models + +// UserInformation 用户信息模型 +type UserInformation struct { + // ID 数据库用户编号 + ID uint `gorm:"primaryKey" json:"id"` + // Username 用户名 + Username string `json:"username"` + // Password 用户密码 + Password string `json:"password"` + // Classname 所在班级 + Classname string `json:"classname"` + // StudentID 学号 + StudentID string `json:"student_id"` + // Permission 权限 + Permission uint `json:"permission"` +} -- Gitee From c31cb56c1b810ebbfb887efd6009585d4f852207 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 8 Aug 2022 20:38:08 +0800 Subject: [PATCH 11/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E8=AF=B7=E6=B1=82=E5=A4=84=E7=90=86=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/user_handlers.go | 143 ++++++++++++++++++++++++++++++++++++++ main.go | 6 ++ 2 files changed, 149 insertions(+) create mode 100644 handlers/user_handlers.go diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go new file mode 100644 index 0000000..54088fd --- /dev/null +++ b/handlers/user_handlers.go @@ -0,0 +1,143 @@ +package handlers + +import ( + "ddlBackend/database" + "ddlBackend/models" + "ddlBackend/tool" + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "strconv" +) + +// ReadUsersHandler 读取所有用户信息的处理函数 +func ReadUsersHandler(context *gin.Context) { + var users []models.UserInformation + + result := database.Database.Table("user_informations").Find(&users) + if result.Error != nil { + // 如果读取中出错 + tool.DDLLog(result.Error.Error()) + context.JSON(http.StatusInternalServerError, gin.H{ + "error": result.Error.Error(), + }) + return + } + + context.JSON(http.StatusOK, users) + return +} + +// ReadSingleUserHandler 读取单个用户信息处理函数 +func ReadSingleUserHandler(context *gin.Context) { + var user models.UserInformation + id := context.Param("id") + idNum, err := strconv.Atoi(id) + if err != nil { + // url中参数读取出错 + tool.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + } + + result := database.Database.Table("user_informations").First(&user, idNum) + if result.Error != nil { + // 没找到 + tool.DDLLog(result.Error.Error()) + context.JSON(http.StatusNotFound, gin.H{ + "error": result.Error.Error(), + }) + return + } + + context.JSON(http.StatusOK, user) + return +} + +// CreateUserHandler 创建用户处理函数 +func CreateUserHandler(context *gin.Context) { + var user models.UserInformation + err := context.ShouldBindJSON(&user) + if err != nil { + // 绑定json对象出错 + tool.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + result := database.Database.Table("user_informations").Create(&user) + if result.Error != nil { + tool.DDLLog(result.Error.Error()) + context.JSON(http.StatusInternalServerError, gin.H{ + "error": result.Error.Error(), + }) + return + } + + context.JSON(http.StatusCreated, user) + return +} + +// UpdateUserHandler 更新用户信息 +func UpdateUserHandler(context *gin.Context) { + id := context.Param("id") + idNum, err := strconv.Atoi(id) + if err != nil { + tool.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var user models.UserInformation + err = context.ShouldBindJSON(&user) + if err != nil { + tool.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + if user.ID != uint(idNum) { + // 请求体和url参数不匹配 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": fmt.Sprintf("the id %d in the url and %d in the body are not the same", user.ID, idNum), + }) + return + } + + database.Database.Table("user_informations").Save(&user) + context.JSON(http.StatusNoContent, gin.H{}) + return +} + +func DeleteUserHandler(context *gin.Context) { + id := context.Param("id") + idNum, err := strconv.Atoi(id) + if err != nil { + tool.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + var user models.UserInformation + result := database.Database.Table("user_informations").First(&user, idNum) + if result.Error != nil { + tool.DDLLog(result.Error.Error()) + context.JSON(http.StatusNotFound, gin.H{ + "error": result.Error.Error(), + }) + return + } + + database.Database.Table("user_informations").Delete(&user) + context.JSON(http.StatusNoContent, gin.H{}) + return +} diff --git a/main.go b/main.go index 38bf528..17e22ce 100644 --- a/main.go +++ b/main.go @@ -34,6 +34,12 @@ func main() { route.PUT("/ddlNotices/:class/:id", handlers.UpdateClassIDDDLHandler) route.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) + route.GET("/users", handlers.ReadUsersHandler) + route.POST("/users", handlers.CreateUserHandler) + route.GET("/users/:id", handlers.ReadSingleUserHandler) + route.PUT("/users/:id", handlers.UpdateUserHandler) + route.DELETE("/users/:id", handlers.DeleteUserHandler) + err = route.Run(tool.Setting.AppPort) if err != nil { tool.DDLLog(err.Error()) -- Gitee From 6572f88657476bf515448aa0c795d34769717de3 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 9 Aug 2022 11:23:37 +0800 Subject: [PATCH 12/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E7=99=BB=E5=BD=95API=20=E6=B7=BB=E5=8A=A0=E4=BA=86?= =?UTF-8?q?=E9=89=B4=E6=9D=83=E7=9B=B8=E5=85=B3=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/user_handlers.go | 125 ++++++++++++++++++++++++++++++++++++- main.go | 13 ++-- models/user_information.go | 6 ++ models/user_permission.go | 10 +++ tool/jwt.go | 32 ++++++++++ 5 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 models/user_permission.go diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index 54088fd..d550475 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -12,6 +12,23 @@ import ( // ReadUsersHandler 读取所有用户信息的处理函数 func ReadUsersHandler(context *gin.Context) { + ok, err := tool.CheckPermission(context, models.Root) + if err != nil { + // 验证权限过程中出错 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + // 权限不够 + // 返回 401 未授权 + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + var users []models.UserInformation result := database.Database.Table("user_informations").Find(&users) @@ -30,6 +47,23 @@ func ReadUsersHandler(context *gin.Context) { // ReadSingleUserHandler 读取单个用户信息处理函数 func ReadSingleUserHandler(context *gin.Context) { + ok, err := tool.CheckPermission(context, models.Root) + if err != nil { + // 验证权限过程中出错 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + // 权限不够 + // 返回 401 未授权 + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + var user models.UserInformation id := context.Param("id") idNum, err := strconv.Atoi(id) @@ -57,8 +91,25 @@ func ReadSingleUserHandler(context *gin.Context) { // CreateUserHandler 创建用户处理函数 func CreateUserHandler(context *gin.Context) { + ok, err := tool.CheckPermission(context, models.Root) + if err != nil { + // 验证权限过程中出错 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + // 权限不够 + // 返回 401 未授权 + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + var user models.UserInformation - err := context.ShouldBindJSON(&user) + err = context.ShouldBindJSON(&user) if err != nil { // 绑定json对象出错 tool.DDLLog(err.Error()) @@ -83,6 +134,23 @@ func CreateUserHandler(context *gin.Context) { // UpdateUserHandler 更新用户信息 func UpdateUserHandler(context *gin.Context) { + ok, err := tool.CheckPermission(context, models.Root) + if err != nil { + // 验证权限过程中出错 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + // 权限不够 + // 返回 401 未授权 + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + id := context.Param("id") idNum, err := strconv.Atoi(id) if err != nil { @@ -116,7 +184,25 @@ func UpdateUserHandler(context *gin.Context) { return } +// DeleteUserHandler 删除用户信息处理函数 func DeleteUserHandler(context *gin.Context) { + ok, err := tool.CheckPermission(context, models.Root) + if err != nil { + // 验证权限过程中出错 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + // 权限不够 + // 返回 401 未授权 + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + id := context.Param("id") idNum, err := strconv.Atoi(id) if err != nil { @@ -141,3 +227,40 @@ func DeleteUserHandler(context *gin.Context) { context.JSON(http.StatusNoContent, gin.H{}) return } + +// AdminLoginHandler 管理员登录处理函数 +func AdminLoginHandler(context *gin.Context) { + var loginModel models.AdminLoginModel + + err := context.ShouldBindJSON(&loginModel) + if err != nil { + // 绑定JSON出错 + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + } + + var user models.UserInformation + result := database.Database.Table("user_informations").Where("username = ? AND password = ?", loginModel.Username, loginModel.Password).First(&user) + if result.Error != nil { + // 数据库中查无此人 + context.JSON(http.StatusBadRequest, gin.H{ + "error": result.Error.Error(), + }) + return + } + + token, err := tool.GenerateJWTToken(user) + if err != nil { + // 产生JWT令牌中错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + context.JSON(http.StatusOK, gin.H{ + "token": token, + }) + return +} diff --git a/main.go b/main.go index 17e22ce..50211d0 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "ddlBackend/Middleware" "ddlBackend/database" "ddlBackend/handlers" "ddlBackend/tool" @@ -34,11 +35,13 @@ func main() { route.PUT("/ddlNotices/:class/:id", handlers.UpdateClassIDDDLHandler) route.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) - route.GET("/users", handlers.ReadUsersHandler) - route.POST("/users", handlers.CreateUserHandler) - route.GET("/users/:id", handlers.ReadSingleUserHandler) - route.PUT("/users/:id", handlers.UpdateUserHandler) - route.DELETE("/users/:id", handlers.DeleteUserHandler) + // 用户管理相关API需要验证 + route.GET("/users", handlers.ReadUsersHandler).Use(Middleware.JWTAuthMiddleware()) + route.POST("/users", handlers.CreateUserHandler).Use(Middleware.JWTAuthMiddleware()) + route.GET("/users/:id", handlers.ReadSingleUserHandler).Use(Middleware.JWTAuthMiddleware()) + route.PUT("/users/:id", handlers.UpdateUserHandler).Use(Middleware.JWTAuthMiddleware()) + route.DELETE("/users/:id", handlers.DeleteUserHandler).Use(Middleware.JWTAuthMiddleware()) + route.POST("/users/login", handlers.AdminLoginHandler) err = route.Run(tool.Setting.AppPort) if err != nil { diff --git a/models/user_information.go b/models/user_information.go index 5d2a0e8..b3a2682 100644 --- a/models/user_information.go +++ b/models/user_information.go @@ -15,3 +15,9 @@ type UserInformation struct { // Permission 权限 Permission uint `json:"permission"` } + +// AdminLoginModel 管理员登录JSON模型 +type AdminLoginModel struct { + Username string `json:"username"` + Password string `json:"password"` +} diff --git a/models/user_permission.go b/models/user_permission.go new file mode 100644 index 0000000..052c58c --- /dev/null +++ b/models/user_permission.go @@ -0,0 +1,10 @@ +package models + +const ( + // User 用户 只可读取信息 + User = iota + // Administrator 管理员 可控制小班的内容 + Administrator + // Root 根管理员 可控制所有的内容 + Root +) diff --git a/tool/jwt.go b/tool/jwt.go index 5f1b81c..4e593dc 100644 --- a/tool/jwt.go +++ b/tool/jwt.go @@ -2,7 +2,9 @@ package tool import ( "ddlBackend/models" + "errors" "github.com/dgrijalva/jwt-go" + "github.com/gin-gonic/gin" "time" ) @@ -45,3 +47,33 @@ func ParseJWTToken(token string) (*models.JWTClaims, error) { return nil, err } + +// GetClaimsInContext 获得HTTP上下文中的JWT令牌信息 +func GetClaimsInContext(context *gin.Context) (*models.JWTClaims, error) { + value, exist := context.Get("Claims") + if !exist { + // 没有找到令牌信息 + return nil, errors.New("no JWT claims") + } + + claims, ok := value.(models.JWTClaims) + if !ok { + return nil, errors.New("can not read claims") + } + + return &claims, nil +} + +// CheckPermission 验证请求者的权限 +func CheckPermission(context *gin.Context, permission uint) (bool, error) { + claims, err := GetClaimsInContext(context) + if err != nil { + return false, err + } + + if claims.Permission >= permission { + return true, nil + } else { + return false, nil + } +} -- Gitee From 27db6e7b30ccb6a63656cfda8893ed0bc34d9026 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 9 Aug 2022 14:04:35 +0800 Subject: [PATCH 13/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E4=BB=8E?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E5=88=9B=E5=BB=BA=E6=A0=B9?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E7=9A=84=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 11 +++++++++++ tool/config.go | 22 ++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/database/database.go b/database/database.go index 27c1576..ee35e31 100644 --- a/database/database.go +++ b/database/database.go @@ -51,3 +51,14 @@ func GetDDLTable(className string) (*gorm.DB, error) { } return nil, errors.New(fmt.Sprintf("The table named %s not exists", className)) } + +// AdminLogin 管理员登录验证函数 +func AdminLogin(username string, password string) (*models.UserInformation, error) { + var user models.UserInformation + result := Database.Table("user_informations").Where("username = ? AND password = ?", username, password).First(&user) + if result.Error != nil { + return nil, result.Error + } + + return &user, nil +} diff --git a/tool/config.go b/tool/config.go index 060f62b..1a42835 100644 --- a/tool/config.go +++ b/tool/config.go @@ -2,18 +2,29 @@ package tool import ( "bufio" + "ddlBackend/database" + "ddlBackend/models" "encoding/json" "os" ) type Config struct { - AppPort string `json:"app_port"` - JWTSecret string `json:"jwt_secret"` + AppPort string `json:"app_port"` + JWTSecret string `json:"jwt_secret"` + RootConfig models.UserInformation `json:"root_config"` } +// DefaultSetting 默认配置文件 var DefaultSetting = Config{ AppPort: ":8080", JWTSecret: "MakeBuptGreatAgain", + RootConfig: models.UserInformation{ + Username: "root", + Password: "123456", + Classname: "dddd", + StudentID: "0000000000", + Permission: models.Root, + }, } // Setting 配置文件对象 @@ -48,5 +59,12 @@ func ReadConfig() error { return err } + // 将配置文件中指定的Root管理员存入数据库 + _, err = database.AdminLogin(Setting.RootConfig.Username, Setting.RootConfig.Password) + if err != nil { + // 如果登录失败 说明数据库中没有该Root用户 则添加 + database.Database.Table("user_informations").Create(&Setting.RootConfig) + } + return nil } -- Gitee From e16179cecd66d91f0929349cccb34efda3ee580a Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 9 Aug 2022 16:22:20 +0800 Subject: [PATCH 14/41] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=9B=B8=E5=85=B3API?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 8 ++++++++ main.go | 17 +++++++++++------ tool/config.go | 8 -------- tool/jwt.go | 4 ++-- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/database/database.go b/database/database.go index ee35e31..77a0fde 100644 --- a/database/database.go +++ b/database/database.go @@ -2,6 +2,7 @@ package database import ( "ddlBackend/models" + "ddlBackend/tool" "errors" "fmt" "gorm.io/driver/sqlite" @@ -39,6 +40,13 @@ func OpenDatabase() (err error) { } } + // 将配置文件中设置的根管理员存入数据库 + _, err = AdminLogin(tool.Setting.RootConfig.Username, tool.Setting.RootConfig.Password) + if err != nil { + // 引发没有找到的错误 + Database.Table("user_informations").Create(&tool.Setting.RootConfig) + } + return nil } diff --git a/main.go b/main.go index 50211d0..7fb4eea 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,8 @@ func main() { route := gin.Default() + route.POST("/login", handlers.AdminLoginHandler) + route.GET("/ddlNotices", handlers.ReadDDLHandler) route.POST("/ddlNotices", handlers.CreateDDLHandler) @@ -36,12 +38,15 @@ func main() { route.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) // 用户管理相关API需要验证 - route.GET("/users", handlers.ReadUsersHandler).Use(Middleware.JWTAuthMiddleware()) - route.POST("/users", handlers.CreateUserHandler).Use(Middleware.JWTAuthMiddleware()) - route.GET("/users/:id", handlers.ReadSingleUserHandler).Use(Middleware.JWTAuthMiddleware()) - route.PUT("/users/:id", handlers.UpdateUserHandler).Use(Middleware.JWTAuthMiddleware()) - route.DELETE("/users/:id", handlers.DeleteUserHandler).Use(Middleware.JWTAuthMiddleware()) - route.POST("/users/login", handlers.AdminLoginHandler) + userRoute := route.Group("/users") + userRoute.Use(Middleware.JWTAuthMiddleware()) + { + userRoute.GET("/", handlers.ReadUsersHandler) + userRoute.POST("/", handlers.CreateUserHandler) + userRoute.GET("/:id", handlers.ReadSingleUserHandler) + userRoute.PUT("/:id", handlers.UpdateUserHandler) + userRoute.DELETE("/:id", handlers.DeleteUserHandler) + } err = route.Run(tool.Setting.AppPort) if err != nil { diff --git a/tool/config.go b/tool/config.go index 1a42835..d89f0ad 100644 --- a/tool/config.go +++ b/tool/config.go @@ -2,7 +2,6 @@ package tool import ( "bufio" - "ddlBackend/database" "ddlBackend/models" "encoding/json" "os" @@ -59,12 +58,5 @@ func ReadConfig() error { return err } - // 将配置文件中指定的Root管理员存入数据库 - _, err = database.AdminLogin(Setting.RootConfig.Username, Setting.RootConfig.Password) - if err != nil { - // 如果登录失败 说明数据库中没有该Root用户 则添加 - database.Database.Table("user_informations").Create(&Setting.RootConfig) - } - return nil } diff --git a/tool/jwt.go b/tool/jwt.go index 4e593dc..70341c2 100644 --- a/tool/jwt.go +++ b/tool/jwt.go @@ -27,13 +27,13 @@ func GenerateJWTToken(info models.UserInformation) (string, error) { } tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - return tokenClaims.SignedString(Setting.JWTSecret) + return tokenClaims.SignedString([]byte(Setting.JWTSecret)) } // ParseJWTToken 解析令牌并返回其中的信息 func ParseJWTToken(token string) (*models.JWTClaims, error) { tokenClaims, err := jwt.ParseWithClaims(token, &models.JWTClaims{}, func(token *jwt.Token) (interface{}, error) { - return Setting.JWTSecret, nil + return []byte(Setting.JWTSecret), nil }) if tokenClaims != nil { -- Gitee From c859e89464f6264751477436f1cc5ae717a1f99d Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 9 Aug 2022 18:22:37 +0800 Subject: [PATCH 15/41] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BF=AE=E6=94=B9DDL?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=88=97=E8=A1=A8API=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=BA=AB=E4=BB=BD=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 32 +++++++++++++++++++++++++- handlers/ddl_class_id_handlers.go | 38 +++++++++++++++++++++++++++---- handlers/ddl_handlers.go | 19 +++++++++++++++- main.go | 18 +++++++++------ 4 files changed, 93 insertions(+), 14 deletions(-) diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index d265677..dc023fc 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -14,8 +14,23 @@ import ( func CreateClassDDLHandler(context *gin.Context) { className := context.Param("class") + ok, err := checkClassAdminPermission(context, className) + if err != nil { + // 解析令牌和验证权限中遇到问题 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + var ddlNotice models.DDLNotice - err := context.ShouldBindJSON(&ddlNotice) + err = context.ShouldBindJSON(&ddlNotice) if err != nil { // 请求体绑定失败 // 返回 400 错误请求 @@ -102,3 +117,18 @@ func ReadClassDDLHandler(context *gin.Context) { context.JSON(http.StatusOK, ddlNotices) return } + +// checkClassAdminPermission 检查当前请求令牌的持有者是否有权限修改当前班级的内容 +func checkClassAdminPermission(context *gin.Context, classname string) (bool, error) { + claims, err := tool.GetClaimsInContext(context) + + if err != nil { + return false, err + } + + if claims.Classname == classname && claims.Permission >= models.Administrator { + return true, nil + } else { + return false, nil + } +} diff --git a/handlers/ddl_class_id_handlers.go b/handlers/ddl_class_id_handlers.go index 7800e25..437a1f7 100644 --- a/handlers/ddl_class_id_handlers.go +++ b/handlers/ddl_class_id_handlers.go @@ -41,7 +41,7 @@ func ReadClassIDDDLHandler(context *gin.Context) { } var ddlNotice models.DDLNotice - result := db.Where("id = ?", idNum).Find(&ddlNotice) + result := db.First(&ddlNotice, idNum) if result.Error != nil { context.JSON(http.StatusNotFound, gin.H{ "error": result.Error.Error(), @@ -56,8 +56,22 @@ func UpdateClassIDDDLHandler(context *gin.Context) { className := context.Param("class") id := context.Param("id") + ok, err := checkClassAdminPermission(context, className) + if err != nil { + // 解析令牌和验证权限中遇到问题 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + var db *gorm.DB - var err error db, err = database.GetDDLTable(className) if err != nil { // 获取指定班级的数据库失败 @@ -82,7 +96,7 @@ func UpdateClassIDDDLHandler(context *gin.Context) { } var ddlNotice models.DDLNotice - result := db.Where("id = ?", idNum).Find(&ddlNotice) + result := db.First(&ddlNotice, idNum) if result.Error != nil { // 读取指定的事件失败 @@ -122,8 +136,22 @@ func DeleteClassIDDDLHandler(context *gin.Context) { className := context.Param("class") id := context.Param("id") + ok, err := checkClassAdminPermission(context, className) + if err != nil { + // 解析令牌和验证权限中遇到问题 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + var db *gorm.DB - var err error db, err = database.GetDDLTable(className) if err != nil { // 获取指定班级的数据库失败 @@ -148,7 +176,7 @@ func DeleteClassIDDDLHandler(context *gin.Context) { } var ddlNotice models.DDLNotice - result := db.Where("id = ?", idNum).Find(&ddlNotice) + result := db.First(&ddlNotice, idNum) if result.Error != nil { // 读取指定的事件失败 diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go index d85b229..a7fbd81 100644 --- a/handlers/ddl_handlers.go +++ b/handlers/ddl_handlers.go @@ -12,9 +12,26 @@ import ( // CreateDDLHandler 创建DDL事件处理函数 func CreateDDLHandler(context *gin.Context) { + ok, err := tool.CheckPermission(context, models.Root) + if err != nil { + // 验证身份中出错 + // 返回 500 服务器错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + // 验证未通过 + // 返回 401 未授权错误 + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + var ddlNotice models.DDLNotice - err := context.ShouldBindJSON(&ddlNotice) + err = context.ShouldBindJSON(&ddlNotice) if err != nil { // 绑定json数据失败 // 返回 400 错误请求 diff --git a/main.go b/main.go index 7fb4eea..5c0d760 100644 --- a/main.go +++ b/main.go @@ -25,17 +25,21 @@ func main() { route := gin.Default() + // 登录 route.POST("/login", handlers.AdminLoginHandler) - + // 获取DDL事件列表 route.GET("/ddlNotices", handlers.ReadDDLHandler) - route.POST("/ddlNotices", handlers.CreateDDLHandler) - route.GET("/ddlNotices/:class", handlers.ReadClassDDLHandler) - route.POST("/ddlNotices/:class", handlers.CreateClassDDLHandler) - route.GET("/ddlNotices/:class/:id", handlers.ReadClassIDDDLHandler) - route.PUT("/ddlNotices/:class/:id", handlers.UpdateClassIDDDLHandler) - route.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) + + ddlNoticesRoute := route.Group("") + ddlNoticesRoute.Use(Middleware.JWTAuthMiddleware()) + { + ddlNoticesRoute.POST("/ddlNotices", handlers.CreateDDLHandler) + ddlNoticesRoute.POST("/ddlNotices/:class", handlers.CreateClassDDLHandler) + ddlNoticesRoute.PUT("/ddlNotices/:class/:id", handlers.UpdateClassIDDDLHandler) + ddlNoticesRoute.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) + } // 用户管理相关API需要验证 userRoute := route.Group("/users") -- Gitee From ba5aa70e9f90fc1c840072ce1b50bf9dceb05cf2 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Wed, 10 Aug 2022 16:36:51 +0800 Subject: [PATCH 16/41] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BA=86=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E6=96=87=E4=BB=B6=E5=92=8C=E4=B8=8B=E8=BD=BD=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=A4=84=E7=90=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 ++- go.mod | 1 + go.sum | 2 ++ handlers/picture_handlers.go | 69 ++++++++++++++++++++++++++++++++++++ main.go | 11 ++++++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 handlers/picture_handlers.go diff --git a/.gitignore b/.gitignore index 6e61bdf..45e5d17 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,7 @@ ddlBackend *.db # Setting File -config.json \ No newline at end of file +config.json + +# Pictures Directory +picture/ \ No newline at end of file diff --git a/go.mod b/go.mod index 6da1942..2b5e7e5 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/satori/go.uuid v1.2.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect diff --git a/go.sum b/go.sum index 3196667..bbecd6f 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/handlers/picture_handlers.go b/handlers/picture_handlers.go new file mode 100644 index 0000000..a727621 --- /dev/null +++ b/handlers/picture_handlers.go @@ -0,0 +1,69 @@ +package handlers + +import ( + "ddlBackend/models" + "ddlBackend/tool" + "github.com/gin-gonic/gin" + "github.com/satori/go.uuid" + "net/http" + "regexp" + "strings" +) + +// UploadPictureHandler 上传文件处理函数 +func UploadPictureHandler(context *gin.Context) { + ok, err := tool.CheckPermission(context, models.Administrator) + + if err != nil { + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + if !ok { + context.JSON(http.StatusUnauthorized, gin.H{}) + return + } + + file, err := context.FormFile("picture") + + if err != nil { + tool.DDLLog(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + // 利用正则表达式判断文件名是否符合规则 + pattern, _ := regexp.Compile("^.*\\.((png)|(jpg))$") + if !pattern.MatchString(file.Filename) { + context.JSON(http.StatusBadRequest, gin.H{ + "error": "Only png and jpg picture allowed", + }) + return + } + + // 获得图片的后缀名 + fileNames := strings.Split(file.Filename, ".") + fileEndName := fileNames[len(fileNames)-1] + + // 利用uuid生成图片文件的新名称 + fileName := "./picture/" + uuid.NewV4().String() + "." + fileEndName + err = context.SaveUploadedFile(file, fileName) + if err != nil { + tool.DDLLog(err.Error()) + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + context.JSON(http.StatusCreated, gin.H{ + // 这里只取文件名称第一位之后的值 + // 第一位是. 是没有必要的 + "address": fileName[1:], + }) + return +} diff --git a/main.go b/main.go index 5c0d760..95720d4 100644 --- a/main.go +++ b/main.go @@ -32,6 +32,10 @@ func main() { route.GET("/ddlNotices/:class", handlers.ReadClassDDLHandler) route.GET("/ddlNotices/:class/:id", handlers.ReadClassIDDDLHandler) + // 图片文件路径 + route.Static("/picture", "./picture") + + // 修改DDL事件列表需要身份验证 ddlNoticesRoute := route.Group("") ddlNoticesRoute.Use(Middleware.JWTAuthMiddleware()) { @@ -41,6 +45,13 @@ func main() { ddlNoticesRoute.DELETE("/ddlNotices/:class/:id", handlers.DeleteClassIDDDLHandler) } + // 其他需要身份验证的API + adminRoute := route.Group("") + adminRoute.Use(Middleware.JWTAuthMiddleware()) + { + adminRoute.POST("/upload", handlers.UploadPictureHandler) + } + // 用户管理相关API需要验证 userRoute := route.Group("/users") userRoute.Use(Middleware.JWTAuthMiddleware()) -- Gitee From ce6bab0154262a20a6f9f2dfdfcb12359ae08ee6 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Wed, 10 Aug 2022 16:47:34 +0800 Subject: [PATCH 17/41] =?UTF-8?q?=E5=8F=98=E6=9B=B4=E4=BA=86=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 10 +++++----- handlers/ddl_class_id_handlers.go | 14 +++++++------- handlers/ddl_handlers.go | 8 ++++---- handlers/picture_handlers.go | 4 ++-- handlers/user_handlers.go | 18 +++++++++--------- main.go | 8 ++++---- tool/config.go | 2 +- tool/log.go | 8 ++++---- 8 files changed, 36 insertions(+), 36 deletions(-) diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index dc023fc..91311d7 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -34,7 +34,7 @@ func CreateClassDDLHandler(context *gin.Context) { if err != nil { // 请求体绑定失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -55,7 +55,7 @@ func CreateClassDDLHandler(context *gin.Context) { if err != nil { // 无法获取对应班级的数据库 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -66,7 +66,7 @@ func CreateClassDDLHandler(context *gin.Context) { if result.Error != nil { // 在数据库中创建失败 // 返回 500 服务器错误 - tool.DDLLog(result.Error.Error()) + tool.DDLLogError(result.Error.Error()) context.JSON(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), }) @@ -93,7 +93,7 @@ func ReadClassDDLHandler(context *gin.Context) { if err != nil { // 请求参数转换失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -106,7 +106,7 @@ func ReadClassDDLHandler(context *gin.Context) { if err != nil { // 无法获取对应班级的数据库 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) diff --git a/handlers/ddl_class_id_handlers.go b/handlers/ddl_class_id_handlers.go index 437a1f7..a4ab481 100644 --- a/handlers/ddl_class_id_handlers.go +++ b/handlers/ddl_class_id_handlers.go @@ -21,7 +21,7 @@ func ReadClassIDDDLHandler(context *gin.Context) { if err != nil { // 获取指定班级的数据库失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -33,7 +33,7 @@ func ReadClassIDDDLHandler(context *gin.Context) { if err != nil { // 转换id字符串失败 // 返回 400 请求错误 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -76,7 +76,7 @@ func UpdateClassIDDDLHandler(context *gin.Context) { if err != nil { // 获取指定班级的数据库失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -88,7 +88,7 @@ func UpdateClassIDDDLHandler(context *gin.Context) { if err != nil { // 转换id字符串失败 // 返回 400 请求错误 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -111,7 +111,7 @@ func UpdateClassIDDDLHandler(context *gin.Context) { if err != nil { // 绑定请求体失败 // 返回 400 请求错误 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -156,7 +156,7 @@ func DeleteClassIDDDLHandler(context *gin.Context) { if err != nil { // 获取指定班级的数据库失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -168,7 +168,7 @@ func DeleteClassIDDDLHandler(context *gin.Context) { if err != nil { // 转换id字符串失败 // 返回 400 请求错误 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go index a7fbd81..022edf6 100644 --- a/handlers/ddl_handlers.go +++ b/handlers/ddl_handlers.go @@ -35,7 +35,7 @@ func CreateDDLHandler(context *gin.Context) { if err != nil { // 绑定json数据失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -47,7 +47,7 @@ func CreateDDLHandler(context *gin.Context) { if err != nil { // 获取对应班级数据库失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -58,7 +58,7 @@ func CreateDDLHandler(context *gin.Context) { if result.Error != nil { // 在数据库中创建失败 // 返回 500 服务器错误 - tool.DDLLog(result.Error.Error()) + tool.DDLLogError(result.Error.Error()) context.JSONP(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), }) @@ -83,7 +83,7 @@ func ReadDDLHandler(context *gin.Context) { if err != nil { // 请求参数转换失败 // 返回 400 错误请求 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) diff --git a/handlers/picture_handlers.go b/handlers/picture_handlers.go index a727621..55015df 100644 --- a/handlers/picture_handlers.go +++ b/handlers/picture_handlers.go @@ -29,7 +29,7 @@ func UploadPictureHandler(context *gin.Context) { file, err := context.FormFile("picture") if err != nil { - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -53,7 +53,7 @@ func UploadPictureHandler(context *gin.Context) { fileName := "./picture/" + uuid.NewV4().String() + "." + fileEndName err = context.SaveUploadedFile(file, fileName) if err != nil { - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusInternalServerError, gin.H{ "error": err.Error(), }) diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index d550475..edffa6b 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -34,7 +34,7 @@ func ReadUsersHandler(context *gin.Context) { result := database.Database.Table("user_informations").Find(&users) if result.Error != nil { // 如果读取中出错 - tool.DDLLog(result.Error.Error()) + tool.DDLLogError(result.Error.Error()) context.JSON(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), }) @@ -69,7 +69,7 @@ func ReadSingleUserHandler(context *gin.Context) { idNum, err := strconv.Atoi(id) if err != nil { // url中参数读取出错 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -78,7 +78,7 @@ func ReadSingleUserHandler(context *gin.Context) { result := database.Database.Table("user_informations").First(&user, idNum) if result.Error != nil { // 没找到 - tool.DDLLog(result.Error.Error()) + tool.DDLLogError(result.Error.Error()) context.JSON(http.StatusNotFound, gin.H{ "error": result.Error.Error(), }) @@ -112,7 +112,7 @@ func CreateUserHandler(context *gin.Context) { err = context.ShouldBindJSON(&user) if err != nil { // 绑定json对象出错 - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -121,7 +121,7 @@ func CreateUserHandler(context *gin.Context) { result := database.Database.Table("user_informations").Create(&user) if result.Error != nil { - tool.DDLLog(result.Error.Error()) + tool.DDLLogError(result.Error.Error()) context.JSON(http.StatusInternalServerError, gin.H{ "error": result.Error.Error(), }) @@ -154,7 +154,7 @@ func UpdateUserHandler(context *gin.Context) { id := context.Param("id") idNum, err := strconv.Atoi(id) if err != nil { - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -164,7 +164,7 @@ func UpdateUserHandler(context *gin.Context) { var user models.UserInformation err = context.ShouldBindJSON(&user) if err != nil { - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -206,7 +206,7 @@ func DeleteUserHandler(context *gin.Context) { id := context.Param("id") idNum, err := strconv.Atoi(id) if err != nil { - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) context.JSON(http.StatusBadRequest, gin.H{ "error": err.Error(), }) @@ -216,7 +216,7 @@ func DeleteUserHandler(context *gin.Context) { var user models.UserInformation result := database.Database.Table("user_informations").First(&user, idNum) if result.Error != nil { - tool.DDLLog(result.Error.Error()) + tool.DDLLogError(result.Error.Error()) context.JSON(http.StatusNotFound, gin.H{ "error": result.Error.Error(), }) diff --git a/main.go b/main.go index 95720d4..a2587d6 100644 --- a/main.go +++ b/main.go @@ -12,14 +12,14 @@ func main() { // 读取配置文件 err := tool.ReadConfig() if err != nil { - tool.DDLLog(err.Error()) - tool.DDLLog("Read config file failed, using default setting") + tool.DDLLogError(err.Error()) + tool.DDLLogError("Read config file failed, using default setting") } // 打开数据库 err = database.OpenDatabase() if err != nil { - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) return } @@ -65,7 +65,7 @@ func main() { err = route.Run(tool.Setting.AppPort) if err != nil { - tool.DDLLog(err.Error()) + tool.DDLLogError(err.Error()) return } } diff --git a/tool/config.go b/tool/config.go index d89f0ad..7cb2674 100644 --- a/tool/config.go +++ b/tool/config.go @@ -37,7 +37,7 @@ func ReadConfig() error { err := file.Close() if err != nil { // 关闭文件中错误 - DDLLog(err.Error()) + DDLLogError(err.Error()) } }(file) diff --git a/tool/log.go b/tool/log.go index 4ec0fa6..c1930da 100644 --- a/tool/log.go +++ b/tool/log.go @@ -5,8 +5,8 @@ import ( "time" ) -// DDLLog 日志记录函数 -func DDLLog(message string) { - now := time.Now() - fmt.Printf("%v %s\n", now, message) +// DDLLogError 记录错误日志 +func DDLLogError(message string) { + timeString := time.Now().Format("01-02 15:04:05") + fmt.Printf("%s DDL-Error: %s", timeString, message) } -- Gitee From d1a79deb15d6ad4e1361c1b394887699651a4424 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Thu, 11 Aug 2022 16:12:54 +0800 Subject: [PATCH 18/41] =?UTF-8?q?=E6=99=AE=E9=80=9A=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 17 ++++++++++-- handlers/user_handlers.go | 57 ++++++++++++++++++++++++++++++++++---- main.go | 1 + models/user_information.go | 10 +++++-- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/database/database.go b/database/database.go index 77a0fde..10c14a9 100644 --- a/database/database.go +++ b/database/database.go @@ -41,7 +41,7 @@ func OpenDatabase() (err error) { } // 将配置文件中设置的根管理员存入数据库 - _, err = AdminLogin(tool.Setting.RootConfig.Username, tool.Setting.RootConfig.Password) + _, err = AdminLogin(tool.Setting.RootConfig.StudentID, tool.Setting.RootConfig.Password) if err != nil { // 引发没有找到的错误 Database.Table("user_informations").Create(&tool.Setting.RootConfig) @@ -61,9 +61,20 @@ func GetDDLTable(className string) (*gorm.DB, error) { } // AdminLogin 管理员登录验证函数 -func AdminLogin(username string, password string) (*models.UserInformation, error) { +func AdminLogin(studentID string, password string) (*models.UserInformation, error) { var user models.UserInformation - result := Database.Table("user_informations").Where("username = ? AND password = ?", username, password).First(&user) + result := Database.Table("user_informations").Where("student_id = ? AND password = ?", studentID, password).First(&user) + if result.Error != nil { + return nil, result.Error + } + + return &user, nil +} + +// UserLogin 用户登录函数 +func UserLogin(username string, studentID string) (*models.UserInformation, error) { + var user models.UserInformation + result := Database.Table("user_informations").Where("username = ? AND student_id = ?", username, studentID).First(&user) if result.Error != nil { return nil, result.Error } diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index edffa6b..d5c0274 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -240,19 +240,64 @@ func AdminLoginHandler(context *gin.Context) { }) } - var user models.UserInformation - result := database.Database.Table("user_informations").Where("username = ? AND password = ?", loginModel.Username, loginModel.Password).First(&user) - if result.Error != nil { + user, err := database.AdminLogin(loginModel.StudentID, loginModel.Password) + if err != nil { + // 数据库中查无此用户 + context.JSON(http.StatusNotFound, gin.H{ + "error": err.Error(), + }) + return + } + + token, err := tool.GenerateJWTToken(*user) + if err != nil { + // 产生JWT令牌中错误 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + context.JSON(http.StatusOK, gin.H{ + "token": token, + }) + return +} + +// UserLoginHandler 用户登录处理函数 +func UserLoginHandler(context *gin.Context) { + var loginModel models.UserLoginModel + + err := context.ShouldBindJSON(&loginModel) + if err != nil { + // 绑定JSON出错 + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + user, err := database.UserLogin(loginModel.Username, loginModel.StudentID) + if err != nil { // 数据库中查无此人 + context.JSON(http.StatusNotFound, gin.H{ + "error": err.Error(), + }) + return + } + + // 如果该用户的权限大于普通用户 + // 则不能通过学号姓名验证的方式获得令牌 + if user.Permission > models.User { context.JSON(http.StatusBadRequest, gin.H{ - "error": result.Error.Error(), + "error": "该用户身份为管理员,请通过学号密码登录", }) return } - token, err := tool.GenerateJWTToken(user) + token, err := tool.GenerateJWTToken(*user) if err != nil { - // 产生JWT令牌中错误 + // 产生令牌出错 context.JSON(http.StatusInternalServerError, gin.H{ "error": err.Error(), }) diff --git a/main.go b/main.go index a2587d6..8604c2a 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,7 @@ func main() { // 登录 route.POST("/login", handlers.AdminLoginHandler) + route.POST("/auth", handlers.UserLoginHandler) // 获取DDL事件列表 route.GET("/ddlNotices", handlers.ReadDDLHandler) route.GET("/ddlNotices/:class", handlers.ReadClassDDLHandler) diff --git a/models/user_information.go b/models/user_information.go index b3a2682..6a2f38b 100644 --- a/models/user_information.go +++ b/models/user_information.go @@ -18,6 +18,12 @@ type UserInformation struct { // AdminLoginModel 管理员登录JSON模型 type AdminLoginModel struct { - Username string `json:"username"` - Password string `json:"password"` + StudentID string `json:"student_id"` + Password string `json:"password"` +} + +// UserLoginModel 用户登录JSON模型 +type UserLoginModel struct { + Username string `json:"username"` + StudentID string `json:"student_id"` } -- Gitee From 54491fe3b1dd748ef090c9eea650f387bb01adbb Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 12 Aug 2022 14:20:00 +0800 Subject: [PATCH 19/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=95=99=E5=8A=A1=E8=AF=BE=E8=A1=A8grpc=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- go.mod | 15 ++++-- go.sum | 113 +++++++++++++++++++++++++++++++++++++++++++++- protos/jwgl.proto | 36 +++++++++++++++ 4 files changed, 161 insertions(+), 8 deletions(-) create mode 100755 protos/jwgl.proto diff --git a/.gitignore b/.gitignore index 45e5d17..dc90e4a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ ddlBackend config.json # Pictures Directory -picture/ \ No newline at end of file +picture/ + +# Generated Files +*.pb.go \ No newline at end of file diff --git a/go.mod b/go.mod index 2b5e7e5..d9e1539 100644 --- a/go.mod +++ b/go.mod @@ -2,15 +2,22 @@ module ddlBackend go 1.18 -require github.com/gin-gonic/gin v1.8.1 +require ( + github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/gin-gonic/gin v1.8.1 + github.com/satori/go.uuid v1.2.0 + google.golang.org/grpc v1.48.0 + gorm.io/driver/sqlite v1.3.6 + gorm.io/gorm v1.23.8 +) require ( - github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/goccy/go-json v0.9.7 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -20,14 +27,12 @@ require ( github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect - github.com/satori/go.uuid v1.2.0 // indirect github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect golang.org/x/text v0.3.6 // indirect + google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gorm.io/driver/sqlite v1.3.6 // indirect - gorm.io/gorm v1.23.8 // indirect ) diff --git a/go.sum b/go.sum index bbecd6f..ed8c47c 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,29 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= @@ -18,10 +38,33 @@ github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -53,6 +96,8 @@ github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZO github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= @@ -60,6 +105,7 @@ 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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= @@ -67,23 +113,82 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +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.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -91,6 +196,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -101,3 +208,5 @@ gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMT gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE= gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/protos/jwgl.proto b/protos/jwgl.proto new file mode 100755 index 0000000..816400f --- /dev/null +++ b/protos/jwgl.proto @@ -0,0 +1,36 @@ +syntax = "proto3"; + +option csharp_namespace = "JwglServices"; +option go_package = ".;protos"; + +package jwgl; + +service Jwgler { + rpc GetSemester (GetSemesterRequest) returns (GetSemesterResponse); +} + +// 请求学期课表的信息 +message GetSemesterRequest { + string studentID = 1; + string password = 2; + string semester = 3; +} + +// 返回学期课表的信息 +message GetSemesterResponse { + repeated Course courses = 1; + bytes icsStream = 2; +} + +// 课程信息 +message Course { + string name = 1; + string teacher = 2; + string place = 3; + repeated int32 weeks = 4; + string beginTimeString = 5; + string endTimeString =6; + int32 dayOfWeek = 7; +} + + -- Gitee From 99b2185f53cf61b8f97105cfdb60f3474db03162 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 12 Aug 2022 16:12:31 +0800 Subject: [PATCH 20/41] =?UTF-8?q?grpc=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 8 ++++ handlers/jw_calendar_handler.go | 68 +++++++++++++++++++++++++++++++++ main.go | 2 + models/ics_infomation.go | 23 +++++++++++ 4 files changed, 101 insertions(+) create mode 100644 handlers/jw_calendar_handler.go create mode 100644 models/ics_infomation.go diff --git a/database/database.go b/database/database.go index 10c14a9..bd12471 100644 --- a/database/database.go +++ b/database/database.go @@ -40,6 +40,14 @@ func OpenDatabase() (err error) { } } + // 创建记录ICS信息表 + if !Database.Migrator().HasTable(&models.ICSInformation{}) { + err = Database.AutoMigrate(&models.ICSInformation{}) + if err != nil { + return err + } + } + // 将配置文件中设置的根管理员存入数据库 _, err = AdminLogin(tool.Setting.RootConfig.StudentID, tool.Setting.RootConfig.Password) if err != nil { diff --git a/handlers/jw_calendar_handler.go b/handlers/jw_calendar_handler.go new file mode 100644 index 0000000..ba53735 --- /dev/null +++ b/handlers/jw_calendar_handler.go @@ -0,0 +1,68 @@ +package handlers + +import ( + "context" + "ddlBackend/models" + "ddlBackend/protos" + "ddlBackend/tool" + "github.com/gin-gonic/gin" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "net/http" +) + +func GetSemesterCalendarHandler(context *gin.Context) { + var model models.GetSemesterCalendarModel + err := context.ShouldBindJSON(&model) + if err != nil { + // 绑定请求结构体出错 + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } + + courses, _, err := grpcGetSemester(model) + if err != nil { + tool.DDLLogError(err.Error()) + // RPC中出错 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + context.JSON(http.StatusOK, courses) + return +} + +// grpcGetSemester 远程过程调用获得课表的函数 +func grpcGetSemester(model models.GetSemesterCalendarModel) ([]*protos.Course, []byte, error) { + connection, err := grpc.Dial("localhost:7000", grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + return nil, nil, err + } + + defer func(connection *grpc.ClientConn) { + err := connection.Close() + if err != nil { + // 如果关闭连接失败 + tool.DDLLogError(err.Error()) + } + }(connection) + + client := protos.NewJwglerClient(connection) + + response, err := client.GetSemester(context.Background(), &protos.GetSemesterRequest{ + StudentID: model.StudentID, + Password: model.Password, + Semester: model.Semester, + }) + + if err != nil { + // 调用远程函数出错 + return nil, nil, err + } + + return response.Courses, response.IcsStream, nil +} diff --git a/main.go b/main.go index 8604c2a..f2c4ff3 100644 --- a/main.go +++ b/main.go @@ -33,6 +33,8 @@ func main() { route.GET("/ddlNotices/:class", handlers.ReadClassDDLHandler) route.GET("/ddlNotices/:class/:id", handlers.ReadClassIDDDLHandler) + route.POST("/GetSemester", handlers.GetSemesterCalendarHandler) + // 图片文件路径 route.Static("/picture", "./picture") diff --git a/models/ics_infomation.go b/models/ics_infomation.go new file mode 100644 index 0000000..3b1a0ff --- /dev/null +++ b/models/ics_infomation.go @@ -0,0 +1,23 @@ +package models + +import "time" + +// ICSInformation 存储获得ICS文件以及相关的信息 +type ICSInformation struct { + ID uint `gorm:"primaryKey"` + // StudentID 学号 + StudentID string + // Semester 该课表的所在学期 + Semester string + // ICSStream ICS文件字节流 + ICSStream []byte + // UpdatedAt 更新的时间 + UpdatedAt time.Time +} + +// GetSemesterCalendarModel 获得课表的请求体 +type GetSemesterCalendarModel struct { + StudentID string `json:"student_id"` + Password string `json:"password"` + Semester string `json:"semester"` +} -- Gitee From e6f2f7728fd4c7447991276753aab52b682c7e16 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 12 Aug 2022 17:00:59 +0800 Subject: [PATCH 21/41] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=AF=BE=E8=A1=A8?= =?UTF-8?q?=E3=80=81=E8=8E=B7=E5=8F=96ICS=E6=96=87=E4=BB=B6=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=87=BD=E6=95=B0=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 12 ++++++++ handlers/jw_calendar_handler.go | 49 +++++++++++++++++++++++++++++---- main.go | 3 ++ 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/database/database.go b/database/database.go index bd12471..59a6eff 100644 --- a/database/database.go +++ b/database/database.go @@ -89,3 +89,15 @@ func UserLogin(username string, studentID string) (*models.UserInformation, erro return &user, nil } + +// GetICSInformation 获得ICSInformation +func GetICSInformation(studentID string, semester string) (*models.ICSInformation, error) { + var info models.ICSInformation + result := Database.Table("ics_informations").Where("student_id = ? AND semester = ?", studentID, semester).Find(&info) + + if result.Error != nil { + return nil, result.Error + } + + return &info, nil +} diff --git a/handlers/jw_calendar_handler.go b/handlers/jw_calendar_handler.go index ba53735..6f08254 100644 --- a/handlers/jw_calendar_handler.go +++ b/handlers/jw_calendar_handler.go @@ -2,6 +2,7 @@ package handlers import ( "context" + "ddlBackend/database" "ddlBackend/models" "ddlBackend/protos" "ddlBackend/tool" @@ -22,17 +23,53 @@ func GetSemesterCalendarHandler(context *gin.Context) { return } - courses, _, err := grpcGetSemester(model) + _, err = database.GetICSInformation(model.StudentID, model.Semester) if err != nil { - tool.DDLLogError(err.Error()) - // RPC中出错 - context.JSON(http.StatusInternalServerError, gin.H{ - "error": err.Error(), + // 说明没有请求过 + courses, icsStream, err := grpcGetSemester(model) + if err != nil { + tool.DDLLogError(err.Error()) + // RPC中出错 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + // 在数据库创建这个记录 + newInformation := models.ICSInformation{ + StudentID: model.StudentID, + Semester: model.Semester, + ICSStream: icsStream, + } + database.Database.Table("user_informations").Create(&newInformation) + + context.JSON(http.StatusOK, courses) + return + } else { + context.JSON(http.StatusBadRequest, gin.H{ + "error": "最近才请求过,请稍后再试", + }) + return + } +} + +// GetICSFileHandler 返回ICS文件处理函数 +func GetICSFileHandler(context *gin.Context) { + studentID := context.Param("id") + semester := context.Param("semester") + // 去掉最后的.ics文件后缀 + semester = semester[:len(semester)-4] + + info, err := database.GetICSInformation(studentID, semester) + if err != nil { + context.JSON(http.StatusNotFound, gin.H{ + "error": "请先获得课表再尝试下载ICS日历文件", }) return } - context.JSON(http.StatusOK, courses) + context.Data(http.StatusOK, "text/calendar", info.ICSStream) return } diff --git a/main.go b/main.go index f2c4ff3..598ab26 100644 --- a/main.go +++ b/main.go @@ -28,12 +28,15 @@ func main() { // 登录 route.POST("/login", handlers.AdminLoginHandler) route.POST("/auth", handlers.UserLoginHandler) + // 获取DDL事件列表 route.GET("/ddlNotices", handlers.ReadDDLHandler) route.GET("/ddlNotices/:class", handlers.ReadClassDDLHandler) route.GET("/ddlNotices/:class/:id", handlers.ReadClassIDDDLHandler) + // 获得教务课表的相关API route.POST("/GetSemester", handlers.GetSemesterCalendarHandler) + route.GET("/Calendar/:id/:semester", handlers.GetICSFileHandler) // 图片文件路径 route.Static("/picture", "./picture") -- Gitee From 2f57bd17393b66b6f907b5c9d93e6c61ed2e7456 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 12 Aug 2022 17:24:34 +0800 Subject: [PATCH 22/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E7=9A=84=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4=20?= =?UTF-8?q?=E9=98=B2=E6=AD=A2=E8=BF=87=E4=BA=8E=E9=A2=91=E7=B9=81=E7=9A=84?= =?UTF-8?q?=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/jw_calendar_handler.go | 35 +++++++++++++++++++++++++++------ tool/config.go | 12 ++++++----- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/handlers/jw_calendar_handler.go b/handlers/jw_calendar_handler.go index 6f08254..e57f092 100644 --- a/handlers/jw_calendar_handler.go +++ b/handlers/jw_calendar_handler.go @@ -6,10 +6,12 @@ import ( "ddlBackend/models" "ddlBackend/protos" "ddlBackend/tool" + "fmt" "github.com/gin-gonic/gin" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "net/http" + "time" ) func GetSemesterCalendarHandler(context *gin.Context) { @@ -23,7 +25,7 @@ func GetSemesterCalendarHandler(context *gin.Context) { return } - _, err = database.GetICSInformation(model.StudentID, model.Semester) + info, err := database.GetICSInformation(model.StudentID, model.Semester) if err != nil { // 说明没有请求过 courses, icsStream, err := grpcGetSemester(model) @@ -42,15 +44,36 @@ func GetSemesterCalendarHandler(context *gin.Context) { Semester: model.Semester, ICSStream: icsStream, } - database.Database.Table("user_informations").Create(&newInformation) + database.Database.Table("ics_informations").Create(&newInformation) context.JSON(http.StatusOK, courses) return } else { - context.JSON(http.StatusBadRequest, gin.H{ - "error": "最近才请求过,请稍后再试", - }) - return + duration := time.Now().Sub(info.UpdatedAt) + // 如果上次请求到现在的时间小于超时时间 + if int64(duration) <= tool.Setting.JWGLOutTime*int64(time.Hour) { + targetTime := info.UpdatedAt.Add(time.Duration(tool.Setting.JWGLOutTime * int64(time.Hour))) + context.JSON(http.StatusBadRequest, gin.H{ + "error": fmt.Sprintf("Too frequent requests, please try after %s", targetTime.Format("06-01-02 15:04")), + }) + } else { + // 已经超过超时时间 + courses, icsStream, err := grpcGetSemester(model) + if err != nil { + tool.DDLLogError(err.Error()) + // RPC中出错 + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + info.ICSStream = icsStream + database.Database.Table("ics_informations").Save(info) + + context.JSON(http.StatusOK, courses) + return + } } } diff --git a/tool/config.go b/tool/config.go index 7cb2674..8843f64 100644 --- a/tool/config.go +++ b/tool/config.go @@ -8,15 +8,17 @@ import ( ) type Config struct { - AppPort string `json:"app_port"` - JWTSecret string `json:"jwt_secret"` - RootConfig models.UserInformation `json:"root_config"` + AppPort string `json:"app_port"` + JWTSecret string `json:"jwt_secret"` + JWGLOutTime int64 `json:"jwgl_out_time"` + RootConfig models.UserInformation `json:"root_config"` } // DefaultSetting 默认配置文件 var DefaultSetting = Config{ - AppPort: ":8080", - JWTSecret: "MakeBuptGreatAgain", + AppPort: ":8080", + JWTSecret: "MakeBuptGreatAgain", + JWGLOutTime: 24, RootConfig: models.UserInformation{ Username: "root", Password: "123456", -- Gitee From 1819f94e2657b5df09c70520729783e7fa53d831 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 13 Aug 2022 15:14:05 +0800 Subject: [PATCH 23/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=AF=B4?= =?UTF-8?q?=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- README.md | 98 +++++++++++ go.mod | 2 +- protos/jwgl.pb.go | 369 +++++++++++++++++++++++++++++++++++++++++ protos/jwgl_grpc.pb.go | 105 ++++++++++++ 5 files changed, 574 insertions(+), 5 deletions(-) create mode 100644 README.md create mode 100644 protos/jwgl.pb.go create mode 100644 protos/jwgl_grpc.pb.go diff --git a/.gitignore b/.gitignore index dc90e4a..45e5d17 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,4 @@ ddlBackend config.json # Pictures Directory -picture/ - -# Generated Files -*.pb.go \ No newline at end of file +picture/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5f5dcaa --- /dev/null +++ b/README.md @@ -0,0 +1,98 @@ +# DDLBackend + +## 特点 + +- RESTful风格的DDL管理API + +- JWT令牌身份认证 + +## 安装 + +> 采用go 1.18 构建 + +将仓库克隆到本地 + +```bash +git clone https://github.com/jackfiled/DDLBackend.git +``` + +切换进入软件目录,使用`go build`编译可执行程序,运行程序。 + +```bash +cd DDLBackend +go build +./DDLBackend + +... +[GIN-debug] Listening and serving HTTP on :8080 +``` + +看见最后一行输出服务器在8080端口上监听说明运行成功。 + +### 配置文件 + +程序采用`config.json`文件作为配置文件,该文件的模板如下 +```json +{ + // 服务器运行时执行的端口 + "app_port": ":4000", + // JWT签发密钥时使用的字符串 + "jwt_secret": "MakeBUPTGreatAgain", + // 请求教务系统API的超时时间 + "jwgl_out_time": 0, + // 根管理员的设置 + // 该管理员将在程序运行时自动创建 + "root_config": { + // 用户名 + "username": "root", + // 密码 + "password": "123456", + // 所属的班级 + "classname": "dddd", + // 学号 + "student_id": "0000000000", + // 权限 + // 0-User 用户 只能够查看信息而不能修改信息 + // 1-Admin 管理员 可以修改自己所在班级的信息 + // 2-Root 根管理员 可以修改所有的信息 + "permission": 2 + } +} +``` + +在根目录下不存在`config.json`配置文件的时候,程序会采用下述默认配置运行 + +```json +{ + // 服务器运行时执行的端口 + "app_port": ":8080", + // JWT签发密钥时使用的字符串 + "jwt_secret": "MakeBUPTGreatAgain", + // 请求教务系统API的超时时间 单位是小时 + "jwgl_out_time": 24, + // 根管理员的设置 + // 该管理员将在程序运行时自动创建 + "root_config": { + // 用户名 + "username": "root", + // 密码 + "password": "123456", + // 所属的班级 + "classname": "dddd", + // 学号 + "student_id": "0000000000", + // 权限 + // 0-User 用户 只能够查看信息而不能修改信息 + // 1-Admin 管理员 可以修改自己所在班级的信息 + // 2-Root 根管理员 可以修改所有的信息 + "permission": 2 + } +} +``` + +## API文档 + +使用[Apifox](https://www.apifox.cn/)产生的文档[链接](https://www.apifox.cn/apidoc/shared-5d0ad1be-c569-466d-9c59-3e4686b7e482/api-33104131) + + + diff --git a/go.mod b/go.mod index d9e1539..dd6fb8d 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/gin-gonic/gin v1.8.1 github.com/satori/go.uuid v1.2.0 google.golang.org/grpc v1.48.0 + google.golang.org/protobuf v1.28.0 gorm.io/driver/sqlite v1.3.6 gorm.io/gorm v1.23.8 ) @@ -33,6 +34,5 @@ require ( golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect golang.org/x/text v0.3.6 // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect - google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/protos/jwgl.pb.go b/protos/jwgl.pb.go new file mode 100644 index 0000000..217bce9 --- /dev/null +++ b/protos/jwgl.pb.go @@ -0,0 +1,369 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.6.1 +// source: protos/jwgl.proto + +package protos + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// 请求学期课表的信息 +type GetSemesterRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StudentID string `protobuf:"bytes,1,opt,name=studentID,proto3" json:"studentID,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Semester string `protobuf:"bytes,3,opt,name=semester,proto3" json:"semester,omitempty"` +} + +func (x *GetSemesterRequest) Reset() { + *x = GetSemesterRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_jwgl_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSemesterRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSemesterRequest) ProtoMessage() {} + +func (x *GetSemesterRequest) ProtoReflect() protoreflect.Message { + mi := &file_protos_jwgl_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSemesterRequest.ProtoReflect.Descriptor instead. +func (*GetSemesterRequest) Descriptor() ([]byte, []int) { + return file_protos_jwgl_proto_rawDescGZIP(), []int{0} +} + +func (x *GetSemesterRequest) GetStudentID() string { + if x != nil { + return x.StudentID + } + return "" +} + +func (x *GetSemesterRequest) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *GetSemesterRequest) GetSemester() string { + if x != nil { + return x.Semester + } + return "" +} + +// 返回学期课表的信息 +type GetSemesterResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Courses []*Course `protobuf:"bytes,1,rep,name=courses,proto3" json:"courses,omitempty"` + IcsStream []byte `protobuf:"bytes,2,opt,name=icsStream,proto3" json:"icsStream,omitempty"` +} + +func (x *GetSemesterResponse) Reset() { + *x = GetSemesterResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_jwgl_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetSemesterResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetSemesterResponse) ProtoMessage() {} + +func (x *GetSemesterResponse) ProtoReflect() protoreflect.Message { + mi := &file_protos_jwgl_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetSemesterResponse.ProtoReflect.Descriptor instead. +func (*GetSemesterResponse) Descriptor() ([]byte, []int) { + return file_protos_jwgl_proto_rawDescGZIP(), []int{1} +} + +func (x *GetSemesterResponse) GetCourses() []*Course { + if x != nil { + return x.Courses + } + return nil +} + +func (x *GetSemesterResponse) GetIcsStream() []byte { + if x != nil { + return x.IcsStream + } + return nil +} + +// 课程信息 +type Course struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Teacher string `protobuf:"bytes,2,opt,name=teacher,proto3" json:"teacher,omitempty"` + Place string `protobuf:"bytes,3,opt,name=place,proto3" json:"place,omitempty"` + Weeks []int32 `protobuf:"varint,4,rep,packed,name=weeks,proto3" json:"weeks,omitempty"` + BeginTimeString string `protobuf:"bytes,5,opt,name=beginTimeString,proto3" json:"beginTimeString,omitempty"` + EndTimeString string `protobuf:"bytes,6,opt,name=endTimeString,proto3" json:"endTimeString,omitempty"` + DayOfWeek int32 `protobuf:"varint,7,opt,name=dayOfWeek,proto3" json:"dayOfWeek,omitempty"` +} + +func (x *Course) Reset() { + *x = Course{} + if protoimpl.UnsafeEnabled { + mi := &file_protos_jwgl_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Course) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Course) ProtoMessage() {} + +func (x *Course) ProtoReflect() protoreflect.Message { + mi := &file_protos_jwgl_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Course.ProtoReflect.Descriptor instead. +func (*Course) Descriptor() ([]byte, []int) { + return file_protos_jwgl_proto_rawDescGZIP(), []int{2} +} + +func (x *Course) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Course) GetTeacher() string { + if x != nil { + return x.Teacher + } + return "" +} + +func (x *Course) GetPlace() string { + if x != nil { + return x.Place + } + return "" +} + +func (x *Course) GetWeeks() []int32 { + if x != nil { + return x.Weeks + } + return nil +} + +func (x *Course) GetBeginTimeString() string { + if x != nil { + return x.BeginTimeString + } + return "" +} + +func (x *Course) GetEndTimeString() string { + if x != nil { + return x.EndTimeString + } + return "" +} + +func (x *Course) GetDayOfWeek() int32 { + if x != nil { + return x.DayOfWeek + } + return 0 +} + +var File_protos_jwgl_proto protoreflect.FileDescriptor + +var file_protos_jwgl_proto_rawDesc = []byte{ + 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x6a, 0x77, 0x67, 0x6c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6a, 0x77, 0x67, 0x6c, 0x22, 0x6a, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x53, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x6d, + 0x65, 0x73, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x6d, + 0x65, 0x73, 0x74, 0x65, 0x72, 0x22, 0x5b, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x53, 0x65, 0x6d, 0x65, + 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x07, + 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, + 0x6a, 0x77, 0x67, 0x6c, 0x2e, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x75, + 0x72, 0x73, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x63, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x63, 0x73, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x22, 0xd0, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x65, 0x61, 0x63, 0x68, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x74, 0x65, 0x61, 0x63, 0x68, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x65, 0x65, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x05, + 0x52, 0x05, 0x77, 0x65, 0x65, 0x6b, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x62, 0x65, 0x67, 0x69, 0x6e, + 0x54, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x12, 0x24, 0x0a, 0x0d, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, + 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x61, 0x79, 0x4f, 0x66, + 0x57, 0x65, 0x65, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x61, 0x79, 0x4f, + 0x66, 0x57, 0x65, 0x65, 0x6b, 0x32, 0x4c, 0x0a, 0x06, 0x4a, 0x77, 0x67, 0x6c, 0x65, 0x72, 0x12, + 0x42, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x53, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x72, 0x12, 0x18, + 0x2e, 0x6a, 0x77, 0x67, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6a, 0x77, 0x67, 0x6c, 0x2e, + 0x47, 0x65, 0x74, 0x53, 0x65, 0x6d, 0x65, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x19, 0x5a, 0x08, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0xaa, + 0x02, 0x0c, 0x4a, 0x77, 0x67, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_protos_jwgl_proto_rawDescOnce sync.Once + file_protos_jwgl_proto_rawDescData = file_protos_jwgl_proto_rawDesc +) + +func file_protos_jwgl_proto_rawDescGZIP() []byte { + file_protos_jwgl_proto_rawDescOnce.Do(func() { + file_protos_jwgl_proto_rawDescData = protoimpl.X.CompressGZIP(file_protos_jwgl_proto_rawDescData) + }) + return file_protos_jwgl_proto_rawDescData +} + +var file_protos_jwgl_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_protos_jwgl_proto_goTypes = []interface{}{ + (*GetSemesterRequest)(nil), // 0: jwgl.GetSemesterRequest + (*GetSemesterResponse)(nil), // 1: jwgl.GetSemesterResponse + (*Course)(nil), // 2: jwgl.Course +} +var file_protos_jwgl_proto_depIdxs = []int32{ + 2, // 0: jwgl.GetSemesterResponse.courses:type_name -> jwgl.Course + 0, // 1: jwgl.Jwgler.GetSemester:input_type -> jwgl.GetSemesterRequest + 1, // 2: jwgl.Jwgler.GetSemester:output_type -> jwgl.GetSemesterResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_protos_jwgl_proto_init() } +func file_protos_jwgl_proto_init() { + if File_protos_jwgl_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_protos_jwgl_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSemesterRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protos_jwgl_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetSemesterResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protos_jwgl_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Course); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_protos_jwgl_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_protos_jwgl_proto_goTypes, + DependencyIndexes: file_protos_jwgl_proto_depIdxs, + MessageInfos: file_protos_jwgl_proto_msgTypes, + }.Build() + File_protos_jwgl_proto = out.File + file_protos_jwgl_proto_rawDesc = nil + file_protos_jwgl_proto_goTypes = nil + file_protos_jwgl_proto_depIdxs = nil +} diff --git a/protos/jwgl_grpc.pb.go b/protos/jwgl_grpc.pb.go new file mode 100644 index 0000000..c3bdd26 --- /dev/null +++ b/protos/jwgl_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.6.1 +// source: protos/jwgl.proto + +package protos + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// JwglerClient is the client API for Jwgler service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type JwglerClient interface { + GetSemester(ctx context.Context, in *GetSemesterRequest, opts ...grpc.CallOption) (*GetSemesterResponse, error) +} + +type jwglerClient struct { + cc grpc.ClientConnInterface +} + +func NewJwglerClient(cc grpc.ClientConnInterface) JwglerClient { + return &jwglerClient{cc} +} + +func (c *jwglerClient) GetSemester(ctx context.Context, in *GetSemesterRequest, opts ...grpc.CallOption) (*GetSemesterResponse, error) { + out := new(GetSemesterResponse) + err := c.cc.Invoke(ctx, "/jwgl.Jwgler/GetSemester", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// JwglerServer is the server API for Jwgler service. +// All implementations must embed UnimplementedJwglerServer +// for forward compatibility +type JwglerServer interface { + GetSemester(context.Context, *GetSemesterRequest) (*GetSemesterResponse, error) + mustEmbedUnimplementedJwglerServer() +} + +// UnimplementedJwglerServer must be embedded to have forward compatible implementations. +type UnimplementedJwglerServer struct { +} + +func (UnimplementedJwglerServer) GetSemester(context.Context, *GetSemesterRequest) (*GetSemesterResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSemester not implemented") +} +func (UnimplementedJwglerServer) mustEmbedUnimplementedJwglerServer() {} + +// UnsafeJwglerServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to JwglerServer will +// result in compilation errors. +type UnsafeJwglerServer interface { + mustEmbedUnimplementedJwglerServer() +} + +func RegisterJwglerServer(s grpc.ServiceRegistrar, srv JwglerServer) { + s.RegisterService(&Jwgler_ServiceDesc, srv) +} + +func _Jwgler_GetSemester_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSemesterRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(JwglerServer).GetSemester(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/jwgl.Jwgler/GetSemester", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(JwglerServer).GetSemester(ctx, req.(*GetSemesterRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Jwgler_ServiceDesc is the grpc.ServiceDesc for Jwgler service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Jwgler_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "jwgl.Jwgler", + HandlerType: (*JwglerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetSemester", + Handler: _Jwgler_GetSemester_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "protos/jwgl.proto", +} -- Gitee From 1b154e1889fb4c0b9aec21ebea0e385a23a0c9a4 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 13 Aug 2022 19:29:04 +0800 Subject: [PATCH 24/41] =?UTF-8?q?=E5=B0=86=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E7=9A=84=E5=90=AF=E5=8A=A8=E4=BA=A4=E7=BB=99endless=E6=8F=90?= =?UTF-8?q?=E4=BE=9B=E4=BB=A5=E6=94=AF=E6=8C=81=E5=90=AF=E5=8A=A8=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E9=87=8D=E5=90=AF=E7=AD=89=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 +-------------- go.mod | 1 + go.sum | 2 ++ main.go | 4 +++- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 5f5dcaa..ab29c0f 100644 --- a/README.md +++ b/README.md @@ -63,28 +63,15 @@ go build 在根目录下不存在`config.json`配置文件的时候,程序会采用下述默认配置运行 ```json -{ - // 服务器运行时执行的端口 +{ "app_port": ":8080", - // JWT签发密钥时使用的字符串 "jwt_secret": "MakeBUPTGreatAgain", - // 请求教务系统API的超时时间 单位是小时 "jwgl_out_time": 24, - // 根管理员的设置 - // 该管理员将在程序运行时自动创建 "root_config": { - // 用户名 "username": "root", - // 密码 "password": "123456", - // 所属的班级 "classname": "dddd", - // 学号 "student_id": "0000000000", - // 权限 - // 0-User 用户 只能够查看信息而不能修改信息 - // 1-Admin 管理员 可以修改自己所在班级的信息 - // 2-Root 根管理员 可以修改所有的信息 "permission": 2 } } diff --git a/go.mod b/go.mod index dd6fb8d..4c67c5a 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.18 require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 github.com/gin-gonic/gin v1.8.1 github.com/satori/go.uuid v1.2.0 google.golang.org/grpc v1.48.0 diff --git a/go.sum b/go.sum index ed8c47c..ae629c8 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc= +github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= diff --git a/main.go b/main.go index 598ab26..963b515 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,8 @@ import ( "ddlBackend/database" "ddlBackend/handlers" "ddlBackend/tool" + + "github.com/fvbock/endless" "github.com/gin-gonic/gin" ) @@ -69,7 +71,7 @@ func main() { userRoute.DELETE("/:id", handlers.DeleteUserHandler) } - err = route.Run(tool.Setting.AppPort) + err = endless.ListenAndServe(tool.Setting.AppPort, route) if err != nil { tool.DDLLogError(err.Error()) return -- Gitee From 5878ec88eee253fc5d1b9e3d073c983ecf88eca1 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 15 Aug 2022 17:04:47 +0800 Subject: [PATCH 25/41] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E9=83=A8?= =?UTF-8?q?=E5=88=86=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/picture_handlers.go | 8 ++++---- handlers/user_handlers.go | 12 +++--------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/handlers/picture_handlers.go b/handlers/picture_handlers.go index 55015df..f01ae80 100644 --- a/handlers/picture_handlers.go +++ b/handlers/picture_handlers.go @@ -3,11 +3,12 @@ package handlers import ( "ddlBackend/models" "ddlBackend/tool" - "github.com/gin-gonic/gin" - "github.com/satori/go.uuid" "net/http" "regexp" "strings" + + "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" ) // UploadPictureHandler 上传文件处理函数 @@ -37,7 +38,7 @@ func UploadPictureHandler(context *gin.Context) { } // 利用正则表达式判断文件名是否符合规则 - pattern, _ := regexp.Compile("^.*\\.((png)|(jpg))$") + pattern, _ := regexp.Compile(`^.*\\.((png)|(jpg))$`) if !pattern.MatchString(file.Filename) { context.JSON(http.StatusBadRequest, gin.H{ "error": "Only png and jpg picture allowed", @@ -65,5 +66,4 @@ func UploadPictureHandler(context *gin.Context) { // 第一位是. 是没有必要的 "address": fileName[1:], }) - return } diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index d5c0274..26bd494 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -5,9 +5,10 @@ import ( "ddlBackend/models" "ddlBackend/tool" "fmt" - "github.com/gin-gonic/gin" "net/http" "strconv" + + "github.com/gin-gonic/gin" ) // ReadUsersHandler 读取所有用户信息的处理函数 @@ -42,7 +43,6 @@ func ReadUsersHandler(context *gin.Context) { } context.JSON(http.StatusOK, users) - return } // ReadSingleUserHandler 读取单个用户信息处理函数 @@ -86,7 +86,6 @@ func ReadSingleUserHandler(context *gin.Context) { } context.JSON(http.StatusOK, user) - return } // CreateUserHandler 创建用户处理函数 @@ -129,7 +128,6 @@ func CreateUserHandler(context *gin.Context) { } context.JSON(http.StatusCreated, user) - return } // UpdateUserHandler 更新用户信息 @@ -174,14 +172,13 @@ func UpdateUserHandler(context *gin.Context) { if user.ID != uint(idNum) { // 请求体和url参数不匹配 context.JSON(http.StatusInternalServerError, gin.H{ - "error": fmt.Sprintf("the id %d in the url and %d in the body are not the same", user.ID, idNum), + "error": fmt.Sprintf("the id %d in the url and %d in the body are not the same", idNum, user.ID), }) return } database.Database.Table("user_informations").Save(&user) context.JSON(http.StatusNoContent, gin.H{}) - return } // DeleteUserHandler 删除用户信息处理函数 @@ -225,7 +222,6 @@ func DeleteUserHandler(context *gin.Context) { database.Database.Table("user_informations").Delete(&user) context.JSON(http.StatusNoContent, gin.H{}) - return } // AdminLoginHandler 管理员登录处理函数 @@ -261,7 +257,6 @@ func AdminLoginHandler(context *gin.Context) { context.JSON(http.StatusOK, gin.H{ "token": token, }) - return } // UserLoginHandler 用户登录处理函数 @@ -307,5 +302,4 @@ func UserLoginHandler(context *gin.Context) { context.JSON(http.StatusOK, gin.H{ "token": token, }) - return } -- Gitee From ea94da4dc06a01aec211de1df8ba4570b483dd01 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 15 Aug 2022 19:33:00 +0800 Subject: [PATCH 26/41] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + client/user_manager.py | 121 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 client/user_manager.py diff --git a/.gitignore b/.gitignore index 45e5d17..c833018 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Binary file go_build_* ddlBackend +__pycache__/ # Database File *.db diff --git a/client/user_manager.py b/client/user_manager.py new file mode 100644 index 0000000..bf64856 --- /dev/null +++ b/client/user_manager.py @@ -0,0 +1,121 @@ +import requests +import json + + +class Manager: + rootUrl: str = "http://localhost:4000" + header: map + + def __init__(self, root=None) -> None: + if root == None: + print("Use the default url {}".format(self.rootUrl)) + else: + self.rootUrl = root + + def getRootUserToken(self, student_id: str, password: str) -> bool: + url = self.rootUrl + "/login" + response = requests.post(url, json={ + "student_id": student_id, + "password": password + }) + if response.status_code == 200: + jsonMap = json.loads(response.text) + self.header = { + "Authorization": "Bearer " + jsonMap["token"] + } + return True + else: + print(response.text) + return False + + def readUsers(self): + url = self.rootUrl + "/users" + + response = requests.get(url, headers=self.header) + + if response.status_code == 200: + lst = json.loads(response.text) + users = [] + for item in lst: + user = UserModel() + user.fromJson(item) + users.append(user) + return users + else: + print(response.text) + return + + def readUser(self, id): + url = self.rootUrl + "/users/" + str(id) + response = requests.get(url, headers=self.header) + + if response.status_code == 200: + jsonMap = json.loads(response.text) + user = UserModel() + user.fromJson(jsonMap) + return user + else: + print(response.text) + + def createUser(self, user): + url = self.rootUrl + "/users" + + response = requests.post(url, json=user.toJson(), headers=self.header) + + if response.status_code == 201: + jsonMap = json.loads(response.text) + user = UserModel() + user.fromJson(jsonMap) + print(user.toString()) + else: + print(response.text) + + def updateUser(self, user): + url = self.rootUrl + "/users/" + str(user.id) + + jsonMap = user.toJson() + jsonMap["id"] = user.id + + response = requests.put(url, json=jsonMap, headers=self.header) + + if response.status_code != 204: + print(response.text) + + def deleteUser(self, id: int): + url = self.rootUrl + "/users/" + str(id) + + response = requests.delete(url, headers=self.header) + + if response.status_code != 204: + print(response.text) + + + +class UserModel: + id: int + username: str + password: str + student_id: str + permission: int + class_name: str + + def fromJson(self, json: map): + self.id = json["id"] + self.username = json["username"] + self.password = json["password"] + self.student_id = json["student_id"] + self.permission = json["permission"] + self.class_name = json["classname"] + + def toJson(self): + result = {} + result["username"] = self.username + result["student_id"] = self.student_id + result["permission"] = self.permission + result["classname"] = self.class_name + result["password"] = self.password + return result + + def toString(self): + return "id:{}, name:{}, permission:{}".format(self.id, self.username, self.permission) + -- Gitee From a7e712291e420f3eea85e2d267f2578279f9cf17 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Mon, 15 Aug 2022 20:59:59 +0800 Subject: [PATCH 27/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=A7=A3?= =?UTF-8?q?=E6=9E=90excel=E8=A1=A8=E6=A0=BC=E5=B9=B6=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.py | 19 +++++++++++++++++++ client/permission.xlsx | Bin 0 -> 18571 bytes client/user_manager.py | 28 ++++++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 client/client.py create mode 100755 client/permission.xlsx diff --git a/client/client.py b/client/client.py new file mode 100644 index 0000000..26759ad --- /dev/null +++ b/client/client.py @@ -0,0 +1,19 @@ +import user_manager + +manager = user_manager.Manager() + +manager.header = { + "Authorization": "Bearer " + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvb3QiLCJjbGFzc25hbWUiOiJkZGRkIiwicGVybWlzc2lvbiI6MiwiZXhwIjoxNjYwNjM2NzM1LCJpc3MiOiJTcXVpZFdhcmQifQ.irxMPA7eVP8hm_1DReQyXAxfvt8gebxXwxYouSFDD0Y" +} + +def upload_excel(): + users = user_manager.parse_excel("permission.xlsx") + + for user in users: + manager.createUser(user) + +def get_users(): + users = manager.readUsers() + + for user in users: + print(user.toString()) diff --git a/client/permission.xlsx b/client/permission.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..dde650ba5224c3c5be320cd08e25cfd5ac24cbba GIT binary patch literal 18571 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 Ta1aa(5%@;|&{$p!^zQ!wG1+dP literal 0 HcmV?d00001 diff --git a/client/user_manager.py b/client/user_manager.py index bf64856..62bfa3e 100644 --- a/client/user_manager.py +++ b/client/user_manager.py @@ -1,3 +1,4 @@ +import openpyxl import requests import json @@ -90,7 +91,6 @@ class Manager: print(response.text) - class UserModel: id: int username: str @@ -117,5 +117,29 @@ class UserModel: return result def toString(self): - return "id:{}, name:{}, permission:{}".format(self.id, self.username, self.permission) + return """username: {} +student_id: {} +classname: {} +permission: {}""".format(self.username, self.student_id, self.class_name, self.permission) + + def checkSame(self, other: "UserModel"): + return self.username == other.username and self.student_id == other.student_id and self.class_name == other.class_name and self.permission == other.permission + + +def parse_excel(path: str)-> list: + work_book = openpyxl.load_workbook(path) + work_sheet = work_book.active + users = [] + + for row in work_sheet.values: + user = UserModel() + user.class_name = str(row[0] - 2021211000) + user.student_id = str(row[1]) + user.username = row[2] + user.permission = row[3] + user.password = "" + + users.append(user) + + return users \ No newline at end of file -- Gitee From f9dd951052fab82327fec65e9788a0c76440d4c3 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 16 Aug 2022 14:48:43 +0800 Subject: [PATCH 28/41] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E9=87=87=E7=94=A8=E7=94=A8=E6=88=B7=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=97=B6=E8=BF=94=E5=9B=9E=E7=9A=84=E9=94=99=E8=AF=AF=E4=B8=BA?= =?UTF-8?q?403?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 16 ++++++++++++---- handlers/ddl_class_id_handlers.go | 8 +++----- handlers/ddl_handlers.go | 16 ++++++++++++---- handlers/jw_calendar_handler.go | 8 ++++---- handlers/user_handlers.go | 7 ++++--- 5 files changed, 35 insertions(+), 20 deletions(-) diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index 91311d7..28659ac 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -4,10 +4,11 @@ import ( "ddlBackend/database" "ddlBackend/models" "ddlBackend/tool" - "github.com/gin-gonic/gin" - "gorm.io/gorm" "net/http" "strconv" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" ) // CreateClassDDLHandler 班级url下创建DDL事件处理函数 @@ -74,7 +75,6 @@ func CreateClassDDLHandler(context *gin.Context) { } context.JSON(http.StatusCreated, ddlNotice) - return } // ReadClassDDLHandler 班级url下读取DDL事件处理函数 @@ -89,6 +89,15 @@ func ReadClassDDLHandler(context *gin.Context) { var err error var startNum, stepNum int startNum, err = strconv.Atoi(start) + if err != nil { + // 请求参数转换失败 + // 返回 400 错误请求 + tool.DDLLogError(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } stepNum, err = strconv.Atoi(step) if err != nil { // 请求参数转换失败 @@ -115,7 +124,6 @@ func ReadClassDDLHandler(context *gin.Context) { db.Where("notice_type = ?", noticeType).Offset(startNum).Limit(stepNum).Find(&ddlNotices) context.JSON(http.StatusOK, ddlNotices) - return } // checkClassAdminPermission 检查当前请求令牌的持有者是否有权限修改当前班级的内容 diff --git a/handlers/ddl_class_id_handlers.go b/handlers/ddl_class_id_handlers.go index a4ab481..fd6d1ad 100644 --- a/handlers/ddl_class_id_handlers.go +++ b/handlers/ddl_class_id_handlers.go @@ -5,10 +5,11 @@ import ( "ddlBackend/models" "ddlBackend/tool" "fmt" - "github.com/gin-gonic/gin" - "gorm.io/gorm" "net/http" "strconv" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" ) func ReadClassIDDDLHandler(context *gin.Context) { @@ -49,7 +50,6 @@ func ReadClassIDDDLHandler(context *gin.Context) { } else { context.JSON(http.StatusOK, ddlNotice) } - return } func UpdateClassIDDDLHandler(context *gin.Context) { @@ -129,7 +129,6 @@ func UpdateClassIDDDLHandler(context *gin.Context) { db.Save(&ddlNotice) context.JSON(http.StatusNoContent, gin.H{}) - return } func DeleteClassIDDDLHandler(context *gin.Context) { @@ -189,5 +188,4 @@ func DeleteClassIDDDLHandler(context *gin.Context) { db.Delete(&ddlNotice) context.JSON(http.StatusNoContent, gin.H{}) - return } diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go index 022edf6..99ecb9b 100644 --- a/handlers/ddl_handlers.go +++ b/handlers/ddl_handlers.go @@ -4,10 +4,11 @@ import ( "ddlBackend/database" "ddlBackend/models" "ddlBackend/tool" - "github.com/gin-gonic/gin" - "gorm.io/gorm" "net/http" "strconv" + + "github.com/gin-gonic/gin" + "gorm.io/gorm" ) // CreateDDLHandler 创建DDL事件处理函数 @@ -66,7 +67,6 @@ func CreateDDLHandler(context *gin.Context) { } context.JSON(http.StatusCreated, ddlNotice) - return } // ReadDDLHandler 读取DDL事件处理函数 @@ -79,6 +79,15 @@ func ReadDDLHandler(context *gin.Context) { var err error var startNum, stepNum int startNum, err = strconv.Atoi(start) + if err != nil { + // 请求参数转换失败 + // 返回 400 错误请求 + tool.DDLLogError(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } stepNum, err = strconv.Atoi(step) if err != nil { // 请求参数转换失败 @@ -99,5 +108,4 @@ func ReadDDLHandler(context *gin.Context) { } context.JSON(http.StatusOK, ddlNotices) - return } diff --git a/handlers/jw_calendar_handler.go b/handlers/jw_calendar_handler.go index e57f092..1c7716c 100644 --- a/handlers/jw_calendar_handler.go +++ b/handlers/jw_calendar_handler.go @@ -7,11 +7,12 @@ import ( "ddlBackend/protos" "ddlBackend/tool" "fmt" + "net/http" + "time" + "github.com/gin-gonic/gin" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "net/http" - "time" ) func GetSemesterCalendarHandler(context *gin.Context) { @@ -49,7 +50,7 @@ func GetSemesterCalendarHandler(context *gin.Context) { context.JSON(http.StatusOK, courses) return } else { - duration := time.Now().Sub(info.UpdatedAt) + duration := time.Since(info.UpdatedAt) // 如果上次请求到现在的时间小于超时时间 if int64(duration) <= tool.Setting.JWGLOutTime*int64(time.Hour) { targetTime := info.UpdatedAt.Add(time.Duration(tool.Setting.JWGLOutTime * int64(time.Hour))) @@ -93,7 +94,6 @@ func GetICSFileHandler(context *gin.Context) { } context.Data(http.StatusOK, "text/calendar", info.ICSStream) - return } // grpcGetSemester 远程过程调用获得课表的函数 diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index 26bd494..edd11a7 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -281,10 +281,11 @@ func UserLoginHandler(context *gin.Context) { return } - // 如果该用户的权限大于普通用户 - // 则不能通过学号姓名验证的方式获得令牌 if user.Permission > models.User { - context.JSON(http.StatusBadRequest, gin.H{ + // 如果该用户的权限大于普通用户 + // 则不能通过学号姓名验证的方式获得令牌 + // 返回 403 Forbidden + context.JSON(http.StatusForbidden, gin.H{ "error": "该用户身份为管理员,请通过学号密码登录", }) return -- Gitee From 0e96e9dfb95e38454223f4021f0cd727b54010d1 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 16 Aug 2022 15:47:51 +0800 Subject: [PATCH 29/41] =?UTF-8?q?=E5=B0=86JWT=E4=BB=A4=E7=89=8C=E4=B8=AD?= =?UTF-8?q?=E6=90=BA=E5=B8=A6=E7=9A=84=E4=BF=A1=E6=81=AF=E4=BB=8E=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=90=8D=E6=94=B9=E4=B8=BA=E5=AD=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/jwt_claims.go | 2 +- tool/jwt.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/models/jwt_claims.go b/models/jwt_claims.go index d6aa4e8..ee0c02d 100644 --- a/models/jwt_claims.go +++ b/models/jwt_claims.go @@ -4,7 +4,7 @@ import "github.com/dgrijalva/jwt-go" // JWTClaims JWT实体信息 type JWTClaims struct { - Username string `json:"username"` + StudentID string `json:"student_id"` Classname string `json:"classname"` Permission uint `json:"permission"` jwt.StandardClaims diff --git a/tool/jwt.go b/tool/jwt.go index 70341c2..70c9d41 100644 --- a/tool/jwt.go +++ b/tool/jwt.go @@ -3,9 +3,10 @@ package tool import ( "ddlBackend/models" "errors" + "time" + "github.com/dgrijalva/jwt-go" "github.com/gin-gonic/gin" - "time" ) // GenerateJWTToken 生成JWT令牌 @@ -15,7 +16,7 @@ func GenerateJWTToken(info models.UserInformation) (string, error) { // 设置token中的信息 claims := models.JWTClaims{ - Username: info.Username, + StudentID: info.StudentID, Classname: info.Classname, Permission: info.Permission, StandardClaims: jwt.StandardClaims{ -- Gitee From 1e84acd6da16bb56fc17d5e6db7104dc8806dfee Mon Sep 17 00:00:00 2001 From: jackfiled Date: Tue, 16 Aug 2022 15:59:41 +0800 Subject: [PATCH 30/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=E7=AE=A1=E7=90=86=E5=91=98=E5=AF=86=E7=A0=81=E5=87=BD?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/permission.xlsx | Bin 18571 -> 18601 bytes client/user_manager.py | 2 +- database/database.go | 4 +-- handlers/user_handlers.go | 51 ++++++++++++++++++++++++++++++++++++++ main.go | 1 + 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/client/permission.xlsx b/client/permission.xlsx index dde650ba5224c3c5be320cd08e25cfd5ac24cbba..32a247b8eda3984432248619c601b85c40df09c7 100755 GIT binary patch delta 8533 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 -^JtUII^@PHK;;HLj$U^%lhe-X0bTSsCJD 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 diff --git a/client/user_manager.py b/client/user_manager.py index 62bfa3e..ce804ea 100644 --- a/client/user_manager.py +++ b/client/user_manager.py @@ -138,7 +138,7 @@ def parse_excel(path: str)-> list: user.student_id = str(row[1]) user.username = row[2] user.permission = row[3] - user.password = "" + user.password = "123456" users.append(user) diff --git a/database/database.go b/database/database.go index 59a6eff..030a0d4 100644 --- a/database/database.go +++ b/database/database.go @@ -3,8 +3,8 @@ package database import ( "ddlBackend/models" "ddlBackend/tool" - "errors" "fmt" + "gorm.io/driver/sqlite" "gorm.io/gorm" ) @@ -65,7 +65,7 @@ func GetDDLTable(className string) (*gorm.DB, error) { return Database.Table(className).Order("ddl_time DESC"), nil } } - return nil, errors.New(fmt.Sprintf("The table named %s not exists", className)) + return nil, fmt.Errorf("the table named %s not exists", className) } // AdminLogin 管理员登录验证函数 diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index edd11a7..4d82a06 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -304,3 +304,54 @@ func UserLoginHandler(context *gin.Context) { "token": token, }) } + +// 管理员修改密码处理函数 +func AdminUpdatePasswordhandler(context *gin.Context) { + claims, err := tool.GetClaimsInContext(context) + if err != nil { + // 解析JWT令牌信息错误 + // 返回 500 服务器错误 + tool.DDLLogError(err.Error()) + context.JSON(http.StatusInternalServerError, gin.H{ + "error": err.Error(), + }) + return + } + + // 修改管理员密码的请求体保持和登录一致 + // 需要学号和新的密码 + var loginModel models.AdminLoginModel + err = context.ShouldBindJSON(&loginModel) + if err != nil { + // 绑定JSON出错 + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + } + + var user models.UserInformation + result := database.Database.Table("user_informations").Where("student_id =?", loginModel.StudentID).Find(&user) + if result.Error != nil { + // 数据库中未发现该用户 + context.JSON(http.StatusNotFound, gin.H{ + "error": result.Error.Error(), + }) + return + } + + // 修改密码的权限要求: + // 令牌持有账号和欲修改密码的账号是同一个账号 + // 令牌的权限在管理员及以上 + if claims.StudentID == loginModel.StudentID && claims.Permission >= models.Administrator { + user.Password = loginModel.Password + database.Database.Table("user_informations").Save(&user) + + context.JSON(http.StatusOK, gin.H{}) + return + } else { + context.JSON(http.StatusBadRequest, gin.H{ + "error": "permission denied", + }) + return + } +} diff --git a/main.go b/main.go index 963b515..94b4878 100644 --- a/main.go +++ b/main.go @@ -66,6 +66,7 @@ func main() { { userRoute.GET("/", handlers.ReadUsersHandler) userRoute.POST("/", handlers.CreateUserHandler) + userRoute.POST("/password", handlers.AdminUpdatePasswordhandler) userRoute.GET("/:id", handlers.ReadSingleUserHandler) userRoute.PUT("/:id", handlers.UpdateUserHandler) userRoute.DELETE("/:id", handlers.DeleteUserHandler) -- Gitee From 29d574d9806c3bb6fb61344dd4c476c71e86205c Mon Sep 17 00:00:00 2001 From: jackfiled Date: Wed, 17 Aug 2022 12:21:30 +0800 Subject: [PATCH 31/41] =?UTF-8?q?=E5=B0=86=E5=AF=86=E7=A0=81=E5=93=88?= =?UTF-8?q?=E5=B8=8C=E4=B9=8B=E5=90=8E=E5=86=8D=E5=82=A8=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/permission.xlsx | Bin 18601 -> 15264 bytes database/database.go | 2 ++ handlers/user_handlers.go | 6 ++++++ tool/password.go | 18 ++++++++++++++++++ 4 files changed, 26 insertions(+) create mode 100644 tool/password.go diff --git a/client/permission.xlsx b/client/permission.xlsx index 32a247b8eda3984432248619c601b85c40df09c7..6746edc9ec0da007e1e1c7cc5a403f25ce73aa28 100755 GIT binary patch delta 8348 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 delta 11751 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 diff --git a/database/database.go b/database/database.go index 030a0d4..44ccb39 100644 --- a/database/database.go +++ b/database/database.go @@ -70,6 +70,8 @@ func GetDDLTable(className string) (*gorm.DB, error) { // AdminLogin 管理员登录验证函数 func AdminLogin(studentID string, password string) (*models.UserInformation, error) { + password = tool.Sha256PasswordWithSalt(password) + var user models.UserInformation result := Database.Table("user_informations").Where("student_id = ? AND password = ?", studentID, password).First(&user) if result.Error != nil { diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index 4d82a06..eb8ccc6 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -118,6 +118,9 @@ func CreateUserHandler(context *gin.Context) { return } + // 将密码加盐哈希之后储存在数据库中 + user.Password = tool.Sha256PasswordWithSalt(user.Password) + result := database.Database.Table("user_informations").Create(&user) if result.Error != nil { tool.DDLLogError(result.Error.Error()) @@ -177,6 +180,9 @@ func UpdateUserHandler(context *gin.Context) { return } + // 密码加盐哈希之后再存入数据库 + user.Password = tool.Sha256PasswordWithSalt(user.Password) + database.Database.Table("user_informations").Save(&user) context.JSON(http.StatusNoContent, gin.H{}) } diff --git a/tool/password.go b/tool/password.go new file mode 100644 index 0000000..5d38a44 --- /dev/null +++ b/tool/password.go @@ -0,0 +1,18 @@ +package tool + +import ( + "crypto/sha256" + "encoding/hex" +) + +// 密码加盐hash10000次函数 +func Sha256PasswordWithSalt(password string) string { + salt := []byte(Setting.PasswordSalt) + result := sha256.Sum256(append([]byte(password), salt...)) + + for i := 0; i < 9999; i++ { + result = sha256.Sum256(append(result[:], salt...)) + } + + return hex.EncodeToString(result[:]) +} -- Gitee From ccc245325bd9271cb37b624c86b7a7a19bf87478 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Wed, 17 Aug 2022 17:36:19 +0800 Subject: [PATCH 32/41] =?UTF-8?q?=E5=B0=86Grpc=E6=9C=8D=E5=8A=A1=E7=9A=84?= =?UTF-8?q?=E5=9C=B0=E5=9D=80=E6=B7=BB=E5=8A=A0=E5=88=B0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=9C=A8?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=AD=E6=9C=AA=E6=89=BE=E5=88=B0?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E6=96=87=E4=BB=B6=E4=B8=8D=E6=8A=A5=E9=94=99?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 2 +- .../{jw_calendar_handler.go => jw_handlers.go} | 2 +- tool/config.go | 18 +++++++++++------- 3 files changed, 13 insertions(+), 9 deletions(-) rename handlers/{jw_calendar_handler.go => jw_handlers.go} (96%) diff --git a/database/database.go b/database/database.go index 44ccb39..6b21c8f 100644 --- a/database/database.go +++ b/database/database.go @@ -95,7 +95,7 @@ func UserLogin(username string, studentID string) (*models.UserInformation, erro // GetICSInformation 获得ICSInformation func GetICSInformation(studentID string, semester string) (*models.ICSInformation, error) { var info models.ICSInformation - result := Database.Table("ics_informations").Where("student_id = ? AND semester = ?", studentID, semester).Find(&info) + result := Database.Table("ics_informations").Where("student_id = ? AND semester = ?", studentID, semester).First(&info) if result.Error != nil { return nil, result.Error diff --git a/handlers/jw_calendar_handler.go b/handlers/jw_handlers.go similarity index 96% rename from handlers/jw_calendar_handler.go rename to handlers/jw_handlers.go index 1c7716c..9d39ef5 100644 --- a/handlers/jw_calendar_handler.go +++ b/handlers/jw_handlers.go @@ -98,7 +98,7 @@ func GetICSFileHandler(context *gin.Context) { // grpcGetSemester 远程过程调用获得课表的函数 func grpcGetSemester(model models.GetSemesterCalendarModel) ([]*protos.Course, []byte, error) { - connection, err := grpc.Dial("localhost:7000", grpc.WithTransportCredentials(insecure.NewCredentials())) + connection, err := grpc.Dial(tool.Setting.JWGrpcAddress, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, nil, err } diff --git a/tool/config.go b/tool/config.go index 8843f64..8c8c38a 100644 --- a/tool/config.go +++ b/tool/config.go @@ -8,17 +8,21 @@ import ( ) type Config struct { - AppPort string `json:"app_port"` - JWTSecret string `json:"jwt_secret"` - JWGLOutTime int64 `json:"jwgl_out_time"` - RootConfig models.UserInformation `json:"root_config"` + AppPort string `json:"app_port"` + JWTSecret string `json:"jwt_secret"` + PasswordSalt string `json:"password_salt"` + JWGLOutTime int64 `json:"jwgl_out_time"` + JWGrpcAddress string `json:"jw_grpc_address"` + RootConfig models.UserInformation `json:"root_config"` } // DefaultSetting 默认配置文件 var DefaultSetting = Config{ - AppPort: ":8080", - JWTSecret: "MakeBuptGreatAgain", - JWGLOutTime: 24, + AppPort: ":8080", + JWTSecret: "MakeBuptGreatAgain", + JWGLOutTime: 24, + PasswordSalt: "MakeBuptGreatAgain", + JWGrpcAddress: "http://rrricardo.top:7000", RootConfig: models.UserInformation{ Username: "root", Password: "123456", -- Gitee From a8a6f9890f4a726fff68acd96666dfd20ab1fe5d Mon Sep 17 00:00:00 2001 From: jackfiled Date: Wed, 17 Aug 2022 20:20:52 +0800 Subject: [PATCH 33/41] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E7=AE=A1=E7=90=86=E8=B4=A6=E5=8F=B7=E5=AD=98=E5=85=A5?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=8D=E4=BC=9A=E8=A2=AB=E5=93=88?= =?UTF-8?q?=E5=B8=8C=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.py | 2 +- client/permission.xlsx | Bin 15264 -> 9955 bytes client/user_manager.py | 1 + database/database.go | 7 +++++-- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client/client.py b/client/client.py index 26759ad..140770e 100644 --- a/client/client.py +++ b/client/client.py @@ -3,7 +3,7 @@ import user_manager manager = user_manager.Manager() manager.header = { - "Authorization": "Bearer " + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJvb3QiLCJjbGFzc25hbWUiOiJkZGRkIiwicGVybWlzc2lvbiI6MiwiZXhwIjoxNjYwNjM2NzM1LCJpc3MiOiJTcXVpZFdhcmQifQ.irxMPA7eVP8hm_1DReQyXAxfvt8gebxXwxYouSFDD0Y" + "Authorization": "Bearer " + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdHVkZW50X2lkIjoiMDAwMDAwMDAwMCIsImNsYXNzbmFtZSI6ImRkZGQiLCJwZXJtaXNzaW9uIjoyLCJleHAiOjE2NjA4MTgxMzIsImlzcyI6IlNxdWlkV2FyZCJ9.dQ81IOrD-nmnNNQB6ZsAjLQAaWzou1hYoUjH3oHRbhE" } def upload_excel(): diff --git a/client/permission.xlsx b/client/permission.xlsx index 6746edc9ec0da007e1e1c7cc5a403f25ce73aa28..6a09ba2517016a6780966707caa846e1c2107e5a 100755 GIT binary patch delta 3875 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 Date: Thu, 18 Aug 2022 17:07:19 +0800 Subject: [PATCH 34/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E5=85=A8=E9=83=A8=E6=B4=BB=E5=8A=A8=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/client.py | 3 +++ client/permission.xlsx | Bin 9955 -> 9955 bytes client/user_manager.py | 2 +- handlers/ddl_class_handlers.go | 18 ++++++++++++++++-- handlers/ddl_handlers.go | 20 ++++++++++++++++++-- handlers/user_handlers.go | 4 ++-- main.go | 2 +- tool/password.go | 2 +- 8 files changed, 42 insertions(+), 9 deletions(-) diff --git a/client/client.py b/client/client.py index 140770e..224e379 100644 --- a/client/client.py +++ b/client/client.py @@ -17,3 +17,6 @@ def get_users(): for user in users: print(user.toString()) + +upload_excel() +get_users() diff --git a/client/permission.xlsx b/client/permission.xlsx index 6a09ba2517016a6780966707caa846e1c2107e5a..2866938e1a01062af6aeb676f4bbe1c1ddb01986 100755 GIT binary patch delta 2037 zcmVW#jW^L1?s`~FcCLz7#rQ2>qZ0v#KGc#v~ z-Th@<8IM#*#+wnsJ2oWB$L@lQ`90@z z0{|L1LZwn|Vp%dTX-(t~Z)pRT85cECuoMrLYy~BSEGboWWjVGTST$h{S|KFjGZ=g} zV>wNE-qo~GD-b~|qJX|ESt|#$I{yq@O~kxw&79XQK-{y6siz(k8Fiiw#N!K84dqQfRsR|htkt!>gqQwY> zu;dH+ZbNkKq+=CW9p7_8WbJL_d?t*7&PZ3OOAzt^50!rr1hM1mCqWqFN>R}eMW?(` zpu@Fa-_=}?JuNvX+&HIyIwmL-7U&Cng^}b5xtC`|l}0D35t=5qR}$R66)Y#B;5%t{ zaddflW}XD6*OMdvHl=c|czgRssbsq>{z0oG*8#8~0xOoQ`;XB8vLYGuc&3B__lM~* zWy7IotopwnVMb{r)K1*u9@1de=v64XcGG` z;EV{8oRdzK>*Qe6TLK+ zH>@f60uI2ohm5CTiR~D=!=g9dutJsKWavcT_iBId7iAA6FpeU<2i2g7jnH!xhd2r` zHiK}Snce{eVUot7nU1q4vt1WEsoN8>-Z1L>DKP72qv>nlLibnI_A_%oy-rj zG@C8->CxYV5~=2iDf`*4|$Llc56? zvlI$50tv-@!U59*000k@Pz)k}Z=)~}$KO}l?_l{I%n<@bAyt~RyM0^j`Rte>SizXu z&ZSkq`wrx2rR+mgiDMXhe*YQIFuC8WhHSxDsoR2ven1JdLYJ~#74+B7CoiMKI^LGN z(Jd780G8fQKYyC+v{~C4z!4<0wxG3hUCx*lH7IU<-9d{hl{Shy{4^_nW;+AC9D-EC zq97PE#bry6gxuW1&{ZV`EVS4tXx$NFpy3Ylx3%o-nWn@oIK|C+(|JOx4iQV)NOu^Z zlqiuuuUc*RvcbCd;fM>eH+V&O$7h+rf2E|PFxu+M`ABBRoUhBjV|R>;3+cN4n=s*s z8Q99cfp4hjV=0Bng%!Pj!Qv0X#ur$BTqfVhvY>zGSr}mNV{bf5X5J`!NWIxO&b-+? zO0w|rVV*?kE1gbCi5>2%A_l60&cb{V29!-F!vOu3u(R)M;`s6hG$0(HNJvRPpG&RR z{l;f>1&Fl6h91d&9sqFLPt;hp$Xq57HhbZcGur-`c{Kb$)B>e0Z)WtmU$L>z#MbS^FBD z5qXn^-=3C~iVlUNEf3y*bh!L|w8U{VRzf>MBht_)RCJMlf|fXr#!6^UXha$sg^CWh z#QP^LaU6}6&;_9pX=oHGx=KMy97kg%G~M`TL>d}}ir%E4C61%961t+3Mx>!psOW79 zTH-hwE1@@pMx>!psOVh^TH+N=hj_wD=q;fUX=oHcug{*BN8UaKEpZ%;mC!pvBht_) zRJ5}x>ZOhuv!64$_xyg5zif>9f`_E$0M)_&Ey62yI5Y)a0I(7^^&hJVYR*cTYEAOatWJPrje%3J#I zxLu(lAxRvPMM&mbGNZ{IO=ln7>sR-?h{HghGyG3XI%2%ok~vKYP3IHh1yJ<4ufIj{ z4YSc8U;_y;vF)=C0{{TxlR6|$0SA+bBrO}oe8K_K0{{RI3;+Na000000000000000 T06MeLB#!|Ex5#bGlVm1;^3Bu~ delta 2033 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 PB#!|Ev8p^DlVm1;vsUF> diff --git a/client/user_manager.py b/client/user_manager.py index b7a98c4..413ad45 100644 --- a/client/user_manager.py +++ b/client/user_manager.py @@ -135,7 +135,7 @@ def parse_excel(path: str)-> list: for row in work_sheet.values: user = UserModel() - user.class_name = str(row[0] - 2021211000) + user.class_name = str(row[0]) user.student_id = str(row[1]) user.username = row[2] user.permission = row[3] diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index 28659ac..7b85b6b 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -87,7 +87,7 @@ func ReadClassDDLHandler(context *gin.Context) { // 将过滤器参数从字符串转换为数字 var err error - var startNum, stepNum int + var startNum, stepNum, noticeTypeNum int startNum, err = strconv.Atoi(start) if err != nil { // 请求参数转换失败 @@ -108,6 +108,16 @@ func ReadClassDDLHandler(context *gin.Context) { }) return } + noticeTypeNum, err = strconv.Atoi(noticeType) + if err != nil { + // 请求参数转换失败 + // 返回 400 错误请求 + tool.DDLLogError(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } var ddlNotices []models.DDLNotice var db *gorm.DB @@ -122,7 +132,11 @@ func ReadClassDDLHandler(context *gin.Context) { return } - db.Where("notice_type = ?", noticeType).Offset(startNum).Limit(stepNum).Find(&ddlNotices) + if noticeTypeNum == models.ALL { + db.Where("noticeType != ?", models.ALL).Offset(startNum).Limit(stepNum).Find(&ddlNotices) + } else { + db.Where("noticeType = ?", noticeTypeNum).Offset(startNum).Limit(stepNum).Find(&ddlNotices) + } context.JSON(http.StatusOK, ddlNotices) } diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go index 99ecb9b..96912ab 100644 --- a/handlers/ddl_handlers.go +++ b/handlers/ddl_handlers.go @@ -77,7 +77,7 @@ func ReadDDLHandler(context *gin.Context) { // 将过滤器参数从字符串转换为数字 var err error - var startNum, stepNum int + var startNum, stepNum, noticeTypeNum int startNum, err = strconv.Atoi(start) if err != nil { // 请求参数转换失败 @@ -98,12 +98,28 @@ func ReadDDLHandler(context *gin.Context) { }) return } + noticeTypeNum, err = strconv.Atoi(noticeType) + if err != nil { + // 请求参数转换失败 + // 返回 400 错误请求 + tool.DDLLogError(err.Error()) + context.JSON(http.StatusBadRequest, gin.H{ + "error": err.Error(), + }) + return + } var ddlNotices []models.DDLNotice for _, value := range database.DDLTables { db, _ := database.GetDDLTable(value) var list []models.DDLNotice - db.Where("notice_type = ?", noticeType).Offset(startNum).Limit(stepNum).Find(&list) + if noticeTypeNum == models.ALL { + // 筛选所有的活动事件 + db.Where("noticeType != ?", models.DDL).Offset(startNum).Limit(stepNum).Find(&list) + } else { + // 筛选指定类型的事件 + db.Where("noticeType = ?", noticeTypeNum).Offset(startNum).Limit(stepNum).Find(&list) + } ddlNotices = append(ddlNotices, list...) } diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index eb8ccc6..76499e8 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -311,8 +311,8 @@ func UserLoginHandler(context *gin.Context) { }) } -// 管理员修改密码处理函数 -func AdminUpdatePasswordhandler(context *gin.Context) { +// AdminUpdatePasswordHandler 管理员修改密码处理函数 +func AdminUpdatePasswordHandler(context *gin.Context) { claims, err := tool.GetClaimsInContext(context) if err != nil { // 解析JWT令牌信息错误 diff --git a/main.go b/main.go index 94b4878..34ccc76 100644 --- a/main.go +++ b/main.go @@ -66,7 +66,7 @@ func main() { { userRoute.GET("/", handlers.ReadUsersHandler) userRoute.POST("/", handlers.CreateUserHandler) - userRoute.POST("/password", handlers.AdminUpdatePasswordhandler) + userRoute.POST("/password", handlers.AdminUpdatePasswordHandler) userRoute.GET("/:id", handlers.ReadSingleUserHandler) userRoute.PUT("/:id", handlers.UpdateUserHandler) userRoute.DELETE("/:id", handlers.DeleteUserHandler) diff --git a/tool/password.go b/tool/password.go index 5d38a44..fa8d8e6 100644 --- a/tool/password.go +++ b/tool/password.go @@ -5,7 +5,7 @@ import ( "encoding/hex" ) -// 密码加盐hash10000次函数 +// Sha256PasswordWithSalt 密码加盐hash10000次函数 func Sha256PasswordWithSalt(password string) string { salt := []byte(Setting.PasswordSalt) result := sha256.Sum256(append([]byte(password), salt...)) -- Gitee From 6d377d524b3cedf70b66cba55a934cb3a22e6660 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Thu, 18 Aug 2022 17:45:54 +0800 Subject: [PATCH 35/41] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86sql=E8=AF=AD?= =?UTF-8?q?=E5=8F=A5=E4=B8=AD=E7=9A=84=E6=8B=BC=E5=86=99=E9=94=99=E8=AF=AF?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E4=BA=86=E6=A0=B9=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E6=97=A0=E6=B3=95=E4=BF=AE=E6=94=B9=E5=85=B6=E4=BB=96?= =?UTF-8?q?=E7=8F=AD=E7=BA=A7=E5=86=85=E5=AE=B9=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 18 +++++++++++++++--- handlers/ddl_handlers.go | 13 +++++++++++-- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index 7b85b6b..16da713 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -42,6 +42,15 @@ func CreateClassDDLHandler(context *gin.Context) { return } + if ddlNotice.NoticeType == models.ALL { + // 类别设置为 1 全部 + // 不允许创建 + context.JSON(http.StatusBadRequest, gin.H{ + "error": "all notice type of ddl is prohibited", + }) + return + } + if className != ddlNotice.ClassName { // 请求url和请求体中班级不符 // 返回 400 错误请求 @@ -133,9 +142,9 @@ func ReadClassDDLHandler(context *gin.Context) { } if noticeTypeNum == models.ALL { - db.Where("noticeType != ?", models.ALL).Offset(startNum).Limit(stepNum).Find(&ddlNotices) + db.Where("notice_type != ?", models.ALL).Offset(startNum).Limit(stepNum).Find(&ddlNotices) } else { - db.Where("noticeType = ?", noticeTypeNum).Offset(startNum).Limit(stepNum).Find(&ddlNotices) + db.Where("notice_type = ?", noticeTypeNum).Offset(startNum).Limit(stepNum).Find(&ddlNotices) } context.JSON(http.StatusOK, ddlNotices) } @@ -148,7 +157,10 @@ func checkClassAdminPermission(context *gin.Context, classname string) (bool, er return false, err } - if claims.Classname == classname && claims.Permission >= models.Administrator { + // 权限为根管理员 + // 或者为本班的管理员 + // 即可修改该班的内容 + if claims.Permission > models.Administrator && (claims.Classname == classname || claims.Permission > models.User) { return true, nil } else { return false, nil diff --git a/handlers/ddl_handlers.go b/handlers/ddl_handlers.go index 96912ab..58fc94a 100644 --- a/handlers/ddl_handlers.go +++ b/handlers/ddl_handlers.go @@ -43,6 +43,15 @@ func CreateDDLHandler(context *gin.Context) { return } + if ddlNotice.NoticeType == models.ALL { + // 类别设置为 1 全部 + // 不允许创建 + context.JSON(http.StatusBadRequest, gin.H{ + "error": "all notice type of ddl is prohibited", + }) + return + } + var db *gorm.DB db, err = database.GetDDLTable(ddlNotice.ClassName) if err != nil { @@ -115,10 +124,10 @@ func ReadDDLHandler(context *gin.Context) { var list []models.DDLNotice if noticeTypeNum == models.ALL { // 筛选所有的活动事件 - db.Where("noticeType != ?", models.DDL).Offset(startNum).Limit(stepNum).Find(&list) + db.Where("notice_type != ?", models.DDL).Offset(startNum).Limit(stepNum).Find(&list) } else { // 筛选指定类型的事件 - db.Where("noticeType = ?", noticeTypeNum).Offset(startNum).Limit(stepNum).Find(&list) + db.Where("notice_type = ?", noticeTypeNum).Offset(startNum).Limit(stepNum).Find(&list) } ddlNotices = append(ddlNotices, list...) } -- Gitee From e9d6da453ba3c3aae3ff75e28cab879e1f388e86 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 19 Aug 2022 14:56:23 +0800 Subject: [PATCH 36/41] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=8F=AD=E7=BA=A7?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E7=9A=84=E5=91=BD=E5=90=8D=E5=92=8C=E5=9C=A8?= =?UTF-8?q?json=E4=B8=AD=E7=9A=84=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handlers/ddl_class_handlers.go | 2 +- handlers/user_handlers.go | 10 ++++++++-- models/jwt_claims.go | 2 +- models/user_information.go | 4 ++-- tool/config.go | 2 +- tool/jwt.go | 2 +- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/handlers/ddl_class_handlers.go b/handlers/ddl_class_handlers.go index 16da713..27e05e0 100644 --- a/handlers/ddl_class_handlers.go +++ b/handlers/ddl_class_handlers.go @@ -160,7 +160,7 @@ func checkClassAdminPermission(context *gin.Context, classname string) (bool, er // 权限为根管理员 // 或者为本班的管理员 // 即可修改该班的内容 - if claims.Permission > models.Administrator && (claims.Classname == classname || claims.Permission > models.User) { + if claims.Permission > models.Administrator && (claims.ClassName == classname || claims.Permission > models.User) { return true, nil } else { return false, nil diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index 76499e8..9c1896b 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -261,7 +261,10 @@ func AdminLoginHandler(context *gin.Context) { } context.JSON(http.StatusOK, gin.H{ - "token": token, + "token": token, + "username": user.Username, + "class_name": user.ClassName, + "student_id": user.StudentID, }) } @@ -307,7 +310,10 @@ func UserLoginHandler(context *gin.Context) { } context.JSON(http.StatusOK, gin.H{ - "token": token, + "token": token, + "username": user.Username, + "class_name": user.ClassName, + "student_id": user.StudentID, }) } diff --git a/models/jwt_claims.go b/models/jwt_claims.go index ee0c02d..738b618 100644 --- a/models/jwt_claims.go +++ b/models/jwt_claims.go @@ -5,7 +5,7 @@ import "github.com/dgrijalva/jwt-go" // JWTClaims JWT实体信息 type JWTClaims struct { StudentID string `json:"student_id"` - Classname string `json:"classname"` + ClassName string `json:"class_name"` Permission uint `json:"permission"` jwt.StandardClaims } diff --git a/models/user_information.go b/models/user_information.go index 6a2f38b..512e5a9 100644 --- a/models/user_information.go +++ b/models/user_information.go @@ -8,8 +8,8 @@ type UserInformation struct { Username string `json:"username"` // Password 用户密码 Password string `json:"password"` - // Classname 所在班级 - Classname string `json:"classname"` + // ClassName 所在班级 + ClassName string `json:"class_name"` // StudentID 学号 StudentID string `json:"student_id"` // Permission 权限 diff --git a/tool/config.go b/tool/config.go index 8c8c38a..8239ad8 100644 --- a/tool/config.go +++ b/tool/config.go @@ -26,7 +26,7 @@ var DefaultSetting = Config{ RootConfig: models.UserInformation{ Username: "root", Password: "123456", - Classname: "dddd", + ClassName: "dddd", StudentID: "0000000000", Permission: models.Root, }, diff --git a/tool/jwt.go b/tool/jwt.go index 70c9d41..18aeaac 100644 --- a/tool/jwt.go +++ b/tool/jwt.go @@ -17,7 +17,7 @@ func GenerateJWTToken(info models.UserInformation) (string, error) { // 设置token中的信息 claims := models.JWTClaims{ StudentID: info.StudentID, - Classname: info.Classname, + ClassName: info.ClassName, Permission: info.Permission, StandardClaims: jwt.StandardClaims{ // token失效时间 -- Gitee From 7afe56db4de6c0357fb909ef6fe76fb9bce43303 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Fri, 19 Aug 2022 17:20:58 +0800 Subject: [PATCH 37/41] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=AF=B9mysql?= =?UTF-8?q?=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/database.go | 7 ++++++- database/mysql.go | 18 ++++++++++++++++++ go.mod | 4 +++- go.sum | 7 +++++-- handlers/user_handlers.go | 2 ++ tool/config.go | 6 +++++- 6 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 database/mysql.go diff --git a/database/database.go b/database/database.go index f218c5c..dcc9ed2 100644 --- a/database/database.go +++ b/database/database.go @@ -5,6 +5,7 @@ import ( "ddlBackend/tool" "fmt" + "gorm.io/driver/mysql" "gorm.io/driver/sqlite" "gorm.io/gorm" ) @@ -17,7 +18,11 @@ var Database *gorm.DB // OpenDatabase 打开数据库函数 func OpenDatabase() (err error) { - Database, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) + if tool.Setting.UseMysql { + Database, err = gorm.Open(mysql.Open(tool.Setting.MysqlConfig.GenerateConnectionString()), &gorm.Config{}) + } else { + Database, err = gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) + } if err != nil { return err } diff --git a/database/mysql.go b/database/mysql.go new file mode 100644 index 0000000..322fd39 --- /dev/null +++ b/database/mysql.go @@ -0,0 +1,18 @@ +package database + +import "fmt" + +// MysqlModel Mysql数据库连接信息类 +type MysqlModel struct { + Username string `json:"username"` + Password string `json:"password"` + Address string `json:"address"` + DatabaseName string `json:"database_name"` +} + +func (model *MysqlModel) GenerateConnectionString() string { + result := fmt.Sprintf("%s:%s@tcp(%s)/%s", model.Username, model.Password, model.Address, model.DatabaseName) + // 配置字符串 + result = result + "?charset=utf8mb4&parseTime=True&loc=Local" + return result +} diff --git a/go.mod b/go.mod index 4c67c5a..1a7aa1c 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/satori/go.uuid v1.2.0 google.golang.org/grpc v1.48.0 google.golang.org/protobuf v1.28.0 + gorm.io/driver/mysql v1.3.6 gorm.io/driver/sqlite v1.3.6 gorm.io/gorm v1.23.8 ) @@ -18,6 +19,7 @@ require ( github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.10.0 // indirect + github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/goccy/go-json v0.9.7 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect @@ -25,7 +27,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-isatty v0.0.14 // indirect - github.com/mattn/go-sqlite3 v1.14.14 // indirect + github.com/mattn/go-sqlite3 v1.14.12 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect diff --git a/go.sum b/go.sum index ae629c8..dc568c7 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -86,9 +88,8 @@ github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= -github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= @@ -205,6 +206,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.3.6 h1:BhX1Y/RyALb+T9bZ3t07wLnPZBukt+IRkMn8UZSNbGM= +gorm.io/driver/mysql v1.3.6/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ= gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE= gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= diff --git a/handlers/user_handlers.go b/handlers/user_handlers.go index 9c1896b..5c2eb84 100644 --- a/handlers/user_handlers.go +++ b/handlers/user_handlers.go @@ -265,6 +265,7 @@ func AdminLoginHandler(context *gin.Context) { "username": user.Username, "class_name": user.ClassName, "student_id": user.StudentID, + "permission": user.Permission, }) } @@ -314,6 +315,7 @@ func UserLoginHandler(context *gin.Context) { "username": user.Username, "class_name": user.ClassName, "student_id": user.StudentID, + "permission": user.Permission, }) } diff --git a/tool/config.go b/tool/config.go index 8239ad8..53b90fc 100644 --- a/tool/config.go +++ b/tool/config.go @@ -2,6 +2,7 @@ package tool import ( "bufio" + "ddlBackend/database" "ddlBackend/models" "encoding/json" "os" @@ -14,6 +15,8 @@ type Config struct { JWGLOutTime int64 `json:"jwgl_out_time"` JWGrpcAddress string `json:"jw_grpc_address"` RootConfig models.UserInformation `json:"root_config"` + UseMysql bool `json:"use_mysql"` + MysqlConfig database.MysqlModel `json:"mysql_config"` } // DefaultSetting 默认配置文件 @@ -22,7 +25,7 @@ var DefaultSetting = Config{ JWTSecret: "MakeBuptGreatAgain", JWGLOutTime: 24, PasswordSalt: "MakeBuptGreatAgain", - JWGrpcAddress: "http://rrricardo.top:7000", + JWGrpcAddress: "rrricardo.top:7000", RootConfig: models.UserInformation{ Username: "root", Password: "123456", @@ -30,6 +33,7 @@ var DefaultSetting = Config{ StudentID: "0000000000", Permission: models.Root, }, + UseMysql: false, } // Setting 配置文件对象 -- Gitee From 71e21810cc06477d99bc79dfbd57fed5eb686544 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 20 Aug 2022 15:33:24 +0800 Subject: [PATCH 38/41] =?UTF-8?q?=E5=9C=A8README=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=AF=B9=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E7=9A=84=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 102 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index ab29c0f..b30a933 100644 --- a/README.md +++ b/README.md @@ -32,54 +32,86 @@ go build ### 配置文件 程序采用`config.json`文件作为配置文件,该文件的模板如下 + ```json { - // 服务器运行时执行的端口 - "app_port": ":4000", - // JWT签发密钥时使用的字符串 - "jwt_secret": "MakeBUPTGreatAgain", - // 请求教务系统API的超时时间 - "jwgl_out_time": 0, - // 根管理员的设置 - // 该管理员将在程序运行时自动创建 - "root_config": { - // 用户名 - "username": "root", - // 密码 - "password": "123456", - // 所属的班级 - "classname": "dddd", - // 学号 - "student_id": "0000000000", - // 权限 - // 0-User 用户 只能够查看信息而不能修改信息 - // 1-Admin 管理员 可以修改自己所在班级的信息 - // 2-Root 根管理员 可以修改所有的信息 - "permission": 2 - } + "app_port": ":4000", + "jwt_secret": "MakeBUPTGreatAgain", + "jwgl_out_time": 0, + "root_config": { + "username": "root", + "password": "123456", + "class_name": "dddd", + "student_id": "0000000000", + "permission": 2 + }, + "use_mysql": false, + "mysql_config": { + "username": "admin", + "password": "123456", + "address": "localhost:3306", + "database_name": "name" + } } ``` +配置文件中各个字段的意义如下: + +- `app_port` 服务器运行的端口号 +- `jwt_secret` 签发JWT令牌时采用的密钥 +- `jwgl_out_time` 请求教务系统时,为避免过于频繁的请求而设置的超时时间 +- `root_config` 为方便管理 在程序开始运行时会自动在数据库中创建的管理用户账号 +- `use_mysql` 程序是否使用`mysql`作为数据库 + +`root_config`下述字段的意义如下: + +- `username`: 用户名/姓名 +- `password`: 密码 +- `class_name`: 所属班级 +- `student_id`: 学号 +- `permission`: 权限 + +`mysql_config`下述字段的意义如下: + +- `username`: 数据库用户名 +- `password`: 对应用户的密码 +- `address`: 数据库所在的地址 +- `database_name`: 数据库名称 + +> 在程序中,班级可被设置为"dddd"以表示大班或者"304"~"309"以表示各小班 +> +> 在程序中,人员的权限可被设置为如下三个层级: +> +> - 0 普通用户 只能查看而无法修改任何内容 +> - 1 班级管理员 可以修改本班的内容 +> - 2 根管理员 可以修改所有的内容 +> +> 在`use_mysql`字段被设置为`false`的状态下,`mysql_config`字段可以不填写 + 在根目录下不存在`config.json`配置文件的时候,程序会采用下述默认配置运行 ```json -{ - "app_port": ":8080", - "jwt_secret": "MakeBUPTGreatAgain", - "jwgl_out_time": 24, - "root_config": { - "username": "root", - "password": "123456", - "classname": "dddd", - "student_id": "0000000000", - "permission": 2 - } +{ + "app_port": ":8080", + "jwt_secret": "MakeBUPTGreatAgain", + "jwgl_out_time": 24, + "root_config": { + "username": "root", + "password": "123456", + "classname": "dddd", + "student_id": "0000000000", + "permission": 2 + }, + "use_mysql": false } ``` +程序会在当前文件夹中自动创建一个`test.db`的数据库文件,采用`sqlite`作为默认的数据库。 + ## API文档 -使用[Apifox](https://www.apifox.cn/)产生的文档[链接](https://www.apifox.cn/apidoc/shared-5d0ad1be-c569-466d-9c59-3e4686b7e482/api-33104131) +使用[Apifox](https://www.apifox.cn/) +产生的文档[链接](https://www.apifox.cn/apidoc/shared-5d0ad1be-c569-466d-9c59-3e4686b7e482/api-33104131) -- Gitee From 68e461202e88d906e51db50254897ab9c5bf175a Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 20 Aug 2022 16:09:16 +0800 Subject: [PATCH 39/41] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/mysql.go => models/mysql_model.go | 2 +- tool/config.go | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) rename database/mysql.go => models/mysql_model.go (96%) diff --git a/database/mysql.go b/models/mysql_model.go similarity index 96% rename from database/mysql.go rename to models/mysql_model.go index 322fd39..442f522 100644 --- a/database/mysql.go +++ b/models/mysql_model.go @@ -1,4 +1,4 @@ -package database +package models import "fmt" diff --git a/tool/config.go b/tool/config.go index 53b90fc..61b6815 100644 --- a/tool/config.go +++ b/tool/config.go @@ -2,7 +2,6 @@ package tool import ( "bufio" - "ddlBackend/database" "ddlBackend/models" "encoding/json" "os" @@ -16,7 +15,7 @@ type Config struct { JWGrpcAddress string `json:"jw_grpc_address"` RootConfig models.UserInformation `json:"root_config"` UseMysql bool `json:"use_mysql"` - MysqlConfig database.MysqlModel `json:"mysql_config"` + MysqlConfig models.MysqlModel `json:"mysql_config"` } // DefaultSetting 默认配置文件 -- Gitee From f7e5609aef291f1870da7c5742b850a15bc0c6eb Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 20 Aug 2022 16:28:05 +0800 Subject: [PATCH 40/41] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=BC=BA=E9=99=B7=E7=9A=84jwt-go=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Middleware/jwt_middleware.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- models/jwt_claims.go | 4 ++-- tool/jwt.go | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Middleware/jwt_middleware.go b/Middleware/jwt_middleware.go index 8456c80..61c34ef 100644 --- a/Middleware/jwt_middleware.go +++ b/Middleware/jwt_middleware.go @@ -33,7 +33,7 @@ func JWTAuthMiddleware() gin.HandlerFunc { "error": err.Error(), }) context.Abort() - } else if time.Now().Unix() > claims.ExpiresAt { + } else if time.Now().Unix() > claims.ExpiresAt.Unix() { // 令牌过期 context.JSON(http.StatusUnauthorized, gin.H{ "error": "The token has been expired", diff --git a/go.mod b/go.mod index 1a7aa1c..03cae07 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module ddlBackend go 1.18 require ( - github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 github.com/gin-gonic/gin v1.8.1 + github.com/golang-jwt/jwt/v4 v4.4.2 github.com/satori/go.uuid v1.2.0 google.golang.org/grpc v1.48.0 google.golang.org/protobuf v1.28.0 diff --git a/go.sum b/go.sum index dc568c7..dca64c5 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -42,6 +40,8 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= diff --git a/models/jwt_claims.go b/models/jwt_claims.go index 738b618..fae9f91 100644 --- a/models/jwt_claims.go +++ b/models/jwt_claims.go @@ -1,11 +1,11 @@ package models -import "github.com/dgrijalva/jwt-go" +import "github.com/golang-jwt/jwt/v4" // JWTClaims JWT实体信息 type JWTClaims struct { StudentID string `json:"student_id"` ClassName string `json:"class_name"` Permission uint `json:"permission"` - jwt.StandardClaims + jwt.RegisteredClaims } diff --git a/tool/jwt.go b/tool/jwt.go index 18aeaac..9bf528d 100644 --- a/tool/jwt.go +++ b/tool/jwt.go @@ -5,8 +5,8 @@ import ( "errors" "time" - "github.com/dgrijalva/jwt-go" "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v4" ) // GenerateJWTToken 生成JWT令牌 @@ -19,9 +19,9 @@ func GenerateJWTToken(info models.UserInformation) (string, error) { StudentID: info.StudentID, ClassName: info.ClassName, Permission: info.Permission, - StandardClaims: jwt.StandardClaims{ + RegisteredClaims: jwt.RegisteredClaims{ // token失效时间 - ExpiresAt: expireTime.Unix(), + ExpiresAt: jwt.NewNumericDate(expireTime), // token签发人 Issuer: "SquidWard", }, -- Gitee From 532407ba6483b021eb16fe2259168077900d6bc2 Mon Sep 17 00:00:00 2001 From: Ricardo Ren <66121838+jackfiled@users.noreply.github.com> Date: Sat, 20 Aug 2022 16:29:35 +0800 Subject: [PATCH 41/41] Create LICENSE --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. -- Gitee