Files
zhixing-system/zhixing-web/src/features/selection/api/selection.api.ts
T
yuxuanhui 12642f3c2d feat(selection): rework results layout and add sector filter
- move the filter bar out of the list column into a full-width top section;
  list and detail stay side by side below on md+, stacking search > list >
  detail on small screens
- add sector select fed by the run's concept-board aggregates; options show
  per-sector stock counts ordered by count desc, stale selections reset when
  the aggregate list changes
- persist sector in the route search, results/runs query keys, and refresh
  sector aggregates when a selection run finishes
2026-09-05 19:48:41 +08:00

99 lines
2.7 KiB
TypeScript

import { requestJson } from "@/shared/api/request-json"
import {
selectionResultPageSize,
type SelectionChart,
type SelectionResults,
type SelectionResultsQuery,
type SelectionRunAccepted,
type SelectionRunRequest,
type SelectionSectors,
type SelectionStrategy,
} from "./selection.types"
export function getSelectionChart(
tsCode: string,
targetTradeDate: string,
strategy?: SelectionStrategy,
signal?: AbortSignal,
) {
const params = new URLSearchParams({
target_trade_date: targetTradeDate,
})
if (strategy) params.set("strategy", strategy)
return requestJson<SelectionChart>(
`/api/v1/selection/stocks/${encodeURIComponent(tsCode)}/chart?${params.toString()}`,
{ signal },
)
}
export function getSelectionResults(
strategy: SelectionStrategy,
targetTradeDate?: string,
query: SelectionResultsQuery = { page: 1, pageSize: selectionResultPageSize },
signal?: AbortSignal,
) {
const params = buildSelectionQueryParams(query)
params.set("strategy", strategy)
if (targetTradeDate) params.set("target_trade_date", targetTradeDate)
return requestJson<SelectionResults>(
`/api/v1/selection/results?${params.toString()}`,
{ signal },
)
}
export function getSelectionRun(
runId: string,
query: SelectionResultsQuery = { page: 1, pageSize: selectionResultPageSize },
signal?: AbortSignal,
) {
const params = buildSelectionQueryParams(query)
return requestJson<SelectionResults>(
`/api/v1/selection/runs/${runId}?${params.toString()}`,
{
signal,
},
)
}
function buildSelectionQueryParams(query: SelectionResultsQuery) {
const params = new URLSearchParams({
page: String(query.page),
page_size: String(query.pageSize),
})
if (query.search) params.set("search", query.search)
if (query.category) params.set("category", query.category)
if (query.sort) params.set("sort", query.sort)
if (query.sector) params.set("sector", query.sector)
return params
}
export function getSelectionResultSectors(
strategy: SelectionStrategy,
targetTradeDate?: string,
sectorType: "concept" | "industry" = "concept",
signal?: AbortSignal,
) {
const params = new URLSearchParams({
strategy,
sector_type: sectorType,
})
if (targetTradeDate) params.set("target_trade_date", targetTradeDate)
return requestJson<SelectionSectors>(
`/api/v1/selection/sectors?${params.toString()}`,
{ signal },
)
}
export function triggerSelectionRun(
request: SelectionRunRequest,
signal?: AbortSignal,
) {
return requestJson<SelectionRunAccepted>("/api/v1/selection/runs", {
body: JSON.stringify(request),
headers: { "Content-Type": "application/json" },
method: "POST",
signal,
})
}