-
Notifications
You must be signed in to change notification settings - Fork 54.3k
fix(hooks): 修复 WebUI 首页股票分析时,切换其他频道再返回首页,股票分析进度停滞的问题 #1207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f09942f
fix(hooks): 同步API中的活动任务以修复组件卸载时的状态不一致
DengGuiXing 32ff14f
feat(mx): 集成东方财富妙想API并新增AI选股功能
DengGuiXing 92996ae
Remove specific files from .gitignore
BigRou b73495e
refactor(screen): 实现AI选股页面状态管理与界面中文化优化
DengGuiXing a349455
Merge branch 'main' of https://github.com/BigRou/daily_stock_analysis
DengGuiXing 2f66923
feat(mx): 集成东方财富妙想API并新增AI选股功能
DengGuiXing File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # -*- coding: utf-8 -*- | ||
| """ | ||
| =================================== | ||
| AI 选股 API 端点(基于东方财富妙想智能选股) | ||
| =================================== | ||
|
|
||
| 职责: | ||
| 1. 接收自然语言选股条件 | ||
| 2. 复用 miaoxiang_tools 中的 smart_stock_screen 实现 | ||
| 3. 返回结构化选股结果 | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| import logging | ||
| from typing import Any, Dict, List, Optional | ||
|
|
||
| from fastapi import APIRouter, HTTPException | ||
| from pydantic import BaseModel, Field | ||
|
|
||
| from src.agent.tools.miaoxiang_tools import _handle_smart_stock_screen | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
| router = APIRouter() | ||
|
|
||
|
|
||
| class ScreenQueryRequest(BaseModel): | ||
| """AI 选股请求""" | ||
| query: str = Field(..., min_length=1, max_length=500, description="自然语言选股条件,如 '今天涨幅超过5%的A股'") | ||
|
|
||
|
|
||
| class ScreenQueryResponse(BaseModel): | ||
| """AI 选股响应""" | ||
| success: bool | ||
| query: str | ||
| results_count: int = 0 | ||
| returned_count: int = 0 | ||
| data_source: Optional[str] = None | ||
| results: List[Dict[str, Any]] = Field(default_factory=list) | ||
| message: Optional[str] = None | ||
| error: Optional[str] = None | ||
|
|
||
|
|
||
| @router.post( | ||
| "/query", | ||
| response_model=ScreenQueryResponse, | ||
| summary="AI 智能选股", | ||
| description="通过自然语言条件调用东方财富妙想 API 筛选股票。需配置 MX_APIKEY。", | ||
| ) | ||
| def screen_query(payload: ScreenQueryRequest) -> ScreenQueryResponse: | ||
| query = payload.query.strip() | ||
| if not query: | ||
| raise HTTPException(status_code=400, detail="选股条件不能为空") | ||
|
|
||
| logger.info("AI screen query: %s", query) | ||
| result = _handle_smart_stock_screen(query) | ||
|
|
||
| # Error case: MX_APIKEY not configured or all keys failed | ||
| if "error" in result: | ||
| err_msg = result["error"] | ||
| if "not configured" in err_msg or "MX_APIKEY" in err_msg: | ||
| raise HTTPException( | ||
| status_code=503, | ||
| detail="AI 选股功能未启用:请在设置页配置 MX_APIKEY(东方财富妙想 API Key)。", | ||
| ) | ||
| return ScreenQueryResponse( | ||
| success=False, | ||
| query=query, | ||
| error=err_msg, | ||
| ) | ||
|
|
||
| return ScreenQueryResponse( | ||
| success=bool(result.get("success", False)), | ||
| query=result.get("query", query), | ||
| results_count=int(result.get("results_count", 0) or 0), | ||
| returned_count=int(result.get("returned_count", 0) or 0), | ||
| data_source=result.get("data_source"), | ||
| results=result.get("results", []) or [], | ||
| message=result.get("message"), | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import apiClient from './index'; | ||
| import { toCamelCase } from './utils'; | ||
|
|
||
| // ============ Types ============ | ||
|
|
||
| /** A single stock row returned by the AI screen endpoint. */ | ||
| export type ScreenResultRow = Record<string, string>; | ||
|
|
||
| export interface ScreenResponse { | ||
| success: boolean; | ||
| query: string; | ||
| resultsCount: number; | ||
| returnedCount: number; | ||
| dataSource?: string; | ||
| results: ScreenResultRow[]; | ||
| message?: string; | ||
| error?: string; | ||
| } | ||
|
|
||
| // ============ API ============ | ||
|
|
||
| export const screenApi = { | ||
| /** | ||
| * Trigger an AI-powered stock screen using natural language conditions. | ||
| * @param query Natural language screening query (e.g. "今天涨幅超过5%的A股") | ||
| */ | ||
| query: async (query: string): Promise<ScreenResponse> => { | ||
| const response = await apiClient.post<Record<string, unknown>>( | ||
| '/api/v1/screen/query', | ||
| { query }, | ||
| ); | ||
| return toCamelCase<ScreenResponse>(response.data); | ||
| }, | ||
| }; | ||
|
|
||
| export default screenApi; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
analysisApi.getTasks({ limit: 50 })returns only the newest tasks regardless of status, soserverActiveIdscan be incomplete when many recent completed/failed tasks exist. In that case this loop removes still-running tasks fromactiveTasks, andremoveTaskmarks them dismissed instockPoolStore, so later SSEtask_progress/task_startedupdates are ignored and the UI can permanently lose in-flight task progress after channel switches. Restrict this reconciliation to a server response that is guaranteed to include all active tasks (e.g. status filter for pending/processing without truncating them).Useful? React with 👍 / 👎.