91 lines
4.2 KiB
Go
91 lines
4.2 KiB
Go
package wallet
|
||
|
||
import (
|
||
"context"
|
||
"hyapp/pkg/appcode"
|
||
"hyapp/pkg/xerr"
|
||
"hyapp/services/wallet-service/internal/domain/ledger"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// ProcessHostSalarySettlementBatch 执行主播/代理工资结算批处理;日结和半月结不清空周期钻石,月底只做逻辑清算标记。
|
||
func (s *Service) ProcessHostSalarySettlementBatch(ctx context.Context, command ledger.HostSalarySettlementBatchCommand) (ledger.HostSalarySettlementBatchResult, error) {
|
||
if s.repository == nil {
|
||
return ledger.HostSalarySettlementBatchResult{}, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||
}
|
||
switch strings.TrimSpace(command.SettlementType) {
|
||
case ledger.HostSalarySettlementModeDaily, ledger.HostSalarySettlementModeHalfMonth, ledger.HostSalarySettlementTypeMonthEnd:
|
||
default:
|
||
return ledger.HostSalarySettlementBatchResult{}, xerr.New(xerr.InvalidArgument, "settlement_type is invalid")
|
||
}
|
||
if command.BatchSize <= 0 {
|
||
command.BatchSize = 100
|
||
}
|
||
if command.BatchSize > 500 {
|
||
command.BatchSize = 500
|
||
}
|
||
if strings.TrimSpace(command.RunID) == "" || strings.TrimSpace(command.WorkerID) == "" {
|
||
return ledger.HostSalarySettlementBatchResult{}, xerr.New(xerr.InvalidArgument, "run_id and worker_id are required")
|
||
}
|
||
command.AppCode = appcode.Normalize(command.AppCode)
|
||
if command.NowMs <= 0 {
|
||
command.NowMs = s.now().UTC().UnixMilli()
|
||
}
|
||
if strings.TrimSpace(command.CycleKey) == "" {
|
||
command.CycleKey = hostSalaryCycleKey(command.NowMs)
|
||
}
|
||
ctx = appcode.WithContext(ctx, command.AppCode)
|
||
return s.repository.ProcessHostSalarySettlementBatch(ctx, command)
|
||
}
|
||
|
||
func hostSalaryCycleKey(nowMs int64) string {
|
||
// 结算周期按 UTC 月锚定,和送礼入账的 host_period_diamond_accounts.cycle_key 保持同一口径。
|
||
return time.UnixMilli(nowMs).UTC().Format("2006-01")
|
||
}
|
||
|
||
// GetActiveHostSalaryPolicy 读取主播所在区域当前生效的工资政策,返回的 policy 与工资结算使用同一张 runtime 表。
|
||
func (s *Service) GetActiveHostSalaryPolicy(ctx context.Context, appCode string, regionID int64, settlementMode string, triggerMode string, nowMs int64) (ledger.HostSalaryPolicy, bool, error) {
|
||
if regionID <= 0 {
|
||
return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.InvalidArgument, "region_id is required")
|
||
}
|
||
if s.repository == nil {
|
||
return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||
}
|
||
settlementMode = strings.TrimSpace(settlementMode)
|
||
if settlementMode != "" && settlementMode != ledger.HostSalarySettlementModeDaily && settlementMode != ledger.HostSalarySettlementModeHalfMonth {
|
||
return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.InvalidArgument, "settlement_mode is invalid")
|
||
}
|
||
triggerMode = strings.TrimSpace(triggerMode)
|
||
if triggerMode != "" && triggerMode != ledger.HostSalarySettlementTriggerAutomatic && triggerMode != ledger.HostSalarySettlementTriggerManual {
|
||
return ledger.HostSalaryPolicy{}, false, xerr.New(xerr.InvalidArgument, "settlement_trigger_mode is invalid")
|
||
}
|
||
if nowMs <= 0 {
|
||
nowMs = s.now().UTC().UnixMilli()
|
||
}
|
||
appCode = appcode.Normalize(appCode)
|
||
ctx = appcode.WithContext(ctx, appCode)
|
||
// H5 展示可以不传 trigger mode,此时 automatic/manual 政策都可展示;结算任务仍会传具体 trigger 精确匹配。
|
||
return s.repository.GetActiveHostSalaryPolicy(ctx, regionID, settlementMode, triggerMode, nowMs)
|
||
}
|
||
|
||
// GetHostSalaryProgress 返回主播当前工资周期的钻石累计;没有收礼账户时返回 0,避免 H5 用其他等级系统兜底导致进度口径错误。
|
||
func (s *Service) GetHostSalaryProgress(ctx context.Context, appCode string, userID int64, cycleKey string, nowMs int64) (ledger.HostSalaryProgress, error) {
|
||
if userID <= 0 {
|
||
return ledger.HostSalaryProgress{}, xerr.New(xerr.InvalidArgument, "host_user_id is required")
|
||
}
|
||
if s.repository == nil {
|
||
return ledger.HostSalaryProgress{}, xerr.New(xerr.Unavailable, "wallet repository is not configured")
|
||
}
|
||
if nowMs <= 0 {
|
||
nowMs = s.now().UTC().UnixMilli()
|
||
}
|
||
cycleKey = strings.TrimSpace(cycleKey)
|
||
if cycleKey == "" {
|
||
cycleKey = hostSalaryCycleKey(nowMs)
|
||
}
|
||
appCode = appcode.Normalize(appCode)
|
||
ctx = appcode.WithContext(ctx, appCode)
|
||
return s.repository.GetHostSalaryProgress(ctx, userID, cycleKey)
|
||
}
|