feat(subscription): load vip and credit plans from api
This commit is contained in:
@@ -15,6 +15,7 @@ export class PaymentPlan {
|
||||
declare readonly originalAmountCents: number | null;
|
||||
declare readonly dailyPriceCents: number | null;
|
||||
declare readonly currency: string;
|
||||
declare readonly pricingTier: string;
|
||||
declare readonly vipDays: number | null;
|
||||
declare readonly dolAmount: number | null;
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"success": true,
|
||||
"data": {
|
||||
"plans": [
|
||||
{
|
||||
"plan_id": "credit_1000",
|
||||
"plan_name": "1000 Credits",
|
||||
"order_type": "credit_recharge",
|
||||
"amount_cents": 990,
|
||||
"original_amount_cents": null,
|
||||
"daily_price_cents": null,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": null,
|
||||
"dol_amount": 1000
|
||||
},
|
||||
{
|
||||
"plan_id": "credit_2000",
|
||||
"plan_name": "2000 Credits",
|
||||
"order_type": "credit_recharge",
|
||||
"amount_cents": 1690,
|
||||
"original_amount_cents": null,
|
||||
"daily_price_cents": null,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": null,
|
||||
"dol_amount": 2000
|
||||
},
|
||||
{
|
||||
"plan_id": "credit_3000",
|
||||
"plan_name": "3000 Credits",
|
||||
"order_type": "credit_recharge",
|
||||
"amount_cents": 2290,
|
||||
"original_amount_cents": null,
|
||||
"daily_price_cents": null,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": null,
|
||||
"dol_amount": 3000
|
||||
},
|
||||
{
|
||||
"plan_id": "credit_5000",
|
||||
"plan_name": "5000 Credits",
|
||||
"order_type": "credit_recharge",
|
||||
"amount_cents": 3490,
|
||||
"original_amount_cents": null,
|
||||
"daily_price_cents": null,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": null,
|
||||
"dol_amount": 5000
|
||||
},
|
||||
{
|
||||
"plan_id": "credit_10000",
|
||||
"plan_name": "10000 Credits",
|
||||
"order_type": "credit_recharge",
|
||||
"amount_cents": 6490,
|
||||
"original_amount_cents": null,
|
||||
"daily_price_cents": null,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": null,
|
||||
"dol_amount": 10000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"success": true,
|
||||
"data": {
|
||||
"plans": [
|
||||
{
|
||||
"plan_id": "vip_monthly",
|
||||
"plan_name": "月度会员",
|
||||
"order_type": "vip_monthly",
|
||||
"amount_cents": 1999,
|
||||
"original_amount_cents": 2499,
|
||||
"daily_price_cents": 66,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": 30,
|
||||
"dol_amount": null
|
||||
},
|
||||
{
|
||||
"plan_id": "vip_quarterly",
|
||||
"plan_name": "季度会员",
|
||||
"order_type": "vip_quarterly",
|
||||
"amount_cents": 4999,
|
||||
"original_amount_cents": 5999,
|
||||
"daily_price_cents": 55,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": 90,
|
||||
"dol_amount": null
|
||||
},
|
||||
{
|
||||
"plan_id": "vip_yearly",
|
||||
"plan_name": "年度会员",
|
||||
"order_type": "vip_yearly",
|
||||
"amount_cents": 17999,
|
||||
"original_amount_cents": 19999,
|
||||
"daily_price_cents": 49,
|
||||
"currency": "USD",
|
||||
"pricing_tier": "T1",
|
||||
"vip_days": 365,
|
||||
"dol_amount": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
CreatePaymentOrderResponse,
|
||||
PayChannel,
|
||||
PaymentOrderStatusResponse,
|
||||
PaymentPlan,
|
||||
PaymentPlansResponse,
|
||||
PaymentVipStatusResponse,
|
||||
} from "@/data/dto/payment";
|
||||
@@ -16,6 +17,12 @@ export interface IPaymentRepository {
|
||||
/** 获取套餐列表。 */
|
||||
getPlans(): Promise<Result<PaymentPlansResponse>>;
|
||||
|
||||
/** 获取会员套餐列表。 */
|
||||
getVipPlans(): Promise<Result<PaymentPlan[]>>;
|
||||
|
||||
/** 获取积分套餐列表。 */
|
||||
getCreditPlans(): Promise<Result<PaymentPlan[]>>;
|
||||
|
||||
/** 创建支付订单。 */
|
||||
createOrder(
|
||||
planId: string,
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
CreatePaymentOrderResponse,
|
||||
PayChannel,
|
||||
PaymentOrderStatusResponse,
|
||||
PaymentPlan,
|
||||
PaymentPlansResponse,
|
||||
PaymentVipStatusResponse,
|
||||
} from "@/data/dto/payment";
|
||||
@@ -25,6 +26,22 @@ export class PaymentRepository implements IPaymentRepository {
|
||||
return Result.wrap(() => this.api.getPlans());
|
||||
}
|
||||
|
||||
/** 获取会员套餐列表。 */
|
||||
async getVipPlans(): Promise<Result<PaymentPlan[]>> {
|
||||
return Result.wrap(async () => {
|
||||
const response = await this.api.getPlans();
|
||||
return response.plans.filter(isVipPaymentPlan);
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取积分套餐列表。 */
|
||||
async getCreditPlans(): Promise<Result<PaymentPlan[]>> {
|
||||
return Result.wrap(async () => {
|
||||
const response = await this.api.getPlans();
|
||||
return response.plans.filter(isCreditPaymentPlan);
|
||||
});
|
||||
}
|
||||
|
||||
/** 创建支付订单。 */
|
||||
async createOrder(
|
||||
planId: string,
|
||||
@@ -54,3 +71,23 @@ export class PaymentRepository implements IPaymentRepository {
|
||||
|
||||
/** 全局单例。 */
|
||||
export const paymentRepository = new PaymentRepository(paymentApi);
|
||||
|
||||
export function isVipPaymentPlan(plan: PaymentPlan): boolean {
|
||||
const orderType = plan.orderType.toLowerCase();
|
||||
const planId = plan.planId.toLowerCase();
|
||||
return orderType.startsWith("vip_") || planId.startsWith("vip_");
|
||||
}
|
||||
|
||||
export function isCreditPaymentPlan(plan: PaymentPlan): boolean {
|
||||
const orderType = plan.orderType.toLowerCase();
|
||||
const planId = plan.planId.toLowerCase();
|
||||
return (
|
||||
plan.dolAmount !== null ||
|
||||
orderType.startsWith("dol_") ||
|
||||
orderType.startsWith("credit_") ||
|
||||
planId.startsWith("dol_") ||
|
||||
planId.startsWith("credit_") ||
|
||||
orderType.includes("credit") ||
|
||||
planId.includes("credit")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ const PaymentPlanWireSchema = z.object({
|
||||
original_amount_cents: z.number().nullable().default(null),
|
||||
daily_price_cents: z.number().nullable().default(null),
|
||||
currency: z.string(),
|
||||
pricing_tier: z.string(),
|
||||
vip_days: z.number().nullable(),
|
||||
dol_amount: z.number().nullable(),
|
||||
});
|
||||
@@ -28,6 +29,7 @@ export const PaymentPlanSchema = z
|
||||
original_amount_cents: data.originalAmountCents,
|
||||
daily_price_cents: data.dailyPriceCents,
|
||||
currency: data.currency,
|
||||
pricing_tier: data.pricingTier,
|
||||
vip_days: data.vipDays,
|
||||
dol_amount: data.dolAmount,
|
||||
};
|
||||
@@ -42,6 +44,7 @@ export const PaymentPlanSchema = z
|
||||
originalAmountCents: data.original_amount_cents,
|
||||
dailyPriceCents: data.daily_price_cents,
|
||||
currency: data.currency,
|
||||
pricingTier: data.pricing_tier,
|
||||
vipDays: data.vip_days,
|
||||
dolAmount: data.dol_amount,
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user