feat: 实现后端和管理后台基础架构
## 后端架构 (Go + Gin + GORM) - ✅ 完整的分层架构 (API/Service/Repository) - ✅ PostgreSQL数据库设计和迁移脚本 - ✅ JWT认证系统和权限控制 - ✅ 用户、照片、分类、标签等核心模型 - ✅ 中间件系统 (认证、CORS、日志) - ✅ 配置管理和环境变量支持 - ✅ 结构化日志和错误处理 - ✅ Makefile构建和部署脚本 ## 管理后台架构 (React + TypeScript) - ✅ Vite + React 18 + TypeScript现代化架构 - ✅ 路由系统和状态管理 (Zustand + TanStack Query) - ✅ 基于Radix UI的组件库基础 - ✅ 认证流程和权限控制 - ✅ 响应式设计和主题系统 ## 数据库设计 - ✅ 用户表 (角色权限、认证信息) - ✅ 照片表 (元数据、EXIF、状态管理) - ✅ 分类表 (层级结构、封面图片) - ✅ 标签表 (使用统计、标签云) - ✅ 关联表 (照片-标签多对多) ## 技术特点 - 🚀 高性能: Gin框架 + GORM ORM - 🔐 安全: JWT认证 + 密码加密 + 权限控制 - 📊 监控: 结构化日志 + 健康检查 - 🎨 现代化: React 18 + TypeScript + Vite - 📱 响应式: Tailwind CSS + Radix UI 参考文档: docs/development/saved-docs/
This commit is contained in:
118
backend/internal/api/handlers/auth_handler.go
Normal file
118
backend/internal/api/handlers/auth_handler.go
Normal file
@ -0,0 +1,118 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"github.com/gin-gonic/gin"
|
||||
"photography-backend/internal/models"
|
||||
"photography-backend/internal/service/auth"
|
||||
"photography-backend/internal/api/middleware"
|
||||
"photography-backend/pkg/response"
|
||||
)
|
||||
|
||||
// AuthHandler 认证处理器
|
||||
type AuthHandler struct {
|
||||
authService *auth.AuthService
|
||||
}
|
||||
|
||||
// NewAuthHandler 创建认证处理器
|
||||
func NewAuthHandler(authService *auth.AuthService) *AuthHandler {
|
||||
return &AuthHandler{
|
||||
authService: authService,
|
||||
}
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
func (h *AuthHandler) Login(c *gin.Context) {
|
||||
var req models.LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
loginResp, err := h.authService.Login(&req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, response.Error(http.StatusUnauthorized, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.Success(loginResp))
|
||||
}
|
||||
|
||||
// Register 用户注册
|
||||
func (h *AuthHandler) Register(c *gin.Context) {
|
||||
var req models.CreateUserRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.authService.Register(&req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, response.Success(user))
|
||||
}
|
||||
|
||||
// RefreshToken 刷新令牌
|
||||
func (h *AuthHandler) RefreshToken(c *gin.Context) {
|
||||
var req models.RefreshTokenRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
loginResp, err := h.authService.RefreshToken(&req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusUnauthorized, response.Error(http.StatusUnauthorized, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.Success(loginResp))
|
||||
}
|
||||
|
||||
// GetProfile 获取用户资料
|
||||
func (h *AuthHandler) GetProfile(c *gin.Context) {
|
||||
userID, exists := middleware.GetCurrentUser(c)
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, response.Error(http.StatusUnauthorized, "User not authenticated"))
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.authService.GetUserByID(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, response.Error(http.StatusInternalServerError, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.Success(user))
|
||||
}
|
||||
|
||||
// UpdatePassword 更新密码
|
||||
func (h *AuthHandler) UpdatePassword(c *gin.Context) {
|
||||
userID, exists := middleware.GetCurrentUser(c)
|
||||
if !exists {
|
||||
c.JSON(http.StatusUnauthorized, response.Error(http.StatusUnauthorized, "User not authenticated"))
|
||||
return
|
||||
}
|
||||
|
||||
var req models.UpdatePasswordRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.authService.UpdatePassword(userID, &req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, response.Error(http.StatusBadRequest, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, response.Success(gin.H{"message": "Password updated successfully"}))
|
||||
}
|
||||
|
||||
// Logout 用户登出
|
||||
func (h *AuthHandler) Logout(c *gin.Context) {
|
||||
// 简单实现,实际应用中可能需要将token加入黑名单
|
||||
c.JSON(http.StatusOK, response.Success(gin.H{"message": "Logged out successfully"}))
|
||||
}
|
||||
Reference in New Issue
Block a user