206 lines
6.0 KiB
TypeScript
206 lines
6.0 KiB
TypeScript
/**
|
||
* API 客户端 - 新架构
|
||
* 所有 API 调用使用新的 PostgreSQL 后端
|
||
*/
|
||
|
||
import type {
|
||
DataCheckResponse,
|
||
FetchDataRequest,
|
||
FetchDataResponse,
|
||
DataUpdateResponse,
|
||
FinancialDataResponse,
|
||
DataSourceListResponse,
|
||
AnalysisStartRequest,
|
||
AnalysisStartResponse,
|
||
AnalysisStatusResponse,
|
||
AnalysisResultResponse
|
||
} from './types'
|
||
|
||
const API_BASE = "/api";
|
||
|
||
// ========== 搜索相关 ==========
|
||
export async function searchStock(query: string, model?: string) {
|
||
const res = await fetch(`${API_BASE}/search`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ query, model: model || "gemini-2.0-flash" }),
|
||
});
|
||
if (!res.ok) throw new Error("Search failed");
|
||
return res.json() as Promise<{ market: string; symbol: string; company_name: string }[]>;
|
||
}
|
||
|
||
export async function searchLocalCompanies(query: string) {
|
||
const res = await fetch(`${API_BASE}/data/search_local?q=${query}`);
|
||
if (!res.ok) throw new Error("Local search failed");
|
||
return res.json() as Promise<{ market: string; symbol: string; company_name: string }[]>;
|
||
}
|
||
|
||
// ========== 配置相关 ==========
|
||
export async function getConfig() {
|
||
const res = await fetch(`${API_BASE}/config`);
|
||
if (!res.ok) throw new Error("Failed to fetch config");
|
||
return res.json();
|
||
}
|
||
|
||
export async function updateConfig(key: string, value: string) {
|
||
const res = await fetch(`${API_BASE}/config`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify({ key, value }),
|
||
});
|
||
if (!res.ok) throw new Error("Failed to update config");
|
||
return res.json();
|
||
}
|
||
|
||
// ========== 数据管理 API (新架构) ==========
|
||
|
||
/**
|
||
* 检查数据状态
|
||
*/
|
||
export async function checkDataStatus(
|
||
market: string,
|
||
symbol: string,
|
||
dataSource: string
|
||
): Promise<DataCheckResponse> {
|
||
const res = await fetch(
|
||
`${API_BASE}/data/check?market=${market}&symbol=${symbol}&data_source=${dataSource}`
|
||
)
|
||
if (!res.ok) throw new Error("Failed to check data status")
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 获取可用数据源列表
|
||
*/
|
||
export async function getAvailableSources(market: string): Promise<DataSourceListResponse> {
|
||
const res = await fetch(`${API_BASE}/data/sources?market=${market}`)
|
||
if (!res.ok) throw new Error("Failed to fetch available sources")
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 触发数据获取/更新
|
||
*/
|
||
export async function fetchFinancialData(request: FetchDataRequest): Promise<FetchDataResponse> {
|
||
const res = await fetch(`${API_BASE}/data/fetch`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(request)
|
||
})
|
||
if (!res.ok) {
|
||
const error = await res.json()
|
||
throw new Error(error.detail || "Failed to fetch data")
|
||
}
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 查询数据获取状态
|
||
*/
|
||
export async function getFetchStatus(updateId: number): Promise<DataUpdateResponse> {
|
||
const res = await fetch(`${API_BASE}/data/status/${updateId}`)
|
||
if (!res.ok) throw new Error("Failed to get fetch status")
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 读取财务数据
|
||
*/
|
||
export async function getFinancialData(
|
||
companyId: number,
|
||
dataSource: string
|
||
): Promise<FinancialDataResponse> {
|
||
const res = await fetch(
|
||
`${API_BASE}/data/financial?company_id=${companyId}&data_source=${dataSource}`
|
||
)
|
||
if (!res.ok) throw new Error("Failed to get financial data")
|
||
return res.json()
|
||
}
|
||
|
||
// ========== AI 分析 API (新架构) ==========
|
||
|
||
/**
|
||
* 启动 AI 分析
|
||
*/
|
||
export async function startAIAnalysis(request: AnalysisStartRequest): Promise<AnalysisStartResponse> {
|
||
const res = await fetch(`${API_BASE}/analysis/start`, {
|
||
method: "POST",
|
||
headers: { "Content-Type": "application/json" },
|
||
body: JSON.stringify(request)
|
||
})
|
||
if (!res.ok) {
|
||
const error = await res.json()
|
||
throw new Error(error.detail || "Failed to start analysis")
|
||
}
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 查询AI分析状态
|
||
*/
|
||
export async function getAnalysisStatus(analysisId: number): Promise<AnalysisStatusResponse> {
|
||
const res = await fetch(`${API_BASE}/analysis/status/${analysisId}`)
|
||
if (!res.ok) throw new Error("Failed to get analysis status")
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 获取AI分析结果
|
||
*/
|
||
export async function getAnalysisResult(analysisId: number): Promise<AnalysisResultResponse> {
|
||
const res = await fetch(`${API_BASE}/analysis/result/${analysisId}`)
|
||
if (!res.ok) throw new Error("Failed to get analysis result")
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 获取历史分析列表
|
||
*/
|
||
export async function getAnalysisHistory(
|
||
companyId: number,
|
||
dataSource?: string
|
||
): Promise<AnalysisStatusResponse[]> {
|
||
let url = `${API_BASE}/analysis/history?company_id=${companyId}`
|
||
if (dataSource) {
|
||
url += `&data_source=${dataSource}`
|
||
}
|
||
const res = await fetch(url)
|
||
if (!res.ok) throw new Error("Failed to get analysis history")
|
||
return res.json()
|
||
}
|
||
|
||
/**
|
||
* 获取最近更新的公司列表
|
||
*/
|
||
export async function getRecentCompanies(dataSource?: string): Promise<any[]> {
|
||
let url = `${API_BASE}/data/recent`
|
||
if (dataSource) {
|
||
url += `?data_source=${dataSource}`
|
||
}
|
||
const res = await fetch(url)
|
||
if (!res.ok) throw new Error("Failed to fetch recent companies")
|
||
return res.json()
|
||
}
|
||
|
||
// ========== 兼容性函数 ==========
|
||
/**
|
||
* 获取所有分析报告(兼容旧API)
|
||
* 注意:新架构中没有全局报告列表,这里返回空数组
|
||
* TODO: 考虑实现公司级别的历史记录或移除此组件
|
||
*/
|
||
export async function getReports() {
|
||
// 新架构不支持全局报告列表
|
||
// 返回空数组以避免错误
|
||
console.warn("getReports() is deprecated. Use getAnalysisHistory(companyId) instead.")
|
||
return []
|
||
}
|
||
|
||
/**
|
||
* 获取单个报告详情(兼容旧API)
|
||
*/
|
||
export async function getReport(reportId: number) {
|
||
const res = await fetch(`${API_BASE}/reports/${reportId}`)
|
||
if (!res.ok) throw new Error("Failed to get report")
|
||
return res.json()
|
||
}
|