优化:历史数据接口对接
This commit is contained in:
parent
d44e7157e8
commit
9dd61be92f
185
src/api/historyRecord.ts
Normal file
185
src/api/historyRecord.ts
Normal file
@ -0,0 +1,185 @@
|
||||
/**
|
||||
* 历史记录接口:getHistoryRecordListClient(需鉴权)、getHistoryRecordPublic(无需鉴权)
|
||||
* 用于 Wallet.vue 历史 Tab 数据
|
||||
*/
|
||||
|
||||
import { buildQuery, get } from './request'
|
||||
import type { PageResult } from './types'
|
||||
|
||||
/** 单条历史记录(与 doc.json definitions["polymarket.HistoryRecord"] 对齐) */
|
||||
export interface HistoryRecordItem {
|
||||
ID?: number
|
||||
asset?: string
|
||||
bio?: string
|
||||
conditionId?: string
|
||||
createdAt?: string
|
||||
eventSlug?: string
|
||||
icon?: string
|
||||
name?: string
|
||||
outcome?: string
|
||||
outcomeIndex?: number
|
||||
price?: number
|
||||
profileImage?: string
|
||||
profileImageOptimized?: string
|
||||
proxyWallet?: string
|
||||
pseudonym?: string
|
||||
side?: string
|
||||
size?: number
|
||||
slug?: string
|
||||
timestamp?: number
|
||||
title?: string
|
||||
transactionHash?: string
|
||||
type?: string
|
||||
updatedAt?: string
|
||||
}
|
||||
|
||||
/** GET /hr/getHistoryRecordPublic 请求参数 */
|
||||
export interface GetHistoryRecordPublicParams {
|
||||
page?: number
|
||||
pageSize?: number
|
||||
keyword?: string
|
||||
slug?: string
|
||||
title?: string
|
||||
name?: string
|
||||
bio?: string
|
||||
createdAtRange?: string[]
|
||||
}
|
||||
|
||||
/** GET /hr/getHistoryRecordListClient 请求参数(客户端分页,需鉴权) */
|
||||
export interface GetHistoryRecordListClientParams {
|
||||
page?: number
|
||||
pageSize?: number
|
||||
userId?: number
|
||||
keyword?: string
|
||||
slug?: string
|
||||
title?: string
|
||||
name?: string
|
||||
bio?: string
|
||||
createdAtRange?: string[]
|
||||
}
|
||||
|
||||
/** 响应 data 可能为分页或数组 */
|
||||
export interface HistoryRecordPublicResponse {
|
||||
code: number
|
||||
data?: PageResult<HistoryRecordItem> | HistoryRecordItem[]
|
||||
msg: string
|
||||
}
|
||||
|
||||
/** getHistoryRecordListClient 响应 data 为 PageResult */
|
||||
export interface HistoryRecordListClientResponse {
|
||||
code: number
|
||||
data?: PageResult<HistoryRecordItem>
|
||||
msg: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端分页获取历史记录(需鉴权:x-token、x-user-id)
|
||||
* GET /hr/getHistoryRecordListClient
|
||||
*/
|
||||
export async function getHistoryRecordListClient(
|
||||
params: GetHistoryRecordListClientParams = {},
|
||||
config?: { headers?: Record<string, string> },
|
||||
): Promise<HistoryRecordListClientResponse> {
|
||||
const query = buildQuery({
|
||||
page: params.page,
|
||||
pageSize: params.pageSize,
|
||||
userId: params.userId,
|
||||
keyword: params.keyword,
|
||||
slug: params.slug,
|
||||
title: params.title,
|
||||
name: params.name,
|
||||
bio: params.bio,
|
||||
createdAtRange: params.createdAtRange,
|
||||
})
|
||||
return get<HistoryRecordListClientResponse>('/hr/getHistoryRecordListClient', query, config)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取历史记录(公开接口,无需鉴权)
|
||||
* GET /hr/getHistoryRecordPublic
|
||||
*/
|
||||
export async function getHistoryRecordPublic(
|
||||
params: GetHistoryRecordPublicParams = {},
|
||||
): Promise<HistoryRecordPublicResponse> {
|
||||
const query = buildQuery({
|
||||
page: params.page,
|
||||
pageSize: params.pageSize,
|
||||
keyword: params.keyword,
|
||||
slug: params.slug,
|
||||
title: params.title,
|
||||
name: params.name,
|
||||
bio: params.bio,
|
||||
createdAtRange: params.createdAtRange,
|
||||
})
|
||||
return get<HistoryRecordPublicResponse>('/hr/getHistoryRecordPublic', query)
|
||||
}
|
||||
|
||||
/** 钱包 History 展示项(与 Wallet.vue HistoryItem / order.HistoryDisplayItem 一致) */
|
||||
export interface HistoryDisplayItem {
|
||||
id: string
|
||||
market: string
|
||||
side: 'Yes' | 'No'
|
||||
activity: string
|
||||
value: string
|
||||
activityDetail?: string
|
||||
profitLoss?: string
|
||||
profitLossNegative?: boolean
|
||||
timeAgo?: string
|
||||
avgPrice?: string
|
||||
shares?: string
|
||||
iconChar?: string
|
||||
iconClass?: string
|
||||
}
|
||||
|
||||
function formatTimeAgo(createdAt: string | undefined, timestamp?: number): string {
|
||||
const ms = createdAt ? new Date(createdAt).getTime() : (timestamp != null ? timestamp * 1000 : 0)
|
||||
if (!ms) return ''
|
||||
const diff = Date.now() - ms
|
||||
if (diff < 60000) return 'Just now'
|
||||
if (diff < 3600000) return `${Math.floor(diff / 60000)} minutes ago`
|
||||
if (diff < 86400000) return `${Math.floor(diff / 3600000)} hours ago`
|
||||
if (diff < 604800000) return `${Math.floor(diff / 86400000)} days ago`
|
||||
return new Date(ms).toLocaleDateString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 HistoryRecordItem 映射为钱包 History 展示项
|
||||
*/
|
||||
export function mapHistoryRecordToDisplayItem(record: HistoryRecordItem): HistoryDisplayItem {
|
||||
const id = String(record.ID ?? '')
|
||||
const market = record.title ?? record.name ?? record.eventSlug ?? ''
|
||||
const outcome = (record.outcome ?? record.side ?? 'Yes').toString()
|
||||
const side = outcome === 'No' || outcome === 'Down' ? 'No' : 'Yes'
|
||||
const typeLabel = record.type ?? 'Trade'
|
||||
const activity = `${typeLabel} ${outcome}`.trim()
|
||||
const price = record.price ?? 0
|
||||
const size = record.size ?? 0
|
||||
const valueUsd = price * size
|
||||
const value = `$${Math.abs(valueUsd).toFixed(2)}`
|
||||
const priceCents = Math.round(price * 100)
|
||||
const activityDetail = size > 0 ? `Sold ${Math.floor(size)} ${outcome} at ${priceCents}¢` : value
|
||||
const timeAgo = formatTimeAgo(record.createdAt, record.timestamp)
|
||||
return {
|
||||
id,
|
||||
market,
|
||||
side,
|
||||
activity,
|
||||
value,
|
||||
activityDetail,
|
||||
profitLoss: value,
|
||||
profitLossNegative: valueUsd < 0,
|
||||
timeAgo,
|
||||
avgPrice: priceCents ? `${priceCents}¢` : undefined,
|
||||
shares: size > 0 ? String(Math.floor(size)) : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
/** 从响应中取出 list 并映射为展示项,同时返回 total(数组时为 length) */
|
||||
export function getHistoryRecordList(
|
||||
data: HistoryRecordPublicResponse['data'],
|
||||
): { list: HistoryDisplayItem[]; total: number } {
|
||||
if (!data) return { list: [], total: 0 }
|
||||
const list = Array.isArray(data) ? data : (data as PageResult<HistoryRecordItem>).list ?? []
|
||||
const total = Array.isArray(data) ? data.length : (data as PageResult<HistoryRecordItem>).total ?? list.length
|
||||
return { list: list.map(mapHistoryRecordToDisplayItem), total }
|
||||
}
|
||||
@ -16,6 +16,8 @@ export interface ClobPositionMarket {
|
||||
outcomes?: string[]
|
||||
outcomePrices?: string[] | number[]
|
||||
clobTokenIds?: string[]
|
||||
/** 市场是否已关闭,closed=true 表示可结算/可领取 */
|
||||
closed?: boolean
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
@ -162,8 +164,8 @@ export interface PositionDisplayItem {
|
||||
marketID?: string
|
||||
/** Token ID(用于 claimPosition,API 返回 tokenId) */
|
||||
tokenID?: string
|
||||
/** 是否待领取/未结算(needClaim 为 true 时显示领取按钮) */
|
||||
needClaim?: boolean
|
||||
/** 所属市场是否已关闭,market.closed=true 表示可结算/可领取 */
|
||||
marketClosed?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,6 +232,7 @@ export function mapPositionToDisplayItem(pos: ClobPositionItem): PositionDisplay
|
||||
const marketID = String(pos.marketID ?? pos.market?.ID ?? '')
|
||||
const tokenID = pos.tokenId ?? (pos as { tokenID?: string }).tokenID ?? ''
|
||||
const imageUrl = (pos.market?.image ?? pos.market?.icon) as string | undefined
|
||||
const marketClosed = pos.market?.closed === true
|
||||
|
||||
return {
|
||||
id,
|
||||
@ -252,6 +255,6 @@ export function mapPositionToDisplayItem(pos: ClobPositionItem): PositionDisplay
|
||||
availableSharesNum: availableNum >= 0 ? availableNum : undefined,
|
||||
marketID: marketID || undefined,
|
||||
tokenID: tokenID || undefined,
|
||||
needClaim: pos.needClaim,
|
||||
marketClosed,
|
||||
}
|
||||
}
|
||||
|
||||
97
src/api/priceHistory.ts
Normal file
97
src/api/priceHistory.ts
Normal file
@ -0,0 +1,97 @@
|
||||
/**
|
||||
* 价格历史接口(GET /pmPriceHistory/getPmPriceHistoryPublic)
|
||||
* 用于 TradeDetail.vue 折线图数据
|
||||
*/
|
||||
|
||||
import { buildQuery, get } from './request'
|
||||
import type { ApiResponse } from './types'
|
||||
import type { PageResult } from './types'
|
||||
|
||||
/** 单条价格历史(与 doc.json definitions["polymarket.PmPriceHistory"] 对齐) */
|
||||
export interface PmPriceHistoryItem {
|
||||
ID?: number
|
||||
createdAt?: string
|
||||
fidelity?: number
|
||||
interval?: string
|
||||
/** 市场标识 */
|
||||
market?: string
|
||||
/** 价格(通常 0–1 小数,前端展示可乘 100 为百分比) */
|
||||
price?: number
|
||||
/** 时间戳(Unix 秒) */
|
||||
time?: number
|
||||
updatedAt?: string
|
||||
}
|
||||
|
||||
/** GET /pmPriceHistory/getPmPriceHistoryPublic 请求参数 */
|
||||
export interface GetPmPriceHistoryPublicParams {
|
||||
/** 市场标识(必填,用于筛选) */
|
||||
market: string
|
||||
page?: number
|
||||
pageSize?: number
|
||||
/** 数据间隔 */
|
||||
interval?: string
|
||||
/** 时间筛选 */
|
||||
time?: number
|
||||
/** 创建时间范围 */
|
||||
createdAtRange?: string[]
|
||||
fidelity?: number
|
||||
keyword?: string
|
||||
order?: string
|
||||
sort?: string
|
||||
price?: number
|
||||
}
|
||||
|
||||
/** 响应 data 为 PageResult<PmPriceHistoryItem> */
|
||||
export interface PmPriceHistoryPublicResponse {
|
||||
code: number
|
||||
data?: PageResult<PmPriceHistoryItem>
|
||||
msg: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取价格历史(公开接口,无需鉴权)
|
||||
* GET /pmPriceHistory/getPmPriceHistoryPublic
|
||||
*/
|
||||
export async function getPmPriceHistoryPublic(
|
||||
params: GetPmPriceHistoryPublicParams,
|
||||
config?: { headers?: Record<string, string> },
|
||||
): Promise<PmPriceHistoryPublicResponse> {
|
||||
const { market, page = 1, pageSize = 500, interval, time, createdAtRange, fidelity, keyword, order, sort, price } = params
|
||||
const query = buildQuery({
|
||||
market,
|
||||
page,
|
||||
pageSize,
|
||||
interval,
|
||||
time,
|
||||
createdAtRange,
|
||||
fidelity,
|
||||
keyword,
|
||||
order,
|
||||
sort,
|
||||
price,
|
||||
})
|
||||
return get<PmPriceHistoryPublicResponse>('/pmPriceHistory/getPmPriceHistoryPublic', query, config)
|
||||
}
|
||||
|
||||
/** 图表单点格式 [timestamp_ms, value_0_100] */
|
||||
export type ChartDataPoint = [number, number]
|
||||
|
||||
/**
|
||||
* 将接口返回的 list 转为 ECharts 折线图数据
|
||||
* - time 转为毫秒时间戳
|
||||
* - price 若 ≤1 视为小数概率,乘 100;否则视为 0–100
|
||||
*/
|
||||
export function priceHistoryToChartData(list: PmPriceHistoryItem[]): ChartDataPoint[] {
|
||||
if (!list?.length) return []
|
||||
const out: ChartDataPoint[] = []
|
||||
for (const item of list) {
|
||||
const t = item.time
|
||||
const p = item.price
|
||||
if (t == null || p == null || !Number.isFinite(Number(t))) continue
|
||||
const tsMs = Number(t) < 1e12 ? Number(t) * 1000 : Number(t)
|
||||
const value = Number(p) <= 1 ? Number(p) * 100 : Number(p)
|
||||
out.push([tsMs, value])
|
||||
}
|
||||
out.sort((a, b) => a[0] - b[0])
|
||||
return out
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user