feat: 充值页面 + 订单明细页面 + 页面调度器增强 (0.0.20)

新增页面:
  - RechargePage — 积分充值表单(预设金额/自定义金额/支付宝/协议勾选)
    + 支付状态跟踪(form/pending/paid/expired/failed 五阶段)
    + 订单状态轮询(3s 间隔,终态自动停止)
    + PAGE_LOCK 事件(待支付时禁止关闭 Modal)
  - OrdersPage — 订单明细列表(状态筛选 + 分页 + 继续支付)
    + Segmented 状态 Tab(全部/待支付/已支付/已过期/失败)
    + 待支付订单"继续支付"按钮

  事件总线增强:
  - 新增 EVENTS.CLOSE_PAGE — 页面内部关闭容器
  - 新增 EVENTS.PAGE_LOCK — 锁定/解锁容器关闭(防止操作中断)

  PageDispatcher 增强:
  - 注册 RechargePage(/recharge)和 OrdersPage(/orders)
  - 响应 CLOSE_PAGE / PAGE_LOCK 事件
  - Modal/Drawer 锁定态下禁用遮罩关闭

  支付 API 模块:
  - PaymentAPI.createOrder / getOrdersListInfo / getOrderInfo
  - 完整类型定义(请求/响应体、状态常量、中文映射)

  杂项:
  - 导航栏"充值积分"→"充值"(精简)
This commit is contained in:
2026-06-15 15:08:05 +08:00
parent 4472d406d9
commit 06e6486aa3
7 changed files with 984 additions and 6 deletions

View File

@@ -0,0 +1,99 @@
import { get, post } from '@/services/request';
export const PAYMENT_METHODS = {
Alipay: 'alipay',
WeChat: 'wechat',
Mock: "mock"
} as const;
export type PaymentMethod = typeof PAYMENT_METHODS[keyof typeof PAYMENT_METHODS];
export type AvailablePaymentMethod = typeof PAYMENT_METHODS.Alipay;
export interface CreateOrderRequestBody {
amount_cent: number,
payment_channel: AvailablePaymentMethod
}
export const PAYMENT_STATUS = {
Pending: 'pending', // 待支付
Paid: 'paid', // 已支付
Expired: 'expired', // 已过期
Failed: 'failed', // 支付失败
} as const;
export type PaymentStatus = typeof PAYMENT_STATUS[keyof typeof PAYMENT_STATUS];
// 中文映射表
export const PAYMENT_STATUS_TEXT_MAP: Record<PaymentStatus, string> = {
[PAYMENT_STATUS.Pending]: '待支付',
[PAYMENT_STATUS.Paid]: '已支付',
[PAYMENT_STATUS.Expired]: '已过期',
[PAYMENT_STATUS.Failed]: '支付失败',
};
// 辅助函数:根据状态获取中文
export function getPaymentStatusText(status: PaymentStatus): string {
return PAYMENT_STATUS_TEXT_MAP[status];
}
export interface CreateOrderResponseBody {
id: string,
user_id: string,
amount_cent: number,
status: PaymentStatus,
payment_channel: AvailablePaymentMethod,
out_trade_no: string,
transaction_id: string,
pay_url: string,
expires_at: Date,
paid_at: Date,
created_at: Date,
}
export interface OrderListRequestParam {
status?: PaymentStatus,
page: number,
page_size: number,
}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface OrderListResponseBody extends CreateOrderResponseBody {
}
export interface OrderInfoRequestParam {
order_id: string,
}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface OrderInfoResponseBody extends CreateOrderResponseBody {
}
const PaymentUrlObj = {
createOrder: "/api/v1/payments/orders",
getOrderList: "/api/v1/payments/orders",
getOrderInfo: "/api/v1/payments/orders/{order_id}",
};
// ============================================================
// 调用方式PaymentAPI.createOrder() / PaymentAPI.getOrdersListInfo() 等
// ============================================================
export class PaymentAPI {
/** 创建支付订单 */
static async createOrder(body: CreateOrderRequestBody): Promise<CreateOrderResponseBody> {
return await post<CreateOrderResponseBody>(PaymentUrlObj.createOrder, body);
}
/** 获取订单列表(支持按状态筛选 + 分页) */
static async getOrdersListInfo(param: OrderListRequestParam, signal?: AbortSignal): Promise<OrderListResponseBody[]> {
return await get<OrderListResponseBody[]>(PaymentUrlObj.getOrderList, param as unknown as Record<string, unknown>, { signal });
}
/** 获取单个订单详情 */
static async getOrderInfo(param: OrderInfoRequestParam): Promise<OrderInfoResponseBody> {
const url = PaymentUrlObj.getOrderInfo.replace('{order_id}', param.order_id);
return await get<OrderInfoResponseBody>(url);
}
}