Refactor frontend workspaces and centralize API contracts
Organize domain APIs and types under common/apis, shared components under named folders, and private workspace logic alongside each page. Use Bearer sessions, explicit response envelopes, session-aware routing and streams, and configurable login captcha presentation for the deployed backend contract. Preserve news, economic calendar, crawler, market, chat, Skills, settings, and demo trading workflows with responsive layouts and explicit configuration saves. Validate with frontend lint, type checking, 22 test groups, production builds, and deployed desktop/mobile page checks.
This commit is contained in:
1 parent
77b33e5e77
commit
bc480fb806
102 files changed
+4716
-1707
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import type * as News from "./type"
|
||||
import { request } from "@/http/axios"
|
||||
import { consumeStream } from "@/http/stream"
|
||||
|
||||
/** 分页查询新闻 */
|
||||
export function listNewsApi(params: News.NewsQuery) {
|
||||
return request<News.ListNewsResponseData>({
|
||||
url: "/news",
|
||||
method: "get",
|
||||
params,
|
||||
paramsSerializer: { indexes: null }
|
||||
})
|
||||
}
|
||||
|
||||
/** 读取新闻详情 */
|
||||
export function getNewsApi(id: number) {
|
||||
return request<News.GetNewsResponseData>({
|
||||
url: `/news/${id}`,
|
||||
method: "get"
|
||||
})
|
||||
}
|
||||
|
||||
/** 读取新闻修订记录 */
|
||||
export function listRevisionsApi(id: number) {
|
||||
return request<News.ListRevisionsResponseData>({
|
||||
url: `/news/${id}/revisions`,
|
||||
method: "get"
|
||||
})
|
||||
}
|
||||
|
||||
/** 只读订阅,重连由订阅生命周期负责。 */
|
||||
export function subscribeNewsApi(signal: AbortSignal, version: number, onOpen: () => void, onMessage: (data: News.NewsEvent) => void) {
|
||||
return consumeStream<News.NewsEvent>("/api/news/stream", { signal }, version, onOpen, (name, data) => {
|
||||
if (name === "news") onMessage(data)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
export interface NewsBrief {
|
||||
id: number
|
||||
source_code: string
|
||||
url: string
|
||||
title: string
|
||||
summary: string
|
||||
excerpt: string
|
||||
author: string | null
|
||||
tags: string[]
|
||||
is_paywalled: boolean
|
||||
published_at: string
|
||||
first_seen_at: string
|
||||
revision_no: number
|
||||
}
|
||||
|
||||
export interface NewsQuery {
|
||||
source?: string[]
|
||||
q?: string
|
||||
start?: string
|
||||
end?: string
|
||||
/** 从 1 开始 */
|
||||
page?: number
|
||||
limit?: number
|
||||
}
|
||||
|
||||
export interface ListNewsResponseData { items: NewsBrief[], total: number }
|
||||
|
||||
export interface NewsDetail extends NewsBrief {
|
||||
content_html: string
|
||||
source_updated_at: string | null
|
||||
last_seen_at: string
|
||||
extra: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface Revision {
|
||||
revision_no: number
|
||||
title: string
|
||||
summary: string
|
||||
content_html: string
|
||||
captured_at: string
|
||||
}
|
||||
|
||||
export interface NewsEvent {
|
||||
id: number
|
||||
source_code: string
|
||||
kind: "new" | "revised"
|
||||
}
|
||||
|
||||
export type GetNewsResponseData = NewsDetail
|
||||
|
||||
export type ListRevisionsResponseData = Revision[]
|
||||
Reference in new issue
Block a user