后台独立登录页面,并加入权限控制。

This commit is contained in:
2026-08-11 18:04:02 +08:00
parent 808f2e7523
commit a1d57d6b44
12 changed files with 638 additions and 178 deletions
+61
View File
@@ -18,6 +18,50 @@ func JWTSecret() []byte {
return jwtSecret
}
// AdminMenuItem 后台菜单项
type AdminMenuItem struct {
Key string `json:"key"` // 页面标识,与页面 div 的 data-page 对应
Name string `json:"name"` // 菜单显示名称
}
// AdminMenuGroup 后台菜单分组(Group 为空表示顶级菜单)
type AdminMenuGroup struct {
Group string `json:"group"`
Items []AdminMenuItem `json:"items"`
}
// GetMenusByRole 根据角色返回后台菜单
func GetMenusByRole(role string) []AdminMenuGroup {
if role == "admin" {
return []AdminMenuGroup{
{Group: "", Items: []AdminMenuItem{
{Key: "dashboard", Name: "仪表盘"},
}},
{Group: "内容管理", Items: []AdminMenuItem{
{Key: "posts", Name: "文章管理"},
{Key: "categories", Name: "分类管理"},
{Key: "tags", Name: "标签管理"},
{Key: "pages", Name: "页面管理"},
{Key: "comments", Name: "评论管理"},
}},
{Group: "系统管理", Items: []AdminMenuItem{
{Key: "users", Name: "用户管理"},
{Key: "files", Name: "文件管理"},
{Key: "themes", Name: "主题管理"},
{Key: "settings", Name: "基础设置"},
}},
}
}
// 普通用户:仪表盘 + 文章管理 + 评论管理
return []AdminMenuGroup{
{Group: "", Items: []AdminMenuItem{
{Key: "dashboard", Name: "仪表盘"},
{Key: "posts", Name: "文章管理"},
{Key: "comments", Name: "评论管理"},
}},
}
}
// 登录请求
type LoginRequest struct {
Username string `json:"username" binding:"required"`
@@ -88,6 +132,9 @@ func Login(c *gin.Context) {
return
}
// 同时写入 Cookie,供服务端渲染后台页面时识别登录态
c.SetCookie("token", tokenString, 7*24*3600, "/", "", false, true)
c.JSON(http.StatusOK, gin.H{
"token": tokenString,
"user": gin.H{
@@ -100,9 +147,23 @@ func Login(c *gin.Context) {
"last_login_at": user.LastLoginAt,
"login_count": user.LoginCount,
},
// 菜单由登录接口根据角色返回
"menus": GetMenusByRole(user.Role),
})
}
// 退出登录(清除服务端 Cookie)
func Logout(c *gin.Context) {
c.SetCookie("token", "", -1, "/", "", false, true)
c.JSON(http.StatusOK, gin.H{"message": "已退出登录"})
}
// WebLogout 前台页面退出登录(清除 Cookie 后回首页)
func WebLogout(c *gin.Context) {
c.SetCookie("token", "", -1, "/", "", false, true)
c.Redirect(http.StatusFound, "/")
}
// 获取当前用户信息
func GetCurrentUser(c *gin.Context) {
userID, _ := c.Get("userID")