This commit is contained in:
2025-07-20 20:53:26 +08:00
parent 83bf9aea7d
commit 8ad1d7288e
158 changed files with 18156 additions and 13188 deletions

View File

@@ -0,0 +1,456 @@
package examples
import (
"context"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
"tyapi-server/internal/domains/user/entities"
"tyapi-server/internal/domains/user/repositories"
"tyapi-server/internal/domains/user/repositories/queries"
"tyapi-server/internal/shared/database"
"tyapi-server/internal/shared/interfaces"
)
// ModernCachedUserRepository 现代化的用户仓储(使用新缓存方案)
type ModernCachedUserRepository struct {
*database.CachedBaseRepositoryImpl
}
// 编译时检查接口实现
var _ repositories.UserRepository = (*ModernCachedUserRepository)(nil)
// NewModernCachedUserRepository 创建现代化缓存用户仓储
func NewModernCachedUserRepository(db *gorm.DB, logger *zap.Logger) repositories.UserRepository {
return &ModernCachedUserRepository{
CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(db, logger, "users"),
}
}
// ================ Repository[T] 接口实现 ================
// Create 创建用户(自动失效相关缓存)
func (r *ModernCachedUserRepository) Create(ctx context.Context, user entities.User) (entities.User, error) {
r.GetLogger().Info("创建用户", zap.String("phone", user.Phone))
// 使用基础创建方法GORM插件会自动处理缓存失效
err := r.CreateEntity(ctx, &user)
return user, err
}
// GetByID 根据ID获取用户自动缓存30分钟
func (r *ModernCachedUserRepository) GetByID(ctx context.Context, id string) (entities.User, error) {
var user entities.User
// 使用智能缓存查询自动缓存30分钟
err := r.SmartGetByID(ctx, id, &user)
return user, err
}
// Update 更新用户(自动失效相关缓存)
func (r *ModernCachedUserRepository) Update(ctx context.Context, user entities.User) error {
r.GetLogger().Info("更新用户", zap.String("user_id", user.ID))
// 使用基础更新方法GORM插件会自动处理缓存失效
return r.UpdateEntity(ctx, &user)
}
// CreateBatch 批量创建用户
func (r *ModernCachedUserRepository) CreateBatch(ctx context.Context, users []entities.User) error {
r.GetLogger().Info("批量创建用户", zap.Int("count", len(users)))
return r.CreateBatchEntity(ctx, &users)
}
// GetByIDs 根据ID列表获取用户带缓存
func (r *ModernCachedUserRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.User, error) {
var users []entities.User
// 使用批量缓存查询缓存15分钟
err := r.BatchGetWithCache(ctx, ids, &users, 15*time.Minute)
return users, err
}
// UpdateBatch 批量更新用户
func (r *ModernCachedUserRepository) UpdateBatch(ctx context.Context, users []entities.User) error {
r.GetLogger().Info("批量更新用户", zap.Int("count", len(users)))
return r.UpdateBatchEntity(ctx, &users)
}
// DeleteBatch 批量删除用户
func (r *ModernCachedUserRepository) DeleteBatch(ctx context.Context, ids []string) error {
r.GetLogger().Info("批量删除用户", zap.Strings("ids", ids))
return r.DeleteBatchEntity(ctx, ids, &entities.User{})
}
// List 获取用户列表(智能缓存)
func (r *ModernCachedUserRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.User, error) {
var users []entities.User
// 使用智能列表查询,根据查询复杂度自动选择缓存策略
err := r.SmartList(ctx, &users, options)
return users, err
}
// ================ BaseRepository 接口实现 ================
// Delete 删除用户
func (r *ModernCachedUserRepository) Delete(ctx context.Context, id string) error {
return r.DeleteEntity(ctx, id, &entities.User{})
}
// Exists 检查用户是否存在(带缓存)
func (r *ModernCachedUserRepository) Exists(ctx context.Context, id string) (bool, error) {
return r.ExistsEntity(ctx, id, &entities.User{})
}
// Count 统计用户数量(智能缓存)
func (r *ModernCachedUserRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
var count int64
// 计算缓存TTL
cacheTTL := 10 * time.Minute
if options.Search != "" {
cacheTTL = 2 * time.Minute // 搜索查询缓存时间更短
}
err := r.CountWithCache(ctx, &count, cacheTTL, &entities.User{}, "", nil)
return count, err
}
// SoftDelete 软删除用户
func (r *ModernCachedUserRepository) SoftDelete(ctx context.Context, id string) error {
return r.SoftDeleteEntity(ctx, id, &entities.User{})
}
// Restore 恢复用户
func (r *ModernCachedUserRepository) Restore(ctx context.Context, id string) error {
return r.RestoreEntity(ctx, id, &entities.User{})
}
// ================ 业务专用方法使用新缓存API ================
// GetByPhone 根据手机号获取用户缓存15分钟
func (r *ModernCachedUserRepository) GetByPhone(ctx context.Context, phone string) (*entities.User, error) {
var user entities.User
// 使用智能字段查询自动缓存15分钟
err := r.SmartGetByField(ctx, &user, "phone", phone, 15*time.Minute)
if err != nil {
return nil, err
}
return &user, nil
}
// GetByUsername 根据用户名获取用户缓存15分钟
func (r *ModernCachedUserRepository) GetByUsername(ctx context.Context, username string) (*entities.User, error) {
var user entities.User
err := r.SmartGetByField(ctx, &user, "username", username, 15*time.Minute)
if err != nil {
return nil, err
}
return &user, nil
}
// GetByUserType 根据用户类型获取用户列表
func (r *ModernCachedUserRepository) GetByUserType(ctx context.Context, userType string) ([]*entities.User, error) {
var users []*entities.User
err := r.FindWithCache(ctx, &users, 30*time.Minute, "user_type = ?", userType)
return users, err
}
// ListUsers 获取用户列表(带分页和筛选)
func (r *ModernCachedUserRepository) ListUsers(ctx context.Context, query *queries.ListUsersQuery) ([]*entities.User, int64, error) {
var users []*entities.User
var total int64
// 构建查询条件
db := r.GetDB(ctx).Set("cache:enabled", true).Set("cache:ttl", 15*time.Minute)
// 应用筛选条件
if query.Phone != "" {
db = db.Where("phone LIKE ?", "%"+query.Phone+"%")
}
if query.StartDate != "" {
db = db.Where("created_at >= ?", query.StartDate)
}
if query.EndDate != "" {
db = db.Where("created_at <= ?", query.EndDate)
}
// 统计总数
if err := db.Model(&entities.User{}).Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用分页
offset := (query.Page - 1) * query.PageSize
if err := db.Offset(offset).Limit(query.PageSize).Find(&users).Error; err != nil {
return nil, 0, err
}
return users, total, nil
}
// ValidateUser 验证用户登录
func (r *ModernCachedUserRepository) ValidateUser(ctx context.Context, phone, password string) (*entities.User, error) {
// 登录验证不使用缓存,确保安全性
var user entities.User
db := r.WithoutCache().GetDB(ctx)
err := db.Where("phone = ? AND password = ?", phone, password).First(&user).Error
if err != nil {
return nil, err
}
return &user, nil
}
// UpdateLastLogin 更新最后登录时间
func (r *ModernCachedUserRepository) UpdateLastLogin(ctx context.Context, userID string) error {
now := time.Now()
return r.GetDB(ctx).Model(&entities.User{}).
Where("id = ?", userID).
Updates(map[string]interface{}{
"last_login_at": &now,
"updated_at": now,
}).Error
}
// UpdatePassword 更新密码
func (r *ModernCachedUserRepository) UpdatePassword(ctx context.Context, userID string, newPassword string) error {
return r.GetDB(ctx).Model(&entities.User{}).
Where("id = ?", userID).
Update("password", newPassword).Error
}
// CheckPassword 检查密码
func (r *ModernCachedUserRepository) CheckPassword(ctx context.Context, userID string, password string) (bool, error) {
var count int64
err := r.GetDB(ctx).Model(&entities.User{}).
Where("id = ? AND password = ?", userID, password).
Count(&count).Error
return count > 0, err
}
// ActivateUser 激活用户
func (r *ModernCachedUserRepository) ActivateUser(ctx context.Context, userID string) error {
return r.GetDB(ctx).Model(&entities.User{}).
Where("id = ?", userID).
Update("active", true).Error
}
// DeactivateUser 停用用户
func (r *ModernCachedUserRepository) DeactivateUser(ctx context.Context, userID string) error {
return r.GetDB(ctx).Model(&entities.User{}).
Where("id = ?", userID).
Update("active", false).Error
}
// UpdateLoginStats 更新登录统计
func (r *ModernCachedUserRepository) UpdateLoginStats(ctx context.Context, userID string) error {
return r.GetDB(ctx).Model(&entities.User{}).
Where("id = ?", userID).
Updates(map[string]interface{}{
"login_count": gorm.Expr("login_count + 1"),
"last_login_at": time.Now(),
}).Error
}
// GetStats 获取用户统计信息
func (r *ModernCachedUserRepository) GetStats(ctx context.Context) (*repositories.UserStats, error) {
var stats repositories.UserStats
// 使用短期缓存获取统计信息
db := r.GetDB(ctx).Set("cache:enabled", true).Set("cache:ttl", 5*time.Minute)
// 总用户数
if err := db.Model(&entities.User{}).Count(&stats.TotalUsers).Error; err != nil {
return nil, err
}
// 活跃用户数
if err := db.Model(&entities.User{}).Where("active = ?", true).Count(&stats.ActiveUsers).Error; err != nil {
return nil, err
}
// 今日注册数
today := time.Now().Truncate(24 * time.Hour)
if err := db.Model(&entities.User{}).Where("created_at >= ?", today).Count(&stats.TodayRegistrations).Error; err != nil {
return nil, err
}
// 今日登录数
if err := db.Model(&entities.User{}).Where("last_login_at >= ?", today).Count(&stats.TodayLogins).Error; err != nil {
return nil, err
}
return &stats, nil
}
// GetStatsByDateRange 获取指定日期范围的用户统计
func (r *ModernCachedUserRepository) GetStatsByDateRange(ctx context.Context, startDate, endDate string) (*repositories.UserStats, error) {
var stats repositories.UserStats
db := r.GetDB(ctx).Set("cache:enabled", true).Set("cache:ttl", 10*time.Minute)
// 指定时间范围内的注册数
if err := db.Model(&entities.User{}).
Where("created_at >= ? AND created_at <= ?", startDate, endDate).
Count(&stats.TodayRegistrations).Error; err != nil {
return nil, err
}
// 指定时间范围内的登录数
if err := db.Model(&entities.User{}).
Where("last_login_at >= ? AND last_login_at <= ?", startDate, endDate).
Count(&stats.TodayLogins).Error; err != nil {
return nil, err
}
return &stats, nil
}
// GetActiveUsers 获取活跃用户(使用短期缓存)
func (r *ModernCachedUserRepository) GetActiveUsers(ctx context.Context) ([]entities.User, error) {
var users []entities.User
// 活跃用户查询使用短期缓存5分钟
err := r.WithShortCache().FindWithCache(ctx, &users, 5*time.Minute, "active = ?", true)
return users, err
}
// GetUsersByType 根据用户类型获取用户(使用中期缓存)
func (r *ModernCachedUserRepository) GetUsersByType(ctx context.Context, userType string) ([]entities.User, error) {
var users []entities.User
// 用户类型查询使用中期缓存30分钟
err := r.WithMediumCache().FindWithCache(ctx, &users, 30*time.Minute, "user_type = ?", userType)
return users, err
}
// GetRecentUsers 获取最近注册用户(禁用缓存,实时数据)
func (r *ModernCachedUserRepository) GetRecentUsers(ctx context.Context, limit int) ([]entities.User, error) {
var users []entities.User
// 最近用户查询禁用缓存,保证数据实时性
db := r.WithoutCache().GetDB(ctx)
err := db.Order("created_at DESC").Limit(limit).Find(&users).Error
return users, err
}
// GetPopularUsers 获取热门用户(使用长期缓存)
func (r *ModernCachedUserRepository) GetPopularUsers(ctx context.Context, limit int) ([]entities.User, error) {
var users []entities.User
// 热门用户查询使用长期缓存2小时
err := r.WithLongCache().GetDB(ctx).
Order("login_count DESC").
Limit(limit).
Find(&users).Error
return users, err
}
// SearchUsers 搜索用户(智能缓存策略)
func (r *ModernCachedUserRepository) SearchUsers(ctx context.Context, keyword string, limit int) ([]entities.User, error) {
var users []entities.User
// 搜索查询使用短期缓存,避免频繁的数据库查询
db := r.GetDB(ctx).
Set("cache:enabled", true).
Set("cache:ttl", 2*time.Minute). // 搜索结果缓存2分钟
Where("username LIKE ? OR phone LIKE ?", "%"+keyword+"%", "%"+keyword+"%").
Limit(limit)
err := db.Find(&users).Error
return users, err
}
// ================ 缓存管理方法 ================
// WarmupUserCache 预热用户缓存
func (r *ModernCachedUserRepository) WarmupUserCache(ctx context.Context) error {
r.GetLogger().Info("开始预热用户缓存")
// 定义预热查询
queries := []database.WarmupQuery{
{
Name: "active_users",
TTL: 30 * time.Minute,
Dest: &[]entities.User{},
},
{
Name: "user_types",
TTL: 60 * time.Minute,
Dest: &[]entities.User{},
},
{
Name: "recent_users",
TTL: 10 * time.Minute,
Dest: &[]entities.User{},
},
}
return r.WarmupCommonQueries(ctx, queries)
}
// RefreshUserCache 刷新用户缓存
func (r *ModernCachedUserRepository) RefreshUserCache(ctx context.Context) error {
r.GetLogger().Info("刷新用户缓存")
// 刷新用户相关的所有缓存
return r.RefreshCache(ctx, "users:*")
}
// GetUserCacheStats 获取用户缓存统计
func (r *ModernCachedUserRepository) GetUserCacheStats() map[string]interface{} {
stats := r.GetCacheInfo()
stats["specific_patterns"] = []string{
"gorm_cache:users:*",
"user:id:*",
"user:phone:*",
}
return stats
}
// ================ 使用示例 ================
// ExampleUsage 使用示例
func (r *ModernCachedUserRepository) ExampleUsage(ctx context.Context) {
// 1. 基础查询(自动缓存)
user, _ := r.GetByID(ctx, "user-123")
r.GetLogger().Info("获取用户", zap.String("username", user.Username))
// 2. 手动控制缓存
// 使用短期缓存查询
var activeUsers []entities.User
_ = r.WithShortCache().FindWithCache(ctx, &activeUsers, 5*time.Minute, "active = ?", true)
r.GetLogger().Info("活跃用户数", zap.Int("count", len(activeUsers)))
// 禁用缓存查询
var recentUsers []entities.User
_ = r.WithoutCache().FindWhere(ctx, &recentUsers, "created_at > ?", time.Now().AddDate(0, 0, -7))
r.GetLogger().Info("最近用户数", zap.Int("count", len(recentUsers)))
// 3. 智能缓存查询
options := interfaces.ListOptions{
Page: 1,
PageSize: 20,
Filters: map[string]interface{}{"active": true},
Sort: "created_at",
Order: "desc",
}
users, _ := r.List(ctx, options) // 自动根据查询复杂度选择缓存策略
r.GetLogger().Info("用户列表", zap.Int("count", len(users)))
// 4. 缓存预热
r.WarmupUserCache(ctx)
}