114 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package mysql
import (
"context"
"database/sql"
"errors"
"strconv"
"strings"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
"hyapp/services/wallet-service/internal/domain/ledger"
)
const (
// charge_amount 是 ca15f098 上线时的兼容口径Agency 比例直接作用于礼物实扣金额,
// 因而主播比例与 Agency 比例必须共同受 100% 资金池约束。
agencyPointShareBaseChargeAmount = "charge_amount"
// host_income 表示平台在主播本次实际 POINT 收益之外追加 Agency 奖励。
// 该口径先完成礼物类型和主播政策换算,再对最终主播收益取比例,允许出现 100%+20%。
agencyPointShareBaseHostIncome = "host_income"
)
type walletPolicyInstance struct {
InstanceCode string
TemplateCode string
TemplateVersion string
RegionID int64
HostPointAsset string
HostPointRatioPPM int64
HostGiftTypeRatioEnabled bool
AgencyPointRatioPPM int64
AgencyPointShareBase string
PointsPerUSD int64
WithdrawFeeBPS int64
}
func (r *Repository) resolveActiveWalletPolicy(ctx context.Context, tx *sql.Tx, appCode string, regionID int64, nowMS int64) (walletPolicyInstance, bool, error) {
appCode = appcode.Normalize(appCode)
if regionID < 0 {
return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "region_id is invalid")
}
row := tx.QueryRowContext(ctx, `
SELECT instance_code, template_code, template_version, region_id, host_point_asset_type,
host_point_ratio_ppm,
COALESCE(JSON_UNQUOTE(JSON_EXTRACT(rule_json, '$.host.use_gift_type_ratio')), 'false'),
agency_point_ratio_ppm,
COALESCE(JSON_UNQUOTE(JSON_EXTRACT(rule_json, '$.agency.share_base')), 'charge_amount'),
points_per_usd, withdraw_fee_bps
FROM wallet_policy_instances
WHERE app_code = ?
AND region_id IN (?, 0)
AND status = 'active'
AND effective_from_ms <= ?
AND (effective_to_ms = 0 OR effective_to_ms > ?)
ORDER BY CASE WHEN region_id = ? THEN 0 ELSE 1 END, published_at_ms DESC, instance_code DESC
LIMIT 1`,
appCode, regionID, nowMS, nowMS, regionID,
)
var item walletPolicyInstance
var hostGiftTypeRatioRaw string
if err := row.Scan(
&item.InstanceCode,
&item.TemplateCode,
&item.TemplateVersion,
&item.RegionID,
&item.HostPointAsset,
&item.HostPointRatioPPM,
&hostGiftTypeRatioRaw,
&item.AgencyPointRatioPPM,
&item.AgencyPointShareBase,
&item.PointsPerUSD,
&item.WithdrawFeeBPS,
); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return walletPolicyInstance{}, false, nil
}
return walletPolicyInstance{}, false, err
}
item.HostPointAsset = strings.ToUpper(strings.TrimSpace(item.HostPointAsset))
if item.HostPointAsset == "" {
item.HostPointAsset = ledger.AssetPoint
}
parsedGiftTypeRatio, err := strconv.ParseBool(strings.ToLower(strings.TrimSpace(hostGiftTypeRatioRaw)))
if err != nil {
return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "wallet policy host gift type ratio flag is invalid")
}
item.HostGiftTypeRatioEnabled = parsedGiftTypeRatio
item.AgencyPointShareBase = strings.ToLower(strings.TrimSpace(item.AgencyPointShareBase))
if item.AgencyPointShareBase == "" {
item.AgencyPointShareBase = agencyPointShareBaseChargeAmount
}
if item.HostPointAsset != ledger.AssetPoint ||
item.HostPointRatioPPM <= 0 || item.HostPointRatioPPM > 1_000_000 ||
item.AgencyPointRatioPPM < 0 || item.AgencyPointRatioPPM > 1_000_000 ||
item.PointsPerUSD <= 0 || item.WithdrawFeeBPS < 0 || item.WithdrawFeeBPS > 10_000 {
return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "wallet policy instance is invalid")
}
switch item.AgencyPointShareBase {
case agencyPointShareBaseChargeAmount:
// 旧实例没有 share_base必须继续执行原先的总资金池守恒约束否则一次重新发布就会
// 把历史 70%+20% 配置悄然解释成可超发政策。
if item.HostPointRatioPPM+item.AgencyPointRatioPPM > 1_000_000 {
return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "wallet policy instance is invalid")
}
case agencyPointShareBaseHostIncome:
// host_income 是额外平台奖励Agency 百分比相对于主播实际到账值独立校验,不能与
// host_point_ratio_ppm 相加后套用旧的 100% 上限。
default:
return walletPolicyInstance{}, false, xerr.New(xerr.InvalidArgument, "wallet policy agency share base is invalid")
}
return item, true, nil
}