2026-05-11 19:26:01 +08:00

543 lines
20 KiB
Go

package grpc
import (
"context"
walletv1 "hyapp.local/api/proto/wallet/v1"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
resourcedomain "hyapp/services/wallet-service/internal/domain/resource"
)
func (s *Server) ListResources(ctx context.Context, req *walletv1.ListResourcesRequest) (*walletv1.ListResourcesResponse, error) {
items, total, err := s.svc.ListResources(ctx, resourcedomain.ListResourcesQuery{
AppCode: req.GetAppCode(),
ResourceType: req.GetResourceType(),
Status: req.GetStatus(),
Keyword: req.GetKeyword(),
Page: req.GetPage(),
PageSize: req.GetPageSize(),
ActiveOnly: req.GetActiveOnly(),
ManagerGrantOnly: req.GetManagerGrantOnly(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &walletv1.ListResourcesResponse{Resources: make([]*walletv1.Resource, 0, len(items)), Total: total}
for _, item := range items {
resp.Resources = append(resp.Resources, resourceToProto(item))
}
return resp, nil
}
func (s *Server) GetResource(ctx context.Context, req *walletv1.GetResourceRequest) (*walletv1.GetResourceResponse, error) {
resource, err := s.svc.GetResource(ctx, req.GetAppCode(), req.GetResourceId())
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.GetResourceResponse{Resource: resourceToProto(resource)}, nil
}
func (s *Server) CreateResource(ctx context.Context, req *walletv1.CreateResourceRequest) (*walletv1.ResourceResponse, error) {
resource, err := s.svc.CreateResource(ctx, resourceCommandFromCreate(req))
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceResponse{Resource: resourceToProto(resource)}, nil
}
func (s *Server) UpdateResource(ctx context.Context, req *walletv1.UpdateResourceRequest) (*walletv1.ResourceResponse, error) {
resource, err := s.svc.UpdateResource(ctx, resourceCommandFromUpdate(req))
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceResponse{Resource: resourceToProto(resource)}, nil
}
func (s *Server) SetResourceStatus(ctx context.Context, req *walletv1.SetResourceStatusRequest) (*walletv1.ResourceResponse, error) {
resource, err := s.svc.SetResourceStatus(ctx, resourcedomain.StatusCommand{
AppCode: req.GetAppCode(),
ID: req.GetResourceId(),
Status: req.GetStatus(),
OperatorUserID: req.GetOperatorUserId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceResponse{Resource: resourceToProto(resource)}, nil
}
func (s *Server) ListResourceGroups(ctx context.Context, req *walletv1.ListResourceGroupsRequest) (*walletv1.ListResourceGroupsResponse, error) {
items, total, err := s.svc.ListResourceGroups(ctx, resourcedomain.ListResourceGroupsQuery{
AppCode: req.GetAppCode(),
Status: req.GetStatus(),
Keyword: req.GetKeyword(),
Page: req.GetPage(),
PageSize: req.GetPageSize(),
ActiveOnly: req.GetActiveOnly(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &walletv1.ListResourceGroupsResponse{Groups: make([]*walletv1.ResourceGroup, 0, len(items)), Total: total}
for _, item := range items {
resp.Groups = append(resp.Groups, resourceGroupToProto(item))
}
return resp, nil
}
func (s *Server) GetResourceGroup(ctx context.Context, req *walletv1.GetResourceGroupRequest) (*walletv1.GetResourceGroupResponse, error) {
group, err := s.svc.GetResourceGroup(ctx, req.GetAppCode(), req.GetGroupId())
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.GetResourceGroupResponse{Group: resourceGroupToProto(group)}, nil
}
func (s *Server) CreateResourceGroup(ctx context.Context, req *walletv1.CreateResourceGroupRequest) (*walletv1.ResourceGroupResponse, error) {
group, err := s.svc.CreateResourceGroup(ctx, resourceGroupCommandFromCreate(req))
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceGroupResponse{Group: resourceGroupToProto(group)}, nil
}
func (s *Server) UpdateResourceGroup(ctx context.Context, req *walletv1.UpdateResourceGroupRequest) (*walletv1.ResourceGroupResponse, error) {
group, err := s.svc.UpdateResourceGroup(ctx, resourceGroupCommandFromUpdate(req))
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceGroupResponse{Group: resourceGroupToProto(group)}, nil
}
func (s *Server) SetResourceGroupStatus(ctx context.Context, req *walletv1.SetResourceGroupStatusRequest) (*walletv1.ResourceGroupResponse, error) {
group, err := s.svc.SetResourceGroupStatus(ctx, resourcedomain.StatusCommand{
AppCode: req.GetAppCode(),
ID: req.GetGroupId(),
Status: req.GetStatus(),
OperatorUserID: req.GetOperatorUserId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceGroupResponse{Group: resourceGroupToProto(group)}, nil
}
func (s *Server) ListGiftConfigs(ctx context.Context, req *walletv1.ListGiftConfigsRequest) (*walletv1.ListGiftConfigsResponse, error) {
items, total, err := s.svc.ListGiftConfigs(ctx, resourcedomain.ListGiftConfigsQuery{
AppCode: req.GetAppCode(),
Status: req.GetStatus(),
Keyword: req.GetKeyword(),
Page: req.GetPage(),
PageSize: req.GetPageSize(),
ActiveOnly: req.GetActiveOnly(),
RegionID: req.GetRegionId(),
FilterRegion: req.GetFilterRegion(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &walletv1.ListGiftConfigsResponse{Gifts: make([]*walletv1.GiftConfig, 0, len(items)), Total: total}
for _, item := range items {
resp.Gifts = append(resp.Gifts, giftConfigToProto(item))
}
return resp, nil
}
func (s *Server) CreateGiftConfig(ctx context.Context, req *walletv1.CreateGiftConfigRequest) (*walletv1.GiftConfigResponse, error) {
gift, err := s.svc.CreateGiftConfig(ctx, giftConfigCommandFromCreate(req))
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.GiftConfigResponse{Gift: giftConfigToProto(gift)}, nil
}
func (s *Server) UpdateGiftConfig(ctx context.Context, req *walletv1.UpdateGiftConfigRequest) (*walletv1.GiftConfigResponse, error) {
gift, err := s.svc.UpdateGiftConfig(ctx, giftConfigCommandFromUpdate(req))
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.GiftConfigResponse{Gift: giftConfigToProto(gift)}, nil
}
func (s *Server) SetGiftConfigStatus(ctx context.Context, req *walletv1.SetGiftConfigStatusRequest) (*walletv1.GiftConfigResponse, error) {
gift, err := s.svc.SetGiftConfigStatus(ctx, resourcedomain.StatusCommand{
AppCode: req.GetAppCode(),
StringID: req.GetGiftId(),
Status: req.GetStatus(),
OperatorUserID: req.GetOperatorUserId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.GiftConfigResponse{Gift: giftConfigToProto(gift)}, nil
}
func (s *Server) GrantResource(ctx context.Context, req *walletv1.GrantResourceRequest) (*walletv1.ResourceGrantResponse, error) {
grant, err := s.svc.GrantResource(ctx, resourcedomain.GrantResourceCommand{
AppCode: req.GetAppCode(),
CommandID: req.GetCommandId(),
TargetUserID: req.GetTargetUserId(),
ResourceID: req.GetResourceId(),
Quantity: req.GetQuantity(),
DurationMS: req.GetDurationMs(),
Reason: req.GetReason(),
OperatorUserID: req.GetOperatorUserId(),
GrantSource: req.GetGrantSource(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceGrantResponse{Grant: resourceGrantToProto(grant)}, nil
}
func (s *Server) GrantResourceGroup(ctx context.Context, req *walletv1.GrantResourceGroupRequest) (*walletv1.ResourceGrantResponse, error) {
grant, err := s.svc.GrantResourceGroup(ctx, resourcedomain.GrantResourceGroupCommand{
AppCode: req.GetAppCode(),
CommandID: req.GetCommandId(),
TargetUserID: req.GetTargetUserId(),
GroupID: req.GetGroupId(),
Reason: req.GetReason(),
OperatorUserID: req.GetOperatorUserId(),
GrantSource: req.GetGrantSource(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.ResourceGrantResponse{Grant: resourceGrantToProto(grant)}, nil
}
func (s *Server) ListUserResources(ctx context.Context, req *walletv1.ListUserResourcesRequest) (*walletv1.ListUserResourcesResponse, error) {
items, err := s.svc.ListUserResources(ctx, resourcedomain.ListUserResourcesQuery{
AppCode: req.GetAppCode(),
UserID: req.GetUserId(),
ResourceType: req.GetResourceType(),
ActiveOnly: req.GetActiveOnly(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &walletv1.ListUserResourcesResponse{Resources: make([]*walletv1.UserResourceEntitlement, 0, len(items))}
for _, item := range items {
resp.Resources = append(resp.Resources, userResourceToProto(item))
}
return resp, nil
}
func (s *Server) EquipUserResource(ctx context.Context, req *walletv1.EquipUserResourceRequest) (*walletv1.EquipUserResourceResponse, error) {
item, err := s.svc.EquipUserResource(ctx, resourcedomain.EquipUserResourceCommand{
AppCode: req.GetAppCode(),
UserID: req.GetUserId(),
ResourceID: req.GetResourceId(),
EntitlementID: req.GetEntitlementId(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
return &walletv1.EquipUserResourceResponse{Resource: userResourceToProto(item)}, nil
}
func (s *Server) ListResourceGrants(ctx context.Context, req *walletv1.ListResourceGrantsRequest) (*walletv1.ListResourceGrantsResponse, error) {
items, total, err := s.svc.ListResourceGrants(ctx, resourcedomain.ListResourceGrantsQuery{
AppCode: req.GetAppCode(),
TargetUserID: req.GetTargetUserId(),
Status: req.GetStatus(),
Page: req.GetPage(),
PageSize: req.GetPageSize(),
})
if err != nil {
return nil, xerr.ToGRPCError(err)
}
resp := &walletv1.ListResourceGrantsResponse{Grants: make([]*walletv1.ResourceGrant, 0, len(items)), Total: total}
for _, item := range items {
resp.Grants = append(resp.Grants, resourceGrantToProto(item))
}
return resp, nil
}
func resourceCommandFromCreate(req *walletv1.CreateResourceRequest) resourcedomain.ResourceCommand {
return resourcedomain.ResourceCommand{
AppCode: req.GetAppCode(),
ResourceCode: req.GetResourceCode(),
ResourceType: req.GetResourceType(),
Name: req.GetName(),
Status: req.GetStatus(),
Grantable: req.GetGrantable(),
GrantStrategy: req.GetGrantStrategy(),
WalletAssetType: req.GetWalletAssetType(),
WalletAssetAmount: req.GetWalletAssetAmount(),
UsageScopes: req.GetUsageScopes(),
AssetURL: req.GetAssetUrl(),
PreviewURL: req.GetPreviewUrl(),
AnimationURL: req.GetAnimationUrl(),
MetadataJSON: req.GetMetadataJson(),
SortOrder: req.GetSortOrder(),
OperatorUserID: req.GetOperatorUserId(),
ManagerGrantEnabled: managerGrantEnabledOrDefault(req.ManagerGrantEnabled),
}
}
func resourceCommandFromUpdate(req *walletv1.UpdateResourceRequest) resourcedomain.ResourceCommand {
command := resourceCommandFromCreate(&walletv1.CreateResourceRequest{
AppCode: req.GetAppCode(),
ResourceCode: req.GetResourceCode(),
ResourceType: req.GetResourceType(),
Name: req.GetName(),
Status: req.GetStatus(),
Grantable: req.GetGrantable(),
GrantStrategy: req.GetGrantStrategy(),
WalletAssetType: req.GetWalletAssetType(),
WalletAssetAmount: req.GetWalletAssetAmount(),
UsageScopes: req.GetUsageScopes(),
AssetUrl: req.GetAssetUrl(),
PreviewUrl: req.GetPreviewUrl(),
AnimationUrl: req.GetAnimationUrl(),
MetadataJson: req.GetMetadataJson(),
SortOrder: req.GetSortOrder(),
OperatorUserId: req.GetOperatorUserId(),
ManagerGrantEnabled: managerGrantEnabledOrDefault(req.ManagerGrantEnabled),
})
command.ResourceID = req.GetResourceId()
return command
}
func resourceGroupCommandFromCreate(req *walletv1.CreateResourceGroupRequest) resourcedomain.ResourceGroupCommand {
return resourcedomain.ResourceGroupCommand{
AppCode: req.GetAppCode(),
GroupCode: req.GetGroupCode(),
Name: req.GetName(),
Status: req.GetStatus(),
Description: req.GetDescription(),
SortOrder: req.GetSortOrder(),
Items: groupItemInputs(req.GetItems()),
OperatorUserID: req.GetOperatorUserId(),
}
}
func resourceGroupCommandFromUpdate(req *walletv1.UpdateResourceGroupRequest) resourcedomain.ResourceGroupCommand {
return resourcedomain.ResourceGroupCommand{
AppCode: req.GetAppCode(),
GroupID: req.GetGroupId(),
GroupCode: req.GetGroupCode(),
Name: req.GetName(),
Status: req.GetStatus(),
Description: req.GetDescription(),
SortOrder: req.GetSortOrder(),
Items: groupItemInputs(req.GetItems()),
OperatorUserID: req.GetOperatorUserId(),
}
}
func giftConfigCommandFromCreate(req *walletv1.CreateGiftConfigRequest) resourcedomain.GiftConfigCommand {
return resourcedomain.GiftConfigCommand{
AppCode: req.GetAppCode(),
GiftID: req.GetGiftId(),
ResourceID: req.GetResourceId(),
Status: req.GetStatus(),
Name: req.GetName(),
SortOrder: req.GetSortOrder(),
PresentationJSON: req.GetPresentationJson(),
PriceVersion: req.GetPriceVersion(),
CoinPrice: req.GetCoinPrice(),
GiftPointAmount: req.GetGiftPointAmount(),
HeatValue: req.GetHeatValue(),
EffectiveAtMS: req.GetEffectiveAtMs(),
GiftTypeCode: req.GetGiftTypeCode(),
ChargeAssetType: req.GetChargeAssetType(),
EffectiveFromMS: req.GetEffectiveFromMs(),
EffectiveToMS: req.GetEffectiveToMs(),
EffectTypes: req.GetEffectTypes(),
OperatorUserID: req.GetOperatorUserId(),
RegionIDs: req.GetRegionIds(),
}
}
func giftConfigCommandFromUpdate(req *walletv1.UpdateGiftConfigRequest) resourcedomain.GiftConfigCommand {
return resourcedomain.GiftConfigCommand{
AppCode: req.GetAppCode(),
GiftID: req.GetGiftId(),
ResourceID: req.GetResourceId(),
Status: req.GetStatus(),
Name: req.GetName(),
SortOrder: req.GetSortOrder(),
PresentationJSON: req.GetPresentationJson(),
PriceVersion: req.GetPriceVersion(),
CoinPrice: req.GetCoinPrice(),
GiftPointAmount: req.GetGiftPointAmount(),
HeatValue: req.GetHeatValue(),
EffectiveAtMS: req.GetEffectiveAtMs(),
GiftTypeCode: req.GetGiftTypeCode(),
ChargeAssetType: req.GetChargeAssetType(),
EffectiveFromMS: req.GetEffectiveFromMs(),
EffectiveToMS: req.GetEffectiveToMs(),
EffectTypes: req.GetEffectTypes(),
OperatorUserID: req.GetOperatorUserId(),
RegionIDs: req.GetRegionIds(),
}
}
func groupItemInputs(items []*walletv1.ResourceGroupItemInput) []resourcedomain.ResourceGroupItemInput {
out := make([]resourcedomain.ResourceGroupItemInput, 0, len(items))
for _, item := range items {
if item == nil {
continue
}
out = append(out, resourcedomain.ResourceGroupItemInput{
ItemType: item.GetItemType(),
ResourceID: item.GetResourceId(),
WalletAssetType: item.GetWalletAssetType(),
WalletAssetAmount: item.GetWalletAssetAmount(),
Quantity: item.GetQuantity(),
DurationMS: item.GetDurationMs(),
SortOrder: item.GetSortOrder(),
})
}
return out
}
func resourceToProto(resource resourcedomain.Resource) *walletv1.Resource {
return &walletv1.Resource{
AppCode: appcode.Normalize(resource.AppCode),
ResourceId: resource.ResourceID,
ResourceCode: resource.ResourceCode,
ResourceType: resource.ResourceType,
Name: resource.Name,
Status: resource.Status,
Grantable: resource.Grantable,
GrantStrategy: resource.GrantStrategy,
WalletAssetType: resource.WalletAssetType,
WalletAssetAmount: resource.WalletAssetAmount,
UsageScopes: resource.UsageScopes,
AssetUrl: resource.AssetURL,
PreviewUrl: resource.PreviewURL,
AnimationUrl: resource.AnimationURL,
MetadataJson: resource.MetadataJSON,
SortOrder: resource.SortOrder,
CreatedByUserId: resource.CreatedByUserID,
UpdatedByUserId: resource.UpdatedByUserID,
CreatedAtMs: resource.CreatedAtMS,
UpdatedAtMs: resource.UpdatedAtMS,
ManagerGrantEnabled: resource.ManagerGrantEnabled,
}
}
func managerGrantEnabledOrDefault(value *bool) bool {
if value == nil {
// 新建/编辑入口如果没显式携带开关,仍按产品规则默认允许经理中心赠送。
return true
}
return *value
}
func resourceGroupToProto(group resourcedomain.ResourceGroup) *walletv1.ResourceGroup {
items := make([]*walletv1.ResourceGroupItem, 0, len(group.Items))
for _, item := range group.Items {
items = append(items, &walletv1.ResourceGroupItem{
GroupItemId: item.GroupItemID,
GroupId: item.GroupID,
ResourceId: item.ResourceID,
Resource: resourceToProto(item.Resource),
Quantity: item.Quantity,
DurationMs: item.DurationMS,
SortOrder: item.SortOrder,
CreatedAtMs: item.CreatedAtMS,
UpdatedAtMs: item.UpdatedAtMS,
ItemType: item.ItemType,
WalletAssetType: item.WalletAssetType,
WalletAssetAmount: item.WalletAssetAmount,
})
}
return &walletv1.ResourceGroup{
AppCode: appcode.Normalize(group.AppCode),
GroupId: group.GroupID,
GroupCode: group.GroupCode,
Name: group.Name,
Status: group.Status,
Description: group.Description,
SortOrder: group.SortOrder,
Items: items,
CreatedByUserId: group.CreatedByUserID,
UpdatedByUserId: group.UpdatedByUserID,
CreatedAtMs: group.CreatedAtMS,
UpdatedAtMs: group.UpdatedAtMS,
}
}
func giftConfigToProto(gift resourcedomain.GiftConfig) *walletv1.GiftConfig {
return &walletv1.GiftConfig{
AppCode: appcode.Normalize(gift.AppCode),
GiftId: gift.GiftID,
ResourceId: gift.ResourceID,
Resource: resourceToProto(gift.Resource),
Status: gift.Status,
Name: gift.Name,
SortOrder: gift.SortOrder,
PresentationJson: gift.PresentationJSON,
PriceVersion: gift.PriceVersion,
ChargeAssetType: gift.ChargeAssetType,
CoinPrice: gift.CoinPrice,
GiftPointAmount: gift.GiftPointAmount,
HeatValue: gift.HeatValue,
GiftTypeCode: gift.GiftTypeCode,
EffectiveFromMs: gift.EffectiveFromMS,
EffectiveToMs: gift.EffectiveToMS,
EffectTypes: gift.EffectTypes,
CreatedByUserId: gift.CreatedByUserID,
UpdatedByUserId: gift.UpdatedByUserID,
CreatedAtMs: gift.CreatedAtMS,
UpdatedAtMs: gift.UpdatedAtMS,
RegionIds: gift.RegionIDs,
}
}
func userResourceToProto(item resourcedomain.UserResourceEntitlement) *walletv1.UserResourceEntitlement {
return &walletv1.UserResourceEntitlement{
AppCode: appcode.Normalize(item.AppCode),
EntitlementId: item.EntitlementID,
UserId: item.UserID,
ResourceId: item.ResourceID,
Resource: resourceToProto(item.Resource),
Status: item.Status,
Quantity: item.Quantity,
RemainingQuantity: item.RemainingQuantity,
EffectiveAtMs: item.EffectiveAtMS,
ExpiresAtMs: item.ExpiresAtMS,
SourceGrantId: item.SourceGrantID,
CreatedAtMs: item.CreatedAtMS,
UpdatedAtMs: item.UpdatedAtMS,
}
}
func resourceGrantToProto(grant resourcedomain.ResourceGrant) *walletv1.ResourceGrant {
items := make([]*walletv1.ResourceGrantItem, 0, len(grant.Items))
for _, item := range grant.Items {
items = append(items, &walletv1.ResourceGrantItem{
GrantItemId: item.GrantItemID,
GrantId: item.GrantID,
ResourceId: item.ResourceID,
ResourceSnapshotJson: item.ResourceSnapshotJSON,
Quantity: item.Quantity,
DurationMs: item.DurationMS,
ResultType: item.ResultType,
WalletTransactionId: item.WalletTransactionID,
EntitlementId: item.EntitlementID,
CreatedAtMs: item.CreatedAtMS,
})
}
return &walletv1.ResourceGrant{
AppCode: appcode.Normalize(grant.AppCode),
GrantId: grant.GrantID,
CommandId: grant.CommandID,
TargetUserId: grant.TargetUserID,
GrantSource: grant.GrantSource,
GrantSubjectType: grant.GrantSubjectType,
GrantSubjectId: grant.GrantSubjectID,
Status: grant.Status,
Reason: grant.Reason,
OperatorUserId: grant.OperatorUserID,
Items: items,
CreatedAtMs: grant.CreatedAtMS,
UpdatedAtMs: grant.UpdatedAtMS,
}
}