223 lines
6.4 KiB
Go
223 lines
6.4 KiB
Go
package client
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"fmt"
|
||
"strconv"
|
||
|
||
"dubbo.apache.org/dubbo-go/v3/common/constant"
|
||
"github.com/topfans/backend/pkg/logger"
|
||
pbAsset "github.com/topfans/backend/pkg/proto/asset"
|
||
pbCommon "github.com/topfans/backend/pkg/proto/common"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
// AssetInfo 资产信息
|
||
type AssetInfo struct {
|
||
AssetId int64
|
||
OwnerUid int64
|
||
StarId int64
|
||
Name string
|
||
CoverUrl string
|
||
LikeCount int32
|
||
}
|
||
|
||
// AssetRPCClient Asset Service RPC客户端接口
|
||
type AssetRPCClient interface {
|
||
// GetAssetForRPC 验证资产是否存在且获取资产信息(用于RPC调用)
|
||
GetAssetForRPC(assetID, userID, starID int64) (*AssetInfo, error)
|
||
|
||
// GetAssetInfo 获取资产信息(简化版,用于展示)
|
||
GetAssetInfo(assetID, userID, starID int64) (*AssetInfo, error)
|
||
|
||
// ClearAssetLikeRecords 清除资产点赞记录(不修改 like_count),在藏品下架时调用
|
||
ClearAssetLikeRecords(assetID int64) error
|
||
}
|
||
|
||
// assetRPCClient Asset Service RPC客户端实现
|
||
type assetRPCClient struct {
|
||
client pbAsset.AssetService
|
||
}
|
||
|
||
// NewAssetRPCClient 创建Asset Service RPC客户端
|
||
func NewAssetRPCClient(client pbAsset.AssetService) AssetRPCClient {
|
||
return &assetRPCClient{
|
||
client: client,
|
||
}
|
||
}
|
||
|
||
// GetAssetForRPC 验证资产是否存在且获取资产信息(用于RPC调用)
|
||
func (c *assetRPCClient) GetAssetForRPC(assetID, userID, starID int64) (*AssetInfo, error) {
|
||
logger.Logger.Debug("Calling AssetService.GetAssetForRPC",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
|
||
ctx := context.Background()
|
||
resp, err := c.client.GetAssetForRPC(ctx, &pbAsset.GetAssetForRPCRequest{
|
||
AssetId: assetID,
|
||
})
|
||
|
||
if err != nil {
|
||
errorMsg := fmt.Sprintf("RPC调用失败: %v", err)
|
||
logger.Logger.Error("Failed to call AssetService.GetAssetForRPC",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
zap.String("error", errorMsg),
|
||
zap.Error(err),
|
||
)
|
||
return nil, errors.New(errorMsg)
|
||
}
|
||
|
||
if resp == nil {
|
||
errorMsg := "AssetService.GetAssetForRPC 返回空响应"
|
||
logger.Logger.Error("AssetService.GetAssetForRPC returned nil response",
|
||
zap.Int64("asset_id", assetID),
|
||
)
|
||
return nil, errors.New(errorMsg)
|
||
}
|
||
|
||
// StatusCode_STATUS_OK = 200,不是 0
|
||
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
|
||
errorMsg := resp.Base.Message
|
||
if errorMsg == "" {
|
||
errorMsg = fmt.Sprintf("AssetService返回错误码: %d", resp.Base.Code)
|
||
}
|
||
logger.Logger.Warn("AssetService.GetAssetForRPC returned error",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int32("code", int32(resp.Base.Code)),
|
||
zap.String("message", errorMsg),
|
||
)
|
||
return nil, errors.New(errorMsg)
|
||
}
|
||
|
||
// 验证资产是否属于当前用户
|
||
if resp.OwnerUid != userID {
|
||
logger.Logger.Warn("Asset does not belong to user",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int64("owner_uid", resp.OwnerUid),
|
||
zap.Int64("expected_user_id", userID),
|
||
)
|
||
return nil, errors.New("资产不属于当前用户")
|
||
}
|
||
|
||
// 验证资产是否属于同一明星
|
||
if resp.StarId != starID {
|
||
logger.Logger.Warn("Asset does not belong to the same star",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int64("star_id", resp.StarId),
|
||
zap.Int64("expected_star_id", starID),
|
||
)
|
||
return nil, errors.New("资产不属于同一明星")
|
||
}
|
||
|
||
logger.Logger.Debug("AssetService.GetAssetForRPC successful",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int64("owner_uid", resp.OwnerUid),
|
||
)
|
||
|
||
// 注意:GetAssetForRPCResponse 不包含 Name, CoverUrl, LikeCount
|
||
// 这些信息需要通过 GetAsset 获取
|
||
return &AssetInfo{
|
||
AssetId: resp.AssetId,
|
||
OwnerUid: resp.OwnerUid,
|
||
StarId: resp.StarId,
|
||
Name: "", // 需要调用 GetAsset 获取
|
||
CoverUrl: "", // 需要调用 GetAsset 获取
|
||
LikeCount: 0, // 需要调用 GetAsset 获取
|
||
}, nil
|
||
}
|
||
|
||
// GetAssetInfo 获取资产信息(简化版,用于展示)
|
||
func (c *assetRPCClient) GetAssetInfo(assetID, userID, starID int64) (*AssetInfo, error) {
|
||
logger.Logger.Debug("Calling AssetService.GetAsset",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
|
||
// 创建带有用户信息的context(Triple协议要求attachments值为string类型)
|
||
ctx := context.WithValue(context.Background(), constant.AttachmentKey, map[string]interface{}{
|
||
"user_id": strconv.FormatInt(userID, 10),
|
||
"star_id": strconv.FormatInt(starID, 10),
|
||
})
|
||
|
||
resp, err := c.client.GetAsset(ctx, &pbAsset.GetAssetRequest{
|
||
AssetId: assetID,
|
||
})
|
||
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to call AssetService.GetAsset",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Error(err),
|
||
)
|
||
return nil, err
|
||
}
|
||
|
||
// StatusCode_STATUS_OK = 200,不是 0
|
||
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
|
||
errorMsg := resp.Base.Message
|
||
if errorMsg == "" {
|
||
errorMsg = fmt.Sprintf("AssetService返回错误码: %d", resp.Base.Code)
|
||
}
|
||
logger.Logger.Warn("AssetService.GetAsset returned error",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Int32("code", int32(resp.Base.Code)),
|
||
zap.String("message", errorMsg),
|
||
)
|
||
return nil, errors.New(errorMsg)
|
||
}
|
||
|
||
logger.Logger.Debug("AssetService.GetAsset successful",
|
||
zap.Int64("asset_id", assetID),
|
||
)
|
||
|
||
return &AssetInfo{
|
||
AssetId: resp.Asset.AssetId,
|
||
OwnerUid: resp.Asset.OwnerUid,
|
||
StarId: resp.Asset.StarId,
|
||
Name: resp.Asset.Name,
|
||
CoverUrl: resp.Asset.CoverUrl,
|
||
LikeCount: resp.Asset.LikeCount,
|
||
}, nil
|
||
}
|
||
|
||
// ClearAssetLikeRecords 清除资产点赞记录(不修改 like_count)
|
||
func (c *assetRPCClient) ClearAssetLikeRecords(assetID int64) error {
|
||
logger.Logger.Debug("Calling AssetService.ClearAssetLikeRecords",
|
||
zap.Int64("asset_id", assetID),
|
||
)
|
||
|
||
resp, err := c.client.ClearAssetLikeRecords(context.Background(), &pbAsset.ClearAssetLikeRecordsRequest{
|
||
AssetId: assetID,
|
||
})
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to call AssetService.ClearAssetLikeRecords",
|
||
zap.Int64("asset_id", assetID),
|
||
zap.Error(err),
|
||
)
|
||
return fmt.Errorf("清除点赞记录RPC失败: %w", err)
|
||
}
|
||
|
||
if resp == nil || resp.Base == nil {
|
||
return fmt.Errorf("AssetService.ClearAssetLikeRecords 返回空响应")
|
||
}
|
||
|
||
if resp.Base.Code != pbCommon.StatusCode_STATUS_OK {
|
||
errMsg := resp.Base.Message
|
||
if errMsg == "" {
|
||
errMsg = fmt.Sprintf("AssetService返回错误码: %d", resp.Base.Code)
|
||
}
|
||
return errors.New(errMsg)
|
||
}
|
||
|
||
logger.Logger.Debug("AssetService.ClearAssetLikeRecords successful",
|
||
zap.Int64("asset_id", assetID),
|
||
)
|
||
|
||
return nil
|
||
}
|