重构:清退会员遗留档位与商品权益字段

- 删除 RuntimeProfileMembershipTier 枚举与会员权益快照/记录。
- 会员快照与记录的 tier 改为 plan 枚举,新增 cycle_index / cycle_count / cycle_kind。
- 充点商品快照/记录与配置快照/记录移除 tier 及四个 membership_* 字段。
- 充值中心快照/记录改用 membership_plans,取代 membership_products 与 benefits。
- 充点商品重播种为六档并取消首充赠送,删除会员商品构造与档位查表 helper。
- 后台充值商品 upsert 只接受泥点商品,会员商品改由会员计划目录维护。
This commit is contained in:
2026-10-02 14:55:31 +08:00
parent 61d4db4610
commit 103f3b548a
4 changed files with 67 additions and 404 deletions
@@ -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,
+14 -89
View File
@@ -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,
+45 -249
View File
@@ -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]