feat: 支持充值商品配置和档位首充

This commit is contained in:
2026-05-15 06:11:57 +08:00
parent 9c33cc565c
commit c7fe793a9e
36 changed files with 2096 additions and 72 deletions

View File

@@ -11,7 +11,7 @@ use shared_kernel::{
use crate::domain::*;
use crate::errors::*;
use crate::{format_utc_micros, runtime_profile_recharge_product_by_id};
use crate::format_utc_micros;
pub const PROFILE_USER_TAG_MAX_COUNT: usize = 8;
pub const PROFILE_USER_TAG_MAX_CHARS: usize = 16;
@@ -259,9 +259,6 @@ pub fn build_runtime_profile_recharge_order_create_input(
let user_id = normalize_runtime_profile_user_id(user_id)?;
let product_id =
normalize_required_string(product_id).ok_or(RuntimeProfileFieldError::MissingProductId)?;
if runtime_profile_recharge_product_by_id(&product_id).is_none() {
return Err(RuntimeProfileFieldError::UnknownRechargeProduct);
}
let payment_channel = normalize_required_string(payment_channel)
.unwrap_or_else(|| PROFILE_RECHARGE_PAYMENT_CHANNEL_MOCK.to_string());
@@ -273,6 +270,78 @@ pub fn build_runtime_profile_recharge_order_create_input(
})
}
pub fn build_runtime_profile_recharge_product_admin_list_input(
admin_user_id: String,
) -> Result<RuntimeProfileRechargeProductAdminListInput, RuntimeProfileFieldError> {
let admin_user_id = normalize_runtime_profile_user_id(admin_user_id)?;
Ok(RuntimeProfileRechargeProductAdminListInput { admin_user_id })
}
#[allow(clippy::too_many_arguments)]
pub fn build_runtime_profile_recharge_product_admin_upsert_input(
admin_user_id: String,
product_id: String,
title: String,
price_cents: u64,
kind: RuntimeProfileRechargeProductKind,
points_amount: u64,
bonus_points: u64,
duration_days: u32,
badge_label: String,
description: String,
tier: RuntimeProfileMembershipTier,
enabled: bool,
sort_order: i32,
updated_at_micros: i64,
) -> Result<RuntimeProfileRechargeProductAdminUpsertInput, RuntimeProfileFieldError> {
let admin_user_id = normalize_runtime_profile_user_id(admin_user_id)?;
let product_id =
normalize_required_string(product_id).ok_or(RuntimeProfileFieldError::MissingProductId)?;
let title =
normalize_required_string(title).ok_or(RuntimeProfileFieldError::MissingProductTitle)?;
if price_cents == 0 {
return Err(RuntimeProfileFieldError::InvalidRechargeProductPrice);
}
match kind {
RuntimeProfileRechargeProductKind::Points => {
if points_amount == 0 {
return Err(RuntimeProfileFieldError::InvalidRechargeProductPoints);
}
if duration_days != 0 || tier != RuntimeProfileMembershipTier::Normal {
return Err(RuntimeProfileFieldError::InvalidRechargeProductTier);
}
}
RuntimeProfileRechargeProductKind::Membership => {
if duration_days == 0 {
return Err(RuntimeProfileFieldError::InvalidRechargeProductDuration);
}
if points_amount != 0
|| bonus_points != 0
|| tier == RuntimeProfileMembershipTier::Normal
{
return Err(RuntimeProfileFieldError::InvalidRechargeProductTier);
}
}
}
Ok(RuntimeProfileRechargeProductAdminUpsertInput {
admin_user_id,
product_id,
title,
price_cents,
kind,
points_amount,
bonus_points,
duration_days,
badge_label: normalize_optional_string(Some(badge_label)).unwrap_or_default(),
description: normalize_optional_string(Some(description)).unwrap_or_default(),
tier,
enabled,
sort_order,
updated_at_micros,
})
}
pub fn build_runtime_profile_recharge_order_paid_input(
order_id: String,
paid_at_micros: i64,