feat(tip): support dynamic gift products

This commit is contained in:
2026-07-21 13:19:45 +08:00
parent 55cb98ed14
commit 37ff69020b
62 changed files with 2325 additions and 1085 deletions
+16 -5
View File
@@ -13,7 +13,11 @@ import type {
export interface PaymentContextState {
status: string;
planCatalog: MachineContext["planCatalog"];
plans: MachineContext["plans"];
giftCategories: MachineContext["giftCategories"];
giftProducts: MachineContext["giftProducts"];
selectedGiftCategory: string | null;
isFirstRecharge: MachineContext["isFirstRecharge"];
selectedPlanId: string;
payChannel: MachineContext["payChannel"];
@@ -22,11 +26,12 @@ export interface PaymentContextState {
currentOrderId: string | null;
payParams: Record<string, unknown> | null;
orderStatus: MachineContext["orderStatus"];
tipCount: number | null;
thankYouMessage: string | null;
tipMessage: MachineContext["tipMessage"];
tipMessageError: string | null;
errorMessage: string | null;
launchNonce: number;
isLoadingPlans: boolean;
isLoadingTipMessage: boolean;
isCreatingOrder: boolean;
isPollingOrder: boolean;
isPaid: boolean;
@@ -63,7 +68,11 @@ export function usePaymentSelector<T>(
function selectPaymentState(state: PaymentSnapshot): PaymentContextState {
return {
status: String(state.value),
planCatalog: state.context.planCatalog,
plans: state.context.plans,
giftCategories: state.context.giftCategories,
giftProducts: state.context.giftProducts,
selectedGiftCategory: state.context.selectedGiftCategory,
isFirstRecharge: state.context.isFirstRecharge,
selectedPlanId: state.context.selectedPlanId,
payChannel: state.context.payChannel,
@@ -72,17 +81,19 @@ function selectPaymentState(state: PaymentSnapshot): PaymentContextState {
currentOrderId: state.context.currentOrderId,
payParams: state.context.payParams,
orderStatus: state.context.orderStatus,
tipCount: state.context.tipCount,
thankYouMessage: state.context.thankYouMessage,
tipMessage: state.context.tipMessage,
tipMessageError: state.context.tipMessageError,
errorMessage: state.context.errorMessage,
launchNonce: state.context.launchNonce,
isLoadingPlans:
state.matches("loadingCachedPlans") ||
state.matches("loadingPlans") ||
state.matches("loadingGiftProducts") ||
state.matches("refreshingPlans"),
isLoadingTipMessage: state.matches("loadingTipMessage"),
isCreatingOrder: state.matches("creatingOrder"),
isPollingOrder:
state.matches("pollingOrder") || state.matches("waitingForPayment"),
isPaid: state.matches("paid"),
isPaid: state.context.orderStatus === "paid",
};
}