feat: Enhance dependency injection and service integration

- Updated main.go to initialize email service and include it in the dependency injection container.
- Refactored handlers to utilize context in service method calls, improving consistency and error handling.
- Introduced new service options for upload, security, and captcha services, enhancing modularity and testability.
- Removed unused repository implementations to streamline the codebase.

This commit continues the effort to improve the architecture by ensuring all services are properly injected and utilized across the application.
This commit is contained in:
lan
2025-12-02 22:52:33 +08:00
parent 792e96b238
commit 034e02e93a
54 changed files with 2305 additions and 2708 deletions

View File

@@ -1,17 +1,11 @@
package repository
import (
"carrotskin/pkg/database"
"errors"
"gorm.io/gorm"
)
// getDB 获取数据库连接(内部使用)
func getDB() *gorm.DB {
return database.MustGetDB()
}
// IsNotFound 检查是否为记录未找到错误
func IsNotFound(err error) bool {
return errors.Is(err, gorm.ErrRecordNotFound)
@@ -79,4 +73,3 @@ func PaginatedQuery[T any](
return items, total, nil
}

View File

@@ -9,15 +9,23 @@ import (
"gorm.io/gorm"
)
// CreateProfile 创建档案
func CreateProfile(profile *model.Profile) error {
return getDB().Create(profile).Error
// profileRepository ProfileRepository的实现
type profileRepository struct {
db *gorm.DB
}
// FindProfileByUUID 根据UUID查找档案
func FindProfileByUUID(uuid string) (*model.Profile, error) {
// NewProfileRepository 创建ProfileRepository实例
func NewProfileRepository(db *gorm.DB) ProfileRepository {
return &profileRepository{db: db}
}
func (r *profileRepository) Create(profile *model.Profile) error {
return r.db.Create(profile).Error
}
func (r *profileRepository) FindByUUID(uuid string) (*model.Profile, error) {
var profile model.Profile
err := getDB().Where("uuid = ?", uuid).
err := r.db.Where("uuid = ?", uuid).
Preload("Skin").
Preload("Cape").
First(&profile).Error
@@ -27,20 +35,18 @@ func FindProfileByUUID(uuid string) (*model.Profile, error) {
return &profile, nil
}
// FindProfileByName 根据角色名查找档案
func FindProfileByName(name string) (*model.Profile, error) {
func (r *profileRepository) FindByName(name string) (*model.Profile, error) {
var profile model.Profile
err := getDB().Where("name = ?", name).First(&profile).Error
err := r.db.Where("name = ?", name).First(&profile).Error
if err != nil {
return nil, err
}
return &profile, nil
}
// FindProfilesByUserID 获取用户的所有档案
func FindProfilesByUserID(userID int64) ([]*model.Profile, error) {
func (r *profileRepository) FindByUserID(userID int64) ([]*model.Profile, error) {
var profiles []*model.Profile
err := getDB().Where("user_id = ?", userID).
err := r.db.Where("user_id = ?", userID).
Preload("Skin").
Preload("Cape").
Order("created_at DESC").
@@ -48,35 +54,30 @@ func FindProfilesByUserID(userID int64) ([]*model.Profile, error) {
return profiles, err
}
// UpdateProfile 更新档案
func UpdateProfile(profile *model.Profile) error {
return getDB().Save(profile).Error
func (r *profileRepository) Update(profile *model.Profile) error {
return r.db.Save(profile).Error
}
// UpdateProfileFields 更新指定字段
func UpdateProfileFields(uuid string, updates map[string]interface{}) error {
return getDB().Model(&model.Profile{}).
func (r *profileRepository) UpdateFields(uuid string, updates map[string]interface{}) error {
return r.db.Model(&model.Profile{}).
Where("uuid = ?", uuid).
Updates(updates).Error
}
// DeleteProfile 删除档案
func DeleteProfile(uuid string) error {
return getDB().Where("uuid = ?", uuid).Delete(&model.Profile{}).Error
func (r *profileRepository) Delete(uuid string) error {
return r.db.Where("uuid = ?", uuid).Delete(&model.Profile{}).Error
}
// CountProfilesByUserID 统计用户的档案数量
func CountProfilesByUserID(userID int64) (int64, error) {
func (r *profileRepository) CountByUserID(userID int64) (int64, error) {
var count int64
err := getDB().Model(&model.Profile{}).
err := r.db.Model(&model.Profile{}).
Where("user_id = ?", userID).
Count(&count).Error
return count, err
}
// SetActiveProfile 设置档案为活跃状态(同时将用户的其他档案设置为非活跃)
func SetActiveProfile(uuid string, userID int64) error {
return getDB().Transaction(func(tx *gorm.DB) error {
func (r *profileRepository) SetActive(uuid string, userID int64) error {
return r.db.Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&model.Profile{}).
Where("user_id = ?", userID).
Update("is_active", false).Error; err != nil {
@@ -89,44 +90,31 @@ func SetActiveProfile(uuid string, userID int64) error {
})
}
// UpdateProfileLastUsedAt 更新最后使用时间
func UpdateProfileLastUsedAt(uuid string) error {
return getDB().Model(&model.Profile{}).
func (r *profileRepository) UpdateLastUsedAt(uuid string) error {
return r.db.Model(&model.Profile{}).
Where("uuid = ?", uuid).
Update("last_used_at", gorm.Expr("CURRENT_TIMESTAMP")).Error
}
// FindOneProfileByUserID 根据id找一个角色
func FindOneProfileByUserID(userID int64) (*model.Profile, error) {
profiles, err := FindProfilesByUserID(userID)
if err != nil {
return nil, err
}
if len(profiles) == 0 {
return nil, errors.New("未找到角色")
}
return profiles[0], nil
}
func GetProfilesByNames(names []string) ([]*model.Profile, error) {
func (r *profileRepository) GetByNames(names []string) ([]*model.Profile, error) {
var profiles []*model.Profile
err := getDB().Where("name in (?)", names).Find(&profiles).Error
err := r.db.Where("name in (?)", names).Find(&profiles).Error
return profiles, err
}
func GetProfileKeyPair(profileId string) (*model.KeyPair, error) {
func (r *profileRepository) GetKeyPair(profileId string) (*model.KeyPair, error) {
if profileId == "" {
return nil, errors.New("参数不能为空")
}
var profile model.Profile
result := getDB().WithContext(context.Background()).
result := r.db.WithContext(context.Background()).
Select("key_pair").
Where("id = ?", profileId).
First(&profile)
if result.Error != nil {
if IsNotFound(result.Error) {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, errors.New("key pair未找到")
}
return nil, fmt.Errorf("获取key pair失败: %w", result.Error)
@@ -135,7 +123,7 @@ func GetProfileKeyPair(profileId string) (*model.KeyPair, error) {
return &model.KeyPair{}, nil
}
func UpdateProfileKeyPair(profileId string, keyPair *model.KeyPair) error {
func (r *profileRepository) UpdateKeyPair(profileId string, keyPair *model.KeyPair) error {
if profileId == "" {
return errors.New("profileId 不能为空")
}
@@ -143,7 +131,7 @@ func UpdateProfileKeyPair(profileId string, keyPair *model.KeyPair) error {
return errors.New("keyPair 不能为 nil")
}
return getDB().Transaction(func(tx *gorm.DB) error {
return r.db.Transaction(func(tx *gorm.DB) error {
result := tx.WithContext(context.Background()).
Table("profiles").
Where("id = ?", profileId).

View File

@@ -1,149 +0,0 @@
package repository
import (
"carrotskin/internal/model"
"context"
"errors"
"fmt"
"gorm.io/gorm"
)
// profileRepositoryImpl ProfileRepository的实现
type profileRepositoryImpl struct {
db *gorm.DB
}
// NewProfileRepository 创建ProfileRepository实例
func NewProfileRepository(db *gorm.DB) ProfileRepository {
return &profileRepositoryImpl{db: db}
}
func (r *profileRepositoryImpl) Create(profile *model.Profile) error {
return r.db.Create(profile).Error
}
func (r *profileRepositoryImpl) FindByUUID(uuid string) (*model.Profile, error) {
var profile model.Profile
err := r.db.Where("uuid = ?", uuid).
Preload("Skin").
Preload("Cape").
First(&profile).Error
if err != nil {
return nil, err
}
return &profile, nil
}
func (r *profileRepositoryImpl) FindByName(name string) (*model.Profile, error) {
var profile model.Profile
err := r.db.Where("name = ?", name).First(&profile).Error
if err != nil {
return nil, err
}
return &profile, nil
}
func (r *profileRepositoryImpl) FindByUserID(userID int64) ([]*model.Profile, error) {
var profiles []*model.Profile
err := r.db.Where("user_id = ?", userID).
Preload("Skin").
Preload("Cape").
Order("created_at DESC").
Find(&profiles).Error
return profiles, err
}
func (r *profileRepositoryImpl) Update(profile *model.Profile) error {
return r.db.Save(profile).Error
}
func (r *profileRepositoryImpl) UpdateFields(uuid string, updates map[string]interface{}) error {
return r.db.Model(&model.Profile{}).
Where("uuid = ?", uuid).
Updates(updates).Error
}
func (r *profileRepositoryImpl) Delete(uuid string) error {
return r.db.Where("uuid = ?", uuid).Delete(&model.Profile{}).Error
}
func (r *profileRepositoryImpl) CountByUserID(userID int64) (int64, error) {
var count int64
err := r.db.Model(&model.Profile{}).
Where("user_id = ?", userID).
Count(&count).Error
return count, err
}
func (r *profileRepositoryImpl) SetActive(uuid string, userID int64) error {
return r.db.Transaction(func(tx *gorm.DB) error {
if err := tx.Model(&model.Profile{}).
Where("user_id = ?", userID).
Update("is_active", false).Error; err != nil {
return err
}
return tx.Model(&model.Profile{}).
Where("uuid = ? AND user_id = ?", uuid, userID).
Update("is_active", true).Error
})
}
func (r *profileRepositoryImpl) UpdateLastUsedAt(uuid string) error {
return r.db.Model(&model.Profile{}).
Where("uuid = ?", uuid).
Update("last_used_at", gorm.Expr("CURRENT_TIMESTAMP")).Error
}
func (r *profileRepositoryImpl) GetByNames(names []string) ([]*model.Profile, error) {
var profiles []*model.Profile
err := r.db.Where("name in (?)", names).Find(&profiles).Error
return profiles, err
}
func (r *profileRepositoryImpl) GetKeyPair(profileId string) (*model.KeyPair, error) {
if profileId == "" {
return nil, errors.New("参数不能为空")
}
var profile model.Profile
result := r.db.WithContext(context.Background()).
Select("key_pair").
Where("id = ?", profileId).
First(&profile)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, errors.New("key pair未找到")
}
return nil, fmt.Errorf("获取key pair失败: %w", result.Error)
}
return &model.KeyPair{}, nil
}
func (r *profileRepositoryImpl) UpdateKeyPair(profileId string, keyPair *model.KeyPair) error {
if profileId == "" {
return errors.New("profileId 不能为空")
}
if keyPair == nil {
return errors.New("keyPair 不能为 nil")
}
return r.db.Transaction(func(tx *gorm.DB) error {
result := tx.WithContext(context.Background()).
Table("profiles").
Where("id = ?", profileId).
UpdateColumns(map[string]interface{}{
"private_key": keyPair.PrivateKey,
"public_key": keyPair.PublicKey,
})
if result.Error != nil {
return fmt.Errorf("更新 keyPair 失败: %w", result.Error)
}
return nil
})
}

View File

@@ -2,35 +2,42 @@ package repository
import (
"carrotskin/internal/model"
"gorm.io/gorm"
)
// GetSystemConfigByKey 根据键获取配置
func GetSystemConfigByKey(key string) (*model.SystemConfig, error) {
// systemConfigRepository SystemConfigRepository的实现
type systemConfigRepository struct {
db *gorm.DB
}
// NewSystemConfigRepository 创建SystemConfigRepository实例
func NewSystemConfigRepository(db *gorm.DB) SystemConfigRepository {
return &systemConfigRepository{db: db}
}
func (r *systemConfigRepository) GetByKey(key string) (*model.SystemConfig, error) {
var config model.SystemConfig
err := getDB().Where("key = ?", key).First(&config).Error
return HandleNotFound(&config, err)
err := r.db.Where("key = ?", key).First(&config).Error
return handleNotFoundResult(&config, err)
}
// GetPublicSystemConfigs 获取所有公开配置
func GetPublicSystemConfigs() ([]model.SystemConfig, error) {
func (r *systemConfigRepository) GetPublic() ([]model.SystemConfig, error) {
var configs []model.SystemConfig
err := getDB().Where("is_public = ?", true).Find(&configs).Error
err := r.db.Where("is_public = ?", true).Find(&configs).Error
return configs, err
}
// GetAllSystemConfigs 获取所有配置(管理员用)
func GetAllSystemConfigs() ([]model.SystemConfig, error) {
func (r *systemConfigRepository) GetAll() ([]model.SystemConfig, error) {
var configs []model.SystemConfig
err := getDB().Find(&configs).Error
err := r.db.Find(&configs).Error
return configs, err
}
// UpdateSystemConfig 更新配置
func UpdateSystemConfig(config *model.SystemConfig) error {
return getDB().Save(config).Error
func (r *systemConfigRepository) Update(config *model.SystemConfig) error {
return r.db.Save(config).Error
}
// UpdateSystemConfigValue 更新配置值
func UpdateSystemConfigValue(key, value string) error {
return getDB().Model(&model.SystemConfig{}).Where("key = ?", key).Update("value", value).Error
func (r *systemConfigRepository) UpdateValue(key, value string) error {
return r.db.Model(&model.SystemConfig{}).Where("key = ?", key).Update("value", value).Error
}

View File

@@ -1,45 +0,0 @@
package repository
import (
"carrotskin/internal/model"
"gorm.io/gorm"
)
// systemConfigRepositoryImpl SystemConfigRepository的实现
type systemConfigRepositoryImpl struct {
db *gorm.DB
}
// NewSystemConfigRepository 创建SystemConfigRepository实例
func NewSystemConfigRepository(db *gorm.DB) SystemConfigRepository {
return &systemConfigRepositoryImpl{db: db}
}
func (r *systemConfigRepositoryImpl) GetByKey(key string) (*model.SystemConfig, error) {
var config model.SystemConfig
err := r.db.Where("key = ?", key).First(&config).Error
return handleNotFoundResult(&config, err)
}
func (r *systemConfigRepositoryImpl) GetPublic() ([]model.SystemConfig, error) {
var configs []model.SystemConfig
err := r.db.Where("is_public = ?", true).Find(&configs).Error
return configs, err
}
func (r *systemConfigRepositoryImpl) GetAll() ([]model.SystemConfig, error) {
var configs []model.SystemConfig
err := r.db.Find(&configs).Error
return configs, err
}
func (r *systemConfigRepositoryImpl) Update(config *model.SystemConfig) error {
return r.db.Save(config).Error
}
func (r *systemConfigRepositoryImpl) UpdateValue(key, value string) error {
return r.db.Model(&model.SystemConfig{}).Where("key = ?", key).Update("value", value).Error
}

View File

@@ -6,32 +6,37 @@ import (
"gorm.io/gorm"
)
// CreateTexture 创建材质
func CreateTexture(texture *model.Texture) error {
return getDB().Create(texture).Error
// textureRepository TextureRepository的实现
type textureRepository struct {
db *gorm.DB
}
// FindTextureByID 根据ID查找材质
func FindTextureByID(id int64) (*model.Texture, error) {
// NewTextureRepository 创建TextureRepository实例
func NewTextureRepository(db *gorm.DB) TextureRepository {
return &textureRepository{db: db}
}
func (r *textureRepository) Create(texture *model.Texture) error {
return r.db.Create(texture).Error
}
func (r *textureRepository) FindByID(id int64) (*model.Texture, error) {
var texture model.Texture
err := getDB().Preload("Uploader").First(&texture, id).Error
return HandleNotFound(&texture, err)
err := r.db.Preload("Uploader").First(&texture, id).Error
return handleNotFoundResult(&texture, err)
}
// FindTextureByHash 根据Hash查找材质
func FindTextureByHash(hash string) (*model.Texture, error) {
func (r *textureRepository) FindByHash(hash string) (*model.Texture, error) {
var texture model.Texture
err := getDB().Where("hash = ?", hash).First(&texture).Error
return HandleNotFound(&texture, err)
err := r.db.Where("hash = ?", hash).First(&texture).Error
return handleNotFoundResult(&texture, err)
}
// FindTexturesByUploaderID 根据上传者ID查找材质列表
func FindTexturesByUploaderID(uploaderID int64, page, pageSize int) ([]*model.Texture, int64, error) {
db := getDB()
func (r *textureRepository) FindByUploaderID(uploaderID int64, page, pageSize int) ([]*model.Texture, int64, error) {
var textures []*model.Texture
var total int64
query := db.Model(&model.Texture{}).Where("uploader_id = ? AND status != -1", uploaderID)
query := r.db.Model(&model.Texture{}).Where("uploader_id = ? AND status != -1", uploaderID)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
@@ -49,13 +54,11 @@ func FindTexturesByUploaderID(uploaderID int64, page, pageSize int) ([]*model.Te
return textures, total, nil
}
// SearchTextures 搜索材质
func SearchTextures(keyword string, textureType model.TextureType, publicOnly bool, page, pageSize int) ([]*model.Texture, int64, error) {
db := getDB()
func (r *textureRepository) Search(keyword string, textureType model.TextureType, publicOnly bool, page, pageSize int) ([]*model.Texture, int64, error) {
var textures []*model.Texture
var total int64
query := db.Model(&model.Texture{}).Where("status = 1")
query := r.db.Model(&model.Texture{}).Where("status = 1")
if publicOnly {
query = query.Where("is_public = ?", true)
@@ -83,79 +86,67 @@ func SearchTextures(keyword string, textureType model.TextureType, publicOnly bo
return textures, total, nil
}
// UpdateTexture 更新材质
func UpdateTexture(texture *model.Texture) error {
return getDB().Save(texture).Error
func (r *textureRepository) Update(texture *model.Texture) error {
return r.db.Save(texture).Error
}
// UpdateTextureFields 更新材质指定字段
func UpdateTextureFields(id int64, fields map[string]interface{}) error {
return getDB().Model(&model.Texture{}).Where("id = ?", id).Updates(fields).Error
func (r *textureRepository) UpdateFields(id int64, fields map[string]interface{}) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).Updates(fields).Error
}
// DeleteTexture 删除材质(软删除)
func DeleteTexture(id int64) error {
return getDB().Model(&model.Texture{}).Where("id = ?", id).Update("status", -1).Error
func (r *textureRepository) Delete(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).Update("status", -1).Error
}
// IncrementTextureDownloadCount 增加下载次数
func IncrementTextureDownloadCount(id int64) error {
return getDB().Model(&model.Texture{}).Where("id = ?", id).
func (r *textureRepository) IncrementDownloadCount(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).
UpdateColumn("download_count", gorm.Expr("download_count + ?", 1)).Error
}
// IncrementTextureFavoriteCount 增加收藏次数
func IncrementTextureFavoriteCount(id int64) error {
return getDB().Model(&model.Texture{}).Where("id = ?", id).
func (r *textureRepository) IncrementFavoriteCount(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).
UpdateColumn("favorite_count", gorm.Expr("favorite_count + ?", 1)).Error
}
// DecrementTextureFavoriteCount 减少收藏次数
func DecrementTextureFavoriteCount(id int64) error {
return getDB().Model(&model.Texture{}).Where("id = ?", id).
func (r *textureRepository) DecrementFavoriteCount(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).
UpdateColumn("favorite_count", gorm.Expr("favorite_count - ?", 1)).Error
}
// CreateTextureDownloadLog 创建下载日志
func CreateTextureDownloadLog(log *model.TextureDownloadLog) error {
return getDB().Create(log).Error
func (r *textureRepository) CreateDownloadLog(log *model.TextureDownloadLog) error {
return r.db.Create(log).Error
}
// IsTextureFavorited 检查是否已收藏
func IsTextureFavorited(userID, textureID int64) (bool, error) {
func (r *textureRepository) IsFavorited(userID, textureID int64) (bool, error) {
var count int64
err := getDB().Model(&model.UserTextureFavorite{}).
err := r.db.Model(&model.UserTextureFavorite{}).
Where("user_id = ? AND texture_id = ?", userID, textureID).
Count(&count).Error
return count > 0, err
}
// AddTextureFavorite 添加收藏
func AddTextureFavorite(userID, textureID int64) error {
func (r *textureRepository) AddFavorite(userID, textureID int64) error {
favorite := &model.UserTextureFavorite{
UserID: userID,
TextureID: textureID,
}
return getDB().Create(favorite).Error
return r.db.Create(favorite).Error
}
// RemoveTextureFavorite 取消收藏
func RemoveTextureFavorite(userID, textureID int64) error {
return getDB().Where("user_id = ? AND texture_id = ?", userID, textureID).
func (r *textureRepository) RemoveFavorite(userID, textureID int64) error {
return r.db.Where("user_id = ? AND texture_id = ?", userID, textureID).
Delete(&model.UserTextureFavorite{}).Error
}
// GetUserTextureFavorites 获取用户收藏的材质列表
func GetUserTextureFavorites(userID int64, page, pageSize int) ([]*model.Texture, int64, error) {
db := getDB()
func (r *textureRepository) GetUserFavorites(userID int64, page, pageSize int) ([]*model.Texture, int64, error) {
var textures []*model.Texture
var total int64
subQuery := db.Model(&model.UserTextureFavorite{}).
subQuery := r.db.Model(&model.UserTextureFavorite{}).
Select("texture_id").
Where("user_id = ?", userID)
query := db.Model(&model.Texture{}).
query := r.db.Model(&model.Texture{}).
Where("id IN (?) AND status = 1", subQuery)
if err := query.Count(&total).Error; err != nil {
@@ -174,10 +165,9 @@ func GetUserTextureFavorites(userID int64, page, pageSize int) ([]*model.Texture
return textures, total, nil
}
// CountTexturesByUploaderID 统计用户上传的材质数量
func CountTexturesByUploaderID(uploaderID int64) (int64, error) {
func (r *textureRepository) CountByUploaderID(uploaderID int64) (int64, error) {
var count int64
err := getDB().Model(&model.Texture{}).
err := r.db.Model(&model.Texture{}).
Where("uploader_id = ? AND status != -1", uploaderID).
Count(&count).Error
return count, err

View File

@@ -1,175 +0,0 @@
package repository
import (
"carrotskin/internal/model"
"gorm.io/gorm"
)
// textureRepositoryImpl TextureRepository的实现
type textureRepositoryImpl struct {
db *gorm.DB
}
// NewTextureRepository 创建TextureRepository实例
func NewTextureRepository(db *gorm.DB) TextureRepository {
return &textureRepositoryImpl{db: db}
}
func (r *textureRepositoryImpl) Create(texture *model.Texture) error {
return r.db.Create(texture).Error
}
func (r *textureRepositoryImpl) FindByID(id int64) (*model.Texture, error) {
var texture model.Texture
err := r.db.Preload("Uploader").First(&texture, id).Error
return handleNotFoundResult(&texture, err)
}
func (r *textureRepositoryImpl) FindByHash(hash string) (*model.Texture, error) {
var texture model.Texture
err := r.db.Where("hash = ?", hash).First(&texture).Error
return handleNotFoundResult(&texture, err)
}
func (r *textureRepositoryImpl) FindByUploaderID(uploaderID int64, page, pageSize int) ([]*model.Texture, int64, error) {
var textures []*model.Texture
var total int64
query := r.db.Model(&model.Texture{}).Where("uploader_id = ? AND status != -1", uploaderID)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
err := query.Scopes(Paginate(page, pageSize)).
Preload("Uploader").
Order("created_at DESC").
Find(&textures).Error
if err != nil {
return nil, 0, err
}
return textures, total, nil
}
func (r *textureRepositoryImpl) Search(keyword string, textureType model.TextureType, publicOnly bool, page, pageSize int) ([]*model.Texture, int64, error) {
var textures []*model.Texture
var total int64
query := r.db.Model(&model.Texture{}).Where("status = 1")
if publicOnly {
query = query.Where("is_public = ?", true)
}
if textureType != "" {
query = query.Where("type = ?", textureType)
}
if keyword != "" {
query = query.Where("name LIKE ? OR description LIKE ?", "%"+keyword+"%", "%"+keyword+"%")
}
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
err := query.Scopes(Paginate(page, pageSize)).
Preload("Uploader").
Order("created_at DESC").
Find(&textures).Error
if err != nil {
return nil, 0, err
}
return textures, total, nil
}
func (r *textureRepositoryImpl) Update(texture *model.Texture) error {
return r.db.Save(texture).Error
}
func (r *textureRepositoryImpl) UpdateFields(id int64, fields map[string]interface{}) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).Updates(fields).Error
}
func (r *textureRepositoryImpl) Delete(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).Update("status", -1).Error
}
func (r *textureRepositoryImpl) IncrementDownloadCount(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).
UpdateColumn("download_count", gorm.Expr("download_count + ?", 1)).Error
}
func (r *textureRepositoryImpl) IncrementFavoriteCount(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).
UpdateColumn("favorite_count", gorm.Expr("favorite_count + ?", 1)).Error
}
func (r *textureRepositoryImpl) DecrementFavoriteCount(id int64) error {
return r.db.Model(&model.Texture{}).Where("id = ?", id).
UpdateColumn("favorite_count", gorm.Expr("favorite_count - ?", 1)).Error
}
func (r *textureRepositoryImpl) CreateDownloadLog(log *model.TextureDownloadLog) error {
return r.db.Create(log).Error
}
func (r *textureRepositoryImpl) IsFavorited(userID, textureID int64) (bool, error) {
var count int64
err := r.db.Model(&model.UserTextureFavorite{}).
Where("user_id = ? AND texture_id = ?", userID, textureID).
Count(&count).Error
return count > 0, err
}
func (r *textureRepositoryImpl) AddFavorite(userID, textureID int64) error {
favorite := &model.UserTextureFavorite{
UserID: userID,
TextureID: textureID,
}
return r.db.Create(favorite).Error
}
func (r *textureRepositoryImpl) RemoveFavorite(userID, textureID int64) error {
return r.db.Where("user_id = ? AND texture_id = ?", userID, textureID).
Delete(&model.UserTextureFavorite{}).Error
}
func (r *textureRepositoryImpl) GetUserFavorites(userID int64, page, pageSize int) ([]*model.Texture, int64, error) {
var textures []*model.Texture
var total int64
subQuery := r.db.Model(&model.UserTextureFavorite{}).
Select("texture_id").
Where("user_id = ?", userID)
query := r.db.Model(&model.Texture{}).
Where("id IN (?) AND status = 1", subQuery)
if err := query.Count(&total).Error; err != nil {
return nil, 0, err
}
err := query.Scopes(Paginate(page, pageSize)).
Preload("Uploader").
Order("created_at DESC").
Find(&textures).Error
if err != nil {
return nil, 0, err
}
return textures, total, nil
}
func (r *textureRepositoryImpl) CountByUploaderID(uploaderID int64) (int64, error) {
var count int64
err := r.db.Model(&model.Texture{}).
Where("uploader_id = ? AND status != -1", uploaderID).
Count(&count).Error
return count, err
}

View File

@@ -2,66 +2,69 @@ package repository
import (
"carrotskin/internal/model"
"gorm.io/gorm"
)
func CreateToken(token *model.Token) error {
return getDB().Create(token).Error
// tokenRepository TokenRepository的实现
type tokenRepository struct {
db *gorm.DB
}
func GetTokensByUserId(userId int64) ([]*model.Token, error) {
var tokens []*model.Token
err := getDB().Where("user_id = ?", userId).Find(&tokens).Error
return tokens, err
// NewTokenRepository 创建TokenRepository实例
func NewTokenRepository(db *gorm.DB) TokenRepository {
return &tokenRepository{db: db}
}
func BatchDeleteTokens(tokensToDelete []string) (int64, error) {
if len(tokensToDelete) == 0 {
return 0, nil
}
result := getDB().Where("access_token IN ?", tokensToDelete).Delete(&model.Token{})
return result.RowsAffected, result.Error
func (r *tokenRepository) Create(token *model.Token) error {
return r.db.Create(token).Error
}
func FindTokenByID(accessToken string) (*model.Token, error) {
func (r *tokenRepository) FindByAccessToken(accessToken string) (*model.Token, error) {
var token model.Token
err := getDB().Where("access_token = ?", accessToken).First(&token).Error
err := r.db.Where("access_token = ?", accessToken).First(&token).Error
if err != nil {
return nil, err
}
return &token, nil
}
func GetUUIDByAccessToken(accessToken string) (string, error) {
func (r *tokenRepository) GetByUserID(userId int64) ([]*model.Token, error) {
var tokens []*model.Token
err := r.db.Where("user_id = ?", userId).Find(&tokens).Error
return tokens, err
}
func (r *tokenRepository) GetUUIDByAccessToken(accessToken string) (string, error) {
var token model.Token
err := getDB().Where("access_token = ?", accessToken).First(&token).Error
err := r.db.Where("access_token = ?", accessToken).First(&token).Error
if err != nil {
return "", err
}
return token.ProfileId, nil
}
func GetUserIDByAccessToken(accessToken string) (int64, error) {
func (r *tokenRepository) GetUserIDByAccessToken(accessToken string) (int64, error) {
var token model.Token
err := getDB().Where("access_token = ?", accessToken).First(&token).Error
err := r.db.Where("access_token = ?", accessToken).First(&token).Error
if err != nil {
return 0, err
}
return token.UserID, nil
}
func GetTokenByAccessToken(accessToken string) (*model.Token, error) {
var token model.Token
err := getDB().Where("access_token = ?", accessToken).First(&token).Error
if err != nil {
return nil, err
func (r *tokenRepository) DeleteByAccessToken(accessToken string) error {
return r.db.Where("access_token = ?", accessToken).Delete(&model.Token{}).Error
}
func (r *tokenRepository) DeleteByUserID(userId int64) error {
return r.db.Where("user_id = ?", userId).Delete(&model.Token{}).Error
}
func (r *tokenRepository) BatchDelete(accessTokens []string) (int64, error) {
if len(accessTokens) == 0 {
return 0, nil
}
return &token, nil
}
func DeleteTokenByAccessToken(accessToken string) error {
return getDB().Where("access_token = ?", accessToken).Delete(&model.Token{}).Error
}
func DeleteTokenByUserId(userId int64) error {
return getDB().Where("user_id = ?", userId).Delete(&model.Token{}).Error
result := r.db.Where("access_token IN ?", accessTokens).Delete(&model.Token{})
return result.RowsAffected, result.Error
}

View File

@@ -1,71 +0,0 @@
package repository
import (
"carrotskin/internal/model"
"gorm.io/gorm"
)
// tokenRepositoryImpl TokenRepository的实现
type tokenRepositoryImpl struct {
db *gorm.DB
}
// NewTokenRepository 创建TokenRepository实例
func NewTokenRepository(db *gorm.DB) TokenRepository {
return &tokenRepositoryImpl{db: db}
}
func (r *tokenRepositoryImpl) Create(token *model.Token) error {
return r.db.Create(token).Error
}
func (r *tokenRepositoryImpl) FindByAccessToken(accessToken string) (*model.Token, error) {
var token model.Token
err := r.db.Where("access_token = ?", accessToken).First(&token).Error
if err != nil {
return nil, err
}
return &token, nil
}
func (r *tokenRepositoryImpl) GetByUserID(userId int64) ([]*model.Token, error) {
var tokens []*model.Token
err := r.db.Where("user_id = ?", userId).Find(&tokens).Error
return tokens, err
}
func (r *tokenRepositoryImpl) GetUUIDByAccessToken(accessToken string) (string, error) {
var token model.Token
err := r.db.Where("access_token = ?", accessToken).First(&token).Error
if err != nil {
return "", err
}
return token.ProfileId, nil
}
func (r *tokenRepositoryImpl) GetUserIDByAccessToken(accessToken string) (int64, error) {
var token model.Token
err := r.db.Where("access_token = ?", accessToken).First(&token).Error
if err != nil {
return 0, err
}
return token.UserID, nil
}
func (r *tokenRepositoryImpl) DeleteByAccessToken(accessToken string) error {
return r.db.Where("access_token = ?", accessToken).Delete(&model.Token{}).Error
}
func (r *tokenRepositoryImpl) DeleteByUserID(userId int64) error {
return r.db.Where("user_id = ?", userId).Delete(&model.Token{}).Error
}
func (r *tokenRepositoryImpl) BatchDelete(accessTokens []string) (int64, error) {
if len(accessTokens) == 0 {
return 0, nil
}
result := r.db.Where("access_token IN ?", accessTokens).Delete(&model.Token{})
return result.RowsAffected, result.Error
}

View File

@@ -7,60 +7,60 @@ import (
"gorm.io/gorm"
)
// CreateUser 创建用户
func CreateUser(user *model.User) error {
return getDB().Create(user).Error
// userRepository UserRepository的实现
type userRepository struct {
db *gorm.DB
}
// FindUserByID 根据ID查找用户
func FindUserByID(id int64) (*model.User, error) {
// NewUserRepository 创建UserRepository实例
func NewUserRepository(db *gorm.DB) UserRepository {
return &userRepository{db: db}
}
func (r *userRepository) Create(user *model.User) error {
return r.db.Create(user).Error
}
func (r *userRepository) FindByID(id int64) (*model.User, error) {
var user model.User
err := getDB().Where("id = ? AND status != -1", id).First(&user).Error
return HandleNotFound(&user, err)
err := r.db.Where("id = ? AND status != -1", id).First(&user).Error
return handleNotFoundResult(&user, err)
}
// FindUserByUsername 根据用户名查找用户
func FindUserByUsername(username string) (*model.User, error) {
func (r *userRepository) FindByUsername(username string) (*model.User, error) {
var user model.User
err := getDB().Where("username = ? AND status != -1", username).First(&user).Error
return HandleNotFound(&user, err)
err := r.db.Where("username = ? AND status != -1", username).First(&user).Error
return handleNotFoundResult(&user, err)
}
// FindUserByEmail 根据邮箱查找用户
func FindUserByEmail(email string) (*model.User, error) {
func (r *userRepository) FindByEmail(email string) (*model.User, error) {
var user model.User
err := getDB().Where("email = ? AND status != -1", email).First(&user).Error
return HandleNotFound(&user, err)
err := r.db.Where("email = ? AND status != -1", email).First(&user).Error
return handleNotFoundResult(&user, err)
}
// UpdateUser 更新用户
func UpdateUser(user *model.User) error {
return getDB().Save(user).Error
func (r *userRepository) Update(user *model.User) error {
return r.db.Save(user).Error
}
// UpdateUserFields 更新指定字段
func UpdateUserFields(id int64, fields map[string]interface{}) error {
return getDB().Model(&model.User{}).Where("id = ?", id).Updates(fields).Error
func (r *userRepository) UpdateFields(id int64, fields map[string]interface{}) error {
return r.db.Model(&model.User{}).Where("id = ?", id).Updates(fields).Error
}
// DeleteUser 软删除用户
func DeleteUser(id int64) error {
return getDB().Model(&model.User{}).Where("id = ?", id).Update("status", -1).Error
func (r *userRepository) Delete(id int64) error {
return r.db.Model(&model.User{}).Where("id = ?", id).Update("status", -1).Error
}
// CreateLoginLog 创建登录日志
func CreateLoginLog(log *model.UserLoginLog) error {
return getDB().Create(log).Error
func (r *userRepository) CreateLoginLog(log *model.UserLoginLog) error {
return r.db.Create(log).Error
}
// CreatePointLog 创建积分日志
func CreatePointLog(log *model.UserPointLog) error {
return getDB().Create(log).Error
func (r *userRepository) CreatePointLog(log *model.UserPointLog) error {
return r.db.Create(log).Error
}
// UpdateUserPoints 更新用户积分(事务)
func UpdateUserPoints(userID int64, amount int, changeType, reason string) error {
return getDB().Transaction(func(tx *gorm.DB) error {
func (r *userRepository) UpdatePoints(userID int64, amount int, changeType, reason string) error {
return r.db.Transaction(func(tx *gorm.DB) error {
var user model.User
if err := tx.Where("id = ?", userID).First(&user).Error; err != nil {
return err
@@ -90,12 +90,13 @@ func UpdateUserPoints(userID int64, amount int, changeType, reason string) error
})
}
// UpdateUserAvatar 更新用户头像
func UpdateUserAvatar(userID int64, avatarURL string) error {
return getDB().Model(&model.User{}).Where("id = ?", userID).Update("avatar", avatarURL).Error
}
// UpdateUserEmail 更新用户邮箱
func UpdateUserEmail(userID int64, email string) error {
return getDB().Model(&model.User{}).Where("id = ?", userID).Update("email", email).Error
// handleNotFoundResult 处理记录未找到的情况
func handleNotFoundResult[T any](result *T, err error) (*T, error) {
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return result, nil
}

View File

@@ -1,103 +0,0 @@
package repository
import (
"carrotskin/internal/model"
"errors"
"gorm.io/gorm"
)
// userRepositoryImpl UserRepository的实现
type userRepositoryImpl struct {
db *gorm.DB
}
// NewUserRepository 创建UserRepository实例
func NewUserRepository(db *gorm.DB) UserRepository {
return &userRepositoryImpl{db: db}
}
func (r *userRepositoryImpl) Create(user *model.User) error {
return r.db.Create(user).Error
}
func (r *userRepositoryImpl) FindByID(id int64) (*model.User, error) {
var user model.User
err := r.db.Where("id = ? AND status != -1", id).First(&user).Error
return handleNotFoundResult(&user, err)
}
func (r *userRepositoryImpl) FindByUsername(username string) (*model.User, error) {
var user model.User
err := r.db.Where("username = ? AND status != -1", username).First(&user).Error
return handleNotFoundResult(&user, err)
}
func (r *userRepositoryImpl) FindByEmail(email string) (*model.User, error) {
var user model.User
err := r.db.Where("email = ? AND status != -1", email).First(&user).Error
return handleNotFoundResult(&user, err)
}
func (r *userRepositoryImpl) Update(user *model.User) error {
return r.db.Save(user).Error
}
func (r *userRepositoryImpl) UpdateFields(id int64, fields map[string]interface{}) error {
return r.db.Model(&model.User{}).Where("id = ?", id).Updates(fields).Error
}
func (r *userRepositoryImpl) Delete(id int64) error {
return r.db.Model(&model.User{}).Where("id = ?", id).Update("status", -1).Error
}
func (r *userRepositoryImpl) CreateLoginLog(log *model.UserLoginLog) error {
return r.db.Create(log).Error
}
func (r *userRepositoryImpl) CreatePointLog(log *model.UserPointLog) error {
return r.db.Create(log).Error
}
func (r *userRepositoryImpl) UpdatePoints(userID int64, amount int, changeType, reason string) error {
return r.db.Transaction(func(tx *gorm.DB) error {
var user model.User
if err := tx.Where("id = ?", userID).First(&user).Error; err != nil {
return err
}
balanceBefore := user.Points
balanceAfter := balanceBefore + amount
if balanceAfter < 0 {
return errors.New("积分不足")
}
if err := tx.Model(&user).Update("points", balanceAfter).Error; err != nil {
return err
}
log := &model.UserPointLog{
UserID: userID,
ChangeType: changeType,
Amount: amount,
BalanceBefore: balanceBefore,
BalanceAfter: balanceAfter,
Reason: reason,
}
return tx.Create(log).Error
})
}
// handleNotFoundResult 处理记录未找到的情况
func handleNotFoundResult[T any](result *T, err error) (*T, error) {
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, err
}
return result, nil
}

View File

@@ -2,18 +2,31 @@ package repository
import (
"carrotskin/internal/model"
"gorm.io/gorm"
)
func GetYggdrasilPasswordById(id int64) (string, error) {
// yggdrasilRepository YggdrasilRepository的实现
type yggdrasilRepository struct {
db *gorm.DB
}
// NewYggdrasilRepository 创建YggdrasilRepository实例
func NewYggdrasilRepository(db *gorm.DB) YggdrasilRepository {
return &yggdrasilRepository{db: db}
}
func (r *yggdrasilRepository) GetPasswordByID(id int64) (string, error) {
var yggdrasil model.Yggdrasil
err := getDB().Where("id = ?", id).First(&yggdrasil).Error
err := r.db.Where("id = ?", id).First(&yggdrasil).Error
if err != nil {
return "", err
}
return yggdrasil.Password, nil
}
// ResetYggdrasilPassword 重置Yggdrasil密码
func ResetYggdrasilPassword(userId int64, newPassword string) error {
return getDB().Model(&model.Yggdrasil{}).Where("id = ?", userId).Update("password", newPassword).Error
}
func (r *yggdrasilRepository) ResetPassword(id int64, password string) error {
return r.db.Model(&model.Yggdrasil{}).Where("id = ?", id).Update("password", password).Error
}