From 0e248830a96a418cd9f842f1d0322ea32c1fef34 Mon Sep 17 00:00:00 2001 From: jdysya <1912377458@qq.com> Date: Sat, 15 Feb 2025 16:09:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(gateway):=20=E5=AE=9E=E7=8E=B0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=B3=A8=E5=86=8C=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=99=BB=E5=BD=95=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增用户模型和数据库迁移 - 实现用户注册页面和处理逻辑 - 更新登录页面,使用手机号作为用户名 - 添加密码加密存储 - 优化错误处理和用户提示 --- .gitignore | 1 + gateway/.idea/dataSources.xml | 15 +++ gateway/go.mod | 5 +- gateway/go.sum | 34 ++++++ gateway/main.go | 183 ++++++++++++++++++++++++++++---- gateway/templates/login.html | 10 +- gateway/templates/register.html | 86 +++++++++++++++ 7 files changed, 312 insertions(+), 22 deletions(-) create mode 100644 gateway/.idea/dataSources.xml create mode 100644 gateway/templates/register.html diff --git a/.gitignore b/.gitignore index a4a21d3..1e6aafd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ src/.vuepress/.cache/ src/.vuepress/.temp/ src/.vuepress/dist/ .DS_Store +*.db \ No newline at end of file diff --git a/gateway/.idea/dataSources.xml b/gateway/.idea/dataSources.xml new file mode 100644 index 0000000..15e666d --- /dev/null +++ b/gateway/.idea/dataSources.xml @@ -0,0 +1,15 @@ + + + + + sqlite.xerial + true + org.sqlite.JDBC + jdbc:sqlite:$PROJECT_DIR$/family.db + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/gateway/go.mod b/gateway/go.mod index 8955e92..9d9fbf6 100644 --- a/gateway/go.mod +++ b/gateway/go.mod @@ -5,7 +5,9 @@ go 1.23.3 require ( github.com/gin-contrib/sessions v1.0.2 github.com/gin-gonic/gin v1.10.0 + github.com/jinzhu/gorm v1.9.16 github.com/sirupsen/logrus v1.9.3 + golang.org/x/crypto v0.31.0 ) require ( @@ -22,17 +24,18 @@ require ( github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.4.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-sqlite3 v1.14.16 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.31.0 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect diff --git a/gateway/go.sum b/gateway/go.sum index 8b7e353..99d5003 100644 --- a/gateway/go.sum +++ b/gateway/go.sum @@ -1,3 +1,5 @@ +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= @@ -9,6 +11,10 @@ github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQ 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/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA= @@ -25,8 +31,12 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= 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= @@ -38,6 +48,13 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ= github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +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.0.1/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/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -46,8 +63,14 @@ github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -78,15 +101,26 @@ github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +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-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/gateway/main.go b/gateway/main.go index 1ce55c3..1031352 100644 --- a/gateway/main.go +++ b/gateway/main.go @@ -1,19 +1,38 @@ package main import ( - "fmt" "net/http" "os" + "strconv" + "strings" "time" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/sqlite" "github.com/sirupsen/logrus" + "golang.org/x/crypto/bcrypt" ) var logger = logrus.New() +// 在全局变量后新增用户模型 +type Region struct { + ID uint `gorm:"primary_key"` + Name string `gorm:"not null;unique"` +} + +type User struct { + gorm.Model + FullName string `gorm:"not null"` + RegionID uint `gorm:"not null"` // 修改为关联地区ID + Mobile string `gorm:"unique;not null"` + Password string `gorm:"not null"` + Region Region // 关联关系 +} + func init() { // 配置日志格式 logger.SetFormatter(&logrus.JSONFormatter{}) @@ -21,6 +40,14 @@ func init() { } func main() { + // 初始化数据库 + db, err := gorm.Open("sqlite3", "family.db") + if err != nil { + logger.Fatalf("数据库连接失败: %v", err) + } + defer db.Close() + db.AutoMigrate(&Region{}, &User{}) // 同时迁移Region和User表 + // 初始化 Gin 引擎 r := gin.Default() @@ -45,21 +72,137 @@ func main() { // 处理登录请求 r.POST("/login", func(c *gin.Context) { - username := c.PostForm("username") + username := c.PostForm("username") // 修改表单字段名 password := c.PostForm("password") - if username == "admin" && password == "123" { - session := sessions.Default(c) - session.Set("user", username) - if err := session.Save(); err != nil { - logger.Errorf("Session保存失败: %v", err) - c.HTML(http.StatusInternalServerError, "login.html", gin.H{"error": "登录状态保存失败"}) - return - } - c.Redirect(http.StatusSeeOther, "/") // 改用303状态码 + var user User + // 电话号作为用户名 + if err := db.Where("mobile = ?", username).First(&user).Error; err != nil { + c.HTML(http.StatusUnauthorized, "login.html", gin.H{"error": "用户不存在或密码错误"}) return } - c.HTML(http.StatusUnauthorized, "login.html", gin.H{"error": "用户名或密码错误"}) + + // 验证密码 + if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil { + c.HTML(http.StatusUnauthorized, "login.html", gin.H{"error": "用户不存在或密码错误"}) + return + } + + // 保存session(保持原有逻辑) + session := sessions.Default(c) + session.Set("user", user.ID) + if err := session.Save(); err != nil { + logger.Errorf("Session保存失败: %v", err) + c.HTML(http.StatusInternalServerError, "login.html", gin.H{"error": "登录状态保存失败"}) + return + } + c.Redirect(http.StatusSeeOther, "/") // 改用303状态码 + }) + + // 在登录路由后新增注册路由 + // 注册页面 + r.GET("/register", func(c *gin.Context) { + regions, err := getRegions(db) + if err != nil { + c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"}) + return + } + c.HTML(http.StatusOK, "register.html", gin.H{"regions": regions}) + }) + + // 处理注册请求 + r.POST("/register", func(c *gin.Context) { + // 获取地区参数(修改这部分) + regionStr, exists := c.GetPostForm("region") + if !exists { + regions, err := getRegions(db) + if err != nil { + c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"}) + return + } + c.HTML(http.StatusBadRequest, "register.html", gin.H{ + "error": "请选择所在地区", + "regions": regions, + "form": gin.H{ + "fullname": c.PostForm("fullname"), + "mobile": c.PostForm("mobile"), + }, + }) + return + } + + // 转换地区ID为数字 + regionID, err := strconv.ParseUint(regionStr, 10, 32) + if err != nil { + regions, err := getRegions(db) + if err != nil { + c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"}) + return + } + c.HTML(http.StatusBadRequest, "register.html", gin.H{ + "error": "无效的地区参数", + "regions": regions, + "form": gin.H{ + "fullname": c.PostForm("fullname"), + "mobile": c.PostForm("mobile"), + }, + }) + return + } + + user := User{ + FullName: c.PostForm("fullname"), + Mobile: c.PostForm("mobile"), + RegionID: uint(regionID), // 使用转换后的ID + } + + // 验证地区是否存在 + var region Region + if err := db.First(®ion, user.RegionID).Error; err != nil { + regions, err := getRegions(db) + if err != nil { + c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "系统错误"}) + return + } + c.HTML(http.StatusBadRequest, "register.html", gin.H{ + "error": "请选择有效地区", + "regions": regions, + "form": gin.H{ + "fullname": c.PostForm("fullname"), + "mobile": c.PostForm("mobile"), + }, + }) + return + } + + // 验证手机号格式 + if len(user.Mobile) != 11 { + c.HTML(http.StatusBadRequest, "register.html", gin.H{"error": "手机号格式不正确"}) + return + } + + // 密码加密 + password := c.PostForm("password") + hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + logger.Errorf("密码加密失败: %v", err) + c.HTML(http.StatusInternalServerError, "register.html", gin.H{"error": "注册失败"}) + return + } + user.Password = string(hashedPassword) + + // 创建用户 + if err := db.Create(&user).Error; err != nil { + logger.Errorf("用户创建失败: %v", err) + errorMsg := "注册失败" + if strings.Contains(err.Error(), "UNIQUE constraint failed") { + errorMsg = "该手机号已注册" + } + c.HTML(http.StatusBadRequest, "register.html", gin.H{"error": errorMsg}) + return + } + + c.Redirect(http.StatusSeeOther, "/login") }) // 权限校验中间件 @@ -81,12 +224,6 @@ func main() { logAccess(c) http.ServeFile(c.Writer, c.Request, "./static/index.html") }) - r.GET("/guide/:page", func(c *gin.Context) { - // 记录访问痕迹 - logAccess(c) - page := c.Param("page") - http.ServeFile(c.Writer, c.Request, fmt.Sprintf("./static/guide/%s.html", page)) - }) // 在权限校验中间件后添加退出路由 r.GET("/logout", func(c *gin.Context) { @@ -102,6 +239,7 @@ func main() { // 新增通用静态文件路由(放在其他路由之后) r.NoRoute(func(c *gin.Context) { + logAccess(c) filePath := "./static" + c.Request.URL.Path // 检查文件是否存在 if _, err := os.Stat(filePath); err == nil { @@ -129,3 +267,12 @@ func logAccess(c *gin.Context) { "timestamp": timestamp, }).Info("Page accessed") } + +func getRegions(db *gorm.DB) ([]Region, error) { + var regions []Region + if err := db.Find(®ions).Error; err != nil { + logger.Errorf("获取地区数据失败: %v", err) + return nil, err + } + return regions, nil +} diff --git a/gateway/templates/login.html b/gateway/templates/login.html index d6e8c99..a361cf8 100644 --- a/gateway/templates/login.html +++ b/gateway/templates/login.html @@ -112,9 +112,10 @@

余氏族谱管理系统

- - + +
@@ -123,6 +124,9 @@
+ {{ if .error }}

{{ .error }}

{{ end }} diff --git a/gateway/templates/register.html b/gateway/templates/register.html new file mode 100644 index 0000000..29d7770 --- /dev/null +++ b/gateway/templates/register.html @@ -0,0 +1,86 @@ + + + + + + 用户注册 - 余氏族谱 + + + +
+

新用户注册

+
+
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ + + +
+ {{ if .error }} +

{{ .error }}

+ {{ end }} +
+ + \ No newline at end of file