feat: 添加二级导航,解决二级导航的展示问题
This commit is contained in:
374
src/mocks/handlers/simulation.js
Normal file
374
src/mocks/handlers/simulation.js
Normal file
@@ -0,0 +1,374 @@
|
||||
// src/mocks/handlers/simulation.js
|
||||
import { http, HttpResponse, delay } from 'msw';
|
||||
import { getCurrentUser } from '../data/users';
|
||||
|
||||
// 模拟网络延迟(毫秒)
|
||||
const NETWORK_DELAY = 300;
|
||||
|
||||
// 模拟交易账户数据
|
||||
let mockTradingAccount = {
|
||||
account_id: 'sim_001',
|
||||
account_name: '模拟交易账户',
|
||||
initial_capital: 1000000,
|
||||
available_cash: 850000,
|
||||
frozen_cash: 0,
|
||||
position_value: 150000,
|
||||
total_assets: 1000000,
|
||||
total_profit: 0,
|
||||
total_profit_rate: 0,
|
||||
daily_profit: 0,
|
||||
daily_profit_rate: 0,
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
updated_at: new Date().toISOString()
|
||||
};
|
||||
|
||||
// 模拟持仓数据
|
||||
let mockPositions = [
|
||||
{
|
||||
id: 1,
|
||||
stock_code: '600036',
|
||||
stock_name: '招商银行',
|
||||
position_qty: 1000,
|
||||
available_qty: 1000,
|
||||
frozen_qty: 0,
|
||||
avg_cost: 42.50,
|
||||
current_price: 42.80,
|
||||
market_value: 42800,
|
||||
profit: 300,
|
||||
profit_rate: 0.71,
|
||||
today_profit: 100,
|
||||
today_profit_rate: 0.23,
|
||||
updated_at: new Date().toISOString()
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
stock_code: '000001',
|
||||
stock_name: '平安银行',
|
||||
position_qty: 2000,
|
||||
available_qty: 2000,
|
||||
frozen_qty: 0,
|
||||
avg_cost: 12.30,
|
||||
current_price: 12.50,
|
||||
market_value: 25000,
|
||||
profit: 400,
|
||||
profit_rate: 1.63,
|
||||
today_profit: -50,
|
||||
today_profit_rate: -0.20,
|
||||
updated_at: new Date().toISOString()
|
||||
}
|
||||
];
|
||||
|
||||
// 模拟交易历史
|
||||
let mockOrders = [
|
||||
{
|
||||
id: 1,
|
||||
order_no: 'ORD20240101001',
|
||||
stock_code: '600036',
|
||||
stock_name: '招商银行',
|
||||
order_type: 'BUY',
|
||||
price_type: 'MARKET',
|
||||
order_price: 42.50,
|
||||
order_qty: 1000,
|
||||
filled_qty: 1000,
|
||||
filled_price: 42.50,
|
||||
filled_amount: 42500,
|
||||
commission: 12.75,
|
||||
stamp_tax: 0,
|
||||
transfer_fee: 0.42,
|
||||
total_fee: 13.17,
|
||||
status: 'FILLED',
|
||||
reject_reason: null,
|
||||
order_time: '2024-01-15T09:30:00Z',
|
||||
filled_time: '2024-01-15T09:30:05Z'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
order_no: 'ORD20240102001',
|
||||
stock_code: '000001',
|
||||
stock_name: '平安银行',
|
||||
order_type: 'BUY',
|
||||
price_type: 'LIMIT',
|
||||
order_price: 12.30,
|
||||
order_qty: 2000,
|
||||
filled_qty: 2000,
|
||||
filled_price: 12.30,
|
||||
filled_amount: 24600,
|
||||
commission: 7.38,
|
||||
stamp_tax: 0,
|
||||
transfer_fee: 0.25,
|
||||
total_fee: 7.63,
|
||||
status: 'FILLED',
|
||||
reject_reason: null,
|
||||
order_time: '2024-01-16T10:15:00Z',
|
||||
filled_time: '2024-01-16T10:15:10Z'
|
||||
}
|
||||
];
|
||||
|
||||
export const simulationHandlers = [
|
||||
// ==================== 获取模拟账户信息 ====================
|
||||
http.get('/api/simulation/account', async () => {
|
||||
await delay(NETWORK_DELAY);
|
||||
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
// 未登录时返回401
|
||||
if (!currentUser) {
|
||||
return HttpResponse.json({
|
||||
success: false,
|
||||
error: '未登录'
|
||||
}, { status: 401 });
|
||||
}
|
||||
|
||||
console.log('[Mock] 获取模拟账户信息:', currentUser);
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: mockTradingAccount
|
||||
});
|
||||
}),
|
||||
|
||||
// ==================== 获取持仓列表 ====================
|
||||
http.get('/api/simulation/positions', async () => {
|
||||
await delay(NETWORK_DELAY);
|
||||
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
if (!currentUser) {
|
||||
return HttpResponse.json({
|
||||
success: false,
|
||||
error: '未登录'
|
||||
}, { status: 401 });
|
||||
}
|
||||
|
||||
console.log('[Mock] 获取持仓列表');
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: mockPositions
|
||||
});
|
||||
}),
|
||||
|
||||
// ==================== 获取交易订单历史 ====================
|
||||
http.get('/api/simulation/orders', async ({ request }) => {
|
||||
await delay(NETWORK_DELAY);
|
||||
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
if (!currentUser) {
|
||||
return HttpResponse.json({
|
||||
success: false,
|
||||
error: '未登录'
|
||||
}, { status: 401 });
|
||||
}
|
||||
|
||||
const url = new URL(request.url);
|
||||
const limit = parseInt(url.searchParams.get('limit') || '100');
|
||||
|
||||
console.log('[Mock] 获取交易订单历史, limit:', limit);
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: mockOrders.slice(0, limit)
|
||||
});
|
||||
}),
|
||||
|
||||
// ==================== 下单(买入/卖出)====================
|
||||
http.post('/api/simulation/place-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();
|
||||
console.log('[Mock] 下单请求:', body);
|
||||
|
||||
const { stock_code, order_type, order_qty, price_type } = body;
|
||||
|
||||
// 生成订单号
|
||||
const orderNo = 'ORD' + Date.now();
|
||||
|
||||
// 创建新订单
|
||||
const newOrder = {
|
||||
id: mockOrders.length + 1,
|
||||
order_no: orderNo,
|
||||
stock_code: stock_code,
|
||||
stock_name: '模拟股票', // 实际应该查询股票名称
|
||||
order_type: order_type,
|
||||
price_type: price_type,
|
||||
order_price: 0,
|
||||
order_qty: order_qty,
|
||||
filled_qty: order_qty,
|
||||
filled_price: 0,
|
||||
filled_amount: 0,
|
||||
commission: 0,
|
||||
stamp_tax: 0,
|
||||
transfer_fee: 0,
|
||||
total_fee: 0,
|
||||
status: 'FILLED',
|
||||
reject_reason: null,
|
||||
order_time: new Date().toISOString(),
|
||||
filled_time: new Date().toISOString()
|
||||
};
|
||||
|
||||
// 添加到订单列表
|
||||
mockOrders.unshift(newOrder);
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
message: '下单成功',
|
||||
data: {
|
||||
order_no: orderNo,
|
||||
order_id: newOrder.id
|
||||
}
|
||||
});
|
||||
}),
|
||||
|
||||
// ==================== 撤销订单 ====================
|
||||
http.post('/api/simulation/cancel-order/:orderId', async ({ params }) => {
|
||||
await delay(NETWORK_DELAY);
|
||||
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
if (!currentUser) {
|
||||
return HttpResponse.json({
|
||||
success: false,
|
||||
error: '未登录'
|
||||
}, { status: 401 });
|
||||
}
|
||||
|
||||
const { orderId } = params;
|
||||
console.log('[Mock] 撤销订单:', orderId);
|
||||
|
||||
// 查找并更新订单状态
|
||||
const order = mockOrders.find(o => o.id.toString() === orderId || o.order_no === orderId);
|
||||
if (order) {
|
||||
order.status = 'CANCELLED';
|
||||
}
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
message: '撤单成功'
|
||||
});
|
||||
}),
|
||||
|
||||
// ==================== 获取资产统计数据 ====================
|
||||
http.get('/api/simulation/statistics', async ({ request }) => {
|
||||
await delay(NETWORK_DELAY);
|
||||
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
if (!currentUser) {
|
||||
return HttpResponse.json({
|
||||
success: false,
|
||||
error: '未登录'
|
||||
}, { status: 401 });
|
||||
}
|
||||
|
||||
const url = new URL(request.url);
|
||||
const days = parseInt(url.searchParams.get('days') || '30');
|
||||
|
||||
console.log('[Mock] 获取资产统计, days:', days);
|
||||
|
||||
// 生成模拟的资产历史数据
|
||||
const dailyReturns = [];
|
||||
const baseAssets = 1000000;
|
||||
|
||||
for (let i = 0; i < days; i++) {
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - (days - 1 - i));
|
||||
|
||||
// 生成随机波动
|
||||
const randomChange = (Math.random() - 0.5) * 0.02; // ±1%
|
||||
const assets = baseAssets * (1 + randomChange * i / days);
|
||||
|
||||
dailyReturns.push({
|
||||
date: date.toISOString().split('T')[0],
|
||||
closing_assets: assets,
|
||||
total_assets: assets,
|
||||
daily_profit: assets - baseAssets,
|
||||
daily_profit_rate: ((assets - baseAssets) / baseAssets * 100).toFixed(2)
|
||||
});
|
||||
}
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: {
|
||||
daily_returns: dailyReturns,
|
||||
summary: {
|
||||
total_profit: 0,
|
||||
total_profit_rate: 0,
|
||||
win_rate: 50,
|
||||
max_drawdown: -5.2
|
||||
}
|
||||
}
|
||||
});
|
||||
}),
|
||||
|
||||
// ==================== 获取交易记录 ====================
|
||||
http.get('/api/simulation/transactions', async ({ request }) => {
|
||||
await delay(NETWORK_DELAY);
|
||||
|
||||
const currentUser = getCurrentUser();
|
||||
|
||||
if (!currentUser) {
|
||||
return HttpResponse.json({
|
||||
success: false,
|
||||
error: '未登录'
|
||||
}, { status: 401 });
|
||||
}
|
||||
|
||||
const url = new URL(request.url);
|
||||
const limit = parseInt(url.searchParams.get('limit') || '50');
|
||||
|
||||
console.log('[Mock] 获取交易记录, limit:', limit);
|
||||
|
||||
// 返回已成交的订单作为交易记录
|
||||
const transactions = mockOrders
|
||||
.filter(order => order.status === 'FILLED')
|
||||
.slice(0, limit);
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: transactions
|
||||
});
|
||||
}),
|
||||
|
||||
// ==================== 搜索股票 ====================
|
||||
http.get('/api/stocks/search', async ({ request }) => {
|
||||
await delay(200);
|
||||
|
||||
const url = new URL(request.url);
|
||||
const keyword = url.searchParams.get('q') || '';
|
||||
const limit = parseInt(url.searchParams.get('limit') || '10');
|
||||
|
||||
console.log('[Mock] 搜索股票:', keyword);
|
||||
|
||||
// 模拟股票数据
|
||||
const allStocks = [
|
||||
{ stock_code: '000001', stock_name: '平安银行', current_price: 12.50, pinyin_abbr: 'payh', security_type: 'A股', exchange: '深交所' },
|
||||
{ stock_code: '000002', stock_name: '万科A', current_price: 8.32, pinyin_abbr: 'wka', security_type: 'A股', exchange: '深交所' },
|
||||
{ stock_code: '600036', stock_name: '招商银行', current_price: 42.80, pinyin_abbr: 'zsyh', security_type: 'A股', exchange: '上交所' },
|
||||
{ stock_code: '600519', stock_name: '贵州茅台', current_price: 1680.50, pinyin_abbr: 'gzmt', security_type: 'A股', exchange: '上交所' },
|
||||
{ stock_code: '601318', stock_name: '中国平安', current_price: 45.20, pinyin_abbr: 'zgpa', security_type: 'A股', exchange: '上交所' },
|
||||
{ stock_code: '688256', stock_name: '寒武纪', current_price: 1394.94, pinyin_abbr: 'hwj', security_type: 'A股', exchange: '上交所科创板' },
|
||||
];
|
||||
|
||||
// 过滤股票
|
||||
const results = allStocks.filter(stock =>
|
||||
stock.stock_code.includes(keyword) ||
|
||||
stock.stock_name.includes(keyword) ||
|
||||
stock.pinyin_abbr.includes(keyword.toLowerCase())
|
||||
).slice(0, limit);
|
||||
|
||||
return HttpResponse.json({
|
||||
success: true,
|
||||
data: results
|
||||
});
|
||||
})
|
||||
];
|
||||
Reference in New Issue
Block a user