refactor: 重构后端架构为 go-zero 框架,优化项目结构

主要变更:
- 采用 go-zero 框架替代 Gin,提升开发效率
- 重构项目结构,API 文件模块化组织
- 将 model 移至 api/internal/model 目录
- 移除 common 包,改为标准 pkg 目录结构
- 实现统一的仓储模式,支持配置驱动数据库切换
- 简化测试策略,专注 API 集成测试
- 更新 CLAUDE.md 文档,提供详细的开发指导

技术栈更新:
- 框架: Gin → go-zero v1.6.0+
- 代码生成: 引入 goctl 工具
- 架构模式: 四层架构 → go-zero 三层架构 (Handler→Logic→Model)
- 项目布局: 遵循 Go 社区标准和 go-zero 最佳实践
This commit is contained in:
xujiang
2025-07-10 15:05:52 +08:00
parent a2f2f66f88
commit 39a42695d3
52 changed files with 6047 additions and 2349 deletions

View File

@ -3,7 +3,8 @@ package auth
import (
"fmt"
"golang.org/x/crypto/bcrypt"
"photography-backend/internal/models"
"photography-backend/internal/model/entity"
"photography-backend/internal/model/dto"
"photography-backend/internal/repository/postgres"
)
@ -22,23 +23,15 @@ func NewAuthService(userRepo postgres.UserRepository, jwtService *JWTService) *A
}
// Login 用户登录
func (s *AuthService) Login(req *models.LoginRequest) (*models.LoginResponse, error) {
func (s *AuthService) Login(req *dto.LoginRequest) (*dto.LoginResponse, error) {
// 根据用户名或邮箱查找用户
var user *models.User
var user *entity.User
var err error
// 尝试按用户名查找
user, err = s.userRepo.GetByUsername(req.Username)
// 按邮箱查找用户
user, err = s.userRepo.GetByEmail(req.Email)
if err != nil {
return nil, fmt.Errorf("failed to get user: %w", err)
}
// 如果用户名未找到,尝试按邮箱查找
if user == nil {
user, err = s.userRepo.GetByEmail(req.Username)
if err != nil {
return nil, fmt.Errorf("failed to get user by email: %w", err)
}
return nil, fmt.Errorf("failed to get user by email: %w", err)
}
if user == nil {
@ -56,7 +49,7 @@ func (s *AuthService) Login(req *models.LoginRequest) (*models.LoginResponse, er
}
// 生成JWT令牌
tokenPair, err := s.jwtService.GenerateTokenPair(user.ID, user.Username, user.Role)
tokenPair, err := s.jwtService.GenerateTokenPair(user.ID, user.Username, string(user.Role))
if err != nil {
return nil, fmt.Errorf("failed to generate tokens: %w", err)
}
@ -70,17 +63,19 @@ func (s *AuthService) Login(req *models.LoginRequest) (*models.LoginResponse, er
// 清除密码字段
user.Password = ""
return &models.LoginResponse{
AccessToken: tokenPair.AccessToken,
RefreshToken: tokenPair.RefreshToken,
TokenType: tokenPair.TokenType,
ExpiresIn: tokenPair.ExpiresIn,
User: user,
return &dto.LoginResponse{
Token: dto.TokenResponse{
AccessToken: tokenPair.AccessToken,
RefreshToken: tokenPair.RefreshToken,
TokenType: tokenPair.TokenType,
ExpiresIn: tokenPair.ExpiresIn,
},
User: *dto.ConvertToUserResponse(user),
}, nil
}
// Register 用户注册
func (s *AuthService) Register(req *models.CreateUserRequest) (*models.User, error) {
func (s *AuthService) Register(req *dto.CreateUserRequest) (*entity.User, error) {
// 检查用户名是否已存在
existingUser, err := s.userRepo.GetByUsername(req.Username)
if err != nil {
@ -106,7 +101,7 @@ func (s *AuthService) Register(req *models.CreateUserRequest) (*models.User, err
}
// 创建用户
user := &models.User{
user := &entity.User{
Username: req.Username,
Email: req.Email,
Password: string(hashedPassword),
@ -117,7 +112,7 @@ func (s *AuthService) Register(req *models.CreateUserRequest) (*models.User, err
// 如果没有指定角色,默认为普通用户
if user.Role == "" {
user.Role = models.RoleUser
user.Role = entity.UserRoleUser
}
if err := s.userRepo.Create(user); err != nil {
@ -131,7 +126,7 @@ func (s *AuthService) Register(req *models.CreateUserRequest) (*models.User, err
}
// RefreshToken 刷新令牌
func (s *AuthService) RefreshToken(req *models.RefreshTokenRequest) (*models.LoginResponse, error) {
func (s *AuthService) RefreshToken(req *dto.RefreshTokenRequest) (*dto.LoginResponse, error) {
// 验证刷新令牌
claims, err := s.jwtService.ValidateToken(req.RefreshToken)
if err != nil {
@ -154,7 +149,7 @@ func (s *AuthService) RefreshToken(req *models.RefreshTokenRequest) (*models.Log
}
// 生成新的令牌对
tokenPair, err := s.jwtService.GenerateTokenPair(user.ID, user.Username, user.Role)
tokenPair, err := s.jwtService.GenerateTokenPair(user.ID, user.Username, string(user.Role))
if err != nil {
return nil, fmt.Errorf("failed to generate tokens: %w", err)
}
@ -162,17 +157,19 @@ func (s *AuthService) RefreshToken(req *models.RefreshTokenRequest) (*models.Log
// 清除密码字段
user.Password = ""
return &models.LoginResponse{
AccessToken: tokenPair.AccessToken,
RefreshToken: tokenPair.RefreshToken,
TokenType: tokenPair.TokenType,
ExpiresIn: tokenPair.ExpiresIn,
User: user,
return &dto.LoginResponse{
Token: dto.TokenResponse{
AccessToken: tokenPair.AccessToken,
RefreshToken: tokenPair.RefreshToken,
TokenType: tokenPair.TokenType,
ExpiresIn: tokenPair.ExpiresIn,
},
User: *dto.ConvertToUserResponse(user),
}, nil
}
// GetUserByID 根据ID获取用户
func (s *AuthService) GetUserByID(id uint) (*models.User, error) {
func (s *AuthService) GetUserByID(id uint) (*entity.User, error) {
user, err := s.userRepo.GetByID(id)
if err != nil {
return nil, fmt.Errorf("failed to get user: %w", err)
@ -189,7 +186,7 @@ func (s *AuthService) GetUserByID(id uint) (*models.User, error) {
}
// UpdatePassword 更新密码
func (s *AuthService) UpdatePassword(userID uint, req *models.UpdatePasswordRequest) error {
func (s *AuthService) UpdatePassword(userID uint, req *dto.ChangePasswordRequest) error {
// 获取用户信息
user, err := s.userRepo.GetByID(userID)
if err != nil {
@ -221,11 +218,11 @@ func (s *AuthService) UpdatePassword(userID uint, req *models.UpdatePasswordRequ
}
// CheckPermission 检查权限
func (s *AuthService) CheckPermission(userRole string, requiredRole string) bool {
roleLevel := map[string]int{
models.RoleUser: 1,
models.RoleEditor: 2,
models.RoleAdmin: 3,
func (s *AuthService) CheckPermission(userRole entity.UserRole, requiredRole entity.UserRole) bool {
roleLevel := map[entity.UserRole]int{
entity.UserRoleUser: 1,
entity.UserRolePhotographer: 2,
entity.UserRoleAdmin: 3,
}
userLevel, exists := roleLevel[userRole]
@ -242,11 +239,11 @@ func (s *AuthService) CheckPermission(userRole string, requiredRole string) bool
}
// IsAdmin 检查是否为管理员
func (s *AuthService) IsAdmin(userRole string) bool {
return userRole == models.RoleAdmin
func (s *AuthService) IsAdmin(userRole entity.UserRole) bool {
return userRole == entity.UserRoleAdmin
}
// IsEditor 检查是否为编辑者或以上
func (s *AuthService) IsEditor(userRole string) bool {
return userRole == models.RoleEditor || userRole == models.RoleAdmin
// IsPhotographer 检查是否为摄影师或以上
func (s *AuthService) IsPhotographer(userRole entity.UserRole) bool {
return userRole == entity.UserRolePhotographer || userRole == entity.UserRoleAdmin
}