88 lines
3.7 KiB
Go
88 lines
3.7 KiB
Go
package grpc
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
walletv1 "hyapp.local/api/proto/wallet/v1"
|
||
"hyapp/pkg/appcode"
|
||
"hyapp/pkg/xerr"
|
||
"hyapp/services/wallet-service/internal/domain/ledger"
|
||
walletservice "hyapp/services/wallet-service/internal/service/wallet"
|
||
)
|
||
|
||
// CronServer exposes wallet-service owned settlement batches to cron-service.
|
||
type CronServer struct {
|
||
walletv1.UnimplementedWalletCronServiceServer
|
||
|
||
svc *walletservice.Service
|
||
}
|
||
|
||
// NewCronServer 创建只给 cron-service 调用的批处理适配器;真实账务事务仍在 wallet repository 内完成。
|
||
func NewCronServer(svc *walletservice.Service) *CronServer {
|
||
return &CronServer{svc: svc}
|
||
}
|
||
|
||
func (s *CronServer) ProcessHostSalaryDailySettlementBatch(ctx context.Context, req *walletv1.CronBatchRequest) (*walletv1.CronBatchResponse, error) {
|
||
return s.processHostSalarySettlementBatch(ctx, req, ledger.HostSalarySettlementModeDaily)
|
||
}
|
||
|
||
func (s *CronServer) ProcessHostSalaryHalfMonthSettlementBatch(ctx context.Context, req *walletv1.CronBatchRequest) (*walletv1.CronBatchResponse, error) {
|
||
return s.processHostSalarySettlementBatch(ctx, req, ledger.HostSalarySettlementModeHalfMonth)
|
||
}
|
||
|
||
func (s *CronServer) ProcessHostSalaryMonthEndBatch(ctx context.Context, req *walletv1.CronBatchRequest) (*walletv1.CronBatchResponse, error) {
|
||
return s.processHostSalarySettlementBatch(ctx, req, ledger.HostSalarySettlementTypeMonthEnd)
|
||
}
|
||
|
||
// ProcessVipDailyCoinRebateBatch 只把 UTC task_day 和页大小交给 wallet owner;金额快照、
|
||
// 会员日切资格、游标和 available outbox 都在 wallet 的同一事务边界内完成。
|
||
func (s *CronServer) ProcessVipDailyCoinRebateBatch(ctx context.Context, req *walletv1.ProcessVipDailyCoinRebateBatchRequest) (*walletv1.ProcessVipDailyCoinRebateBatchResponse, error) {
|
||
if s.svc == nil {
|
||
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "wallet service is not configured"))
|
||
}
|
||
appCode := appcode.Normalize(req.GetAppCode())
|
||
ctx = appcode.WithContext(ctx, appCode)
|
||
result, err := s.svc.ProcessVipDailyCoinRebateBatch(ctx, ledger.ProcessVipDailyCoinRebateBatchCommand{
|
||
AppCode: appCode, TaskDay: req.GetTaskDay(), BatchSize: int(req.GetBatchSize()),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.ProcessVipDailyCoinRebateBatchResponse{
|
||
Run: vipDailyCoinRebateRunToProto(result.Run), ScannedCount: int32(result.ScannedCount),
|
||
CreatedCount: int32(result.CreatedCount), HasMore: result.HasMore,
|
||
ServerTimeMs: time.Now().UTC().UnixMilli(),
|
||
}, nil
|
||
}
|
||
|
||
func (s *CronServer) processHostSalarySettlementBatch(ctx context.Context, req *walletv1.CronBatchRequest, settlementType string) (*walletv1.CronBatchResponse, error) {
|
||
if s.svc == nil {
|
||
return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "wallet service is not configured"))
|
||
}
|
||
appCode := appcode.Normalize(req.GetAppCode())
|
||
ctx = appcode.WithContext(ctx, appCode)
|
||
// cron-service 只决定触发哪类批次;周期、当前时间、幂等交易和余额入账全部由 wallet-service 统一裁决。
|
||
result, err := s.svc.ProcessHostSalarySettlementBatch(ctx, ledger.HostSalarySettlementBatchCommand{
|
||
AppCode: appCode,
|
||
RunID: req.GetRunId(),
|
||
WorkerID: req.GetWorkerId(),
|
||
BatchSize: int(req.GetBatchSize()),
|
||
SettlementType: settlementType,
|
||
TriggerMode: req.GetTriggerMode(),
|
||
SettlementRole: req.GetSettlementRole(),
|
||
CycleKey: req.GetCycleKey(),
|
||
UserIDs: append([]int64(nil), req.GetUserIds()...),
|
||
})
|
||
if err != nil {
|
||
return nil, xerr.ToGRPCError(err)
|
||
}
|
||
return &walletv1.CronBatchResponse{
|
||
ClaimedCount: int32(result.ClaimedCount),
|
||
ProcessedCount: int32(result.ProcessedCount),
|
||
SuccessCount: int32(result.SuccessCount),
|
||
FailureCount: int32(result.FailureCount),
|
||
HasMore: result.HasMore,
|
||
}, nil
|
||
}
|