Files
mce/internal/router/api.go
Victor_Jay d203447eb3 feat: 设置页新增登录管理 TAB
- Session 结构体新增 IP、UserAgent、Remark 字段,登录/注册时记录设备信息
- Store 接口新增 ListByUID、DeleteByUIDExclude 方法,MemoryStore 完整实现
- SessionManager 新增 ListByUID、DestroyOtherByUID、UpdateRemark 方法
- 新增 UA 轻量解析器(session/ua.go),提取浏览器/OS/设备类型
- 新增 settings_api_sessions.go,提供列表/踢出/一键踢出/备注 4 个 API
- 控制器层声明 sessionManager 最小接口(ISP),SettingsController 注入依赖
- Auth 中间件注入 sid 到 gin context,支持识别当前会话
- 设置页左侧导航增加登录管理入口,tab 白名单新增 sessions
- 前端实现设备列表展示(浏览器/OS/设备图标/IP/时间)、当前设备标识、备注输入、踢出按钮、一键踢出
- settings.css 新增会话管理全套样式及响应式适配
2026-05-30 23:58:37 +08:00

80 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package router
import (
"metazone.cc/metalab/internal/config"
"metazone.cc/metalab/internal/middleware"
"github.com/gin-gonic/gin"
)
// setupAPIRoutes 注册 API 路由
func setupAPIRoutes(r *gin.Engine, cfg *config.Config, d *dependencies) {
// --- 设置页 API需登录 ---
settingsAPI := r.Group("/api/settings")
settingsAPI.Use(d.authMdw.Required())
settingsAPI.Use(middleware.CSRF(cfg))
{
settingsAPI.PUT("/profile", d.settingsCtrl.UpdateProfile)
settingsAPI.POST("/avatar", d.settingsCtrl.UploadAvatar)
settingsAPI.PUT("/password", d.settingsCtrl.ChangePassword)
settingsAPI.POST("/delete-account", d.settingsCtrl.DeleteAccount)
settingsAPI.GET("/audit-status", d.settingsCtrl.AuditStatus)
// 登录管理
settingsAPI.GET("/sessions", d.settingsCtrl.ListSessions)
settingsAPI.DELETE("/sessions/:sid", d.settingsCtrl.DestroySession)
settingsAPI.POST("/sessions/destroy-others", d.settingsCtrl.DestroyOtherSessions)
settingsAPI.PUT("/sessions/:sid/remark", d.settingsCtrl.UpdateSessionRemark)
}
// --- 消息中心 API需登录 ---
messagesAPI := r.Group("/api/messages")
messagesAPI.Use(d.authMdw.Required())
messagesAPI.Use(middleware.CSRF(cfg))
{
messagesAPI.GET("/unread", d.messageCtrl.UnreadCount)
messagesAPI.POST("/:id/read", d.messageCtrl.MarkRead)
messagesAPI.POST("/read-all", d.messageCtrl.MarkAllRead)
}
// --- 认证 API ---
api := r.Group("/api")
api.Use(middleware.CSRF(cfg))
{
api.POST("/auth/check-email", d.tokenCtrl.CheckEmail)
api.POST("/auth/register", d.tokenCtrl.Register)
api.POST("/auth/login", d.tokenCtrl.Login)
api.POST("/auth/confirm-restore", d.tokenCtrl.ConfirmRestore)
api.POST("/auth/logout", d.tokenCtrl.Logout)
api.POST("/auth/refresh", d.tokenCtrl.RefreshToken)
// 帖子公开 API无需登录
api.GET("/posts", d.postCtrl.ListAPI)
api.GET("/posts/:id", d.postCtrl.ShowAPI)
}
// --- 帖子 API需登录 ---
postsAPI := r.Group("/api/posts")
postsAPI.Use(d.authMdw.Required())
postsAPI.Use(middleware.CSRF(cfg))
{
postsAPI.POST("", d.postCtrl.Create)
postsAPI.PUT("/:id", d.postCtrl.Update)
postsAPI.DELETE("/:id", d.postCtrl.Delete)
postsAPI.POST("/:id/submit", d.postCtrl.Submit)
postsAPI.POST("/upload-image", d.postCtrl.UploadImage)
}
// --- 创作中心 API需登录 ---
studioAPI := r.Group("/api/studio")
studioAPI.Use(d.authMdw.Required())
studioAPI.Use(middleware.CSRF(cfg))
{
studioAPI.GET("/overview", d.studioCtrl.OverviewAPI)
studioAPI.GET("/posts", d.studioCtrl.ListPostsAPI)
studioAPI.POST("/posts", d.studioCtrl.Create)
studioAPI.PUT("/posts/:id", d.studioCtrl.Update)
studioAPI.DELETE("/posts/:id", d.studioCtrl.Delete)
studioAPI.POST("/posts/:id/submit", d.studioCtrl.Submit)
}
}