81 lines
2.9 KiB
Go
81 lines
2.9 KiB
Go
package integration
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
walletv1 "hyapp.local/api/proto/wallet/v1"
|
||
"hyapp/services/cron-service/internal/scheduler"
|
||
)
|
||
|
||
// WalletCronClient delegates wallet-owned salary settlement batches to wallet-service.
|
||
type WalletCronClient struct {
|
||
client walletv1.WalletCronServiceClient
|
||
}
|
||
|
||
var walletCronNowUTC = func() time.Time {
|
||
return time.Now().UTC()
|
||
}
|
||
|
||
// NewWalletCronClient creates scheduler handlers backed by wallet-service gRPC.
|
||
func NewWalletCronClient(client walletv1.WalletCronServiceClient) *WalletCronClient {
|
||
return &WalletCronClient{client: client}
|
||
}
|
||
|
||
func (c *WalletCronClient) ProcessHostSalaryDailySettlementBatch(ctx context.Context, req scheduler.BatchRequest) (scheduler.BatchResult, error) {
|
||
resp, err := c.client.ProcessHostSalaryDailySettlementBatch(ctx, walletCronBatchRequest(req))
|
||
return walletCronBatchResult(resp), err
|
||
}
|
||
|
||
func (c *WalletCronClient) ProcessHostSalaryHalfMonthSettlementBatch(ctx context.Context, req scheduler.BatchRequest) (scheduler.BatchResult, error) {
|
||
if !isHostSalaryHalfMonthDue(walletCronNowUTC()) {
|
||
// 半月结是否适用于某个主播由后台工资政策 settlement_mode 决定;cron 这里只负责在月中打开一次全局触发窗口。
|
||
return scheduler.BatchResult{}, nil
|
||
}
|
||
resp, err := c.client.ProcessHostSalaryHalfMonthSettlementBatch(ctx, walletCronBatchRequest(req))
|
||
return walletCronBatchResult(resp), err
|
||
}
|
||
|
||
func (c *WalletCronClient) ProcessHostSalaryMonthEndBatch(ctx context.Context, req scheduler.BatchRequest) (scheduler.BatchResult, error) {
|
||
if !isHostSalaryMonthEndDue(walletCronNowUTC()) {
|
||
// 月末批次负责最终等级差额、剩余钻石折美元和周期关闭;非月末触发只记录一次空跑,不进入 wallet 账务。
|
||
return scheduler.BatchResult{}, nil
|
||
}
|
||
resp, err := c.client.ProcessHostSalaryMonthEndBatch(ctx, walletCronBatchRequest(req))
|
||
return walletCronBatchResult(resp), err
|
||
}
|
||
|
||
func isHostSalaryHalfMonthDue(now time.Time) bool {
|
||
return now.UTC().Day() == 15
|
||
}
|
||
|
||
func isHostSalaryMonthEndDue(now time.Time) bool {
|
||
utc := now.UTC()
|
||
return utc.AddDate(0, 0, 1).Day() == 1
|
||
}
|
||
|
||
func walletCronBatchRequest(req scheduler.BatchRequest) *walletv1.CronBatchRequest {
|
||
// scheduler 的 RunID 同时作为请求幂等标识传给 wallet;wallet 内部会继续按主播和周期生成账务幂等键。
|
||
return &walletv1.CronBatchRequest{
|
||
RequestId: req.RunID,
|
||
AppCode: req.AppCode,
|
||
RunId: req.RunID,
|
||
WorkerId: req.WorkerID,
|
||
BatchSize: int32(req.BatchSize),
|
||
LockTtlMs: req.LockTTL.Milliseconds(),
|
||
}
|
||
}
|
||
|
||
func walletCronBatchResult(resp *walletv1.CronBatchResponse) scheduler.BatchResult {
|
||
if resp == nil {
|
||
return scheduler.BatchResult{}
|
||
}
|
||
return scheduler.BatchResult{
|
||
ClaimedCount: int(resp.GetClaimedCount()),
|
||
ProcessedCount: int(resp.GetProcessedCount()),
|
||
SuccessCount: int(resp.GetSuccessCount()),
|
||
FailureCount: int(resp.GetFailureCount()),
|
||
HasMore: resp.GetHasMore(),
|
||
}
|
||
}
|