topfans/backend/services/assetService/repository/asset_repository.go
2026-04-07 22:29:48 +08:00

262 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}