feat: 登陆付款mock添加
This commit is contained in:
@@ -140,14 +140,14 @@ export const authHandlers = [
|
||||
|
||||
console.log('[Mock] 生成微信二维码:', { sessionId, authUrl });
|
||||
|
||||
// 10秒后自动模拟扫码(方便测试)
|
||||
// 3秒后自动模拟扫码(方便测试,已缩短延迟)
|
||||
setTimeout(() => {
|
||||
const session = mockWechatSessions.get(sessionId);
|
||||
if (session && session.status === 'waiting') {
|
||||
session.status = 'scanned';
|
||||
console.log(`[Mock] 模拟用户扫码: ${sessionId}`);
|
||||
|
||||
// 再过5秒自动确认登录
|
||||
// 再过2秒自动确认登录
|
||||
setTimeout(() => {
|
||||
const session2 = mockWechatSessions.get(sessionId);
|
||||
if (session2 && session2.status === 'scanned') {
|
||||
@@ -160,13 +160,19 @@ export const authHandlers = [
|
||||
phone: null,
|
||||
email: null,
|
||||
has_wechat: true,
|
||||
created_at: new Date().toISOString()
|
||||
created_at: new Date().toISOString(),
|
||||
// 添加默认订阅信息
|
||||
subscription_type: 'free',
|
||||
subscription_status: 'active',
|
||||
subscription_end_date: null,
|
||||
is_subscription_active: true,
|
||||
subscription_days_left: 0
|
||||
};
|
||||
console.log(`[Mock] 模拟用户确认登录: ${sessionId}`, session2.user);
|
||||
}
|
||||
}, 5000);
|
||||
}, 2000);
|
||||
}
|
||||
}, 10000);
|
||||
}, 3000);
|
||||
|
||||
return HttpResponse.json({
|
||||
code: 0,
|
||||
@@ -334,3 +340,90 @@ export const authHandlers = [
|
||||
});
|
||||
})
|
||||
];
|
||||
|
||||
// ==================== Mock 调试工具(仅开发环境) ====================
|
||||
|
||||
/**
|
||||
* 暴露全局API,方便手动触发微信扫码模拟
|
||||
* 使用方式:
|
||||
* 1. 浏览器控制台输入:window.mockWechatScan()
|
||||
* 2. 或者在组件中调用:window.mockWechatScan(sessionId)
|
||||
*/
|
||||
if (process.env.NODE_ENV === 'development' || process.env.REACT_APP_ENABLE_MOCK === 'true') {
|
||||
window.mockWechatScan = (sessionId) => {
|
||||
// 如果没有传入sessionId,尝试获取最新的session
|
||||
let targetSessionId = sessionId;
|
||||
|
||||
if (!targetSessionId) {
|
||||
// 获取最新创建的session
|
||||
const sessions = Array.from(mockWechatSessions.entries());
|
||||
if (sessions.length === 0) {
|
||||
console.warn('[Mock API] 没有活跃的微信session,请先获取二维码');
|
||||
return false;
|
||||
}
|
||||
// 按创建时间排序,获取最新的
|
||||
const latestSession = sessions.sort((a, b) => b[1].createdAt - a[1].createdAt)[0];
|
||||
targetSessionId = latestSession[0];
|
||||
}
|
||||
|
||||
const session = mockWechatSessions.get(targetSessionId);
|
||||
|
||||
if (!session) {
|
||||
console.error('[Mock API] Session不存在:', targetSessionId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (session.status !== 'waiting') {
|
||||
console.warn('[Mock API] Session状态不是waiting,当前状态:', session.status);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 立即触发扫码
|
||||
session.status = 'scanned';
|
||||
console.log(`[Mock API] ✅ 模拟扫码成功: ${targetSessionId}`);
|
||||
|
||||
// 1秒后自动确认登录
|
||||
setTimeout(() => {
|
||||
const session2 = mockWechatSessions.get(targetSessionId);
|
||||
if (session2 && session2.status === 'scanned') {
|
||||
session2.status = 'confirmed';
|
||||
session2.user = {
|
||||
id: 999,
|
||||
nickname: '微信测试用户',
|
||||
wechat_openid: 'mock_openid_' + targetSessionId,
|
||||
avatar_url: 'https://i.pravatar.cc/150?img=99',
|
||||
phone: null,
|
||||
email: null,
|
||||
has_wechat: true,
|
||||
created_at: new Date().toISOString(),
|
||||
subscription_type: 'free',
|
||||
subscription_status: 'active',
|
||||
subscription_end_date: null,
|
||||
is_subscription_active: true,
|
||||
subscription_days_left: 0
|
||||
};
|
||||
console.log(`[Mock API] ✅ 模拟确认登录: ${targetSessionId}`, session2.user);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// 暴露获取当前sessions的方法(调试用)
|
||||
window.getMockWechatSessions = () => {
|
||||
const sessions = Array.from(mockWechatSessions.entries()).map(([id, session]) => ({
|
||||
sessionId: id,
|
||||
status: session.status,
|
||||
createdAt: new Date(session.createdAt).toLocaleString(),
|
||||
hasUser: !!session.user
|
||||
}));
|
||||
console.table(sessions);
|
||||
return sessions;
|
||||
};
|
||||
|
||||
console.log('%c[Mock API] 微信登录调试工具已加载', 'color: #00D084; font-weight: bold');
|
||||
console.log('%c使用方法:', 'color: #666');
|
||||
console.log(' window.mockWechatScan() - 触发最新session的扫码');
|
||||
console.log(' window.mockWechatScan(sessionId) - 触发指定session的扫码');
|
||||
console.log(' window.getMockWechatSessions() - 查看所有活跃的sessions');
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { authHandlers } from './auth';
|
||||
import { accountHandlers } from './account';
|
||||
import { simulationHandlers } from './simulation';
|
||||
import { eventHandlers } from './event';
|
||||
import { paymentHandlers } from './payment';
|
||||
|
||||
// 可以在这里添加更多的 handlers
|
||||
// import { userHandlers } from './user';
|
||||
@@ -14,5 +15,6 @@ export const handlers = [
|
||||
...accountHandlers,
|
||||
...simulationHandlers,
|
||||
...eventHandlers,
|
||||
...paymentHandlers,
|
||||
// ...userHandlers,
|
||||
];
|
||||
|
||||
233
src/mocks/handlers/payment.js
Normal file
233
src/mocks/handlers/payment.js
Normal file
@@ -0,0 +1,233 @@
|
||||
// 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() - 查看所有模拟订单');
|
||||
}
|
||||
Reference in New Issue
Block a user