重构:清退会员遗留档位与商品权益字段
- 删除 RuntimeProfileMembershipTier 枚举与会员权益快照/记录。 - 会员快照与记录的 tier 改为 plan 枚举,新增 cycle_index / cycle_count / cycle_kind。 - 充点商品快照/记录与配置快照/记录移除 tier 及四个 membership_* 字段。 - 充值中心快照/记录改用 membership_plans,取代 membership_products 与 benefits。 - 充点商品重播种为六档并取消首充赠送,删除会员商品构造与档位查表 helper。 - 后台充值商品 upsert 只接受泥点商品,会员商品改由会员计划目录维护。
This commit is contained in:
@@ -1052,16 +1052,7 @@ pub fn build_runtime_profile_recharge_center_record(
|
||||
.into_iter()
|
||||
.map(build_runtime_profile_recharge_product_record)
|
||||
.collect(),
|
||||
membership_products: snapshot
|
||||
.membership_products
|
||||
.into_iter()
|
||||
.map(build_runtime_profile_recharge_product_record)
|
||||
.collect(),
|
||||
benefits: snapshot
|
||||
.benefits
|
||||
.into_iter()
|
||||
.map(build_runtime_profile_membership_benefit_record)
|
||||
.collect(),
|
||||
membership_plans: snapshot.membership_plans,
|
||||
latest_order: snapshot
|
||||
.latest_order
|
||||
.map(build_runtime_profile_recharge_order_record),
|
||||
@@ -1085,11 +1076,6 @@ pub fn build_runtime_profile_recharge_product_record(
|
||||
duration_days: snapshot.duration_days,
|
||||
badge_label: snapshot.badge_label,
|
||||
description: snapshot.description,
|
||||
tier: snapshot.tier,
|
||||
membership_period_points: snapshot.membership_period_points,
|
||||
membership_period_days: snapshot.membership_period_days,
|
||||
membership_queue_limit: snapshot.membership_queue_limit,
|
||||
membership_discount_bps: snapshot.membership_discount_bps,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1106,11 +1092,6 @@ pub fn build_runtime_profile_recharge_product_config_record(
|
||||
duration_days: snapshot.duration_days,
|
||||
badge_label: snapshot.badge_label,
|
||||
description: snapshot.description,
|
||||
tier: snapshot.tier,
|
||||
membership_period_points: snapshot.membership_period_points,
|
||||
membership_period_days: snapshot.membership_period_days,
|
||||
membership_queue_limit: snapshot.membership_queue_limit,
|
||||
membership_discount_bps: snapshot.membership_discount_bps,
|
||||
enabled: snapshot.enabled,
|
||||
sort_order: snapshot.sort_order,
|
||||
created_by: snapshot.created_by,
|
||||
@@ -1122,29 +1103,13 @@ pub fn build_runtime_profile_recharge_product_config_record(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_runtime_profile_membership_benefit_record(
|
||||
snapshot: RuntimeProfileMembershipBenefitSnapshot,
|
||||
) -> RuntimeProfileMembershipBenefitRecord {
|
||||
RuntimeProfileMembershipBenefitRecord {
|
||||
benefit_name: snapshot.benefit_name,
|
||||
normal_value: snapshot.normal_value,
|
||||
month_value: snapshot.month_value,
|
||||
season_value: snapshot.season_value,
|
||||
year_value: snapshot.year_value,
|
||||
starter_value: snapshot.starter_value,
|
||||
basic_value: snapshot.basic_value,
|
||||
pro_value: snapshot.pro_value,
|
||||
ultimate_value: snapshot.ultimate_value,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_runtime_profile_membership_record(
|
||||
snapshot: RuntimeProfileMembershipSnapshot,
|
||||
) -> RuntimeProfileMembershipRecord {
|
||||
RuntimeProfileMembershipRecord {
|
||||
user_id: snapshot.user_id,
|
||||
status: snapshot.status,
|
||||
tier: snapshot.tier,
|
||||
plan: snapshot.plan,
|
||||
started_at: snapshot.started_at_micros.map(format_utc_micros),
|
||||
started_at_micros: snapshot.started_at_micros,
|
||||
expires_at: snapshot.expires_at_micros.map(format_utc_micros),
|
||||
@@ -1157,7 +1122,9 @@ pub fn build_runtime_profile_membership_record(
|
||||
cycle_resets_at_micros: snapshot.cycle_resets_at_micros,
|
||||
cycle_granted_points: snapshot.cycle_granted_points,
|
||||
cycle_remaining_points: snapshot.cycle_remaining_points,
|
||||
cycle_period_days: snapshot.cycle_period_days,
|
||||
cycle_index: snapshot.cycle_index,
|
||||
cycle_count: snapshot.cycle_count,
|
||||
cycle_kind: snapshot.cycle_kind,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -392,11 +392,6 @@ pub fn build_runtime_profile_recharge_product_admin_upsert_input(
|
||||
duration_days: u32,
|
||||
badge_label: String,
|
||||
description: String,
|
||||
tier: RuntimeProfileMembershipTier,
|
||||
membership_period_points: u64,
|
||||
membership_period_days: u32,
|
||||
membership_queue_limit: u32,
|
||||
membership_discount_bps: u32,
|
||||
enabled: bool,
|
||||
sort_order: i32,
|
||||
updated_at_micros: i64,
|
||||
@@ -414,28 +409,13 @@ pub fn build_runtime_profile_recharge_product_admin_upsert_input(
|
||||
if points_amount == 0 {
|
||||
return Err(RuntimeProfileFieldError::InvalidRechargeProductPoints);
|
||||
}
|
||||
if duration_days != 0
|
||||
|| tier != RuntimeProfileMembershipTier::Normal
|
||||
|| membership_period_points != 0
|
||||
|| membership_period_days != 0
|
||||
|| membership_queue_limit != 0
|
||||
|| membership_discount_bps != 0
|
||||
{
|
||||
if duration_days != 0 || bonus_points != 0 {
|
||||
return Err(RuntimeProfileFieldError::InvalidRechargeProductTier);
|
||||
}
|
||||
}
|
||||
// 中文注释:会员商品已迁移到 profile_membership_plan 目录,这里只保留泥点商品。
|
||||
RuntimeProfileRechargeProductKind::Membership => {
|
||||
if duration_days == 0 {
|
||||
return Err(RuntimeProfileFieldError::InvalidRechargeProductDuration);
|
||||
}
|
||||
if points_amount != 0
|
||||
|| bonus_points != 0
|
||||
|| tier == RuntimeProfileMembershipTier::Normal
|
||||
|| membership_period_points == 0
|
||||
|| membership_period_days == 0
|
||||
{
|
||||
return Err(RuntimeProfileFieldError::InvalidRechargeProductTier);
|
||||
}
|
||||
return Err(RuntimeProfileFieldError::InvalidRechargeProductTier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,11 +430,6 @@ pub fn build_runtime_profile_recharge_product_admin_upsert_input(
|
||||
duration_days,
|
||||
badge_label: normalize_optional_string(Some(badge_label)).unwrap_or_default(),
|
||||
description: normalize_optional_string(Some(description)).unwrap_or_default(),
|
||||
tier,
|
||||
membership_period_points,
|
||||
membership_period_days,
|
||||
membership_queue_limit,
|
||||
membership_discount_bps,
|
||||
enabled,
|
||||
sort_order,
|
||||
updated_at_micros,
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
//! 纯领域事实与值对象;SpacetimeDB client 与 HTTP response 不进入本文件。
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::RuntimeProfileMembershipPlanSnapshot;
|
||||
#[cfg(any())]
|
||||
use serde_json::Value;
|
||||
|
||||
@@ -1229,37 +1231,10 @@ impl RuntimeProfileMembershipStatus {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum RuntimeProfileMembershipTier {
|
||||
Normal,
|
||||
Month,
|
||||
Season,
|
||||
Year,
|
||||
Starter,
|
||||
Basic,
|
||||
Pro,
|
||||
Ultimate,
|
||||
}
|
||||
|
||||
impl RuntimeProfileMembershipTier {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Normal => "normal",
|
||||
Self::Month => "month",
|
||||
Self::Season => "season",
|
||||
Self::Year => "year",
|
||||
Self::Starter => "starter",
|
||||
Self::Basic => "basic",
|
||||
Self::Pro => "pro",
|
||||
Self::Ultimate => "ultimate",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 会员档位身份。取代旧的 `RuntimeProfileMembershipTier`,作为唯一权威档位标识。
|
||||
///
|
||||
/// 变体顺序即排序基准(`Normal < Starter < Plus < Pro < Max`),升级比较不再依赖旧枚举别名。
|
||||
/// 变体顺序即排序基准(`Normal < Starter < Plus < Pro < Max`)。对外 wire 只用
|
||||
/// [`RuntimeProfileMembershipPlan::as_str`] 产出的枚举 token。
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum RuntimeProfileMembershipPlan {
|
||||
@@ -1514,11 +1489,6 @@ pub struct RuntimeProfileRechargeProductSnapshot {
|
||||
pub duration_days: u32,
|
||||
pub badge_label: String,
|
||||
pub description: String,
|
||||
pub tier: RuntimeProfileMembershipTier,
|
||||
pub membership_period_points: u64,
|
||||
pub membership_period_days: u32,
|
||||
pub membership_queue_limit: u32,
|
||||
pub membership_discount_bps: u32,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
@@ -1533,11 +1503,6 @@ pub struct RuntimeProfileRechargeProductConfigSnapshot {
|
||||
pub duration_days: u32,
|
||||
pub badge_label: String,
|
||||
pub description: String,
|
||||
pub tier: RuntimeProfileMembershipTier,
|
||||
pub membership_period_points: u64,
|
||||
pub membership_period_days: u32,
|
||||
pub membership_queue_limit: u32,
|
||||
pub membership_discount_bps: u32,
|
||||
pub enabled: bool,
|
||||
pub sort_order: i32,
|
||||
pub created_by: String,
|
||||
@@ -1546,26 +1511,12 @@ pub struct RuntimeProfileRechargeProductConfigSnapshot {
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RuntimeProfileMembershipBenefitSnapshot {
|
||||
pub benefit_name: String,
|
||||
pub normal_value: String,
|
||||
pub month_value: String,
|
||||
pub season_value: String,
|
||||
pub year_value: String,
|
||||
pub starter_value: String,
|
||||
pub basic_value: String,
|
||||
pub pro_value: String,
|
||||
pub ultimate_value: String,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RuntimeProfileMembershipSnapshot {
|
||||
pub user_id: String,
|
||||
pub status: RuntimeProfileMembershipStatus,
|
||||
pub tier: RuntimeProfileMembershipTier,
|
||||
pub plan: RuntimeProfileMembershipPlan,
|
||||
pub started_at_micros: Option<i64>,
|
||||
pub expires_at_micros: Option<i64>,
|
||||
pub updated_at_micros: Option<i64>,
|
||||
@@ -1573,7 +1524,9 @@ pub struct RuntimeProfileMembershipSnapshot {
|
||||
pub cycle_resets_at_micros: Option<i64>,
|
||||
pub cycle_granted_points: u64,
|
||||
pub cycle_remaining_points: u64,
|
||||
pub cycle_period_days: u32,
|
||||
pub cycle_index: u32,
|
||||
pub cycle_count: u32,
|
||||
pub cycle_kind: RuntimeProfileMembershipCycleKind,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
@@ -1765,8 +1718,7 @@ pub struct RuntimeProfileRechargeCenterSnapshot {
|
||||
pub wallet_balance: u64,
|
||||
pub membership: RuntimeProfileMembershipSnapshot,
|
||||
pub point_products: Vec<RuntimeProfileRechargeProductSnapshot>,
|
||||
pub membership_products: Vec<RuntimeProfileRechargeProductSnapshot>,
|
||||
pub benefits: Vec<RuntimeProfileMembershipBenefitSnapshot>,
|
||||
pub membership_plans: Vec<RuntimeProfileMembershipPlanSnapshot>,
|
||||
pub latest_order: Option<RuntimeProfileRechargeOrderSnapshot>,
|
||||
pub has_points_recharged: bool,
|
||||
pub daily_free_points: RuntimeProfileDailyFreePointsSnapshot,
|
||||
@@ -1807,11 +1759,6 @@ pub struct RuntimeProfileRechargeProductAdminUpsertInput {
|
||||
pub duration_days: u32,
|
||||
pub badge_label: String,
|
||||
pub description: String,
|
||||
pub tier: RuntimeProfileMembershipTier,
|
||||
pub membership_period_points: u64,
|
||||
pub membership_period_days: u32,
|
||||
pub membership_queue_limit: u32,
|
||||
pub membership_discount_bps: u32,
|
||||
pub enabled: bool,
|
||||
pub sort_order: i32,
|
||||
pub updated_at_micros: i64,
|
||||
@@ -2628,11 +2575,6 @@ pub struct RuntimeProfileRechargeProductRecord {
|
||||
pub duration_days: u32,
|
||||
pub badge_label: String,
|
||||
pub description: String,
|
||||
pub tier: RuntimeProfileMembershipTier,
|
||||
pub membership_period_points: u64,
|
||||
pub membership_period_days: u32,
|
||||
pub membership_queue_limit: u32,
|
||||
pub membership_discount_bps: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@@ -2646,11 +2588,6 @@ pub struct RuntimeProfileRechargeProductConfigRecord {
|
||||
pub duration_days: u32,
|
||||
pub badge_label: String,
|
||||
pub description: String,
|
||||
pub tier: RuntimeProfileMembershipTier,
|
||||
pub membership_period_points: u64,
|
||||
pub membership_period_days: u32,
|
||||
pub membership_queue_limit: u32,
|
||||
pub membership_discount_bps: u32,
|
||||
pub enabled: bool,
|
||||
pub sort_order: i32,
|
||||
pub created_by: String,
|
||||
@@ -2674,24 +2611,11 @@ pub struct RuntimeProfileWalletConfigRecord {
|
||||
pub daily_free_points_per_day: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct RuntimeProfileMembershipBenefitRecord {
|
||||
pub benefit_name: String,
|
||||
pub normal_value: String,
|
||||
pub month_value: String,
|
||||
pub season_value: String,
|
||||
pub year_value: String,
|
||||
pub starter_value: String,
|
||||
pub basic_value: String,
|
||||
pub pro_value: String,
|
||||
pub ultimate_value: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct RuntimeProfileMembershipRecord {
|
||||
pub user_id: String,
|
||||
pub status: RuntimeProfileMembershipStatus,
|
||||
pub tier: RuntimeProfileMembershipTier,
|
||||
pub plan: RuntimeProfileMembershipPlan,
|
||||
pub started_at: Option<String>,
|
||||
pub started_at_micros: Option<i64>,
|
||||
pub expires_at: Option<String>,
|
||||
@@ -2704,7 +2628,9 @@ pub struct RuntimeProfileMembershipRecord {
|
||||
pub cycle_resets_at_micros: Option<i64>,
|
||||
pub cycle_granted_points: u64,
|
||||
pub cycle_remaining_points: u64,
|
||||
pub cycle_period_days: u32,
|
||||
pub cycle_index: u32,
|
||||
pub cycle_count: u32,
|
||||
pub cycle_kind: RuntimeProfileMembershipCycleKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@@ -2739,8 +2665,7 @@ pub struct RuntimeProfileRechargeCenterRecord {
|
||||
pub wallet_balance: u64,
|
||||
pub membership: RuntimeProfileMembershipRecord,
|
||||
pub point_products: Vec<RuntimeProfileRechargeProductRecord>,
|
||||
pub membership_products: Vec<RuntimeProfileRechargeProductRecord>,
|
||||
pub benefits: Vec<RuntimeProfileMembershipBenefitRecord>,
|
||||
pub membership_plans: Vec<RuntimeProfileMembershipPlanSnapshot>,
|
||||
pub latest_order: Option<RuntimeProfileRechargeOrderRecord>,
|
||||
pub has_points_recharged: bool,
|
||||
pub daily_free_points: RuntimeProfileDailyFreePointsRecord,
|
||||
|
||||
@@ -21,8 +21,6 @@ pub use membership::*;
|
||||
use shared_kernel::format_rfc3339 as format_shared_rfc3339;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
pub const PROFILE_MEMBERSHIP_DEFAULT_PERIOD_DAYS: u32 = 30;
|
||||
|
||||
pub fn format_utc_micros(micros: i64) -> String {
|
||||
let timestamp = OffsetDateTime::from_unix_timestamp_nanos(i128::from(micros) * 1_000)
|
||||
.unwrap_or(OffsetDateTime::UNIX_EPOCH);
|
||||
@@ -31,166 +29,12 @@ pub fn format_utc_micros(micros: i64) -> String {
|
||||
|
||||
pub fn runtime_profile_recharge_point_products() -> Vec<RuntimeProfileRechargeProductSnapshot> {
|
||||
vec![
|
||||
build_points_recharge_product("points_60", "60泥点", 600, 60, 0, "", "60泥点"),
|
||||
build_points_recharge_product(
|
||||
"points_180",
|
||||
"180泥点",
|
||||
1800,
|
||||
180,
|
||||
90,
|
||||
"首充加赠",
|
||||
"首充加赠90泥点",
|
||||
),
|
||||
build_points_recharge_product(
|
||||
"points_300",
|
||||
"300泥点",
|
||||
3000,
|
||||
300,
|
||||
150,
|
||||
"首充加赠",
|
||||
"首充加赠150泥点",
|
||||
),
|
||||
build_points_recharge_product(
|
||||
"points_680",
|
||||
"680泥点",
|
||||
6800,
|
||||
680,
|
||||
340,
|
||||
"首充加赠",
|
||||
"首充加赠340泥点",
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
/// 中文注释:保留旧展示 helper 的兼容入口;首充资格已改为按商品档位在配置表侧计算。
|
||||
pub fn resolve_runtime_profile_recharge_point_products(
|
||||
_has_points_recharged: bool,
|
||||
) -> Vec<RuntimeProfileRechargeProductSnapshot> {
|
||||
runtime_profile_recharge_point_products()
|
||||
}
|
||||
|
||||
pub fn runtime_profile_recharge_membership_products() -> Vec<RuntimeProfileRechargeProductSnapshot>
|
||||
{
|
||||
vec![
|
||||
build_membership_recharge_product(
|
||||
"member_starter",
|
||||
"Starter",
|
||||
1990,
|
||||
30,
|
||||
RuntimeProfileMembershipTier::Starter,
|
||||
"每月200泥点 用于游戏创作",
|
||||
),
|
||||
build_membership_recharge_product(
|
||||
"member_basic",
|
||||
"Basic",
|
||||
6990,
|
||||
30,
|
||||
RuntimeProfileMembershipTier::Basic,
|
||||
"每月800泥点 用于游戏创作",
|
||||
),
|
||||
build_membership_recharge_product(
|
||||
"member_pro",
|
||||
"Pro",
|
||||
19990,
|
||||
30,
|
||||
RuntimeProfileMembershipTier::Pro,
|
||||
"每月2500泥点 用于游戏创作",
|
||||
),
|
||||
build_membership_recharge_product(
|
||||
"member_ultimate",
|
||||
"Ultimate",
|
||||
41990,
|
||||
30,
|
||||
RuntimeProfileMembershipTier::Ultimate,
|
||||
"每月6000泥点 用于游戏创作",
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn runtime_profile_membership_tier_rank(tier: RuntimeProfileMembershipTier) -> Option<u8> {
|
||||
match tier {
|
||||
RuntimeProfileMembershipTier::Normal => None,
|
||||
RuntimeProfileMembershipTier::Month | RuntimeProfileMembershipTier::Starter => Some(1),
|
||||
RuntimeProfileMembershipTier::Season | RuntimeProfileMembershipTier::Basic => Some(2),
|
||||
RuntimeProfileMembershipTier::Year | RuntimeProfileMembershipTier::Pro => Some(3),
|
||||
RuntimeProfileMembershipTier::Ultimate => Some(4),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn runtime_profile_membership_period_points(tier: RuntimeProfileMembershipTier) -> u64 {
|
||||
match tier {
|
||||
RuntimeProfileMembershipTier::Starter => 200,
|
||||
RuntimeProfileMembershipTier::Basic => 800,
|
||||
RuntimeProfileMembershipTier::Pro => 2500,
|
||||
RuntimeProfileMembershipTier::Ultimate => 6000,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn runtime_profile_membership_queue_limit(tier: RuntimeProfileMembershipTier) -> u32 {
|
||||
match tier {
|
||||
RuntimeProfileMembershipTier::Starter | RuntimeProfileMembershipTier::Basic => 2,
|
||||
RuntimeProfileMembershipTier::Pro => 5,
|
||||
RuntimeProfileMembershipTier::Ultimate => 10,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn runtime_profile_membership_discount_bps(tier: RuntimeProfileMembershipTier) -> u32 {
|
||||
match tier {
|
||||
RuntimeProfileMembershipTier::Basic => 8500,
|
||||
RuntimeProfileMembershipTier::Pro => 8000,
|
||||
RuntimeProfileMembershipTier::Ultimate => 7000,
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn runtime_profile_membership_benefits() -> Vec<RuntimeProfileMembershipBenefitSnapshot> {
|
||||
vec![
|
||||
RuntimeProfileMembershipBenefitSnapshot {
|
||||
benefit_name: "特权名称".to_string(),
|
||||
normal_value: "普通".to_string(),
|
||||
month_value: "月卡".to_string(),
|
||||
season_value: "季卡".to_string(),
|
||||
year_value: "年卡".to_string(),
|
||||
starter_value: "Starter".to_string(),
|
||||
basic_value: "Basic".to_string(),
|
||||
pro_value: "Pro".to_string(),
|
||||
ultimate_value: "Ultimate".to_string(),
|
||||
},
|
||||
RuntimeProfileMembershipBenefitSnapshot {
|
||||
benefit_name: "每月泥点".to_string(),
|
||||
normal_value: "0".to_string(),
|
||||
month_value: "0".to_string(),
|
||||
season_value: "0".to_string(),
|
||||
year_value: "0".to_string(),
|
||||
starter_value: "200".to_string(),
|
||||
basic_value: "800".to_string(),
|
||||
pro_value: "2500".to_string(),
|
||||
ultimate_value: "6000".to_string(),
|
||||
},
|
||||
RuntimeProfileMembershipBenefitSnapshot {
|
||||
benefit_name: "同时排队".to_string(),
|
||||
normal_value: "1".to_string(),
|
||||
month_value: "2".to_string(),
|
||||
season_value: "2".to_string(),
|
||||
year_value: "2".to_string(),
|
||||
starter_value: "2".to_string(),
|
||||
basic_value: "2".to_string(),
|
||||
pro_value: "5".to_string(),
|
||||
ultimate_value: "10".to_string(),
|
||||
},
|
||||
RuntimeProfileMembershipBenefitSnapshot {
|
||||
benefit_name: "商业所有权".to_string(),
|
||||
normal_value: "0%".to_string(),
|
||||
month_value: "有".to_string(),
|
||||
season_value: "有".to_string(),
|
||||
year_value: "有".to_string(),
|
||||
starter_value: "有".to_string(),
|
||||
basic_value: "有".to_string(),
|
||||
pro_value: "有".to_string(),
|
||||
ultimate_value: "有".to_string(),
|
||||
},
|
||||
build_points_recharge_product("points_60", "60泥点", 600, 60),
|
||||
build_points_recharge_product("points_180", "180泥点", 1800, 180),
|
||||
build_points_recharge_product("points_300", "300泥点", 3000, 300),
|
||||
build_points_recharge_product("points_680", "680泥点", 6800, 680),
|
||||
build_points_recharge_product("points_1280", "1280泥点", 12800, 1280),
|
||||
build_points_recharge_product("points_3280", "3280泥点", 32800, 3280),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -199,7 +43,6 @@ pub fn runtime_profile_recharge_product_by_id(
|
||||
) -> Option<RuntimeProfileRechargeProductSnapshot> {
|
||||
runtime_profile_recharge_point_products()
|
||||
.into_iter()
|
||||
.chain(runtime_profile_recharge_membership_products())
|
||||
.find(|product| product.product_id == product_id)
|
||||
}
|
||||
|
||||
@@ -215,9 +58,6 @@ fn build_points_recharge_product(
|
||||
title: &str,
|
||||
price_cents: u64,
|
||||
points_amount: u64,
|
||||
bonus_points: u64,
|
||||
badge_label: &str,
|
||||
description: &str,
|
||||
) -> RuntimeProfileRechargeProductSnapshot {
|
||||
RuntimeProfileRechargeProductSnapshot {
|
||||
product_id: product_id.to_string(),
|
||||
@@ -225,41 +65,10 @@ fn build_points_recharge_product(
|
||||
price_cents,
|
||||
kind: RuntimeProfileRechargeProductKind::Points,
|
||||
points_amount,
|
||||
bonus_points,
|
||||
duration_days: 0,
|
||||
badge_label: badge_label.to_string(),
|
||||
description: description.to_string(),
|
||||
tier: RuntimeProfileMembershipTier::Normal,
|
||||
membership_period_points: 0,
|
||||
membership_period_days: 0,
|
||||
membership_queue_limit: 0,
|
||||
membership_discount_bps: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_membership_recharge_product(
|
||||
product_id: &str,
|
||||
title: &str,
|
||||
price_cents: u64,
|
||||
duration_days: u32,
|
||||
tier: RuntimeProfileMembershipTier,
|
||||
description: &str,
|
||||
) -> RuntimeProfileRechargeProductSnapshot {
|
||||
RuntimeProfileRechargeProductSnapshot {
|
||||
product_id: product_id.to_string(),
|
||||
title: title.to_string(),
|
||||
price_cents,
|
||||
kind: RuntimeProfileRechargeProductKind::Membership,
|
||||
points_amount: 0,
|
||||
bonus_points: 0,
|
||||
duration_days,
|
||||
duration_days: 0,
|
||||
badge_label: String::new(),
|
||||
description: description.to_string(),
|
||||
tier,
|
||||
membership_period_points: runtime_profile_membership_period_points(tier),
|
||||
membership_period_days: PROFILE_MEMBERSHIP_DEFAULT_PERIOD_DAYS,
|
||||
membership_queue_limit: runtime_profile_membership_queue_limit(tier),
|
||||
membership_discount_bps: runtime_profile_membership_discount_bps(tier),
|
||||
description: title.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,59 +938,46 @@ mod tests {
|
||||
#[test]
|
||||
fn recharge_product_catalog_matches_reference_prices() {
|
||||
let point_products = runtime_profile_recharge_point_products();
|
||||
let membership_products = runtime_profile_recharge_membership_products();
|
||||
|
||||
assert_eq!(point_products.len(), 4);
|
||||
assert_eq!(point_products[0].product_id, "points_60");
|
||||
assert_eq!(point_products[0].title, "60泥点");
|
||||
assert_eq!(point_products[0].price_cents, 600);
|
||||
assert_eq!(point_products[0].bonus_points, 0);
|
||||
assert_eq!(point_products[0].badge_label, "");
|
||||
assert_eq!(point_products[0].description, "60泥点");
|
||||
assert_eq!(point_products[1].product_id, "points_180");
|
||||
assert_eq!(point_products[1].bonus_points, 90);
|
||||
assert_eq!(point_products[2].bonus_points, 150);
|
||||
assert_eq!(point_products[3].product_id, "points_680");
|
||||
assert_eq!(point_products[3].price_cents, 6800);
|
||||
assert_eq!(point_products[3].bonus_points, 340);
|
||||
assert_eq!(point_products[3].description, "首充加赠340泥点");
|
||||
assert_eq!(membership_products.len(), 4);
|
||||
assert_eq!(membership_products[0].product_id, "member_starter");
|
||||
assert_eq!(membership_products[0].title, "Starter");
|
||||
assert_eq!(membership_products[0].price_cents, 1990);
|
||||
assert_eq!(membership_products[0].membership_period_points, 200);
|
||||
assert_eq!(point_products.len(), 6);
|
||||
for (product, product_id, price_cents, points_amount) in [
|
||||
(&point_products[0], "points_60", 600, 60),
|
||||
(&point_products[1], "points_180", 1800, 180),
|
||||
(&point_products[2], "points_300", 3000, 300),
|
||||
(&point_products[3], "points_680", 6800, 680),
|
||||
(&point_products[4], "points_1280", 12800, 1280),
|
||||
(&point_products[5], "points_3280", 32800, 3280),
|
||||
] {
|
||||
assert_eq!(product.product_id, product_id);
|
||||
assert_eq!(product.price_cents, price_cents);
|
||||
assert_eq!(product.points_amount, points_amount);
|
||||
// 中文注释:新方案取消首充赠送,六档充点一律无赠送、无角标。
|
||||
assert_eq!(product.bonus_points, 0);
|
||||
assert_eq!(product.badge_label, "");
|
||||
}
|
||||
|
||||
let plans = runtime_profile_membership_plan_catalog();
|
||||
assert_eq!(plans.len(), 5);
|
||||
assert_eq!(plans[0].plan, RuntimeProfileMembershipPlan::Normal);
|
||||
assert!(!plans[0].enabled);
|
||||
assert_eq!(plans[0].period_points, 0);
|
||||
assert_eq!(plans[0].concurrent_job_limit, 1);
|
||||
assert_eq!(plans[1].plan, RuntimeProfileMembershipPlan::Starter);
|
||||
assert_eq!(plans[1].month_price_cents, 3_900);
|
||||
assert_eq!(plans[1].year_price_cents, 39_000);
|
||||
assert_eq!(plans[1].period_points, 400);
|
||||
assert_eq!(plans[2].plan, RuntimeProfileMembershipPlan::Plus);
|
||||
assert_eq!(plans[2].period_points, 1_150);
|
||||
assert_eq!(plans[3].plan, RuntimeProfileMembershipPlan::Pro);
|
||||
assert_eq!(plans[3].period_points, 3_650);
|
||||
assert_eq!(plans[4].plan, RuntimeProfileMembershipPlan::Max);
|
||||
assert_eq!(plans[4].month_price_cents, 69_900);
|
||||
assert_eq!(plans[4].year_price_cents, 699_000);
|
||||
assert_eq!(plans[4].period_points, 8_650);
|
||||
assert_eq!(
|
||||
membership_products[0].membership_period_days,
|
||||
PROFILE_MEMBERSHIP_DEFAULT_PERIOD_DAYS
|
||||
plans[4].concurrent_job_limit,
|
||||
MEMBERSHIP_UNLIMITED_CONCURRENCY
|
||||
);
|
||||
assert_eq!(membership_products[3].product_id, "member_ultimate");
|
||||
assert_eq!(membership_products[3].membership_period_points, 6000);
|
||||
assert_eq!(membership_products[3].membership_queue_limit, 10);
|
||||
|
||||
let benefits = runtime_profile_membership_benefits();
|
||||
assert!(
|
||||
benefits
|
||||
.iter()
|
||||
.any(|benefit| benefit.benefit_name == "每月泥点")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recharge_point_products_do_not_hide_all_first_bonus_by_account_flag() {
|
||||
let first_recharge_products = resolve_runtime_profile_recharge_point_products(false);
|
||||
assert_eq!(first_recharge_products[0].bonus_points, 0);
|
||||
assert_eq!(first_recharge_products[0].badge_label, "");
|
||||
assert_eq!(first_recharge_products[0].description, "60泥点");
|
||||
assert_eq!(first_recharge_products[1].bonus_points, 90);
|
||||
assert_eq!(first_recharge_products[1].badge_label, "首充加赠");
|
||||
assert_eq!(first_recharge_products[1].description, "首充加赠90泥点");
|
||||
|
||||
let repeated_recharge_products = resolve_runtime_profile_recharge_point_products(true);
|
||||
assert_eq!(repeated_recharge_products[0].bonus_points, 0);
|
||||
assert_eq!(repeated_recharge_products[1].bonus_points, 90);
|
||||
assert_eq!(repeated_recharge_products[3].bonus_points, 340);
|
||||
assert_eq!(repeated_recharge_products[3].badge_label, "首充加赠");
|
||||
assert_eq!(repeated_recharge_products[3].description, "首充加赠340泥点");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user