feat: integrate asset level system with existing services

- mintService: Add AssetLevelService field and call GetOrCreateRecord after asset creation
- assetLikeService: Add AssetLevelService and call AddLikes/RemoveLikes in LikeAsset/UnlikeAsset
- revenueService: Add AssetLevelService and call AddExhibitionHours in OnExhibitionCompleted

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
zerosaturation 2026-05-25 12:23:23 +08:00
parent c6a8c66e39
commit bee30a1824
3 changed files with 82 additions and 12 deletions

View File

@ -15,9 +15,10 @@ import (
// AssetLikeService 资产点赞业务逻辑层 // AssetLikeService 资产点赞业务逻辑层
type AssetLikeService struct { type AssetLikeService struct {
assetRepo repository.AssetRepository assetRepo repository.AssetRepository
assetLikeRepo repository.AssetLikeRepository assetLikeRepo repository.AssetLikeRepository
db *gorm.DB db *gorm.DB
assetLevelService AssetLevelService // 资产等级服务
} }
// NewAssetLikeService 创建资产点赞Service实例 // NewAssetLikeService 创建资产点赞Service实例
@ -25,11 +26,13 @@ func NewAssetLikeService(
assetRepo repository.AssetRepository, assetRepo repository.AssetRepository,
assetLikeRepo repository.AssetLikeRepository, assetLikeRepo repository.AssetLikeRepository,
db *gorm.DB, db *gorm.DB,
assetLevelService AssetLevelService,
) *AssetLikeService { ) *AssetLikeService {
return &AssetLikeService{ return &AssetLikeService{
assetRepo: assetRepo, assetRepo: assetRepo,
assetLikeRepo: assetLikeRepo, assetLikeRepo: assetLikeRepo,
db: db, db: db,
assetLevelService: assetLevelService,
} }
} }
@ -223,6 +226,19 @@ func (s *AssetLikeService) LikeAsset(ctx context.Context, assetID, userID, starI
zap.Int32("like_count", asset.LikeCount), zap.Int32("like_count", asset.LikeCount),
) )
// 5. 更新资产等级记录(点赞数变化)
if s.assetLevelService != nil {
if newLevel, upgraded, err := s.assetLevelService.AddLikes(assetID, 1); err != nil {
logger.Logger.Warn("Failed to add likes to asset level",
zap.Int64("asset_id", assetID),
zap.Error(err))
} else if upgraded {
logger.Logger.Info("Asset leveled up due to likes",
zap.Int64("asset_id", assetID),
zap.String("new_level", newLevel))
}
}
return asset.LikeCount, nil return asset.LikeCount, nil
} }
@ -338,6 +354,19 @@ func (s *AssetLikeService) UnlikeAsset(ctx context.Context, assetID, userID, sta
zap.Int32("like_count", asset.LikeCount), zap.Int32("like_count", asset.LikeCount),
) )
// 4. 更新资产等级记录(取消点赞)
if s.assetLevelService != nil {
if newLevel, downgraded, err := s.assetLevelService.RemoveLikes(assetID, 1); err != nil {
logger.Logger.Warn("Failed to remove likes from asset level",
zap.Int64("asset_id", assetID),
zap.Error(err))
} else if downgraded {
logger.Logger.Info("Asset downgraded due to like removal",
zap.Int64("asset_id", assetID),
zap.String("new_level", newLevel))
}
}
return asset.LikeCount, nil return asset.LikeCount, nil
} }

View File

@ -67,6 +67,7 @@ type mintService struct {
registryRepo starbookRepo.AssetRegistryRepository // 资产索引仓库(用于星册体系) registryRepo starbookRepo.AssetRegistryRepository // 资产索引仓库(用于星册体系)
localMintCostRepo repository.MintCostRepository // 铸造消耗配置仓库 localMintCostRepo repository.MintCostRepository // 铸造消耗配置仓库
userMintCountRepo repository.UserMintCountRepository // 用户铸爱累计仓库 userMintCountRepo repository.UserMintCountRepository // 用户铸爱累计仓库
assetLevelService AssetLevelService // 资产等级服务
} }
// NewMintService 创建铸造服务实例 // NewMintService 创建铸造服务实例
@ -79,6 +80,7 @@ func NewMintService(
registryRepo starbookRepo.AssetRegistryRepository, registryRepo starbookRepo.AssetRegistryRepository,
localMintCostRepo repository.MintCostRepository, localMintCostRepo repository.MintCostRepository,
userMintCountRepo repository.UserMintCountRepository, userMintCountRepo repository.UserMintCountRepository,
assetLevelService AssetLevelService,
) MintService { ) MintService {
return &mintService{ return &mintService{
assetRepo: assetRepo, assetRepo: assetRepo,
@ -89,6 +91,7 @@ func NewMintService(
registryRepo: registryRepo, registryRepo: registryRepo,
localMintCostRepo: localMintCostRepo, localMintCostRepo: localMintCostRepo,
userMintCountRepo: userMintCountRepo, userMintCountRepo: userMintCountRepo,
assetLevelService: assetLevelService,
} }
} }
@ -439,7 +442,16 @@ func (s *mintService) CreateMintOrder(req *pb.CreateMintOrderRequest, userID, st
return nil, err return nil, err
} }
// 4. 无需异步 AI 处理cover_url 已在步骤 3.2 中直接设置 // 4. 初始化资产等级记录
if s.assetLevelService != nil && asset != nil {
if _, err := s.assetLevelService.GetOrCreateRecord(asset.ID); err != nil {
logger.Logger.Warn("Failed to create asset level record",
zap.Int64("asset_id", asset.ID),
zap.Error(err))
}
}
// 5. 无需异步 AI 处理cover_url 已在步骤 3.2 中直接设置
// 5. 获取所有者的昵称(创建时所有者就是当前用户) // 5. 获取所有者的昵称(创建时所有者就是当前用户)
var ownerNickname string var ownerNickname string

View File

@ -20,24 +20,38 @@ type RevenueService interface {
ClaimExhibitionRevenue(ctx context.Context, userID, starID int64, revenueID int64) (*pb.ClaimExhibitionRevenueResponse, error) ClaimExhibitionRevenue(ctx context.Context, userID, starID int64, revenueID int64) (*pb.ClaimExhibitionRevenueResponse, error)
ClaimAllExhibitionRevenue(ctx context.Context, userID, starID int64) (*pb.ClaimAllExhibitionRevenueResponse, error) ClaimAllExhibitionRevenue(ctx context.Context, userID, starID int64) (*pb.ClaimAllExhibitionRevenueResponse, error)
OnExhibitionCompleted(ctx context.Context, req *pb.OnExhibitionCompletedRequest) (*pb.OnExhibitionCompletedResponse, error) OnExhibitionCompleted(ctx context.Context, req *pb.OnExhibitionCompletedRequest) (*pb.OnExhibitionCompletedResponse, error)
SetAssetLevelService(svc AssetLevelService)
}
// AssetLevelService 资产等级服务接口定义在assetService
type AssetLevelService interface {
GetOrCreateRecord(assetID int64) (interface{}, error)
AddExhibitionHours(assetID int64, hours int) (string, bool, error)
} }
// revenueService 展示收益Service实现 // revenueService 展示收益Service实现
type revenueService struct { type revenueService struct {
revenueRepo repository.RevenueRepository revenueRepo repository.RevenueRepository
userRPCClient client.UserServiceClient userRPCClient client.UserServiceClient
galleryRPCClient client.GalleryServiceClient galleryRPCClient client.GalleryServiceClient
assetLevelService AssetLevelService // 资产等级服务
} }
// NewRevenueService 创建收益Service实例 // NewRevenueService 创建收益Service实例
func NewRevenueService(revenueRepo repository.RevenueRepository, userRPCClient client.UserServiceClient, galleryRPCClient client.GalleryServiceClient) RevenueService { func NewRevenueService(revenueRepo repository.RevenueRepository, userRPCClient client.UserServiceClient, galleryRPCClient client.GalleryServiceClient, assetLevelService AssetLevelService) RevenueService {
return &revenueService{ return &revenueService{
revenueRepo: revenueRepo, revenueRepo: revenueRepo,
userRPCClient: userRPCClient, userRPCClient: userRPCClient,
galleryRPCClient: galleryRPCClient, galleryRPCClient: galleryRPCClient,
assetLevelService: assetLevelService,
} }
} }
// SetAssetLevelService 设置资产等级服务
func (s *revenueService) SetAssetLevelService(svc AssetLevelService) {
s.assetLevelService = svc
}
// GetExhibitionRevenue 获取展示收益列表 // GetExhibitionRevenue 获取展示收益列表
func (s *revenueService) GetExhibitionRevenue(ctx context.Context, userID, starID int64, status string, page, pageSize int32) (*pb.GetExhibitionRevenueResponse, error) { func (s *revenueService) GetExhibitionRevenue(ctx context.Context, userID, starID int64, status string, page, pageSize int32) (*pb.GetExhibitionRevenueResponse, error) {
logger.Logger.Debug("GetExhibitionRevenue", logger.Logger.Debug("GetExhibitionRevenue",
@ -367,6 +381,21 @@ func (s *revenueService) OnExhibitionCompleted(ctx context.Context, req *pb.OnEx
zap.Int64("crystal_reward", crystalReward)) zap.Int64("crystal_reward", crystalReward))
} }
// 增加资产累计展出时长(资产等级系统)
if s.assetLevelService != nil && req.AssetId > 0 && actualHours > 0 {
if newLevel, upgraded, err := s.assetLevelService.AddExhibitionHours(req.AssetId, int(actualHours)); err != nil {
logger.Logger.Warn("OnExhibitionCompleted: failed to add exhibition hours to asset level",
zap.Int64("asset_id", req.AssetId),
zap.Int64("hours", actualHours),
zap.Error(err))
} else if upgraded {
logger.Logger.Info("OnExhibitionCompleted: asset leveled up due to exhibition",
zap.Int64("asset_id", req.AssetId),
zap.String("new_level", newLevel),
zap.Int64("hours", actualHours))
}
}
logger.Logger.Info("OnExhibitionCompleted: success", logger.Logger.Info("OnExhibitionCompleted: success",
zap.Int64("exhibition_id", req.ExhibitionId), zap.Int64("exhibition_id", req.ExhibitionId),
zap.Int64("revenue_record_id", createdRecord.ID)) zap.Int64("revenue_record_id", createdRecord.ID))