package handler import ( "crypto/subtle" "net/http" "github.com/gin-gonic/gin" "github.com/gouki/lunar-server/internal/config" "github.com/gouki/lunar-server/internal/service" ) // adminPage 统一的管理后台页面渲染(补充 Inertia 需要的 url 属性) func adminPage(c *gin.Context, title, page string) { c.HTML(http.StatusOK, "index.html", gin.H{ "title": title, "page": page, "url": c.Request.URL.Path, }) } // AdminLogin 管理员登录:密码正确签发 role=admin 的 JWT func AdminLogin(c *gin.Context) { cfg := config.Load() if cfg.Admin.Password == "" { c.JSON(http.StatusServiceUnavailable, gin.H{ "code": 503, "msg": "后台登录未启用", }) return } var req struct { Password string `json:"password" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{ "code": 400, "msg": "参数错误", }) return } // 恒定时间比较,防时序攻击 if subtle.ConstantTimeCompare([]byte(req.Password), []byte(cfg.Admin.Password)) != 1 { c.JSON(http.StatusUnauthorized, gin.H{ "code": 401, "msg": "密码错误", }) return } userService := service.NewUserService() token, err := userService.GenerateAdminToken(cfg.JWT.Secret) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ "code": 500, "msg": "生成token失败", }) return } // 同时写入 HttpOnly Cookie,支持浏览器直接导航后台页面 c.SetSameSite(http.SameSiteLaxMode) c.SetCookie(service.AdminTokenCookie, token, 12*3600, "/admin", "", cfg.Server.Env == "production", true) c.JSON(http.StatusOK, gin.H{ "code": 0, "msg": "success", "data": gin.H{ "token": token, }, }) } // AdminLogout 管理员登出:清除会话 Cookie func AdminLogout(c *gin.Context) { cfg := config.Load() c.SetCookie(service.AdminTokenCookie, "", -1, "/admin", "", cfg.Server.Env == "production", true) c.JSON(http.StatusOK, gin.H{ "code": 0, "msg": "success", }) } // AdminDashboard 管理后台首页 func AdminDashboard(c *gin.Context) { adminPage(c, "管理后台", "dashboard") } // AdminUsers 用户管理 func AdminUsers(c *gin.Context) { adminPage(c, "用户管理", "users") } // AdminOrders 订单管理 func AdminOrders(c *gin.Context) { adminPage(c, "订单管理", "orders") } // AdminWishes 许愿管理 func AdminWishes(c *gin.Context) { adminPage(c, "许愿管理", "wishes") } // AdminSettings 系统设置 func AdminSettings(c *gin.Context) { adminPage(c, "系统设置", "settings") }