diff --git a/.gitignore b/.gitignore index 7d540f3..73e94e2 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ data/ reports/ logs/ tests/ +backend/server.log diff --git a/backend/server.log b/backend/server.log index 5ec8c19..18665e5 100644 --- a/backend/server.log +++ b/backend/server.log @@ -2900,3 +2900,67 @@ JSON_END 2026-01-13 19:40:44,354 - app.clients.bloomberg_client - INFO - ✅ Completed processing for ALC US Equity 2026-01-13 19:40:44,354 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=94, Msg=Bloomberg data sync complete, Progress=90% 2026-01-13 19:40:45,530 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=94, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-13 20:01:59,302 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-13 20:02:05,051 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGenerateContent?alt=sse "HTTP/1.1 200 OK" +2026-01-13 20:03:07,139 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-13 20:03:11,729 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGenerateContent?alt=sse "HTTP/1.1 200 OK" +2026-01-13 20:04:56,927 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-13 20:05:03,581 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGenerateContent?alt=sse "HTTP/1.1 200 OK" +2026-01-13 20:23:36,883 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=95, Msg=正在初始化数据获取..., Progress=0% +2026-01-13 20:23:37,463 - app.services.data_fetcher_service - INFO - 📝 [数据获取] 股票代码格式化: 688029 -> 688029.SH +2026-01-13 20:23:37,463 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=95, Msg=数据获取失败: Data source 'Tushare' not supported in backend., Progress=0% +2026-01-13 20:23:50,636 - app.main - INFO - 🔍 [搜索] 开始搜索股票: 南微医学 +2026-01-13 20:23:50,644 - app.main - INFO - 🤖 [搜索-LLM] 调用 gemini-3-flash-preview 进行股票搜索 +2026-01-13 20:23:50,655 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-13 20:23:56,156 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:generateContent "HTTP/1.1 200 OK" +2026-01-13 20:23:56,178 - app.main - INFO - ✅ [搜索-LLM] 模型响应完成, 耗时: 5.53秒, Tokens: prompt=304, completion=29, total=333 +2026-01-13 20:23:56,179 - app.main - INFO - ✅ [搜索] 搜索完成, 找到 1 个结果, 总耗时: 5.54秒 +2026-01-13 20:24:08,551 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 688029 +2026-01-13 20:24:08,898 - app.services.bloomberg_service - WARNING - No Bloomberg data found for symbol: 688029 +2026-01-13 20:24:11,878 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=正在初始化数据获取..., Progress=0% +2026-01-13 20:24:12,303 - app.clients.bloomberg_client - INFO - Connecting to Jupyter at http://192.168.3.161:8888... +2026-01-13 20:24:12,656 - app.clients.bloomberg_client - INFO - ✅ Authentication successful. +2026-01-13 20:24:12,681 - app.clients.bloomberg_client - INFO - ✅ Found existing kernel: bc27f3b1-b028-434a-99fa-c1cad4495a87 (remote_env) +2026-01-13 20:24:13,733 - app.clients.bloomberg_client - INFO - ✅ WebSocket connected. +2026-01-13 20:24:13,733 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=数据源连接成功, Progress=10% +2026-01-13 20:24:16,282 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=正在连接 Bloomberg 终端..., Progress=20% +2026-01-13 20:24:17,574 - app.clients.bloomberg_client - INFO - 🚀 Starting fetch for: 688029 CH Equity +2026-01-13 20:24:17,575 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=Starting Bloomberg session..., Progress=20% +2026-01-13 20:24:19,299 - app.clients.bloomberg_client - INFO - Using auto-detected currency: CNY +2026-01-13 20:24:19,299 - app.clients.bloomberg_client - INFO - Fetching Basic Data... +2026-01-13 20:24:19,299 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=Fetching Company Basic Info..., Progress=27% +2026-01-13 20:24:21,477 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:22", "currency": "CNY", "indicator": "company_name", "value": "MICRO-TECH NANJING CO LTD-A", "value_date": "2026-01-13 20:24:22"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:22", "currency": "CNY", "indicator": "pe_ratio", "value": "27.159974278374918", "value_date": "2026-01-13 20:24:22"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:22", "currency": "CNY", "indicator": "pb_ratio", "value": "4.086370642415248", "value_date": "2026-01-13 20:24:22"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:22", "currency": "CNY", "indicator": "Rev_Abroad", "value": "49.85044271634609", "value_date": "2026-01-13 20:24:22"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:22", "currency": "CNY", "indicator": "dividend_yield", "value": "1.693384511176338", "value_date": "2026-01-13 20:24:22"}, {"Company_code": "688029 CH Eq +2026-01-13 20:24:21,477 - app.clients.bloomberg_client - INFO - ✅ Parsed 7 items from remote. +2026-01-13 20:24:21,478 - app.clients.bloomberg_client - INFO - DEBUG: basic_data before save: [{'Company_code': '688029 CH Equity', 'update_date': '2026-01-13 20:24:22', 'currency': 'CNY', 'indicator': 'company_name', 'value': 'MICRO-TECH NANJING CO LTD-A', 'value_date': '2026-01-13 20:24:22'}, {'Company_code': '688029 CH Equity', 'update_date': '2026-01-13 20:24:22', 'currency': 'CNY', 'indicator': 'pe_ratio', 'value': '27.159974278374918', 'value_date': '2026-01-13 20:24:22'}, {'Company_code': '688029 CH Equity', 'update_date': '2026-01-13 20:24:22', 'currency': 'CNY', 'indicator': 'pb_ratio', 'value': '4.086370642415248', 'value_date': '2026-01-13 20:24:22'}, {'Company_code': '688029 CH Equity', 'update_date': '2026-01-13 20:24:22', 'currency': 'CNY', 'indicator': 'Rev_Abroad', 'value': '49.85044271634609', 'value_date': '2026-01-13 20:24:22'}, {'Company_code': '688029 CH Equity', 'update_date': '2026-01-13 20:24:22', 'currency': 'CNY', 'indicator': 'dividend_yield', 'value': '1.693384511176338', 'value_date': '2026-01-13 20:24:22'}, {'Company_code': '688029 CH Equity', 'update_date': '2026-01-13 20:24:22', 'currency': 'CNY', 'indicator': 'IPO_date', 'value': '2019-07-22', 'value_date': '2026-01-13 20:24:22'}, {'Company_code': '688029 CH Equity', 'update_date': '2026-01-13 20:24:22', 'currency': 'CNY', 'indicator': 'market_cap', 'value': '16639.525', 'value_date': '2026-01-13 20:24:22'}] +2026-01-13 20:24:23,015 - app.clients.bloomberg_client - INFO - ✅ Saved 7 records to database. +2026-01-13 20:24:23,016 - app.clients.bloomberg_client - INFO - Fetching Currency Data... +2026-01-13 20:24:23,016 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=正在获取货币指标 (CNY)..., Progress=41% +2026-01-13 20:24:24,452 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:23", "currency": "CNY", "indicator": "Revenue", "value": "414.3097", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:23", "currency": "CNY", "indicator": "Net_Income", "value": "-36.4541", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:23", "currency": "CNY", "indicator": "Cash_From_Operating", "value": "59.337", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:23", "currency": "CNY", "indicator": "Capital_Expenditure", "value": "-35.8324", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:23", "currency": "CNY", "indicator": "Free_Cash_Flow", "value": "23.5046", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:23", "currency": "CNY", "indicator": "Dividends +2026-01-13 20:24:24,453 - app.clients.bloomberg_client - INFO - ✅ Parsed 222 items from remote. +2026-01-13 20:24:45,100 - app.clients.bloomberg_client - INFO - ✅ Saved 222 records to database. +2026-01-13 20:24:45,102 - app.clients.bloomberg_client - INFO - Fetching Non-Currency Data... +2026-01-13 20:24:45,102 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=正在获取非货币指标..., Progress=55% +2026-01-13 20:24:46,409 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:45", "currency": "CNY", "indicator": "ROE", "value": "-11.7949", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:45", "currency": "CNY", "indicator": "ROA", "value": "-7.2528", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:45", "currency": "CNY", "indicator": "Gross_Margin", "value": "57.2046", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:45", "currency": "CNY", "indicator": "EBITDA_margin", "value": "-2.426", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:45", "currency": "CNY", "indicator": "Net_Profit_Margin", "value": "-8.7988", "value_date": "2016-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:24:45", "currency": "CNY", "indicator": "Tax_Rate", "value": "0.15", "val +2026-01-13 20:24:46,410 - app.clients.bloomberg_client - INFO - ✅ Parsed 163 items from remote. +2026-01-13 20:25:05,444 - app.clients.bloomberg_client - INFO - ✅ Saved 163 records to database. +2026-01-13 20:25:05,456 - app.clients.bloomberg_client - INFO - Fetching Price Data (Aligned)... +2026-01-13 20:25:05,456 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=正在获取价格指标..., Progress=69% +2026-01-13 20:25:06,884 - app.clients.bloomberg_client - INFO - Found 9 revenue reporting dates. Fetching aligned price data... +2026-01-13 20:25:17,623 - app.clients.bloomberg_client - INFO - REMOTE RAW OUTPUT: JSON_START +[{"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:25:06", "currency": "CNY", "indicator": "Last_Price", "value": "67.59", "value_date": "2024-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:25:06", "currency": "CNY", "indicator": "Market_Cap", "value": "12696.6073", "value_date": "2024-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:25:06", "currency": "CNY", "indicator": "Dividend_Yield", "value": "2.2193", "value_date": "2024-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:25:06", "currency": "CNY", "indicator": "Last_Price", "value": "96.8", "value_date": "2023-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:25:06", "currency": "CNY", "indicator": "Market_Cap", "value": "18183.6304", "value_date": "2023-12-31"}, {"Company_code": "688029 CH Equity", "update_date": "2026-01-13 20:25:06", "currency": "CNY", "indicator": "Dividend_Yield", "value": +2026-01-13 20:25:17,624 - app.clients.bloomberg_client - INFO - ✅ Parsed 17 items from remote. +2026-01-13 20:25:22,020 - app.clients.bloomberg_client - INFO - ✅ Saved 17 records to database. +2026-01-13 20:25:22,026 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=Finalizing data..., Progress=82% +2026-01-13 20:25:24,501 - app.clients.bloomberg_client - INFO - ✅ Cleanup and View Refresh completed. +2026-01-13 20:25:24,502 - app.clients.bloomberg_client - INFO - ✅ Completed processing for 688029 CH Equity +2026-01-13 20:25:24,502 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=Bloomberg data sync complete, Progress=90% +2026-01-13 20:25:25,959 - app.services.data_fetcher_service - INFO - 🔄 [进度更新] ID=96, Msg=Bloomberg 数据同步完成, Progress=100% +2026-01-13 20:26:45,348 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-13 20:26:52,042 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGenerateContent?alt=sse "HTTP/1.1 200 OK" +2026-01-13 20:27:39,016 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-13 20:27:46,782 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGenerateContent?alt=sse "HTTP/1.1 200 OK" +2026-01-13 20:28:32,248 - google_genai.models - INFO - AFC is enabled with max remote calls: 10. +2026-01-13 20:28:39,401 - httpx - INFO - HTTP Request: POST https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:streamGenerateContent?alt=sse "HTTP/1.1 200 OK" diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index ee4bb45..ff4aa7d 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from "react" import { useSearchParams } from "next/navigation" +import { cn } from "@/lib/utils" import { SearchStock } from "@/components/search-stock" import { HistoryList } from "@/components/history-list" import { DataSourceSelector } from "@/components/data-source-selector" @@ -12,7 +13,7 @@ import { AnalysisReport } from "@/components/analysis-report" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" -import { ArrowLeft, Building2, RefreshCw, Loader2, CheckCircle2 } from "lucide-react" +import { ArrowLeft, Building2, RefreshCw, Loader2, CheckCircle2, ChevronLeft, ChevronRight } from "lucide-react" import type { SearchResult } from "@/lib/types" import { useFinancialData } from "@/hooks/use-financial-data" import { Progress } from "@/components/ui/progress" @@ -29,6 +30,7 @@ export default function Home() { // 状态管理 const [selectedCompany, setSelectedCompany] = useState(null) const [selectedDataSource, setSelectedDataSource] = useState("iFinD") + const [isSidebarOpen, setIsSidebarOpen] = useState(true) const [companyId, setCompanyId] = useState(null) const [analysisId, setAnalysisId] = useState(null) const [oneTimeModel, setOneTimeModel] = useState(undefined) @@ -194,17 +196,38 @@ export default function Home() { return (
{/* Sidebar */} - +
+ +
- {/* Main Content Area */} -
- {renderContent()} -
+ {/* Main Content Area Wrapper */} +
+ {/* Sidebar Toggle Button */} + + + {/* Scrollable Content */} +
+ {renderContent()} +
+
) } diff --git a/frontend/src/components/bloomberg-view.tsx b/frontend/src/components/bloomberg-view.tsx index db312ba..7bb9cdf 100644 --- a/frontend/src/components/bloomberg-view.tsx +++ b/frontend/src/components/bloomberg-view.tsx @@ -328,6 +328,7 @@ function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { calcAssetRatio('prepaid', 'prepaid_to_assets') calcAssetRatio('property_plant&equipment', 'ppe_to_assets') calcAssetRatio('lt_investment', 'lt_investment_to_assets') + calcAssetRatio('goodwill', 'goodwill_to_assets') calcAssetRatio('accounts_payable', 'payables_to_assets') calcAssetRatio('st_defer_rev', 'deferred_revenue_to_assets') calcAssetRatio('st_debt', 'st_debt_to_assets') @@ -339,7 +340,8 @@ function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { const getR = (k: string) => (typeof row[k] === 'number' ? row[k] : 0) const sumKnown = getR('cash_to_assets') + getR('inventory_to_assets') + getR('receivables_to_assets') + getR('prepaid_to_assets') + - getR('ppe_to_assets') + getR('lt_investment_to_assets') + getR('ppe_to_assets') + getR('lt_investment_to_assets') + + getR('goodwill_to_assets') row['other_assets_ratio'] = 100 - sumKnown } @@ -417,7 +419,7 @@ function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { 'net_income', 'netincome_growth', 'cash_from_operating', 'capital_expenditure', 'free_cash_flow', 'dividends_paid', 'dividend_payout_ratio', 'repurchase', - 'total_assets', 'equity', 'goodwill', + 'total_assets', 'equity', '__SECTION_EXPENSE__', 'selling&marketing_to_revenue', 'selling&marketing', 'general&admin_to_revenue', 'general&admin', @@ -434,6 +436,7 @@ function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { 'prepaid_to_assets', 'prepaid', 'ppe_to_assets', 'property_plant&equipment', 'lt_investment_to_assets', 'lt_investment', + 'goodwill_to_assets', 'goodwill', 'other_assets_ratio', 'payables_to_assets', 'accounts_payable', 'deferred_revenue_to_assets', 'st_defer_rev', @@ -526,6 +529,7 @@ function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { 'prepaid_to_assets': 'prepaid', 'ppe_to_assets': 'property_plant&equipment', 'lt_investment_to_assets': 'lt_investment', + 'goodwill_to_assets': 'goodwill', 'payables_to_assets': 'accounts_payable', 'deferred_revenue_to_assets': 'st_defer_rev', 'st_debt_to_assets': 'st_debt', @@ -747,7 +751,8 @@ function RawDataTable({ data, title, selectedCurrency = "Auto", userMarket }: { 'cash_to_assets', 'inventory_to_assets', 'receivables_to_assets', 'prepaid_to_assets', 'ppe_to_assets', 'lt_investment_to_assets', 'payables_to_assets', 'deferred_revenue_to_assets', - 'st_debt_to_assets', 'lt_debt_to_assets', 'other_assets_ratio' + 'st_debt_to_assets', 'lt_debt_to_assets', 'other_assets_ratio', + 'goodwill_to_assets' ] if (assetRatios.includes(indicator) && numVal > 30) { @@ -860,6 +865,7 @@ function formatColumnName(column: string): string { 'st_defer_rev': '短期递延收入', 'deferred_revenue_to_assets': '预收占比', 'goodwill': '商誉', + 'goodwill_to_assets': '商誉占比', 'total_debt_ratio': '总债务比率', 'cash_to_assets': '现金占比', 'inventory_to_assets': '存货占比', @@ -940,7 +946,7 @@ function formatCellValue(column: string, value: any): string { 'other_breakdown_gross', 'other_breakdown_net', 'other_breakdown_sga', 'other_breakdown_rd', 'cash_to_assets', 'inventory_to_assets', 'receivables_to_assets', 'prepaid_to_assets', 'ppe_to_assets', 'lt_investment_to_assets', 'payables_to_assets', 'deferred_revenue_to_assets', 'st_debt_to_assets', 'lt_debt_to_assets', - 'other_assets_ratio' + 'other_assets_ratio', 'goodwill_to_assets' ].includes(lowerCol) // Special handling for Per Employee (Just number formatting, 2 decimals) diff --git a/frontend/src/components/nav-header.tsx b/frontend/src/components/nav-header.tsx index eabfcff..17f0fb1 100644 --- a/frontend/src/components/nav-header.tsx +++ b/frontend/src/components/nav-header.tsx @@ -82,7 +82,7 @@ export function NavHeader() { } return ( -
+
{/* Adjusted constraint */}