后台契约与接口透出会员变更快照与用户会员状态
- shared-contracts 新增 AdminMembershipOrderChangePayload 与 AdminProfileMembershipPayload - AdminProfileWalletPayload.membership_limited_points 改名 monthly_points - AdminRechargeOrderEntryPayload 增加 membership_change 快照字段 - AdminUserDetailResponse 增加 membership 字段 - admin_recharge 映射会员订单快照与用户会员中心投影 Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
@@ -11,6 +11,7 @@ use module_runtime::{
|
||||
PROFILE_RECHARGE_PAYMENT_CHANNEL_WECHAT_H5, PROFILE_RECHARGE_PAYMENT_CHANNEL_WECHAT_JSAPI,
|
||||
PROFILE_RECHARGE_PAYMENT_CHANNEL_WECHAT_MINI_PROGRAM,
|
||||
PROFILE_RECHARGE_PAYMENT_CHANNEL_WECHAT_NATIVE, RuntimeProfileAdminWalletSnapshot,
|
||||
RuntimeProfileMembershipOrderChangeSnapshot, RuntimeProfileMembershipRecord,
|
||||
RuntimeProfileRechargeOrderAdminEntrySnapshot, RuntimeProfileRechargeOrderStatus,
|
||||
RuntimeProfileRechargeProductKind, RuntimeProfileRechargeRefundHoldSnapshot,
|
||||
RuntimeProfileRechargeRefundHoldStatus, RuntimeProfileRechargeRefundObservationSource,
|
||||
@@ -31,15 +32,16 @@ use platform_wechat::pay::{
|
||||
use serde_json::{Value, json};
|
||||
use sha2::{Digest, Sha256};
|
||||
use shared_contracts::admin::{
|
||||
ADMIN_ACTION_PROFILE_WALLET_CONSUMPTION_RECONCILE, AdminProfileWalletPayload,
|
||||
AdminRechargeOrderEntryPayload, AdminRechargeOrderListQuery, AdminRechargeOrderListResponse,
|
||||
AdminRechargeRefundActionResponse, AdminRechargeRefundExecuteRequest,
|
||||
AdminRechargeRefundHoldPayload, AdminRechargeRefundManualReviewResolveRequest,
|
||||
AdminRechargeRefundPayload, AdminRechargeRefundPreviewRequest,
|
||||
AdminRechargeRefundPreviewResponse, AdminRechargeRefundRegisterRequest,
|
||||
AdminUserConsumptionProjectionInitializeResponse, AdminUserConsumptionReconcileRequest,
|
||||
AdminUserConsumptionReconcileResponse, AdminUserDetailQuery, AdminUserDetailResponse,
|
||||
AdminUserSummaryPayload, AdminWalletManualRestrictionPayload, AdminWalletRestrictionRequest,
|
||||
ADMIN_ACTION_PROFILE_WALLET_CONSUMPTION_RECONCILE, AdminMembershipOrderChangePayload,
|
||||
AdminProfileMembershipPayload, AdminProfileWalletPayload, AdminRechargeOrderEntryPayload,
|
||||
AdminRechargeOrderListQuery, AdminRechargeOrderListResponse, AdminRechargeRefundActionResponse,
|
||||
AdminRechargeRefundExecuteRequest, AdminRechargeRefundHoldPayload,
|
||||
AdminRechargeRefundManualReviewResolveRequest, AdminRechargeRefundPayload,
|
||||
AdminRechargeRefundPreviewRequest, AdminRechargeRefundPreviewResponse,
|
||||
AdminRechargeRefundRegisterRequest, AdminUserConsumptionProjectionInitializeResponse,
|
||||
AdminUserConsumptionReconcileRequest, AdminUserConsumptionReconcileResponse,
|
||||
AdminUserDetailQuery, AdminUserDetailResponse, AdminUserSummaryPayload,
|
||||
AdminWalletManualRestrictionPayload, AdminWalletRestrictionRequest,
|
||||
AdminWalletRestrictionResponse, AdminWechatPaymentCheckPayload,
|
||||
};
|
||||
use spacetime_client::SpacetimeClientError;
|
||||
@@ -158,6 +160,12 @@ pub async fn admin_get_user_detail(
|
||||
.map_err(|error| spacetime_error_response(&request_context, error))?;
|
||||
let cumulative_recharged_cents =
|
||||
fetch_admin_user_cumulative_recharged_cents(&state, &user.id).await;
|
||||
let membership_record = state
|
||||
.spacetime_client()
|
||||
.get_profile_recharge_center(user.id.clone())
|
||||
.await
|
||||
.map_err(|error| spacetime_error_response(&request_context, error))?
|
||||
.membership;
|
||||
|
||||
Ok(json_success_body(
|
||||
Some(&request_context),
|
||||
@@ -175,6 +183,7 @@ pub async fn admin_get_user_detail(
|
||||
cumulative_recharged_cents,
|
||||
can_reconcile_consumption: admin.can(ADMIN_ACTION_PROFILE_WALLET_CONSUMPTION_RECONCILE),
|
||||
wallet: map_wallet(wallet_detail.wallet, Some(&admin_display_names)),
|
||||
membership: map_membership(membership_record),
|
||||
recharge_orders: orders
|
||||
.into_iter()
|
||||
.map(|entry| map_order_entry(entry, Some(summary.clone())))
|
||||
@@ -979,6 +988,44 @@ fn map_order_entry(
|
||||
remaining_refundable_cents,
|
||||
refund_eligible: block_reason.is_none(),
|
||||
refund_block_reason_code: block_reason,
|
||||
membership_change: entry.membership_change.map(map_membership_order_change),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_membership_order_change(
|
||||
change: RuntimeProfileMembershipOrderChangeSnapshot,
|
||||
) -> AdminMembershipOrderChangePayload {
|
||||
AdminMembershipOrderChangePayload {
|
||||
change_kind: change.change_kind,
|
||||
plan_before: change.plan_before,
|
||||
plan_after: change.plan_after,
|
||||
cycle_kind_before: change.cycle_kind_before,
|
||||
cycle_kind_after: change.cycle_kind_after,
|
||||
period_points_before: change.period_points_before,
|
||||
period_points_after: change.period_points_after,
|
||||
granted_points_delta: change.granted_points_delta,
|
||||
cycle_index: change.cycle_index,
|
||||
expires_at_before_micros: change.expires_at_before_micros,
|
||||
expires_at_after_micros: change.expires_at_after_micros,
|
||||
cycle_resets_at_before_micros: change.cycle_resets_at_before_micros,
|
||||
cycle_resets_at_after_micros: change.cycle_resets_at_after_micros,
|
||||
price_breakdown_json: change.price_breakdown_json,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_membership(record: RuntimeProfileMembershipRecord) -> AdminProfileMembershipPayload {
|
||||
AdminProfileMembershipPayload {
|
||||
plan: record.plan.as_str().to_string(),
|
||||
status: record.status.as_str().to_string(),
|
||||
cycle_kind: record.cycle_kind.as_str().to_string(),
|
||||
cycle_index: record.cycle_index,
|
||||
cycle_count: record.cycle_count,
|
||||
cycle_granted_points: record.cycle_granted_points,
|
||||
cycle_remaining_points: record.cycle_remaining_points,
|
||||
started_at_micros: record.started_at_micros,
|
||||
expires_at_micros: record.expires_at_micros,
|
||||
cycle_resets_at_micros: record.cycle_resets_at_micros,
|
||||
updated_at_micros: record.updated_at_micros,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,7 +1038,7 @@ fn map_wallet(
|
||||
total_balance: wallet.total_balance,
|
||||
spendable_balance: wallet.spendable_balance,
|
||||
daily_free_points: wallet.daily_free_points,
|
||||
membership_limited_points: wallet.membership_limited_points,
|
||||
monthly_points: wallet.membership_limited_points,
|
||||
permanent_points: wallet.permanent_points,
|
||||
held_points: wallet.held_points,
|
||||
refund_debt_points: wallet.refund_debt_points,
|
||||
|
||||
@@ -1185,7 +1185,8 @@ pub struct AdminProfileWalletPayload {
|
||||
pub total_balance: u64,
|
||||
pub spendable_balance: u64,
|
||||
pub daily_free_points: u64,
|
||||
pub membership_limited_points: u64,
|
||||
/// 月度泥点:当前会员账期内发放、随账期重置而清零的泥点;无会员时为 0。
|
||||
pub monthly_points: u64,
|
||||
pub permanent_points: u64,
|
||||
pub held_points: u64,
|
||||
pub refund_debt_points: u64,
|
||||
@@ -1233,6 +1234,31 @@ pub struct AdminRechargeRefundHoldPayload {
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
/// 会员购买 / 升级的权益变更快照(只读)。
|
||||
///
|
||||
/// 与 `profile_recharge_order` 的末位快照列一一对应,供订单列表与退款人工复核还原变更
|
||||
/// 前后的档位、账期、补点与有效期。非会员订单为 `None`。
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AdminMembershipOrderChangePayload {
|
||||
/// `purchase` 或 `upgrade`。
|
||||
pub change_kind: String,
|
||||
pub plan_before: Option<String>,
|
||||
pub plan_after: Option<String>,
|
||||
pub cycle_kind_before: Option<String>,
|
||||
pub cycle_kind_after: Option<String>,
|
||||
pub period_points_before: Option<u64>,
|
||||
pub period_points_after: Option<u64>,
|
||||
pub granted_points_delta: i64,
|
||||
pub cycle_index: Option<u32>,
|
||||
pub expires_at_before_micros: Option<i64>,
|
||||
pub expires_at_after_micros: Option<i64>,
|
||||
pub cycle_resets_at_before_micros: Option<i64>,
|
||||
pub cycle_resets_at_after_micros: Option<i64>,
|
||||
/// 订单价格拆分 JSON(目标档位价、当前档位价、实付金额);字符串原样透出供人工核对。
|
||||
pub price_breakdown_json: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AdminRechargeOrderEntryPayload {
|
||||
@@ -1262,6 +1288,8 @@ pub struct AdminRechargeOrderEntryPayload {
|
||||
pub remaining_refundable_cents: u64,
|
||||
pub refund_eligible: bool,
|
||||
pub refund_block_reason_code: Option<String>,
|
||||
/// 会员购买 / 升级快照;非会员订单为 `None`。
|
||||
pub membership_change: Option<AdminMembershipOrderChangePayload>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
@@ -1294,9 +1322,27 @@ pub struct AdminUserDetailResponse {
|
||||
pub cumulative_recharged_cents: Option<u64>,
|
||||
pub can_reconcile_consumption: bool,
|
||||
pub wallet: AdminProfileWalletPayload,
|
||||
pub membership: AdminProfileMembershipPayload,
|
||||
pub recharge_orders: Vec<AdminRechargeOrderEntryPayload>,
|
||||
}
|
||||
|
||||
/// 单用户当前会员状态与账期(只读),供后台用户详情判断档位、周期与到期可见性。
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AdminProfileMembershipPayload {
|
||||
pub plan: String,
|
||||
pub status: String,
|
||||
pub cycle_kind: String,
|
||||
pub cycle_index: u32,
|
||||
pub cycle_count: u32,
|
||||
pub cycle_granted_points: u64,
|
||||
pub cycle_remaining_points: u64,
|
||||
pub started_at_micros: Option<i64>,
|
||||
pub expires_at_micros: Option<i64>,
|
||||
pub cycle_resets_at_micros: Option<i64>,
|
||||
pub updated_at_micros: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AdminUserConsumptionReconcileRequest {
|
||||
|
||||
Reference in New Issue
Block a user