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:
129
backend/internal/repository/postgres/user_repository.go
Normal file
129
backend/internal/repository/postgres/user_repository.go
Normal file
@ -0,0 +1,129 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"photography-backend/internal/models"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// UserRepository 用户仓库接口
|
||||
type UserRepository interface {
|
||||
Create(user *models.User) error
|
||||
GetByID(id uint) (*models.User, error)
|
||||
GetByUsername(username string) (*models.User, error)
|
||||
GetByEmail(email string) (*models.User, error)
|
||||
Update(user *models.User) error
|
||||
Delete(id uint) error
|
||||
List(page, limit int, role string, isActive *bool) ([]*models.User, int64, error)
|
||||
UpdateLastLogin(id uint) error
|
||||
}
|
||||
|
||||
// userRepository 用户仓库实现
|
||||
type userRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewUserRepository 创建用户仓库
|
||||
func NewUserRepository(db *gorm.DB) UserRepository {
|
||||
return &userRepository{db: db}
|
||||
}
|
||||
|
||||
// Create 创建用户
|
||||
func (r *userRepository) Create(user *models.User) error {
|
||||
if err := r.db.Create(user).Error; err != nil {
|
||||
return fmt.Errorf("failed to create user: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetByID 根据ID获取用户
|
||||
func (r *userRepository) GetByID(id uint) (*models.User, error) {
|
||||
var user models.User
|
||||
if err := r.db.First(&user, id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get user by id: %w", err)
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// GetByUsername 根据用户名获取用户
|
||||
func (r *userRepository) GetByUsername(username string) (*models.User, error) {
|
||||
var user models.User
|
||||
if err := r.db.Where("username = ?", username).First(&user).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get user by username: %w", err)
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// GetByEmail 根据邮箱获取用户
|
||||
func (r *userRepository) GetByEmail(email string) (*models.User, error) {
|
||||
var user models.User
|
||||
if err := r.db.Where("email = ?", email).First(&user).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get user by email: %w", err)
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
// Update 更新用户
|
||||
func (r *userRepository) Update(user *models.User) error {
|
||||
if err := r.db.Save(user).Error; err != nil {
|
||||
return fmt.Errorf("failed to update user: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除用户
|
||||
func (r *userRepository) Delete(id uint) error {
|
||||
if err := r.db.Delete(&models.User{}, id).Error; err != nil {
|
||||
return fmt.Errorf("failed to delete user: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// List 获取用户列表
|
||||
func (r *userRepository) List(page, limit int, role string, isActive *bool) ([]*models.User, int64, error) {
|
||||
var users []*models.User
|
||||
var total int64
|
||||
|
||||
query := r.db.Model(&models.User{})
|
||||
|
||||
// 添加过滤条件
|
||||
if role != "" {
|
||||
query = query.Where("role = ?", role)
|
||||
}
|
||||
if isActive != nil {
|
||||
query = query.Where("is_active = ?", *isActive)
|
||||
}
|
||||
|
||||
// 计算总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to count users: %w", err)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * limit
|
||||
if err := query.Offset(offset).Limit(limit).
|
||||
Order("created_at DESC").
|
||||
Find(&users).Error; err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to list users: %w", err)
|
||||
}
|
||||
|
||||
return users, total, nil
|
||||
}
|
||||
|
||||
// UpdateLastLogin 更新最后登录时间
|
||||
func (r *userRepository) UpdateLastLogin(id uint) error {
|
||||
if err := r.db.Model(&models.User{}).Where("id = ?", id).
|
||||
Update("last_login", gorm.Expr("NOW()")).Error; err != nil {
|
||||
return fmt.Errorf("failed to update last login: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user