From f8bb46ae6462dc9a33aca90c7fe2f7ebc7589f92 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Mon, 24 Nov 2025 16:46:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0mock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mocks/handlers/agent.js | 233 ++++++++++++++++++++++++++++++++++++ src/mocks/handlers/index.js | 2 + 2 files changed, 235 insertions(+) create mode 100644 src/mocks/handlers/agent.js diff --git a/src/mocks/handlers/agent.js b/src/mocks/handlers/agent.js new file mode 100644 index 00000000..5bac63e1 --- /dev/null +++ b/src/mocks/handlers/agent.js @@ -0,0 +1,233 @@ +// src/mocks/handlers/agent.js +// Agent Chat API Mock Handlers + +import { http, HttpResponse, delay } from 'msw'; + +// 模拟会话数据 +const mockSessions = [ + { + session_id: 'session-001', + title: '贵州茅台投资分析', + created_at: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), + timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), + message_count: 15, + }, + { + session_id: 'session-002', + title: '新能源板块研究', + created_at: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(), + timestamp: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(), + message_count: 8, + }, + { + session_id: 'session-003', + title: '半导体行业分析', + created_at: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), + timestamp: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(), + message_count: 12, + }, +]; + +// 模拟历史消息数据 +const mockHistory = { + 'session-001': [ + { + message_type: 'user', + message: '分析一下贵州茅台的投资价值', + timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), + plan: null, + steps: null, + }, + { + message_type: 'assistant', + message: + '# 贵州茅台投资价值分析\n\n根据最新数据,贵州茅台(600519.SH)具有以下投资亮点:\n\n## 基本面分析\n- **营收增长**:2024年Q3营收同比增长12.5%\n- **净利润率**:保持在50%以上的高水平\n- **ROE**:连续10年超过20%\n\n## 估值分析\n- **PE(TTM)**:35.6倍,略高于历史中位数\n- **PB**:10.2倍,处于合理区间\n\n## 投资建议\n建议关注价格回调机会,长期配置价值显著。', + timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000 + 5000).toISOString(), + plan: JSON.stringify({ + goal: '分析贵州茅台的投资价值', + steps: [ + { step: 1, action: '获取贵州茅台最新股价和财务数据', reasoning: '需要基础数据支持分析' }, + { step: 2, action: '分析公司基本面和盈利能力', reasoning: '评估公司质量' }, + { step: 3, action: '对比行业估值水平', reasoning: '判断估值合理性' }, + { step: 4, action: '给出投资建议', reasoning: '综合判断投资价值' }, + ], + }), + steps: JSON.stringify([ + { + tool: 'get_stock_info', + status: 'success', + result: '获取到贵州茅台最新数据:股价1850元,市值2.3万亿', + }, + { + tool: 'analyze_financials', + status: 'success', + result: '财务分析完成:营收增长稳健,利润率行业领先', + }, + ]), + }, + ], +}; + +// 生成模拟的 Agent 响应 +function generateAgentResponse(message, sessionId) { + const responses = { + 包含: { + 贵州茅台: { + plan: { + goal: '分析贵州茅台相关信息', + steps: [ + { step: 1, action: '搜索贵州茅台最新新闻', reasoning: '了解最新动态' }, + { step: 2, action: '获取股票实时行情', reasoning: '查看当前价格走势' }, + { step: 3, action: '分析财务数据', reasoning: '评估基本面' }, + { step: 4, action: '生成投资建议', reasoning: '综合判断' }, + ], + }, + step_results: [ + { + tool: 'search_news', + status: 'success', + result: '找到5条相关新闻:茅台Q3业绩超预期...', + }, + { + tool: 'get_stock_quote', + status: 'success', + result: '当前价格:1850元,涨幅:+2.3%', + }, + { + tool: 'analyze_financials', + status: 'success', + result: 'ROE: 25.6%, 净利润率: 52.3%', + }, + ], + final_summary: + '# 贵州茅台分析报告\n\n## 最新动态\n茅台Q3业绩超预期,营收增长稳健。\n\n## 行情分析\n当前价格1850元,今日上涨2.3%,成交量活跃。\n\n## 财务表现\n- ROE: 25.6%(行业领先)\n- 净利润率: 52.3%(极高水平)\n- 营收增长: 12.5% YoY\n\n## 投资建议\n**推荐关注**:基本面优秀,估值合理,建议逢低布局。', + }, + 新能源: { + plan: { + goal: '分析新能源行业', + steps: [ + { step: 1, action: '搜索新能源行业新闻', reasoning: '了解行业动态' }, + { step: 2, action: '获取新能源概念股', reasoning: '找到相关标的' }, + { step: 3, action: '分析行业趋势', reasoning: '判断投资机会' }, + ], + }, + step_results: [ + { + tool: 'search_news', + status: 'success', + result: '新能源政策利好频出,行业景气度提升', + }, + { + tool: 'get_concept_stocks', + status: 'success', + result: '新能源板块共182只个股,今日平均涨幅3.2%', + }, + ], + final_summary: + '# 新能源行业分析\n\n## 行业动态\n政策利好频出,行业景气度持续提升。\n\n## 板块表现\n新能源板块今日强势上涨,平均涨幅3.2%。\n\n## 投资机会\n建议关注龙头企业和细分赛道领导者。', + }, + }, + 默认: { + plan: { + goal: '回答用户问题', + steps: [ + { step: 1, action: '理解用户意图', reasoning: '准确把握需求' }, + { step: 2, action: '搜索相关信息', reasoning: '获取数据支持' }, + { step: 3, action: '生成回复', reasoning: '提供专业建议' }, + ], + }, + step_results: [ + { + tool: 'search_related_info', + status: 'success', + result: '已找到相关信息', + }, + ], + final_summary: `我已经收到您的问题:"${message}"\n\n作为您的 AI 投研助手,我可以帮您:\n- 📊 分析股票基本面和技术面\n- 🔥 追踪市场热点和板块动态\n- 📈 研究行业趋势和投资机会\n- 📰 汇总最新财经新闻和研报\n\n请告诉我您想了解哪方面的信息?`, + }, + }; + + // 根据关键词匹配响应 + for (const keyword in responses.包含) { + if (message.includes(keyword)) { + return responses.包含[keyword]; + } + } + + return responses.默认; +} + +// Agent Chat API Handlers +export const agentHandlers = [ + // POST /mcp/agent/chat - 发送消息 + http.post('/mcp/agent/chat', async ({ request }) => { + await delay(800); // 模拟网络延迟 + + const body = await request.json(); + const { message, session_id, user_id, subscription_type } = body; + + // 模拟权限检查(仅 max 用户可用) + if (subscription_type !== 'max') { + return HttpResponse.json( + { + success: false, + error: '很抱歉,「价小前投研」功能仅对 Max 订阅用户开放。请升级您的订阅以使用此功能。', + }, + { status: 403 } + ); + } + + // 生成或使用现有 session_id + const responseSessionId = session_id || `session-${Date.now()}`; + + // 根据消息内容生成响应 + const response = generateAgentResponse(message, responseSessionId); + + return HttpResponse.json({ + success: true, + message: '处理成功', + session_id: responseSessionId, + plan: response.plan, + steps: response.step_results, + final_answer: response.final_summary, + metadata: { + model: body.model || 'kimi-k2-thinking', + timestamp: new Date().toISOString(), + }, + }); + }), + + // GET /mcp/agent/sessions - 获取会话列表 + http.get('/mcp/agent/sessions', async ({ request }) => { + await delay(300); + + const url = new URL(request.url); + const userId = url.searchParams.get('user_id'); + const limit = parseInt(url.searchParams.get('limit') || '50'); + + // 返回模拟的会话列表 + const sessions = mockSessions.slice(0, limit); + + return HttpResponse.json({ + success: true, + data: sessions, + count: sessions.length, + }); + }), + + // GET /mcp/agent/history/:session_id - 获取会话历史 + http.get('/mcp/agent/history/:session_id', async ({ params }) => { + await delay(400); + + const { session_id } = params; + + // 返回模拟的历史消息 + const history = mockHistory[session_id] || []; + + return HttpResponse.json({ + success: true, + data: history, + count: history.length, + }); + }), +]; diff --git a/src/mocks/handlers/index.js b/src/mocks/handlers/index.js index 41699941..361b5852 100644 --- a/src/mocks/handlers/index.js +++ b/src/mocks/handlers/index.js @@ -15,6 +15,7 @@ import { financialHandlers } from './financial'; import { limitAnalyseHandlers } from './limitAnalyse'; import { posthogHandlers } from './posthog'; import { externalHandlers } from './external'; +import { agentHandlers } from './agent'; // 可以在这里添加更多的 handlers // import { userHandlers } from './user'; @@ -34,5 +35,6 @@ export const handlers = [ ...limitAnalyseHandlers, ...posthogHandlers, ...externalHandlers, + ...agentHandlers, // ...userHandlers, ]; From 887525197ace80c4032cb793f91ba48414b2ebfb Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Mon, 24 Nov 2025 16:51:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20StockChartAntdModal=20UI=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/StockChart/StockChartAntdModal.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/StockChart/StockChartAntdModal.js b/src/components/StockChart/StockChartAntdModal.js index b3efef59..626b9030 100644 --- a/src/components/StockChart/StockChartAntdModal.js +++ b/src/components/StockChart/StockChartAntdModal.js @@ -507,8 +507,9 @@ const StockChartAntdModal = ({ footer={null} onCancel={onCancel} width={width} - style={{ position: fixed ? 'fixed' : 'absolute', left: fixed ? 50 : 0, top: fixed ? 50 : 80, zIndex: 2000 }} - mask={false} + centered + zIndex={2500} + mask={true} destroyOnClose={true} bodyStyle={{ maxHeight: 'calc(90vh - 120px)', overflowY: 'auto', padding: '16px' }} >