批量删除
This commit is contained in:
parent
6c3841248e
commit
15810e891d
File diff suppressed because it is too large
Load Diff
@ -672,6 +672,24 @@ message SetResourceStatusRequest {
|
||||
int64 operator_user_id = 5;
|
||||
}
|
||||
|
||||
message DeleteResourceRequest {
|
||||
string request_id = 1;
|
||||
string app_code = 2;
|
||||
int64 resource_id = 3;
|
||||
int64 operator_user_id = 4;
|
||||
}
|
||||
|
||||
message BatchDeleteResourcesRequest {
|
||||
string request_id = 1;
|
||||
string app_code = 2;
|
||||
repeated int64 resource_ids = 3;
|
||||
int64 operator_user_id = 4;
|
||||
}
|
||||
|
||||
message BatchDeleteResourcesResponse {
|
||||
repeated Resource resources = 1;
|
||||
}
|
||||
|
||||
message ResourceResponse {
|
||||
Resource resource = 1;
|
||||
}
|
||||
@ -807,6 +825,17 @@ message CreateGiftConfigRequest {
|
||||
string cp_relation_type = 21;
|
||||
}
|
||||
|
||||
message BatchCreateGiftConfigsRequest {
|
||||
string request_id = 1;
|
||||
string app_code = 2;
|
||||
repeated CreateGiftConfigRequest items = 3;
|
||||
int64 operator_user_id = 4;
|
||||
}
|
||||
|
||||
message BatchCreateGiftConfigsResponse {
|
||||
repeated GiftConfig gifts = 1;
|
||||
}
|
||||
|
||||
message UpdateGiftConfigRequest {
|
||||
string request_id = 1;
|
||||
string app_code = 2;
|
||||
@ -2262,6 +2291,8 @@ service WalletService {
|
||||
rpc CreateResource(CreateResourceRequest) returns (ResourceResponse);
|
||||
rpc UpdateResource(UpdateResourceRequest) returns (ResourceResponse);
|
||||
rpc SetResourceStatus(SetResourceStatusRequest) returns (ResourceResponse);
|
||||
rpc DeleteResource(DeleteResourceRequest) returns (ResourceResponse);
|
||||
rpc BatchDeleteResources(BatchDeleteResourcesRequest) returns (BatchDeleteResourcesResponse);
|
||||
rpc ListResourceGroups(ListResourceGroupsRequest) returns (ListResourceGroupsResponse);
|
||||
rpc GetResourceGroup(GetResourceGroupRequest) returns (GetResourceGroupResponse);
|
||||
rpc CreateResourceGroup(CreateResourceGroupRequest) returns (ResourceGroupResponse);
|
||||
@ -2271,6 +2302,7 @@ service WalletService {
|
||||
rpc ListGiftTypeConfigs(ListGiftTypeConfigsRequest) returns (ListGiftTypeConfigsResponse);
|
||||
rpc GetGiftCatalogVersion(GetGiftCatalogVersionRequest) returns (GetGiftCatalogVersionResponse);
|
||||
rpc CreateGiftConfig(CreateGiftConfigRequest) returns (GiftConfigResponse);
|
||||
rpc BatchCreateGiftConfigs(BatchCreateGiftConfigsRequest) returns (BatchCreateGiftConfigsResponse);
|
||||
rpc UpdateGiftConfig(UpdateGiftConfigRequest) returns (GiftConfigResponse);
|
||||
rpc SetGiftConfigStatus(SetGiftConfigStatusRequest) returns (GiftConfigResponse);
|
||||
rpc DeleteGiftConfig(DeleteGiftConfigRequest) returns (GiftConfigResponse);
|
||||
|
||||
@ -222,6 +222,8 @@ const (
|
||||
WalletService_CreateResource_FullMethodName = "/hyapp.wallet.v1.WalletService/CreateResource"
|
||||
WalletService_UpdateResource_FullMethodName = "/hyapp.wallet.v1.WalletService/UpdateResource"
|
||||
WalletService_SetResourceStatus_FullMethodName = "/hyapp.wallet.v1.WalletService/SetResourceStatus"
|
||||
WalletService_DeleteResource_FullMethodName = "/hyapp.wallet.v1.WalletService/DeleteResource"
|
||||
WalletService_BatchDeleteResources_FullMethodName = "/hyapp.wallet.v1.WalletService/BatchDeleteResources"
|
||||
WalletService_ListResourceGroups_FullMethodName = "/hyapp.wallet.v1.WalletService/ListResourceGroups"
|
||||
WalletService_GetResourceGroup_FullMethodName = "/hyapp.wallet.v1.WalletService/GetResourceGroup"
|
||||
WalletService_CreateResourceGroup_FullMethodName = "/hyapp.wallet.v1.WalletService/CreateResourceGroup"
|
||||
@ -231,6 +233,7 @@ const (
|
||||
WalletService_ListGiftTypeConfigs_FullMethodName = "/hyapp.wallet.v1.WalletService/ListGiftTypeConfigs"
|
||||
WalletService_GetGiftCatalogVersion_FullMethodName = "/hyapp.wallet.v1.WalletService/GetGiftCatalogVersion"
|
||||
WalletService_CreateGiftConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/CreateGiftConfig"
|
||||
WalletService_BatchCreateGiftConfigs_FullMethodName = "/hyapp.wallet.v1.WalletService/BatchCreateGiftConfigs"
|
||||
WalletService_UpdateGiftConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/UpdateGiftConfig"
|
||||
WalletService_SetGiftConfigStatus_FullMethodName = "/hyapp.wallet.v1.WalletService/SetGiftConfigStatus"
|
||||
WalletService_DeleteGiftConfig_FullMethodName = "/hyapp.wallet.v1.WalletService/DeleteGiftConfig"
|
||||
@ -328,6 +331,8 @@ type WalletServiceClient interface {
|
||||
CreateResource(ctx context.Context, in *CreateResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error)
|
||||
UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error)
|
||||
SetResourceStatus(ctx context.Context, in *SetResourceStatusRequest, opts ...grpc.CallOption) (*ResourceResponse, error)
|
||||
DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error)
|
||||
BatchDeleteResources(ctx context.Context, in *BatchDeleteResourcesRequest, opts ...grpc.CallOption) (*BatchDeleteResourcesResponse, error)
|
||||
ListResourceGroups(ctx context.Context, in *ListResourceGroupsRequest, opts ...grpc.CallOption) (*ListResourceGroupsResponse, error)
|
||||
GetResourceGroup(ctx context.Context, in *GetResourceGroupRequest, opts ...grpc.CallOption) (*GetResourceGroupResponse, error)
|
||||
CreateResourceGroup(ctx context.Context, in *CreateResourceGroupRequest, opts ...grpc.CallOption) (*ResourceGroupResponse, error)
|
||||
@ -337,6 +342,7 @@ type WalletServiceClient interface {
|
||||
ListGiftTypeConfigs(ctx context.Context, in *ListGiftTypeConfigsRequest, opts ...grpc.CallOption) (*ListGiftTypeConfigsResponse, error)
|
||||
GetGiftCatalogVersion(ctx context.Context, in *GetGiftCatalogVersionRequest, opts ...grpc.CallOption) (*GetGiftCatalogVersionResponse, error)
|
||||
CreateGiftConfig(ctx context.Context, in *CreateGiftConfigRequest, opts ...grpc.CallOption) (*GiftConfigResponse, error)
|
||||
BatchCreateGiftConfigs(ctx context.Context, in *BatchCreateGiftConfigsRequest, opts ...grpc.CallOption) (*BatchCreateGiftConfigsResponse, error)
|
||||
UpdateGiftConfig(ctx context.Context, in *UpdateGiftConfigRequest, opts ...grpc.CallOption) (*GiftConfigResponse, error)
|
||||
SetGiftConfigStatus(ctx context.Context, in *SetGiftConfigStatusRequest, opts ...grpc.CallOption) (*GiftConfigResponse, error)
|
||||
DeleteGiftConfig(ctx context.Context, in *DeleteGiftConfigRequest, opts ...grpc.CallOption) (*GiftConfigResponse, error)
|
||||
@ -625,6 +631,26 @@ func (c *walletServiceClient) SetResourceStatus(ctx context.Context, in *SetReso
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *walletServiceClient) DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*ResourceResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ResourceResponse)
|
||||
err := c.cc.Invoke(ctx, WalletService_DeleteResource_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *walletServiceClient) BatchDeleteResources(ctx context.Context, in *BatchDeleteResourcesRequest, opts ...grpc.CallOption) (*BatchDeleteResourcesResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(BatchDeleteResourcesResponse)
|
||||
err := c.cc.Invoke(ctx, WalletService_BatchDeleteResources_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *walletServiceClient) ListResourceGroups(ctx context.Context, in *ListResourceGroupsRequest, opts ...grpc.CallOption) (*ListResourceGroupsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListResourceGroupsResponse)
|
||||
@ -715,6 +741,16 @@ func (c *walletServiceClient) CreateGiftConfig(ctx context.Context, in *CreateGi
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *walletServiceClient) BatchCreateGiftConfigs(ctx context.Context, in *BatchCreateGiftConfigsRequest, opts ...grpc.CallOption) (*BatchCreateGiftConfigsResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(BatchCreateGiftConfigsResponse)
|
||||
err := c.cc.Invoke(ctx, WalletService_BatchCreateGiftConfigs_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *walletServiceClient) UpdateGiftConfig(ctx context.Context, in *UpdateGiftConfigRequest, opts ...grpc.CallOption) (*GiftConfigResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GiftConfigResponse)
|
||||
@ -1422,6 +1458,8 @@ type WalletServiceServer interface {
|
||||
CreateResource(context.Context, *CreateResourceRequest) (*ResourceResponse, error)
|
||||
UpdateResource(context.Context, *UpdateResourceRequest) (*ResourceResponse, error)
|
||||
SetResourceStatus(context.Context, *SetResourceStatusRequest) (*ResourceResponse, error)
|
||||
DeleteResource(context.Context, *DeleteResourceRequest) (*ResourceResponse, error)
|
||||
BatchDeleteResources(context.Context, *BatchDeleteResourcesRequest) (*BatchDeleteResourcesResponse, error)
|
||||
ListResourceGroups(context.Context, *ListResourceGroupsRequest) (*ListResourceGroupsResponse, error)
|
||||
GetResourceGroup(context.Context, *GetResourceGroupRequest) (*GetResourceGroupResponse, error)
|
||||
CreateResourceGroup(context.Context, *CreateResourceGroupRequest) (*ResourceGroupResponse, error)
|
||||
@ -1431,6 +1469,7 @@ type WalletServiceServer interface {
|
||||
ListGiftTypeConfigs(context.Context, *ListGiftTypeConfigsRequest) (*ListGiftTypeConfigsResponse, error)
|
||||
GetGiftCatalogVersion(context.Context, *GetGiftCatalogVersionRequest) (*GetGiftCatalogVersionResponse, error)
|
||||
CreateGiftConfig(context.Context, *CreateGiftConfigRequest) (*GiftConfigResponse, error)
|
||||
BatchCreateGiftConfigs(context.Context, *BatchCreateGiftConfigsRequest) (*BatchCreateGiftConfigsResponse, error)
|
||||
UpdateGiftConfig(context.Context, *UpdateGiftConfigRequest) (*GiftConfigResponse, error)
|
||||
SetGiftConfigStatus(context.Context, *SetGiftConfigStatusRequest) (*GiftConfigResponse, error)
|
||||
DeleteGiftConfig(context.Context, *DeleteGiftConfigRequest) (*GiftConfigResponse, error)
|
||||
@ -1572,6 +1611,12 @@ func (UnimplementedWalletServiceServer) UpdateResource(context.Context, *UpdateR
|
||||
func (UnimplementedWalletServiceServer) SetResourceStatus(context.Context, *SetResourceStatusRequest) (*ResourceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetResourceStatus not implemented")
|
||||
}
|
||||
func (UnimplementedWalletServiceServer) DeleteResource(context.Context, *DeleteResourceRequest) (*ResourceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DeleteResource not implemented")
|
||||
}
|
||||
func (UnimplementedWalletServiceServer) BatchDeleteResources(context.Context, *BatchDeleteResourcesRequest) (*BatchDeleteResourcesResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method BatchDeleteResources not implemented")
|
||||
}
|
||||
func (UnimplementedWalletServiceServer) ListResourceGroups(context.Context, *ListResourceGroupsRequest) (*ListResourceGroupsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListResourceGroups not implemented")
|
||||
}
|
||||
@ -1599,6 +1644,9 @@ func (UnimplementedWalletServiceServer) GetGiftCatalogVersion(context.Context, *
|
||||
func (UnimplementedWalletServiceServer) CreateGiftConfig(context.Context, *CreateGiftConfigRequest) (*GiftConfigResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateGiftConfig not implemented")
|
||||
}
|
||||
func (UnimplementedWalletServiceServer) BatchCreateGiftConfigs(context.Context, *BatchCreateGiftConfigsRequest) (*BatchCreateGiftConfigsResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method BatchCreateGiftConfigs not implemented")
|
||||
}
|
||||
func (UnimplementedWalletServiceServer) UpdateGiftConfig(context.Context, *UpdateGiftConfigRequest) (*GiftConfigResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method UpdateGiftConfig not implemented")
|
||||
}
|
||||
@ -2202,6 +2250,42 @@ func _WalletService_SetResourceStatus_Handler(srv interface{}, ctx context.Conte
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _WalletService_DeleteResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteResourceRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WalletServiceServer).DeleteResource(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: WalletService_DeleteResource_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WalletServiceServer).DeleteResource(ctx, req.(*DeleteResourceRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _WalletService_BatchDeleteResources_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(BatchDeleteResourcesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WalletServiceServer).BatchDeleteResources(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: WalletService_BatchDeleteResources_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WalletServiceServer).BatchDeleteResources(ctx, req.(*BatchDeleteResourcesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _WalletService_ListResourceGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListResourceGroupsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@ -2364,6 +2448,24 @@ func _WalletService_CreateGiftConfig_Handler(srv interface{}, ctx context.Contex
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _WalletService_BatchCreateGiftConfigs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(BatchCreateGiftConfigsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WalletServiceServer).BatchCreateGiftConfigs(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: WalletService_BatchCreateGiftConfigs_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WalletServiceServer).BatchCreateGiftConfigs(ctx, req.(*BatchCreateGiftConfigsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _WalletService_UpdateGiftConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(UpdateGiftConfigRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@ -3679,6 +3781,14 @@ var WalletService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "SetResourceStatus",
|
||||
Handler: _WalletService_SetResourceStatus_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "DeleteResource",
|
||||
Handler: _WalletService_DeleteResource_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "BatchDeleteResources",
|
||||
Handler: _WalletService_BatchDeleteResources_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListResourceGroups",
|
||||
Handler: _WalletService_ListResourceGroups_Handler,
|
||||
@ -3715,6 +3825,10 @@ var WalletService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "CreateGiftConfig",
|
||||
Handler: _WalletService_CreateGiftConfig_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "BatchCreateGiftConfigs",
|
||||
Handler: _WalletService_BatchCreateGiftConfigs_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "UpdateGiftConfig",
|
||||
Handler: _WalletService_UpdateGiftConfig_Handler,
|
||||
|
||||
@ -15,6 +15,8 @@ type Client interface {
|
||||
CreateResource(ctx context.Context, req *walletv1.CreateResourceRequest) (*walletv1.ResourceResponse, error)
|
||||
UpdateResource(ctx context.Context, req *walletv1.UpdateResourceRequest) (*walletv1.ResourceResponse, error)
|
||||
SetResourceStatus(ctx context.Context, req *walletv1.SetResourceStatusRequest) (*walletv1.ResourceResponse, error)
|
||||
DeleteResource(ctx context.Context, req *walletv1.DeleteResourceRequest) (*walletv1.ResourceResponse, error)
|
||||
BatchDeleteResources(ctx context.Context, req *walletv1.BatchDeleteResourcesRequest) (*walletv1.BatchDeleteResourcesResponse, error)
|
||||
ListResourceGroups(ctx context.Context, req *walletv1.ListResourceGroupsRequest) (*walletv1.ListResourceGroupsResponse, error)
|
||||
GetResourceGroup(ctx context.Context, req *walletv1.GetResourceGroupRequest) (*walletv1.GetResourceGroupResponse, error)
|
||||
CreateResourceGroup(ctx context.Context, req *walletv1.CreateResourceGroupRequest) (*walletv1.ResourceGroupResponse, error)
|
||||
@ -23,6 +25,7 @@ type Client interface {
|
||||
ListGiftConfigs(ctx context.Context, req *walletv1.ListGiftConfigsRequest) (*walletv1.ListGiftConfigsResponse, error)
|
||||
ListGiftTypeConfigs(ctx context.Context, req *walletv1.ListGiftTypeConfigsRequest) (*walletv1.ListGiftTypeConfigsResponse, error)
|
||||
CreateGiftConfig(ctx context.Context, req *walletv1.CreateGiftConfigRequest) (*walletv1.GiftConfigResponse, error)
|
||||
BatchCreateGiftConfigs(ctx context.Context, req *walletv1.BatchCreateGiftConfigsRequest) (*walletv1.BatchCreateGiftConfigsResponse, error)
|
||||
UpdateGiftConfig(ctx context.Context, req *walletv1.UpdateGiftConfigRequest) (*walletv1.GiftConfigResponse, error)
|
||||
SetGiftConfigStatus(ctx context.Context, req *walletv1.SetGiftConfigStatusRequest) (*walletv1.GiftConfigResponse, error)
|
||||
DeleteGiftConfig(ctx context.Context, req *walletv1.DeleteGiftConfigRequest) (*walletv1.GiftConfigResponse, error)
|
||||
@ -93,6 +96,14 @@ func (c *GRPCClient) SetResourceStatus(ctx context.Context, req *walletv1.SetRes
|
||||
return c.client.SetResourceStatus(ctx, req)
|
||||
}
|
||||
|
||||
func (c *GRPCClient) DeleteResource(ctx context.Context, req *walletv1.DeleteResourceRequest) (*walletv1.ResourceResponse, error) {
|
||||
return c.client.DeleteResource(ctx, req)
|
||||
}
|
||||
|
||||
func (c *GRPCClient) BatchDeleteResources(ctx context.Context, req *walletv1.BatchDeleteResourcesRequest) (*walletv1.BatchDeleteResourcesResponse, error) {
|
||||
return c.client.BatchDeleteResources(ctx, req)
|
||||
}
|
||||
|
||||
func (c *GRPCClient) ListResourceGroups(ctx context.Context, req *walletv1.ListResourceGroupsRequest) (*walletv1.ListResourceGroupsResponse, error) {
|
||||
return c.client.ListResourceGroups(ctx, req)
|
||||
}
|
||||
@ -125,6 +136,10 @@ func (c *GRPCClient) CreateGiftConfig(ctx context.Context, req *walletv1.CreateG
|
||||
return c.client.CreateGiftConfig(ctx, req)
|
||||
}
|
||||
|
||||
func (c *GRPCClient) BatchCreateGiftConfigs(ctx context.Context, req *walletv1.BatchCreateGiftConfigsRequest) (*walletv1.BatchCreateGiftConfigsResponse, error) {
|
||||
return c.client.BatchCreateGiftConfigs(ctx, req)
|
||||
}
|
||||
|
||||
func (c *GRPCClient) UpdateGiftConfig(ctx context.Context, req *walletv1.UpdateGiftConfigRequest) (*walletv1.GiftConfigResponse, error) {
|
||||
return c.client.UpdateGiftConfig(ctx, req)
|
||||
}
|
||||
|
||||
@ -231,6 +231,53 @@ func (h *Handler) UpdateResource(c *gin.Context) {
|
||||
response.OK(c, resource)
|
||||
}
|
||||
|
||||
func (h *Handler) DeleteResource(c *gin.Context) {
|
||||
resourceID, ok := parseID(c, "resource_id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
resp, err := h.wallet.DeleteResource(c.Request.Context(), &walletv1.DeleteResourceRequest{
|
||||
RequestId: middleware.CurrentRequestID(c),
|
||||
AppCode: appctx.FromContext(c.Request.Context()),
|
||||
ResourceId: resourceID,
|
||||
OperatorUserId: actorID(c),
|
||||
})
|
||||
if err != nil {
|
||||
response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
resource := resourceFromProto(resp.GetResource())
|
||||
h.auditLog(c, "delete-resource", "resources", fmt.Sprintf("%d", resource.ResourceID), "success", resource.ResourceCode)
|
||||
response.OK(c, resource)
|
||||
}
|
||||
|
||||
func (h *Handler) BatchDeleteResources(c *gin.Context) {
|
||||
var req resourceDeleteBatchRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil || len(req.ResourceIDs) == 0 {
|
||||
response.BadRequest(c, "资源参数不正确")
|
||||
return
|
||||
}
|
||||
resp, err := h.wallet.BatchDeleteResources(c.Request.Context(), &walletv1.BatchDeleteResourcesRequest{
|
||||
RequestId: middleware.CurrentRequestID(c),
|
||||
AppCode: appctx.FromContext(c.Request.Context()),
|
||||
ResourceIds: req.ResourceIDs,
|
||||
OperatorUserId: actorID(c),
|
||||
})
|
||||
if err != nil {
|
||||
response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
items := make([]resourceDTO, 0, len(resp.GetResources()))
|
||||
deletedIDs := make([]string, 0, len(resp.GetResources()))
|
||||
for _, item := range resp.GetResources() {
|
||||
resource := resourceFromProto(item)
|
||||
items = append(items, resource)
|
||||
deletedIDs = append(deletedIDs, fmt.Sprintf("%d", resource.ResourceID))
|
||||
}
|
||||
h.auditLog(c, "delete-resources", "resources", "batch", "success", strings.Join(deletedIDs, ","))
|
||||
response.OK(c, items)
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateMP4ResourceLayouts(c *gin.Context) {
|
||||
var req resourceMP4LayoutBatchRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@ -500,6 +547,37 @@ func (h *Handler) CreateGift(c *gin.Context) {
|
||||
response.Created(c, gift)
|
||||
}
|
||||
|
||||
func (h *Handler) BatchCreateGifts(c *gin.Context) {
|
||||
var req giftBatchRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil || len(req.Items) == 0 {
|
||||
response.BadRequest(c, "礼物参数不正确")
|
||||
return
|
||||
}
|
||||
items := make([]*walletv1.CreateGiftConfigRequest, 0, len(req.Items))
|
||||
for _, item := range req.Items {
|
||||
items = append(items, item.createProto(c))
|
||||
}
|
||||
resp, err := h.wallet.BatchCreateGiftConfigs(c.Request.Context(), &walletv1.BatchCreateGiftConfigsRequest{
|
||||
RequestId: middleware.CurrentRequestID(c),
|
||||
AppCode: appctx.FromContext(c.Request.Context()),
|
||||
Items: items,
|
||||
OperatorUserId: actorID(c),
|
||||
})
|
||||
if err != nil {
|
||||
response.BadRequest(c, err.Error())
|
||||
return
|
||||
}
|
||||
gifts := make([]giftDTO, 0, len(resp.GetGifts()))
|
||||
giftIDs := make([]string, 0, len(resp.GetGifts()))
|
||||
for _, item := range resp.GetGifts() {
|
||||
gift := giftFromProto(item)
|
||||
gifts = append(gifts, gift)
|
||||
giftIDs = append(giftIDs, gift.GiftID)
|
||||
}
|
||||
h.auditLog(c, "create-gifts", "gift_configs", "batch", "success", strings.Join(giftIDs, ","))
|
||||
response.Created(c, gifts)
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateGift(c *gin.Context) {
|
||||
giftID := strings.TrimSpace(c.Param("gift_id"))
|
||||
if giftID == "" {
|
||||
|
||||
@ -136,6 +136,74 @@ func TestDeleteGiftOnlyCallsGiftConfigDelete(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteResourceCallsWalletDeleteResource(t *testing.T) {
|
||||
wallet := &mockResourceWallet{resources: map[int64]*walletv1.Resource{
|
||||
11: {AppCode: "lalu", ResourceId: 11, ResourceCode: "rose_resource", ResourceType: "gift", Name: "Rose"},
|
||||
}}
|
||||
router := newResourceHandlerTestRouter(New(wallet, nil, nil, time.Second, nil))
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodDelete, "/admin/resources/11", nil)
|
||||
router.ServeHTTP(recorder, request)
|
||||
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("delete resource status mismatch: %d %s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if len(wallet.deletedResources) != 1 {
|
||||
t.Fatalf("expected one resource delete request, got %d", len(wallet.deletedResources))
|
||||
}
|
||||
deleteReq := wallet.deletedResources[0]
|
||||
if deleteReq.GetAppCode() != "lalu" || deleteReq.GetResourceId() != 11 || deleteReq.GetOperatorUserId() != 7 {
|
||||
t.Fatalf("delete resource request mismatch: %+v", deleteReq)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchDeleteResourcesCallsWalletBatchDelete(t *testing.T) {
|
||||
wallet := &mockResourceWallet{resources: map[int64]*walletv1.Resource{
|
||||
11: {AppCode: "lalu", ResourceId: 11, ResourceCode: "rose_resource", ResourceType: "gift", Name: "Rose"},
|
||||
12: {AppCode: "lalu", ResourceId: 12, ResourceCode: "ring_resource", ResourceType: "gift", Name: "Ring"},
|
||||
}}
|
||||
router := newResourceHandlerTestRouter(New(wallet, nil, nil, time.Second, nil))
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodPost, "/admin/resources/batch-delete", strings.NewReader(`{"resourceIds":[11,12]}`))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
router.ServeHTTP(recorder, request)
|
||||
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("batch delete resources status mismatch: %d %s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if len(wallet.batchDeletedResources) != 1 {
|
||||
t.Fatalf("expected one batch resource delete request, got %d", len(wallet.batchDeletedResources))
|
||||
}
|
||||
deleteReq := wallet.batchDeletedResources[0]
|
||||
if deleteReq.GetAppCode() != "lalu" || fmt.Sprint(deleteReq.GetResourceIds()) != "[11 12]" || deleteReq.GetOperatorUserId() != 7 {
|
||||
t.Fatalf("batch delete resource request mismatch: %+v", deleteReq)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchCreateGiftsCallsWalletBatchCreate(t *testing.T) {
|
||||
wallet := &mockResourceWallet{}
|
||||
router := newResourceHandlerTestRouter(New(wallet, nil, nil, time.Second, nil))
|
||||
|
||||
body := `{"items":[{"giftId":"rose","resourceId":11,"status":"active","name":"Rose","priceVersion":"default","giftTypeCode":"normal","chargeAssetType":"COIN","coinPrice":10,"regionIds":[0]},{"giftId":"ring","resourceId":12,"status":"active","name":"Ring","priceVersion":"default","giftTypeCode":"normal","chargeAssetType":"COIN","coinPrice":20,"regionIds":[0]}]}`
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodPost, "/admin/gifts/batch", strings.NewReader(body))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
router.ServeHTTP(recorder, request)
|
||||
|
||||
if recorder.Code != http.StatusCreated {
|
||||
t.Fatalf("batch create gifts status mismatch: %d %s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if len(wallet.batchCreatedGifts) != 1 {
|
||||
t.Fatalf("expected one batch gift create request, got %d", len(wallet.batchCreatedGifts))
|
||||
}
|
||||
createReq := wallet.batchCreatedGifts[0]
|
||||
if createReq.GetAppCode() != "lalu" || len(createReq.GetItems()) != 2 || createReq.GetItems()[0].GetGiftId() != "rose" || createReq.GetItems()[1].GetGiftId() != "ring" {
|
||||
t.Fatalf("batch create gift request mismatch: %+v", createReq)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdentityAutoGrantConfigRouteDoesNotHitResourceGroupID(t *testing.T) {
|
||||
router := newResourceHandlerTestRouter(New(&mockResourceWallet{}, nil, nil, time.Second, nil))
|
||||
|
||||
@ -215,6 +283,7 @@ func newResourceHandlerTestRouter(handler *Handler) *gin.Engine {
|
||||
"gift:create",
|
||||
"gift:status",
|
||||
"resource:create",
|
||||
"resource:delete",
|
||||
"resource-grant:create",
|
||||
"resource-grant:revoke",
|
||||
"resource-grant:view",
|
||||
@ -234,10 +303,13 @@ func newResourceHandlerTestRouter(handler *Handler) *gin.Engine {
|
||||
|
||||
type mockResourceWallet struct {
|
||||
walletclient.Client
|
||||
resources map[int64]*walletv1.Resource
|
||||
updates []*walletv1.UpdateResourceRequest
|
||||
deletedGifts []*walletv1.DeleteGiftConfigRequest
|
||||
listGrantRequests []*walletv1.ListResourceGrantsRequest
|
||||
resources map[int64]*walletv1.Resource
|
||||
updates []*walletv1.UpdateResourceRequest
|
||||
deletedResources []*walletv1.DeleteResourceRequest
|
||||
batchDeletedResources []*walletv1.BatchDeleteResourcesRequest
|
||||
batchCreatedGifts []*walletv1.BatchCreateGiftConfigsRequest
|
||||
deletedGifts []*walletv1.DeleteGiftConfigRequest
|
||||
listGrantRequests []*walletv1.ListResourceGrantsRequest
|
||||
}
|
||||
|
||||
func (m *mockResourceWallet) GetResource(ctx context.Context, req *walletv1.GetResourceRequest) (*walletv1.GetResourceResponse, error) {
|
||||
@ -273,6 +345,43 @@ func (m *mockResourceWallet) UpdateResource(ctx context.Context, req *walletv1.U
|
||||
}}, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceWallet) DeleteResource(ctx context.Context, req *walletv1.DeleteResourceRequest) (*walletv1.ResourceResponse, error) {
|
||||
m.deletedResources = append(m.deletedResources, req)
|
||||
resource := m.resources[req.GetResourceId()]
|
||||
if resource == nil {
|
||||
return nil, fmt.Errorf("resource not found")
|
||||
}
|
||||
return &walletv1.ResourceResponse{Resource: resource}, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceWallet) BatchDeleteResources(ctx context.Context, req *walletv1.BatchDeleteResourcesRequest) (*walletv1.BatchDeleteResourcesResponse, error) {
|
||||
m.batchDeletedResources = append(m.batchDeletedResources, req)
|
||||
resp := &walletv1.BatchDeleteResourcesResponse{Resources: make([]*walletv1.Resource, 0, len(req.GetResourceIds()))}
|
||||
for _, resourceID := range req.GetResourceIds() {
|
||||
resource := m.resources[resourceID]
|
||||
if resource == nil {
|
||||
return nil, fmt.Errorf("resource not found")
|
||||
}
|
||||
resp.Resources = append(resp.Resources, resource)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceWallet) BatchCreateGiftConfigs(ctx context.Context, req *walletv1.BatchCreateGiftConfigsRequest) (*walletv1.BatchCreateGiftConfigsResponse, error) {
|
||||
m.batchCreatedGifts = append(m.batchCreatedGifts, req)
|
||||
resp := &walletv1.BatchCreateGiftConfigsResponse{Gifts: make([]*walletv1.GiftConfig, 0, len(req.GetItems()))}
|
||||
for _, item := range req.GetItems() {
|
||||
resp.Gifts = append(resp.Gifts, &walletv1.GiftConfig{
|
||||
AppCode: item.GetAppCode(),
|
||||
GiftId: item.GetGiftId(),
|
||||
ResourceId: item.GetResourceId(),
|
||||
Status: item.GetStatus(),
|
||||
Name: item.GetName(),
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceWallet) DeleteGiftConfig(ctx context.Context, req *walletv1.DeleteGiftConfigRequest) (*walletv1.GiftConfigResponse, error) {
|
||||
m.deletedGifts = append(m.deletedGifts, req)
|
||||
return &walletv1.GiftConfigResponse{Gift: &walletv1.GiftConfig{
|
||||
|
||||
@ -89,6 +89,10 @@ type resourceMP4LayoutBatchRequest struct {
|
||||
Items []resourceMP4LayoutUpdateRequest `json:"items"`
|
||||
}
|
||||
|
||||
type resourceDeleteBatchRequest struct {
|
||||
ResourceIDs []int64 `json:"resourceIds"`
|
||||
}
|
||||
|
||||
type resourceMP4LayoutUpdateRequest struct {
|
||||
ResourceID int64 `json:"resourceId"`
|
||||
MetadataJSON string `json:"metadataJson"`
|
||||
@ -191,6 +195,10 @@ type giftRequest struct {
|
||||
RegionIDs []int64 `json:"regionIds"`
|
||||
}
|
||||
|
||||
type giftBatchRequest struct {
|
||||
Items []giftRequest `json:"items"`
|
||||
}
|
||||
|
||||
type giftTypeRequest struct {
|
||||
DisplayName string `json:"displayName"`
|
||||
TabName string `json:"tabName"`
|
||||
|
||||
@ -14,8 +14,10 @@ func RegisterRoutes(protected *gin.RouterGroup, h *Handler) {
|
||||
protected.GET("/admin/resources", middleware.RequirePermission("resource:view"), h.ListResources)
|
||||
protected.POST("/admin/resources", middleware.RequirePermission("resource:create"), h.CreateResource)
|
||||
protected.PUT("/admin/resources/mp4-layouts/batch", middleware.RequirePermission("resource:update"), h.UpdateMP4ResourceLayouts)
|
||||
protected.POST("/admin/resources/batch-delete", middleware.RequirePermission("resource:delete"), h.BatchDeleteResources)
|
||||
protected.GET("/admin/resources/:resource_id", middleware.RequirePermission("resource:view"), h.GetResource)
|
||||
protected.PUT("/admin/resources/:resource_id", middleware.RequirePermission("resource:update"), h.UpdateResource)
|
||||
protected.DELETE("/admin/resources/:resource_id", middleware.RequirePermission("resource:delete"), h.DeleteResource)
|
||||
protected.POST("/admin/resources/:resource_id/enable", middleware.RequirePermission("resource:update"), h.EnableResource)
|
||||
protected.POST("/admin/resources/:resource_id/disable", middleware.RequirePermission("resource:update"), h.DisableResource)
|
||||
|
||||
@ -38,6 +40,7 @@ func RegisterRoutes(protected *gin.RouterGroup, h *Handler) {
|
||||
protected.PUT("/admin/gift-types", middleware.RequirePermission("gift:update"), h.UpdateGiftTypes)
|
||||
protected.PUT("/admin/gift-types/:type_code", middleware.RequirePermission("gift:update"), h.UpdateGiftType)
|
||||
protected.POST("/admin/gifts", middleware.RequirePermission("gift:create"), h.CreateGift)
|
||||
protected.POST("/admin/gifts/batch", middleware.RequirePermission("gift:create"), h.BatchCreateGifts)
|
||||
protected.PUT("/admin/gifts/:gift_id", middleware.RequirePermission("gift:update"), h.UpdateGift)
|
||||
protected.DELETE("/admin/gifts/:gift_id", middleware.RequirePermission("gift:delete"), h.DeleteGift)
|
||||
protected.POST("/admin/gifts/:gift_id/enable", middleware.RequirePermission("gift:status"), h.EnableGift)
|
||||
|
||||
@ -15,6 +15,7 @@ const (
|
||||
|
||||
StatusActive = "active"
|
||||
StatusDisabled = "disabled"
|
||||
StatusDeleted = "deleted"
|
||||
|
||||
GrantStrategyWalletCredit = "wallet_credit"
|
||||
GrantStrategyNewEntitlement = "new_entitlement"
|
||||
|
||||
@ -77,6 +77,12 @@ type StatusCommand struct {
|
||||
OperatorUserID int64
|
||||
}
|
||||
|
||||
type BatchDeleteResourcesCommand struct {
|
||||
AppCode string
|
||||
ResourceIDs []int64
|
||||
OperatorUserID int64
|
||||
}
|
||||
|
||||
func NormalizeStatus(value string) string {
|
||||
value = strings.ToLower(strings.TrimSpace(value))
|
||||
if value == "" {
|
||||
|
||||
@ -158,6 +158,8 @@ type ResourceCatalogStore interface {
|
||||
CreateResource(ctx context.Context, command resourcedomain.ResourceCommand) (resourcedomain.Resource, error)
|
||||
UpdateResource(ctx context.Context, command resourcedomain.ResourceCommand) (resourcedomain.Resource, error)
|
||||
SetResourceStatus(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.Resource, error)
|
||||
DeleteResource(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.Resource, error)
|
||||
BatchDeleteResources(ctx context.Context, command resourcedomain.BatchDeleteResourcesCommand) ([]resourcedomain.Resource, error)
|
||||
ListResourceGroups(ctx context.Context, query resourcedomain.ListResourceGroupsQuery) ([]resourcedomain.ResourceGroup, int64, error)
|
||||
GetResourceGroup(ctx context.Context, groupID int64) (resourcedomain.ResourceGroup, error)
|
||||
CreateResourceGroup(ctx context.Context, command resourcedomain.ResourceGroupCommand) (resourcedomain.ResourceGroup, error)
|
||||
@ -167,6 +169,7 @@ type ResourceCatalogStore interface {
|
||||
ListGiftTypeConfigs(ctx context.Context, query resourcedomain.ListGiftTypeConfigsQuery) ([]resourcedomain.GiftTypeConfig, error)
|
||||
GetGiftCatalogVersion(ctx context.Context, appCode string) (int64, error)
|
||||
CreateGiftConfig(ctx context.Context, command resourcedomain.GiftConfigCommand) (resourcedomain.GiftConfig, error)
|
||||
BatchCreateGiftConfigs(ctx context.Context, commands []resourcedomain.GiftConfigCommand) ([]resourcedomain.GiftConfig, error)
|
||||
UpdateGiftConfig(ctx context.Context, command resourcedomain.GiftConfigCommand) (resourcedomain.GiftConfig, error)
|
||||
SetGiftConfigStatus(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.GiftConfig, error)
|
||||
DeleteGiftConfig(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.GiftConfig, error)
|
||||
|
||||
@ -59,6 +59,24 @@ func (s *Service) SetResourceStatus(ctx context.Context, command resourcedomain.
|
||||
return s.repository.SetResourceStatus(ctx, command)
|
||||
}
|
||||
|
||||
func (s *Service) DeleteResource(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.Resource, error) {
|
||||
if s.repository == nil {
|
||||
return resourcedomain.Resource{}, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||||
}
|
||||
command.AppCode = appcode.Normalize(command.AppCode)
|
||||
ctx = appcode.WithContext(ctx, command.AppCode)
|
||||
return s.repository.DeleteResource(ctx, command)
|
||||
}
|
||||
|
||||
func (s *Service) BatchDeleteResources(ctx context.Context, command resourcedomain.BatchDeleteResourcesCommand) ([]resourcedomain.Resource, error) {
|
||||
if s.repository == nil {
|
||||
return nil, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||||
}
|
||||
command.AppCode = appcode.Normalize(command.AppCode)
|
||||
ctx = appcode.WithContext(ctx, command.AppCode)
|
||||
return s.repository.BatchDeleteResources(ctx, command)
|
||||
}
|
||||
|
||||
func (s *Service) ListResourceGroups(ctx context.Context, query resourcedomain.ListResourceGroupsQuery) ([]resourcedomain.ResourceGroup, int64, error) {
|
||||
if s.repository == nil {
|
||||
return nil, 0, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||||
@ -145,6 +163,26 @@ func (s *Service) CreateGiftConfig(ctx context.Context, command resourcedomain.G
|
||||
return s.repository.CreateGiftConfig(ctx, command)
|
||||
}
|
||||
|
||||
func (s *Service) BatchCreateGiftConfigs(ctx context.Context, appCode string, commands []resourcedomain.GiftConfigCommand, operatorUserID int64) ([]resourcedomain.GiftConfig, error) {
|
||||
if s.repository == nil {
|
||||
return nil, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||||
}
|
||||
appCode = appcode.Normalize(appCode)
|
||||
ctx = appcode.WithContext(ctx, appCode)
|
||||
if len(commands) == 0 {
|
||||
return nil, xerr.New(xerr.InvalidArgument, "gift configs are required")
|
||||
}
|
||||
batchCommands := make([]resourcedomain.GiftConfigCommand, 0, len(commands))
|
||||
for _, command := range commands {
|
||||
command.AppCode = appCode
|
||||
if command.OperatorUserID == 0 {
|
||||
command.OperatorUserID = operatorUserID
|
||||
}
|
||||
batchCommands = append(batchCommands, command)
|
||||
}
|
||||
return s.repository.BatchCreateGiftConfigs(ctx, batchCommands)
|
||||
}
|
||||
|
||||
func (s *Service) UpdateGiftConfig(ctx context.Context, command resourcedomain.GiftConfigCommand) (resourcedomain.GiftConfig, error) {
|
||||
if s.repository == nil {
|
||||
return resourcedomain.GiftConfig{}, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||||
|
||||
@ -3694,6 +3694,195 @@ func TestDeleteGiftConfigKeepsResourceData(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteResourceHidesFromDefaultList(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
ctx := context.Background()
|
||||
|
||||
resource, err := svc.CreateResource(ctx, resourcedomain.ResourceCommand{
|
||||
ResourceCode: "delete_resource_hidden",
|
||||
ResourceType: resourcedomain.TypeBadge,
|
||||
Name: "Delete Resource Hidden",
|
||||
Status: resourcedomain.StatusActive,
|
||||
Grantable: true,
|
||||
GrantStrategy: resourcedomain.GrantStrategyNewEntitlement,
|
||||
UsageScopes: []string{"badge"},
|
||||
OperatorUserID: 91001,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create resource failed: %v", err)
|
||||
}
|
||||
|
||||
deleted, err := svc.DeleteResource(ctx, resourcedomain.StatusCommand{
|
||||
ID: resource.ResourceID,
|
||||
OperatorUserID: 91002,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("delete resource failed: %v", err)
|
||||
}
|
||||
if deleted.ResourceID != resource.ResourceID || deleted.Status != resourcedomain.StatusDeleted {
|
||||
t.Fatalf("deleted resource snapshot mismatch: %+v", deleted)
|
||||
}
|
||||
if got := repository.CountRows("resources", "resource_id = ? AND status = ?", resource.ResourceID, resourcedomain.StatusDeleted); got != 1 {
|
||||
t.Fatalf("resource should be soft deleted, got %d", got)
|
||||
}
|
||||
if got := repository.CountRows("resources", "resource_code = ?", "delete_resource_hidden"); got != 0 {
|
||||
t.Fatalf("deleted resource should release resource_code uniqueness, got %d", got)
|
||||
}
|
||||
items, total, err := svc.ListResources(ctx, resourcedomain.ListResourcesQuery{
|
||||
Keyword: "delete_resource_hidden",
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("list resources failed: %v", err)
|
||||
}
|
||||
if total != 0 || len(items) != 0 {
|
||||
t.Fatalf("deleted resource should be hidden from default list: total=%d items=%+v", total, items)
|
||||
}
|
||||
items, total, err = svc.ListResources(ctx, resourcedomain.ListResourcesQuery{
|
||||
Keyword: "delete_resource_hidden",
|
||||
Status: resourcedomain.StatusDeleted,
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("list deleted status resources failed: %v", err)
|
||||
}
|
||||
if total != 0 || len(items) != 0 {
|
||||
t.Fatalf("deleted resource should not be exposed by status filter: total=%d items=%+v", total, items)
|
||||
}
|
||||
loaded, err := svc.GetResource(ctx, "", resource.ResourceID)
|
||||
if err != nil {
|
||||
t.Fatalf("deleted resource should remain readable for historical references: %v", err)
|
||||
}
|
||||
if loaded.Status != resourcedomain.StatusDeleted {
|
||||
t.Fatalf("loaded deleted resource status mismatch: %+v", loaded)
|
||||
}
|
||||
recreated, err := svc.CreateResource(ctx, resourcedomain.ResourceCommand{
|
||||
ResourceCode: "delete_resource_hidden",
|
||||
ResourceType: resourcedomain.TypeBadge,
|
||||
Name: "Recreated Resource",
|
||||
Status: resourcedomain.StatusActive,
|
||||
Grantable: true,
|
||||
GrantStrategy: resourcedomain.GrantStrategyNewEntitlement,
|
||||
UsageScopes: []string{"badge"},
|
||||
OperatorUserID: 91003,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("recreate resource with deleted code failed: %v", err)
|
||||
}
|
||||
if recreated.ResourceID == resource.ResourceID {
|
||||
t.Fatalf("recreated resource should be a new row: old=%d new=%d", resource.ResourceID, recreated.ResourceID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteGiftResourceHidesGiftConfigList(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
ctx := context.Background()
|
||||
|
||||
resource, err := svc.CreateResource(ctx, resourcedomain.ResourceCommand{
|
||||
ResourceCode: "delete_gift_resource_hidden",
|
||||
ResourceType: resourcedomain.TypeGift,
|
||||
Name: "Delete Gift Resource Hidden",
|
||||
Status: resourcedomain.StatusActive,
|
||||
Grantable: true,
|
||||
GrantStrategy: resourcedomain.GrantStrategyIncreaseQuantity,
|
||||
UsageScopes: []string{"gift"},
|
||||
OperatorUserID: 91101,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create gift resource failed: %v", err)
|
||||
}
|
||||
if _, err := svc.CreateGiftConfig(ctx, resourcedomain.GiftConfigCommand{
|
||||
GiftID: "delete-resource-hide-gift",
|
||||
ResourceID: resource.ResourceID,
|
||||
Status: resourcedomain.StatusActive,
|
||||
Name: "Delete Resource Hide Gift",
|
||||
PriceVersion: "default",
|
||||
CoinPrice: 10,
|
||||
HeatValue: 10,
|
||||
OperatorUserID: 91101,
|
||||
RegionIDs: []int64{0},
|
||||
}); err != nil {
|
||||
t.Fatalf("create gift config failed: %v", err)
|
||||
}
|
||||
if _, err := svc.DeleteResource(ctx, resourcedomain.StatusCommand{
|
||||
ID: resource.ResourceID,
|
||||
OperatorUserID: 91102,
|
||||
}); err != nil {
|
||||
t.Fatalf("delete gift resource failed: %v", err)
|
||||
}
|
||||
gifts, total, err := svc.ListGiftConfigs(ctx, resourcedomain.ListGiftConfigsQuery{
|
||||
Keyword: "delete-resource-hide-gift",
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("list gift configs failed: %v", err)
|
||||
}
|
||||
if total != 0 || len(gifts) != 0 {
|
||||
t.Fatalf("gift config should be hidden when resource is deleted: total=%d gifts=%+v", total, gifts)
|
||||
}
|
||||
if got := repository.CountRows("gift_configs", "gift_id = ?", "delete-resource-hide-gift"); got != 1 {
|
||||
t.Fatalf("soft-deleting resource should keep gift config row for history, got %d", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchCreateGiftConfigsRollsBackOnFailure(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
ctx := context.Background()
|
||||
|
||||
resource, err := svc.CreateResource(ctx, resourcedomain.ResourceCommand{
|
||||
ResourceCode: "batch_gift_valid_resource",
|
||||
ResourceType: resourcedomain.TypeGift,
|
||||
Name: "Batch Gift Valid Resource",
|
||||
Status: resourcedomain.StatusActive,
|
||||
Grantable: true,
|
||||
GrantStrategy: resourcedomain.GrantStrategyIncreaseQuantity,
|
||||
UsageScopes: []string{"gift"},
|
||||
OperatorUserID: 91201,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create gift resource failed: %v", err)
|
||||
}
|
||||
_, err = svc.BatchCreateGiftConfigs(ctx, "", []resourcedomain.GiftConfigCommand{
|
||||
{
|
||||
GiftID: "batch-create-rollback-ok",
|
||||
ResourceID: resource.ResourceID,
|
||||
Status: resourcedomain.StatusActive,
|
||||
Name: "Batch Create Rollback OK",
|
||||
PriceVersion: "default",
|
||||
CoinPrice: 10,
|
||||
HeatValue: 10,
|
||||
OperatorUserID: 91201,
|
||||
RegionIDs: []int64{0},
|
||||
},
|
||||
{
|
||||
GiftID: "batch-create-rollback-bad",
|
||||
ResourceID: 99999999,
|
||||
Status: resourcedomain.StatusActive,
|
||||
Name: "Batch Create Rollback Bad",
|
||||
PriceVersion: "default",
|
||||
CoinPrice: 10,
|
||||
HeatValue: 10,
|
||||
OperatorUserID: 91201,
|
||||
RegionIDs: []int64{0},
|
||||
},
|
||||
}, 91201)
|
||||
if err == nil {
|
||||
t.Fatalf("batch create should fail when any item is invalid")
|
||||
}
|
||||
if got := repository.CountRows("gift_configs", "gift_id IN (?, ?)", "batch-create-rollback-ok", "batch-create-rollback-bad"); got != 0 {
|
||||
t.Fatalf("batch create should roll back all gift rows, got %d", got)
|
||||
}
|
||||
if got := repository.CountRows("wallet_gift_prices", "gift_id IN (?, ?)", "batch-create-rollback-ok", "batch-create-rollback-bad"); got != 0 {
|
||||
t.Fatalf("batch create should roll back all gift prices, got %d", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGiftConfigSyncsConfiguredResourcePrice(t *testing.T) {
|
||||
repository := mysqltest.NewRepository(t)
|
||||
svc := walletservice.New(repository)
|
||||
|
||||
@ -305,7 +305,7 @@ func giftConfigSelectSQL() string {
|
||||
}
|
||||
|
||||
func giftConfigWhereSQL(query resourcedomain.ListGiftConfigsQuery) (string, []any) {
|
||||
where := `WHERE gc.app_code = ?`
|
||||
where := `WHERE gc.app_code = ? AND r.status <> 'deleted'`
|
||||
args := []any{query.AppCode}
|
||||
if query.ActiveOnly {
|
||||
where += ` AND gc.status = 'active' AND r.status = 'active' AND r.resource_type = 'gift'
|
||||
|
||||
@ -2,6 +2,7 @@ package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hyapp/pkg/appcode"
|
||||
@ -15,6 +16,41 @@ func (r *Repository) CreateGiftConfig(ctx context.Context, command resourcedomai
|
||||
return r.upsertGiftConfig(ctx, command, false)
|
||||
}
|
||||
|
||||
func (r *Repository) BatchCreateGiftConfigs(ctx context.Context, commands []resourcedomain.GiftConfigCommand) ([]resourcedomain.GiftConfig, error) {
|
||||
if r == nil || r.db == nil {
|
||||
return nil, xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||
}
|
||||
if len(commands) == 0 {
|
||||
return nil, xerr.New(xerr.InvalidArgument, "gift configs are required")
|
||||
}
|
||||
ctx = contextWithCommandApp(ctx, commands[0].AppCode)
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = tx.Rollback() }()
|
||||
|
||||
nowMs := time.Now().UnixMilli()
|
||||
gifts := make([]resourcedomain.GiftConfig, 0, len(commands))
|
||||
events := make([]walletOutboxEvent, 0, len(commands))
|
||||
for _, command := range commands {
|
||||
command.AppCode = appcode.FromContext(ctx)
|
||||
gift, err := r.createGiftConfigTx(ctx, tx, command, nowMs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gifts = append(gifts, gift)
|
||||
events = append(events, resourceOutboxEvent("GiftConfigChanged", fmt.Sprintf("gift:%s:config:%d", command.GiftID, nowMs), 0, command.ResourceID, command, nowMs))
|
||||
}
|
||||
if err := r.insertWalletOutbox(ctx, tx, events); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gifts, nil
|
||||
}
|
||||
|
||||
func (r *Repository) UpdateGiftConfig(ctx context.Context, command resourcedomain.GiftConfigCommand) (resourcedomain.GiftConfig, error) {
|
||||
return r.upsertGiftConfig(ctx, command, true)
|
||||
}
|
||||
@ -118,52 +154,22 @@ func (r *Repository) upsertGiftConfig(ctx context.Context, command resourcedomai
|
||||
}
|
||||
defer func() { _ = tx.Rollback() }()
|
||||
|
||||
resource, err := r.getResourceForUpdate(ctx, tx, command.ResourceID)
|
||||
if err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if resource.ResourceType != resourcedomain.TypeGift {
|
||||
return resourcedomain.GiftConfig{}, xerr.New(xerr.InvalidArgument, "gift config must select gift resource")
|
||||
}
|
||||
command = applyResourcePricingToGiftCommand(command, resource)
|
||||
if resourcedomain.NormalizePriceType(resource.PriceType) == "" && command.CoinPrice <= 0 {
|
||||
return resourcedomain.GiftConfig{}, xerr.New(xerr.InvalidArgument, "gift price is invalid")
|
||||
}
|
||||
if err := validateGiftConfigCommand(command); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if command.Status == resourcedomain.StatusActive && resource.Status != resourcedomain.StatusActive {
|
||||
return resourcedomain.GiftConfig{}, xerr.New(xerr.Conflict, "gift resource is disabled")
|
||||
}
|
||||
if err := r.ensureDefaultGiftTypeConfigs(ctx, tx); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if ok, err := r.giftTypeConfigExistsTx(ctx, tx, command.GiftTypeCode); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
} else if !ok {
|
||||
return resourcedomain.GiftConfig{}, xerr.New(xerr.InvalidArgument, "gift type is not configured")
|
||||
}
|
||||
nowMs := time.Now().UnixMilli()
|
||||
|
||||
presentation := giftPresentationWithCPRelationType(command.PresentationJSON, command.CPRelationType)
|
||||
effectTypesJSON, err := json.Marshal(command.EffectTypes)
|
||||
if err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
var gift resourcedomain.GiftConfig
|
||||
if !update {
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
INSERT INTO gift_configs (
|
||||
app_code, gift_id, resource_id, status, name, sort_order, presentation_json,
|
||||
gift_type_code, effective_from_ms, effective_to_ms, effect_types_json,
|
||||
created_by_user_id, updated_by_user_id, created_at_ms, updated_at_ms
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
command.AppCode, command.GiftID, command.ResourceID, command.Status, command.Name, command.SortOrder, presentation,
|
||||
command.GiftTypeCode, command.EffectiveFromMS, command.EffectiveToMS, string(effectTypesJSON),
|
||||
command.OperatorUserID, command.OperatorUserID, nowMs, nowMs,
|
||||
); err != nil {
|
||||
gift, err = r.createGiftConfigTx(ctx, tx, command, nowMs)
|
||||
if err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
} else {
|
||||
if err := r.prepareGiftConfigCommandTx(ctx, tx, &command); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
presentation := giftPresentationWithCPRelationType(command.PresentationJSON, command.CPRelationType)
|
||||
effectTypesJSON, err := json.Marshal(command.EffectTypes)
|
||||
if err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
result, err := tx.ExecContext(ctx, `
|
||||
UPDATE gift_configs
|
||||
SET resource_id = ?, status = ?, name = ?, sort_order = ?, presentation_json = ?,
|
||||
@ -182,12 +188,12 @@ func (r *Repository) upsertGiftConfig(ctx context.Context, command resourcedomai
|
||||
} else if affected == 0 {
|
||||
return resourcedomain.GiftConfig{}, xerr.New(xerr.NotFound, "gift config not found")
|
||||
}
|
||||
}
|
||||
if err := r.upsertGiftPriceTx(ctx, tx, command, nowMs); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if err := r.replaceGiftConfigRegionsTx(ctx, tx, command.GiftID, command.RegionIDs, nowMs); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
if err := r.upsertGiftPriceTx(ctx, tx, command, nowMs); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if err := r.replaceGiftConfigRegionsTx(ctx, tx, command.GiftID, command.RegionIDs, nowMs); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
}
|
||||
if err := r.insertWalletOutbox(ctx, tx, []walletOutboxEvent{
|
||||
resourceOutboxEvent("GiftConfigChanged", fmt.Sprintf("gift:%s:config:%d", command.GiftID, nowMs), 0, command.ResourceID, command, nowMs),
|
||||
@ -197,5 +203,67 @@ func (r *Repository) upsertGiftConfig(ctx context.Context, command resourcedomai
|
||||
if err := tx.Commit(); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
return r.getGiftConfig(ctx, command.GiftID)
|
||||
if update {
|
||||
return r.getGiftConfig(ctx, command.GiftID)
|
||||
}
|
||||
return gift, nil
|
||||
}
|
||||
|
||||
func (r *Repository) createGiftConfigTx(ctx context.Context, tx *sql.Tx, command resourcedomain.GiftConfigCommand, nowMs int64) (resourcedomain.GiftConfig, error) {
|
||||
if err := r.prepareGiftConfigCommandTx(ctx, tx, &command); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
presentation := giftPresentationWithCPRelationType(command.PresentationJSON, command.CPRelationType)
|
||||
effectTypesJSON, err := json.Marshal(command.EffectTypes)
|
||||
if err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if _, err := tx.ExecContext(ctx, `
|
||||
INSERT INTO gift_configs (
|
||||
app_code, gift_id, resource_id, status, name, sort_order, presentation_json,
|
||||
gift_type_code, effective_from_ms, effective_to_ms, effect_types_json,
|
||||
created_by_user_id, updated_by_user_id, created_at_ms, updated_at_ms
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
command.AppCode, command.GiftID, command.ResourceID, command.Status, command.Name, command.SortOrder, presentation,
|
||||
command.GiftTypeCode, command.EffectiveFromMS, command.EffectiveToMS, string(effectTypesJSON),
|
||||
command.OperatorUserID, command.OperatorUserID, nowMs, nowMs,
|
||||
); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if err := r.upsertGiftPriceTx(ctx, tx, command, nowMs); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
if err := r.replaceGiftConfigRegionsTx(ctx, tx, command.GiftID, command.RegionIDs, nowMs); err != nil {
|
||||
return resourcedomain.GiftConfig{}, err
|
||||
}
|
||||
return r.getGiftConfigForUpdateTx(ctx, tx, command.GiftID)
|
||||
}
|
||||
|
||||
func (r *Repository) prepareGiftConfigCommandTx(ctx context.Context, tx *sql.Tx, command *resourcedomain.GiftConfigCommand) error {
|
||||
resource, err := r.getResourceForUpdate(ctx, tx, command.ResourceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if resource.ResourceType != resourcedomain.TypeGift {
|
||||
return xerr.New(xerr.InvalidArgument, "gift config must select gift resource")
|
||||
}
|
||||
*command = applyResourcePricingToGiftCommand(*command, resource)
|
||||
if resourcedomain.NormalizePriceType(resource.PriceType) == "" && command.CoinPrice <= 0 {
|
||||
return xerr.New(xerr.InvalidArgument, "gift price is invalid")
|
||||
}
|
||||
if err := validateGiftConfigCommand(*command); err != nil {
|
||||
return err
|
||||
}
|
||||
if command.Status == resourcedomain.StatusActive && resource.Status != resourcedomain.StatusActive {
|
||||
return xerr.New(xerr.Conflict, "gift resource is disabled")
|
||||
}
|
||||
if err := r.ensureDefaultGiftTypeConfigs(ctx, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
if ok, err := r.giftTypeConfigExistsTx(ctx, tx, command.GiftTypeCode); err != nil {
|
||||
return err
|
||||
} else if !ok {
|
||||
return xerr.New(xerr.InvalidArgument, "gift type is not configured")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -342,6 +342,75 @@ func (r *Repository) SetResourceStatus(ctx context.Context, command resourcedoma
|
||||
return resource, nil
|
||||
}
|
||||
|
||||
func (r *Repository) DeleteResource(ctx context.Context, command resourcedomain.StatusCommand) (resourcedomain.Resource, error) {
|
||||
resources, err := r.BatchDeleteResources(ctx, resourcedomain.BatchDeleteResourcesCommand{
|
||||
AppCode: command.AppCode,
|
||||
ResourceIDs: []int64{command.ID},
|
||||
OperatorUserID: command.OperatorUserID,
|
||||
})
|
||||
if err != nil {
|
||||
return resourcedomain.Resource{}, err
|
||||
}
|
||||
if len(resources) == 0 {
|
||||
return resourcedomain.Resource{}, xerr.New(xerr.NotFound, "resource not found")
|
||||
}
|
||||
return resources[0], nil
|
||||
}
|
||||
|
||||
func (r *Repository) BatchDeleteResources(ctx context.Context, command resourcedomain.BatchDeleteResourcesCommand) ([]resourcedomain.Resource, error) {
|
||||
if r == nil || r.db == nil {
|
||||
return nil, xerr.New(xerr.Unavailable, "mysql repository is not configured")
|
||||
}
|
||||
ctx = contextWithCommandApp(ctx, command.AppCode)
|
||||
resourceIDs := normalizeResourceDeleteIDs(command.ResourceIDs)
|
||||
if len(resourceIDs) == 0 {
|
||||
return nil, xerr.New(xerr.InvalidArgument, "resource_ids are required")
|
||||
}
|
||||
|
||||
nowMs := time.Now().UnixMilli()
|
||||
tx, err := r.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = tx.Rollback() }()
|
||||
|
||||
deletedResources := make([]resourcedomain.Resource, 0, len(resourceIDs))
|
||||
events := make([]walletOutboxEvent, 0, len(resourceIDs))
|
||||
for _, resourceID := range resourceIDs {
|
||||
resource, err := r.getResourceForUpdate(ctx, tx, resourceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resource.Status == resourcedomain.StatusDeleted {
|
||||
return nil, xerr.New(xerr.NotFound, "resource not found")
|
||||
}
|
||||
result, err := tx.ExecContext(ctx,
|
||||
`UPDATE resources SET resource_code = ?, status = ?, updated_by_user_id = ?, updated_at_ms = ? WHERE app_code = ? AND resource_id = ? AND status <> ?`,
|
||||
deletedResourceCode(resource.ResourceCode, resourceID), resourcedomain.StatusDeleted, command.OperatorUserID, nowMs, appcode.FromContext(ctx), resourceID, resourcedomain.StatusDeleted,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if affected, err := result.RowsAffected(); err != nil {
|
||||
return nil, err
|
||||
} else if affected == 0 {
|
||||
return nil, xerr.New(xerr.NotFound, "resource not found")
|
||||
}
|
||||
resource.Status = resourcedomain.StatusDeleted
|
||||
resource.UpdatedByUserID = command.OperatorUserID
|
||||
resource.UpdatedAtMS = nowMs
|
||||
deletedResources = append(deletedResources, resource)
|
||||
events = append(events, resourceOutboxEvent("ResourceChanged", fmt.Sprintf("resource:%d:delete:%d", resourceID, nowMs), 0, resourceID, resource, nowMs))
|
||||
}
|
||||
if err := r.insertWalletOutbox(ctx, tx, events); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return deletedResources, nil
|
||||
}
|
||||
|
||||
func (r *Repository) getResourceForUpdate(ctx context.Context, tx *sql.Tx, resourceID int64) (resourcedomain.Resource, error) {
|
||||
row := tx.QueryRowContext(ctx, resourceSelectSQL()+` WHERE app_code = ? AND resource_id = ? FOR UPDATE`, appcode.FromContext(ctx), resourceID)
|
||||
resource, err := scanResource(row)
|
||||
@ -418,7 +487,7 @@ func nullableResourceColumnsWithAlias(alias string) string {
|
||||
}
|
||||
|
||||
func resourceWhereSQL(query resourcedomain.ListResourcesQuery) (string, []any) {
|
||||
where := `WHERE app_code = ?`
|
||||
where := `WHERE app_code = ? AND status <> 'deleted'`
|
||||
args := []any{query.AppCode}
|
||||
if query.ManagerGrantOnly {
|
||||
where += ` AND status = 'active' AND grantable = TRUE AND manager_grant_enabled = TRUE`
|
||||
@ -440,6 +509,35 @@ func resourceWhereSQL(query resourcedomain.ListResourcesQuery) (string, []any) {
|
||||
return where, args
|
||||
}
|
||||
|
||||
func normalizeResourceDeleteIDs(resourceIDs []int64) []int64 {
|
||||
seen := make(map[int64]struct{}, len(resourceIDs))
|
||||
normalized := make([]int64, 0, len(resourceIDs))
|
||||
for _, resourceID := range resourceIDs {
|
||||
if resourceID <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[resourceID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[resourceID] = struct{}{}
|
||||
normalized = append(normalized, resourceID)
|
||||
}
|
||||
return normalized
|
||||
}
|
||||
|
||||
func deletedResourceCode(resourceCode string, resourceID int64) string {
|
||||
const maxResourceCodeLength = 96
|
||||
suffix := fmt.Sprintf("__deleted_%d", resourceID)
|
||||
if len(resourceCode)+len(suffix) <= maxResourceCodeLength {
|
||||
return resourceCode + suffix
|
||||
}
|
||||
keepLength := maxResourceCodeLength - len(suffix)
|
||||
if keepLength <= 0 {
|
||||
return suffix[len(suffix)-maxResourceCodeLength:]
|
||||
}
|
||||
return resourceCode[:keepLength] + suffix
|
||||
}
|
||||
|
||||
func normalizeResourceListQuery(query resourcedomain.ListResourcesQuery) resourcedomain.ListResourcesQuery {
|
||||
query.ResourceType = resourcedomain.NormalizeResourceType(query.ResourceType)
|
||||
if query.ResourceType != "" && !resourcedomain.ValidResourceType(query.ResourceType) {
|
||||
|
||||
@ -65,6 +65,34 @@ func (s *Server) SetResourceStatus(ctx context.Context, req *walletv1.SetResourc
|
||||
return &walletv1.ResourceResponse{Resource: resourceToProto(resource)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeleteResource(ctx context.Context, req *walletv1.DeleteResourceRequest) (*walletv1.ResourceResponse, error) {
|
||||
resource, err := s.svc.DeleteResource(ctx, resourcedomain.StatusCommand{
|
||||
AppCode: req.GetAppCode(),
|
||||
ID: req.GetResourceId(),
|
||||
OperatorUserID: req.GetOperatorUserId(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerr.ToGRPCError(err)
|
||||
}
|
||||
return &walletv1.ResourceResponse{Resource: resourceToProto(resource)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) BatchDeleteResources(ctx context.Context, req *walletv1.BatchDeleteResourcesRequest) (*walletv1.BatchDeleteResourcesResponse, error) {
|
||||
resources, err := s.svc.BatchDeleteResources(ctx, resourcedomain.BatchDeleteResourcesCommand{
|
||||
AppCode: req.GetAppCode(),
|
||||
ResourceIDs: req.GetResourceIds(),
|
||||
OperatorUserID: req.GetOperatorUserId(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerr.ToGRPCError(err)
|
||||
}
|
||||
resp := &walletv1.BatchDeleteResourcesResponse{Resources: make([]*walletv1.Resource, 0, len(resources))}
|
||||
for _, resource := range resources {
|
||||
resp.Resources = append(resp.Resources, resourceToProto(resource))
|
||||
}
|
||||
return resp, 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(),
|
||||
@ -175,6 +203,27 @@ func (s *Server) CreateGiftConfig(ctx context.Context, req *walletv1.CreateGiftC
|
||||
return &walletv1.GiftConfigResponse{Gift: giftConfigToProto(gift)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) BatchCreateGiftConfigs(ctx context.Context, req *walletv1.BatchCreateGiftConfigsRequest) (*walletv1.BatchCreateGiftConfigsResponse, error) {
|
||||
commands := make([]resourcedomain.GiftConfigCommand, 0, len(req.GetItems()))
|
||||
for _, item := range req.GetItems() {
|
||||
command := giftConfigCommandFromCreate(item)
|
||||
command.AppCode = req.GetAppCode()
|
||||
if command.OperatorUserID == 0 {
|
||||
command.OperatorUserID = req.GetOperatorUserId()
|
||||
}
|
||||
commands = append(commands, command)
|
||||
}
|
||||
gifts, err := s.svc.BatchCreateGiftConfigs(ctx, req.GetAppCode(), commands, req.GetOperatorUserId())
|
||||
if err != nil {
|
||||
return nil, xerr.ToGRPCError(err)
|
||||
}
|
||||
resp := &walletv1.BatchCreateGiftConfigsResponse{Gifts: make([]*walletv1.GiftConfig, 0, len(gifts))}
|
||||
for _, gift := range gifts {
|
||||
resp.Gifts = append(resp.Gifts, giftConfigToProto(gift))
|
||||
}
|
||||
return resp, 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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user