修改:增加close市场过滤
This commit is contained in:
parent
18ac89a0df
commit
537f3030e7
@ -74,6 +74,13 @@ export function isPmMarketClosed(m: PmEventMarketItem | null | undefined): boole
|
|||||||
return m?.closed === true
|
return m?.closed === true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 过滤掉已关闭的子市场(服务端公开接口已过滤,保留供本地兜底) */
|
||||||
|
export function filterOpenMarkets(
|
||||||
|
markets: PmEventMarketItem[] | undefined,
|
||||||
|
): PmEventMarketItem[] {
|
||||||
|
return (markets ?? []).filter((m) => !isPmMarketClosed(m))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 已结算市场的结果角标:取 outcomePrices 中概率最高项对应 outcomes 文案(兼容 0–1 或 1–100)。
|
* 已结算市场的结果角标:取 outcomePrices 中概率最高项对应 outcomes 文案(兼容 0–1 或 1–100)。
|
||||||
*/
|
*/
|
||||||
@ -430,8 +437,20 @@ function mapMarketToOutcome(m: PmEventMarketItem): EventCardOutcome {
|
|||||||
*/
|
*/
|
||||||
export function mapEventItemToCard(item: PmEventListItem): EventCardItem {
|
export function mapEventItemToCard(item: PmEventListItem): EventCardItem {
|
||||||
const markets = item.markets ?? []
|
const markets = item.markets ?? []
|
||||||
|
if (markets.length === 0) {
|
||||||
|
return buildEventCardItem(item, markets, false, undefined)
|
||||||
|
}
|
||||||
const multi = markets.length > 1
|
const multi = markets.length > 1
|
||||||
const firstMarket = markets[0]
|
const firstMarket = markets[0]
|
||||||
|
return buildEventCardItem(item, markets, multi, firstMarket)
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildEventCardItem(
|
||||||
|
item: PmEventListItem,
|
||||||
|
markets: PmEventMarketItem[],
|
||||||
|
multi: boolean,
|
||||||
|
firstMarket: PmEventMarketItem | undefined,
|
||||||
|
): EventCardItem {
|
||||||
const firstPrices = firstMarket ? parseOutcomePrices(firstMarket) : { yesPrice: 0.5, noPrice: 0.5 }
|
const firstPrices = firstMarket ? parseOutcomePrices(firstMarket) : { yesPrice: 0.5, noPrice: 0.5 }
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -118,14 +118,14 @@
|
|||||||
|
|
||||||
<!-- 可交易市场列表 -->
|
<!-- 可交易市场列表 -->
|
||||||
<v-card
|
<v-card
|
||||||
v-if="activeMarkets.length > 0"
|
v-if="markets.length > 0"
|
||||||
class="markets-list-card"
|
class="markets-list-card"
|
||||||
elevation="0"
|
elevation="0"
|
||||||
rounded="lg"
|
rounded="lg"
|
||||||
>
|
>
|
||||||
<div class="markets-list">
|
<div class="markets-list">
|
||||||
<div
|
<div
|
||||||
v-for="(market, index) in activeMarkets"
|
v-for="(market, index) in markets"
|
||||||
:key="market.ID ?? market.id ?? index"
|
:key="market.ID ?? market.id ?? index"
|
||||||
class="market-row"
|
class="market-row"
|
||||||
:class="{ selected: selectedMarketIndex === index }"
|
:class="{ selected: selectedMarketIndex === index }"
|
||||||
@ -161,46 +161,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
<!-- 已结算子市场(与 design vb1xr 一致:标题 + 行内结果角标) -->
|
|
||||||
<v-card
|
|
||||||
v-if="closedMarkets.length > 0"
|
|
||||||
class="markets-settled-card"
|
|
||||||
elevation="0"
|
|
||||||
rounded="lg"
|
|
||||||
>
|
|
||||||
<div class="markets-settled-head">
|
|
||||||
{{ t('eventMarkets.settledSubMarketsTitle') }}
|
|
||||||
</div>
|
|
||||||
<div class="markets-settled-list">
|
|
||||||
<div
|
|
||||||
v-for="(market, index) in closedMarkets"
|
|
||||||
:key="market.ID ?? market.id ?? `c-${index}`"
|
|
||||||
class="markets-settled-row"
|
|
||||||
@click="goToTradeDetail(market)"
|
|
||||||
>
|
|
||||||
<div class="markets-settled-row-text">
|
|
||||||
<span class="markets-settled-question">{{
|
|
||||||
market.question || t('eventMarkets.marketPlaceholder')
|
|
||||||
}}</span>
|
|
||||||
<span class="markets-settled-vol">{{ formatVolumeLine(market.volume) }}</span>
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
v-if="settledWinnerPill(market)"
|
|
||||||
class="markets-settled-pill"
|
|
||||||
:class="settledPillClass(market)"
|
|
||||||
>
|
|
||||||
{{ settledWinnerPill(market)!.label }}
|
|
||||||
</span>
|
|
||||||
<v-icon class="markets-settled-chevron" size="18">mdi-chevron-right</v-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<!-- 右侧:购买组件(桌面端显示;移动端用底部栏+弹窗) -->
|
<!-- 右侧:购买组件(桌面端显示;移动端用底部栏+弹窗) -->
|
||||||
<v-col v-if="!isMobile" cols="12" class="trade-col">
|
<v-col v-if="!isMobile" cols="12" class="trade-col">
|
||||||
<div v-if="activeMarkets.length > 0" class="trade-sidebar">
|
<div v-if="markets.length > 0" class="trade-sidebar">
|
||||||
<TradeComponent
|
<TradeComponent
|
||||||
:market="tradeMarketPayload"
|
:market="tradeMarketPayload"
|
||||||
:initial-option="tradeInitialOption"
|
:initial-option="tradeInitialOption"
|
||||||
@ -210,7 +175,7 @@
|
|||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
<!-- 移动端:单 market 时显示固定底部 Yes/No 栏 + 三点菜单(Merge/Split) -->
|
<!-- 移动端:单 market 时显示固定底部 Yes/No 栏 + 三点菜单(Merge/Split) -->
|
||||||
<template v-if="isMobile && activeMarkets.length === 1">
|
<template v-if="isMobile && markets.length === 1">
|
||||||
<div class="mobile-trade-bar-spacer" aria-hidden="true"></div>
|
<div class="mobile-trade-bar-spacer" aria-hidden="true"></div>
|
||||||
<div class="mobile-trade-bar">
|
<div class="mobile-trade-bar">
|
||||||
<v-btn
|
<v-btn
|
||||||
@ -261,7 +226,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 移动端交易弹窗:单 market 与多 market 均需(多 market 时通过列表 Buy Yes/No 打开) -->
|
<!-- 移动端交易弹窗:单 market 与多 market 均需(多 market 时通过列表 Buy Yes/No 打开) -->
|
||||||
<template v-if="isMobile && activeMarkets.length > 0">
|
<template v-if="isMobile && markets.length > 0">
|
||||||
<v-bottom-sheet v-model="tradeSheetOpen" content-class="event-markets-trade-sheet">
|
<v-bottom-sheet v-model="tradeSheetOpen" content-class="event-markets-trade-sheet">
|
||||||
<TradeComponent
|
<TradeComponent
|
||||||
v-if="tradeSheetRenderContent"
|
v-if="tradeSheetRenderContent"
|
||||||
@ -297,8 +262,6 @@ import {
|
|||||||
findPmEvent,
|
findPmEvent,
|
||||||
getMarketId,
|
getMarketId,
|
||||||
getClobTokenId,
|
getClobTokenId,
|
||||||
getPmMarketSettledWinner,
|
|
||||||
isPmMarketClosed,
|
|
||||||
type FindPmEventParams,
|
type FindPmEventParams,
|
||||||
type PmEventListItem,
|
type PmEventListItem,
|
||||||
type PmEventMarketItem,
|
type PmEventMarketItem,
|
||||||
@ -340,14 +303,7 @@ const pendingMergeSplitDialog = ref<'merge' | 'split' | null>(null)
|
|||||||
const mobileMenuOpen = ref(false)
|
const mobileMenuOpen = ref(false)
|
||||||
/** TradeComponent 引用,用于从底部栏触发 Merge/Split */
|
/** TradeComponent 引用,用于从底部栏触发 Merge/Split */
|
||||||
const tradeComponentRef = ref<InstanceType<typeof TradeComponent> | null>(null)
|
const tradeComponentRef = ref<InstanceType<typeof TradeComponent> | null>(null)
|
||||||
const markets = computed(() => {
|
const markets = computed(() => eventDetail.value?.markets ?? [])
|
||||||
const list = eventDetail.value?.markets ?? []
|
|
||||||
return list.length > 0 ? list : []
|
|
||||||
})
|
|
||||||
/** 仍可交易的市场(closed !== true) */
|
|
||||||
const activeMarkets = computed(() => markets.value.filter((m) => !isPmMarketClosed(m)))
|
|
||||||
/** 已结算/已关闭的子市场 */
|
|
||||||
const closedMarkets = computed(() => markets.value.filter((m) => isPmMarketClosed(m)))
|
|
||||||
/** 多市场时描述默认折叠,避免首屏过长 */
|
/** 多市场时描述默认折叠,避免首屏过长 */
|
||||||
const isMultiMarket = computed(() => markets.value.length > 1)
|
const isMultiMarket = computed(() => markets.value.length > 1)
|
||||||
const RULES_DESC_COLLAPSE_MIN_LEN = 80
|
const RULES_DESC_COLLAPSE_MIN_LEN = 80
|
||||||
@ -357,9 +313,9 @@ const rulesDescriptionCollapsible = computed(() => {
|
|||||||
const d = eventDetail.value?.description?.trim() ?? ''
|
const d = eventDetail.value?.description?.trim() ?? ''
|
||||||
return d.length > RULES_DESC_COLLAPSE_MIN_LEN
|
return d.length > RULES_DESC_COLLAPSE_MIN_LEN
|
||||||
})
|
})
|
||||||
const selectedMarket = computed(() => activeMarkets.value[selectedMarketIndex.value] ?? null)
|
const selectedMarket = computed(() => markets.value[selectedMarketIndex.value] ?? null)
|
||||||
/** 移动端底部栏显示的市场(选中项或首个),仅在有可交易市场时使用 */
|
/** 移动端底部栏显示的市场(选中项或首个),仅在有可交易市场时使用 */
|
||||||
const barMarket = computed(() => selectedMarket.value ?? activeMarkets.value[0])
|
const barMarket = computed(() => selectedMarket.value ?? markets.value[0])
|
||||||
/** 传给购买组件的市场数据(当前选中的市场) */
|
/** 传给购买组件的市场数据(当前选中的市场) */
|
||||||
const tradeMarketPayload = computed(() => {
|
const tradeMarketPayload = computed(() => {
|
||||||
const m = selectedMarket.value
|
const m = selectedMarket.value
|
||||||
@ -391,26 +347,6 @@ function formatVolume(volume: number | undefined): string {
|
|||||||
return `$${Math.round(volume)} Vol.`
|
return `$${Math.round(volume)} Vol.`
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 已结算列表 secondary 行:Vol. $12.4M / k(与设计稿一致) */
|
|
||||||
function formatVolumeLine(volume: number | undefined): string {
|
|
||||||
if (volume == null || !Number.isFinite(volume)) return 'Vol. —'
|
|
||||||
if (volume >= 1_000_000) return `Vol. $${(volume / 1_000_000).toFixed(1)}M`
|
|
||||||
if (volume >= 1000) return `Vol. $${(volume / 1000).toFixed(1)}k`
|
|
||||||
return `Vol. $${Math.round(volume)}`
|
|
||||||
}
|
|
||||||
|
|
||||||
function settledWinnerPill(market: PmEventMarketItem) {
|
|
||||||
return getPmMarketSettledWinner(market)
|
|
||||||
}
|
|
||||||
|
|
||||||
function settledPillClass(market: PmEventMarketItem): string {
|
|
||||||
const w = getPmMarketSettledWinner(market)
|
|
||||||
if (!w) return 'markets-settled-pill--neutral'
|
|
||||||
if (w.winnerIndex === 0) return 'markets-settled-pill--yes'
|
|
||||||
if (w.winnerIndex === 1) return 'markets-settled-pill--no'
|
|
||||||
return 'markets-settled-pill--neutral'
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatExpiresAt(endDate: string | undefined): string {
|
function formatExpiresAt(endDate: string | undefined): string {
|
||||||
if (!endDate) return ''
|
if (!endDate) return ''
|
||||||
try {
|
try {
|
||||||
@ -710,7 +646,7 @@ async function loadEventDetail() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
activeMarkets,
|
markets,
|
||||||
(list) => {
|
(list) => {
|
||||||
if (selectedMarketIndex.value >= list.length) {
|
if (selectedMarketIndex.value >= list.length) {
|
||||||
selectedMarketIndex.value = Math.max(0, list.length - 1)
|
selectedMarketIndex.value = Math.max(0, list.length - 1)
|
||||||
|
|||||||
@ -517,10 +517,7 @@ function setChartMode(mode: 'yesno' | 'crypto') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 当前市场(用于交易组件与 Split 拆单):取接口返回的第一个市场 */
|
/** 当前市场(用于交易组件与 Split 拆单):取接口返回的第一个市场 */
|
||||||
const currentMarket = computed(() => {
|
const currentMarket = computed(() => eventDetail.value?.markets?.[0] ?? null)
|
||||||
const list = eventDetail.value?.markets ?? []
|
|
||||||
return list[0] ?? null
|
|
||||||
})
|
|
||||||
|
|
||||||
const currentMarketClosed = computed(() => isPmMarketClosed(currentMarket.value))
|
const currentMarketClosed = computed(() => isPmMarketClosed(currentMarket.value))
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user