Files
vf_react/src/mocks/handlers/payment.js
2025-10-22 15:36:55 +08:00

234 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/mocks/handlers/payment.js
import { http, HttpResponse, delay } from 'msw';
import { getCurrentUser } from '../data/users';
// 模拟网络延迟(毫秒)
const NETWORK_DELAY = 500;
// 模拟订单数据存储
const mockOrders = new Map();
let orderIdCounter = 1000;
export const paymentHandlers = [
// ==================== 支付订单管理 ====================
// 1. 创建支付订单
http.post('/api/payment/create-order', async ({ request }) => {
await delay(NETWORK_DELAY);
const currentUser = getCurrentUser();
if (!currentUser) {
return HttpResponse.json({
success: false,
error: '未登录'
}, { status: 401 });
}
const body = await request.json();
const { plan_name, billing_cycle } = body;
console.log('[Mock] 创建支付订单:', { plan_name, billing_cycle, user: currentUser.id });
if (!plan_name || !billing_cycle) {
return HttpResponse.json({
success: false,
error: '参数不完整'
}, { status: 400 });
}
// 模拟价格
const prices = {
pro: { monthly: 0.01, yearly: 0.08 },
max: { monthly: 0.1, yearly: 0.8 }
};
const amount = prices[plan_name]?.[billing_cycle] || 0.01;
// 创建订单
const orderId = `ORDER_${orderIdCounter++}_${Date.now()}`;
const order = {
id: orderId,
user_id: currentUser.id,
plan_name,
billing_cycle,
amount,
status: 'pending',
qr_code_url: `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=weixin://wxpay/bizpayurl?pr=mock_${orderId}`,
created_at: new Date().toISOString(),
expires_at: new Date(Date.now() + 30 * 60 * 1000).toISOString() // 30分钟后过期
};
mockOrders.set(orderId, order);
console.log('[Mock] 订单创建成功:', order);
// 模拟5秒后自动支付成功方便测试
setTimeout(() => {
const existingOrder = mockOrders.get(orderId);
if (existingOrder && existingOrder.status === 'pending') {
existingOrder.status = 'paid';
existingOrder.paid_at = new Date().toISOString();
console.log(`[Mock] 订单自动支付成功: ${orderId}`);
}
}, 5000);
return HttpResponse.json({
success: true,
data: order
});
}),
// 2. 查询订单状态
http.get('/api/payment/order-status/:orderId', async ({ params }) => {
await delay(300);
const currentUser = getCurrentUser();
if (!currentUser) {
return HttpResponse.json({
success: false,
error: '未登录'
}, { status: 401 });
}
const { orderId } = params;
const order = mockOrders.get(orderId);
console.log('[Mock] 查询订单状态:', { orderId, found: !!order });
if (!order) {
return HttpResponse.json({
success: false,
error: '订单不存在'
}, { status: 404 });
}
if (order.user_id !== currentUser.id) {
return HttpResponse.json({
success: false,
error: '无权访问此订单'
}, { status: 403 });
}
return HttpResponse.json({
success: true,
data: order
});
}),
// 3. 获取用户订单列表
http.get('/api/payment/orders', async () => {
await delay(NETWORK_DELAY);
const currentUser = getCurrentUser();
if (!currentUser) {
return HttpResponse.json({
success: false,
error: '未登录'
}, { status: 401 });
}
const userOrders = Array.from(mockOrders.values())
.filter(order => order.user_id === currentUser.id)
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
console.log('[Mock] 获取用户订单列表:', { count: userOrders.length });
return HttpResponse.json({
success: true,
data: userOrders
});
}),
// 4. 取消订单
http.post('/api/payment/cancel-order', async ({ request }) => {
await delay(NETWORK_DELAY);
const currentUser = getCurrentUser();
if (!currentUser) {
return HttpResponse.json({
success: false,
error: '未登录'
}, { status: 401 });
}
const body = await request.json();
const { order_id } = body;
const order = mockOrders.get(order_id);
if (!order) {
return HttpResponse.json({
success: false,
error: '订单不存在'
}, { status: 404 });
}
if (order.user_id !== currentUser.id) {
return HttpResponse.json({
success: false,
error: '无权操作此订单'
}, { status: 403 });
}
if (order.status !== 'pending') {
return HttpResponse.json({
success: false,
error: '只能取消待支付的订单'
}, { status: 400 });
}
order.status = 'cancelled';
order.cancelled_at = new Date().toISOString();
console.log('[Mock] 订单已取消:', order_id);
return HttpResponse.json({
success: true,
message: '订单已取消'
});
})
];
// ==================== Mock 调试工具(仅开发环境) ====================
/**
* 暴露全局API方便手动触发支付成功
* 使用方式window.mockPaymentSuccess(orderId)
*/
if (process.env.NODE_ENV === 'development' || process.env.REACT_APP_ENABLE_MOCK === 'true') {
window.mockPaymentSuccess = (orderId) => {
const order = mockOrders.get(orderId);
if (!order) {
console.error('[Mock Payment] 订单不存在:', orderId);
return false;
}
if (order.status !== 'pending') {
console.warn('[Mock Payment] 订单状态不是待支付:', order.status);
return false;
}
order.status = 'paid';
order.paid_at = new Date().toISOString();
console.log('[Mock Payment] ✅ 支付成功:', orderId);
return true;
};
window.getMockOrders = () => {
const orders = Array.from(mockOrders.entries()).map(([id, order]) => ({
orderId: id,
status: order.status,
amount: order.amount,
plan: `${order.plan_name} - ${order.billing_cycle}`,
createdAt: new Date(order.created_at).toLocaleString()
}));
console.table(orders);
return orders;
};
console.log('%c[Mock Payment] 支付调试工具已加载', 'color: #00D084; font-weight: bold');
console.log('%c使用方法:', 'color: #666');
console.log(' window.mockPaymentSuccess(orderId) - 手动触发订单支付成功');
console.log(' window.getMockOrders() - 查看所有模拟订单');
}