262 lines
6.4 KiB
Go
262 lines
6.4 KiB
Go
package repository
|
||
|
||
import (
|
||
"errors"
|
||
"time"
|
||
|
||
appErrors "github.com/topfans/backend/pkg/errors"
|
||
"github.com/topfans/backend/pkg/models"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// AssetRepository 资产Repository接口
|
||
type AssetRepository interface {
|
||
// Create 创建资产
|
||
Create(asset *models.Asset) error
|
||
|
||
// GetByID 根据ID查询资产
|
||
GetByID(assetID int64) (*models.Asset, error)
|
||
|
||
// GetByIDAndOwner 根据ID和所有者查询资产(用于权限验证)
|
||
GetByIDAndOwner(assetID, ownerUID, starID int64) (*models.Asset, error)
|
||
|
||
// GetByOwner 查询用户的资产列表
|
||
GetByOwner(ownerUID, starID int64, limit, offset int) ([]*models.Asset, error)
|
||
|
||
// CountByOwner 统计用户的资产数量
|
||
CountByOwner(ownerUID, starID int64) (int64, error)
|
||
|
||
// UpdateStatus 更新资产状态
|
||
UpdateStatus(assetID int64, status int32) error
|
||
|
||
// UpdateBlockchainInfo 更新区块链信息
|
||
UpdateBlockchainInfo(assetID int64, txHash string, blockNumber int64, mintedAt int64) error
|
||
|
||
// IncrementLikeCount 增加点赞数
|
||
IncrementLikeCount(assetID int64) error
|
||
|
||
// DecrementLikeCount 减少点赞数
|
||
DecrementLikeCount(assetID int64) error
|
||
|
||
// IsExhibiting 检查资产是否正在展出中
|
||
IsExhibiting(assetID int64) (bool, error)
|
||
}
|
||
|
||
// assetRepository 资产Repository实现
|
||
type assetRepository struct {
|
||
db *gorm.DB
|
||
}
|
||
|
||
// NewAssetRepository 创建资产Repository实例
|
||
func NewAssetRepository(db *gorm.DB) AssetRepository {
|
||
return &assetRepository{
|
||
db: db,
|
||
}
|
||
}
|
||
|
||
// Create 创建资产
|
||
func (r *assetRepository) Create(asset *models.Asset) error {
|
||
if asset == nil {
|
||
return errors.New("asset cannot be nil")
|
||
}
|
||
|
||
if asset.OwnerUID <= 0 {
|
||
return errors.New("owner_uid must be greater than 0")
|
||
}
|
||
|
||
if asset.StarID <= 0 {
|
||
return errors.New("star_id must be greater than 0")
|
||
}
|
||
|
||
if err := r.db.Create(asset).Error; err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetByID 根据ID查询资产
|
||
func (r *assetRepository) GetByID(assetID int64) (*models.Asset, error) {
|
||
if assetID <= 0 {
|
||
return nil, errors.New("asset_id must be greater than 0")
|
||
}
|
||
|
||
var asset models.Asset
|
||
if err := r.db.Where("id = ? AND is_active = ?", assetID, true).
|
||
First(&asset).Error; err != nil {
|
||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||
return nil, appErrors.ErrAssetNotFound
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
return &asset, nil
|
||
}
|
||
|
||
// GetByIDAndOwner 根据ID和所有者查询资产(用于权限验证)
|
||
func (r *assetRepository) GetByIDAndOwner(assetID, ownerUID, starID int64) (*models.Asset, error) {
|
||
if assetID <= 0 {
|
||
return nil, errors.New("asset_id must be greater than 0")
|
||
}
|
||
|
||
if ownerUID <= 0 {
|
||
return nil, errors.New("owner_uid must be greater than 0")
|
||
}
|
||
|
||
if starID <= 0 {
|
||
return nil, errors.New("star_id must be greater than 0")
|
||
}
|
||
|
||
var asset models.Asset
|
||
if err := r.db.Where("id = ? AND owner_uid = ? AND star_id = ? AND is_active = ?",
|
||
assetID, ownerUID, starID, true).
|
||
First(&asset).Error; err != nil {
|
||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||
return nil, appErrors.ErrAssetNotFound
|
||
}
|
||
return nil, err
|
||
}
|
||
|
||
return &asset, nil
|
||
}
|
||
|
||
// GetByOwner 查询用户的资产列表
|
||
func (r *assetRepository) GetByOwner(ownerUID, starID int64, limit, offset int) ([]*models.Asset, error) {
|
||
if ownerUID <= 0 {
|
||
return nil, errors.New("owner_uid must be greater than 0")
|
||
}
|
||
|
||
if starID <= 0 {
|
||
return nil, errors.New("star_id must be greater than 0")
|
||
}
|
||
|
||
var assets []*models.Asset
|
||
query := r.db.Where("owner_uid = ? AND star_id = ? AND is_active = ?", ownerUID, starID, true).
|
||
Order("created_at DESC")
|
||
|
||
if limit > 0 {
|
||
query = query.Limit(limit)
|
||
}
|
||
|
||
if offset > 0 {
|
||
query = query.Offset(offset)
|
||
}
|
||
|
||
if err := query.Find(&assets).Error; err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return assets, nil
|
||
}
|
||
|
||
// CountByOwner 统计用户的资产数量
|
||
func (r *assetRepository) CountByOwner(ownerUID, starID int64) (int64, error) {
|
||
if ownerUID <= 0 {
|
||
return 0, errors.New("owner_uid must be greater than 0")
|
||
}
|
||
|
||
if starID <= 0 {
|
||
return 0, errors.New("star_id must be greater than 0")
|
||
}
|
||
|
||
var count int64
|
||
if err := r.db.Model(&models.Asset{}).
|
||
Where("owner_uid = ? AND star_id = ? AND is_active = ?", ownerUID, starID, true).
|
||
Count(&count).Error; err != nil {
|
||
return 0, err
|
||
}
|
||
|
||
return count, nil
|
||
}
|
||
|
||
// UpdateStatus 更新资产状态
|
||
func (r *assetRepository) UpdateStatus(assetID int64, status int32) error {
|
||
if assetID <= 0 {
|
||
return errors.New("asset_id must be greater than 0")
|
||
}
|
||
|
||
result := r.db.Model(&models.Asset{}).
|
||
Where("id = ?", assetID).
|
||
Update("status", status)
|
||
|
||
if result.Error != nil {
|
||
return result.Error
|
||
}
|
||
|
||
if result.RowsAffected == 0 {
|
||
return appErrors.ErrAssetNotFound
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// UpdateBlockchainInfo 更新区块链信息
|
||
func (r *assetRepository) UpdateBlockchainInfo(assetID int64, txHash string, blockNumber int64, mintedAt int64) error {
|
||
if assetID <= 0 {
|
||
return errors.New("asset_id must be greater than 0")
|
||
}
|
||
|
||
updates := map[string]interface{}{
|
||
"tx_hash": txHash,
|
||
"block_number": blockNumber,
|
||
"minted_at": mintedAt,
|
||
"status": models.AssetStatusActive,
|
||
}
|
||
|
||
result := r.db.Model(&models.Asset{}).
|
||
Where("id = ?", assetID).
|
||
Updates(updates)
|
||
|
||
if result.Error != nil {
|
||
return result.Error
|
||
}
|
||
|
||
if result.RowsAffected == 0 {
|
||
return appErrors.ErrAssetNotFound
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// IncrementLikeCount 增加点赞数
|
||
func (r *assetRepository) IncrementLikeCount(assetID int64) error {
|
||
if assetID <= 0 {
|
||
return errors.New("asset_id must be greater than 0")
|
||
}
|
||
|
||
return r.db.Model(&models.Asset{}).
|
||
Where("id = ?", assetID).
|
||
UpdateColumn("like_count", gorm.Expr("like_count + ?", 1)).Error
|
||
}
|
||
|
||
// DecrementLikeCount 减少点赞数
|
||
func (r *assetRepository) DecrementLikeCount(assetID int64) error {
|
||
if assetID <= 0 {
|
||
return errors.New("asset_id must be greater than 0")
|
||
}
|
||
|
||
return r.db.Model(&models.Asset{}).
|
||
Where("id = ? AND like_count > ?", assetID, 0).
|
||
UpdateColumn("like_count", gorm.Expr("like_count - ?", 1)).Error
|
||
}
|
||
|
||
// IsExhibiting 检查资产是否正在展出中
|
||
// 通过关联 exhibitions 表,查询未过期的展出记录
|
||
func (r *assetRepository) IsExhibiting(assetID int64) (bool, error) {
|
||
if assetID <= 0 {
|
||
return false, errors.New("asset_id must be greater than 0")
|
||
}
|
||
|
||
var count int64
|
||
// 查询 exhibitions 表中是否存在该资产的未过期展出记录
|
||
err := r.db.Model(&models.Exhibition{}).
|
||
Where("asset_id = ? AND expire_at > ?", assetID, time.Now().UnixMilli()).
|
||
Count(&count).Error
|
||
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
|
||
return count > 0, nil
|
||
}
|