200 lines
5.7 KiB
Go
200 lines
5.7 KiB
Go
package repository
|
||
|
||
import (
|
||
"carrotskin/internal/model"
|
||
"carrotskin/pkg/database"
|
||
"context"
|
||
"errors"
|
||
"fmt"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// CreateProfile 创建档案
|
||
func CreateProfile(profile *model.Profile) error {
|
||
db := database.MustGetDB()
|
||
return db.Create(profile).Error
|
||
}
|
||
|
||
// FindProfileByUUID 根据UUID查找档案
|
||
func FindProfileByUUID(uuid string) (*model.Profile, error) {
|
||
db := database.MustGetDB()
|
||
var profile model.Profile
|
||
err := db.Where("uuid = ?", uuid).
|
||
Preload("Skin").
|
||
Preload("Cape").
|
||
First(&profile).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &profile, nil
|
||
}
|
||
|
||
// FindProfileByName 根据角色名查找档案
|
||
func FindProfileByName(name string) (*model.Profile, error) {
|
||
db := database.MustGetDB()
|
||
var profile model.Profile
|
||
err := db.Where("name = ?", name).First(&profile).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &profile, nil
|
||
}
|
||
|
||
// FindProfilesByUserID 获取用户的所有档案
|
||
func FindProfilesByUserID(userID int64) ([]*model.Profile, error) {
|
||
db := database.MustGetDB()
|
||
var profiles []*model.Profile
|
||
err := db.Where("user_id = ?", userID).
|
||
Preload("Skin").
|
||
Preload("Cape").
|
||
Order("created_at DESC").
|
||
Find(&profiles).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return profiles, nil
|
||
}
|
||
|
||
// UpdateProfile 更新档案
|
||
func UpdateProfile(profile *model.Profile) error {
|
||
db := database.MustGetDB()
|
||
return db.Save(profile).Error
|
||
}
|
||
|
||
// UpdateProfileFields 更新指定字段
|
||
func UpdateProfileFields(uuid string, updates map[string]interface{}) error {
|
||
db := database.MustGetDB()
|
||
return db.Model(&model.Profile{}).
|
||
Where("uuid = ?", uuid).
|
||
Updates(updates).Error
|
||
}
|
||
|
||
// DeleteProfile 删除档案
|
||
func DeleteProfile(uuid string) error {
|
||
db := database.MustGetDB()
|
||
return db.Where("uuid = ?", uuid).Delete(&model.Profile{}).Error
|
||
}
|
||
|
||
// CountProfilesByUserID 统计用户的档案数量
|
||
func CountProfilesByUserID(userID int64) (int64, error) {
|
||
db := database.MustGetDB()
|
||
var count int64
|
||
err := db.Model(&model.Profile{}).
|
||
Where("user_id = ?", userID).
|
||
Count(&count).Error
|
||
return count, err
|
||
}
|
||
|
||
// SetActiveProfile 设置档案为活跃状态(同时将用户的其他档案设置为非活跃)
|
||
func SetActiveProfile(uuid string, userID int64) error {
|
||
db := database.MustGetDB()
|
||
return 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
|
||
}
|
||
|
||
// 将指定档案设置为活跃
|
||
if err := tx.Model(&model.Profile{}).
|
||
Where("uuid = ? AND user_id = ?", uuid, userID).
|
||
Update("is_active", true).Error; err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
})
|
||
}
|
||
|
||
// UpdateProfileLastUsedAt 更新最后使用时间
|
||
func UpdateProfileLastUsedAt(uuid string) error {
|
||
db := database.MustGetDB()
|
||
return 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
|
||
}
|
||
profile := profiles[0]
|
||
return profile, nil
|
||
}
|
||
|
||
func GetProfilesByNames(names []string) ([]*model.Profile, error) {
|
||
db := database.MustGetDB()
|
||
var profiles []*model.Profile
|
||
err := db.Where("name in (?)", names).Find(&profiles).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return profiles, nil
|
||
}
|
||
|
||
func GetProfileKeyPair(profileId string) (*model.KeyPair, error) {
|
||
db := database.MustGetDB()
|
||
// 1. 参数校验(保持原逻辑)
|
||
if profileId == "" {
|
||
return nil, errors.New("参数不能为空")
|
||
}
|
||
|
||
// 2. GORM 查询:只查询 key_pair 字段(对应原 mongo 投影)
|
||
var profile *model.Profile
|
||
// 条件:id = profileId(PostgreSQL 主键),只选择 key_pair 字段
|
||
result := db.WithContext(context.Background()).
|
||
Select("key_pair"). // 只查询需要的字段(投影)
|
||
Where("id = ?", profileId). // 查询条件(GORM 自动处理占位符,避免 SQL 注入)
|
||
First(&profile) // 查单条记录
|
||
|
||
// 3. 错误处理(适配 GORM 错误类型)
|
||
if result.Error != nil {
|
||
// 空结果判断(对应原 mongo.ErrNoDocuments / pgx.ErrNoRows)
|
||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||
return nil, errors.New("key pair未找到")
|
||
}
|
||
// 保持原错误封装格式
|
||
return nil, fmt.Errorf("获取key pair失败: %w", result.Error)
|
||
}
|
||
|
||
// 4. JSONB 反序列化为 model.KeyPair
|
||
keyPair := &model.KeyPair{}
|
||
return keyPair, nil
|
||
}
|
||
|
||
func UpdateProfileKeyPair(profileId string, keyPair *model.KeyPair) error {
|
||
db := database.MustGetDB()
|
||
// 仅保留最必要的入参校验(避免无效数据库请求)
|
||
if profileId == "" {
|
||
return errors.New("profileId 不能为空")
|
||
}
|
||
if keyPair == nil {
|
||
return errors.New("keyPair 不能为 nil")
|
||
}
|
||
|
||
// 事务内执行核心更新(保证原子性,出错自动回滚)
|
||
return db.Transaction(func(tx *gorm.DB) error {
|
||
// 核心更新逻辑:按 profileId 匹配,直接更新 key_pair 相关字段
|
||
result := tx.WithContext(context.Background()).
|
||
Table("profiles"). // 目标表名(与 PostgreSQL 表一致)
|
||
Where("id = ?", profileId). // 更新条件:profileId 匹配
|
||
// 直接映射字段(无需序列化,依赖 GORM 自动字段匹配)
|
||
UpdateColumns(map[string]interface{}{
|
||
"private_key": keyPair.PrivateKey, // 数据库 private_key 字段
|
||
"public_key": keyPair.PublicKey, // 数据库 public_key 字段
|
||
// 若 key_pair 是单个字段(非拆分),替换为:"key_pair": keyPair
|
||
})
|
||
|
||
// 仅处理数据库层面的致命错误
|
||
if result.Error != nil {
|
||
return fmt.Errorf("更新 keyPair 失败: %w", result.Error)
|
||
}
|
||
|
||
return nil
|
||
})
|
||
}
|