feat(listings): 商品列表展示在线时间
This commit is contained in:
@@ -27,6 +27,7 @@ import { Link } from 'react-router-dom'
|
||||
import { BrandLogo } from '@/components/BrandLogo'
|
||||
import { HomePortalRow } from '@/features/home/HomePortalRow'
|
||||
import { useListings } from '@/features/listings/api'
|
||||
import { onlineTimeText } from '@/features/listings/labels'
|
||||
import {
|
||||
awmRanges,
|
||||
coinRanges,
|
||||
@@ -138,6 +139,7 @@ function ListingRow({ item }: { item: Listing }) {
|
||||
{ label: '段位', value: item.rank_level },
|
||||
{ label: '登录', value: item.login_platform },
|
||||
{ label: '区服', value: item.server_region },
|
||||
{ label: '在线', value: onlineTimeText(item.asset_summary) },
|
||||
{ label: '折算比', value: ratioText(item) ? `1元≈${ratioText(item)}` : '' },
|
||||
].filter(spec => spec.value)
|
||||
const skins = skinNames(item)
|
||||
@@ -227,6 +229,7 @@ function ListingGridCover({ item }: { item: Listing }) {
|
||||
}
|
||||
|
||||
function ListingGridCard({ item }: { item: Listing }) {
|
||||
const online = onlineTimeText(item.asset_summary)
|
||||
return (
|
||||
<Link to={`/listings/${item.id}`} className="listing-card-link">
|
||||
<Card className="listing-card" hoverable cover={<ListingGridCover item={item} />}>
|
||||
@@ -243,6 +246,7 @@ function ListingGridCard({ item }: { item: Listing }) {
|
||||
<Tag bordered={false}>{item.server_region || '区服待定'}</Tag>
|
||||
<Tag bordered={false}>{item.login_platform || '登录方式待定'}</Tag>
|
||||
{item.rank_level ? <Tag bordered={false}>{item.rank_level}</Tag> : null}
|
||||
{online ? <Tag bordered={false}>在线 {online}</Tag> : null}
|
||||
</div>
|
||||
<div className="listing-card__meta">
|
||||
<span>哈夫币 {formatCoinM(item.haf_coin_amount)}</span>
|
||||
|
||||
@@ -64,6 +64,25 @@ function formatOnlineTime(value: unknown) {
|
||||
return `${start || '—'} 至 ${end || '—'}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品在线时段的统一展示文案,格式与原详情页保持一致(start - end)。
|
||||
* 空值返回空字符串,由调用方决定是否隐藏或替换为占位符。
|
||||
*/
|
||||
export function onlineTimeText(summary?: Record<string, unknown> | null): string {
|
||||
if (!summary || typeof summary !== 'object') return ''
|
||||
|
||||
const value = summary.online_time
|
||||
if (typeof value === 'string') return value.trim()
|
||||
if (!value || typeof value !== 'object') return ''
|
||||
|
||||
const item = value as { start?: unknown; end?: unknown }
|
||||
const start = typeof item.start === 'string' ? item.start.trim() : ''
|
||||
const end = typeof item.end === 'string' ? item.end.trim() : ''
|
||||
if (!start && !end) return ''
|
||||
if (start === end) return start
|
||||
return `${start} - ${end}`
|
||||
}
|
||||
|
||||
export function formatAssetValue(key: string, value: unknown): string {
|
||||
if (value == null || value === '') return '—'
|
||||
if (key === 'online_time') {
|
||||
|
||||
@@ -15,6 +15,7 @@ import { Link } from 'react-router-dom'
|
||||
|
||||
import { BrandLogo } from '@/components/BrandLogo'
|
||||
import { useListings } from '@/features/listings/api'
|
||||
import { onlineTimeText } from '@/features/listings/labels'
|
||||
import {
|
||||
coinRanges,
|
||||
emptyListingFilters,
|
||||
@@ -88,10 +89,12 @@ function MobileChipGroup({
|
||||
}
|
||||
|
||||
function MobileListingCard({ item }: { item: Listing }) {
|
||||
const online = onlineTimeText(item.asset_summary)
|
||||
const specs = [
|
||||
assetText(item, 'season_insurance') ? `保险 ${assetText(item, 'season_insurance')}` : '',
|
||||
assetText(item, 'stamina_level') ? `体力 ${assetText(item, 'stamina_level')}` : '',
|
||||
assetText(item, 'load_level') ? `负重 ${assetText(item, 'load_level')}` : '',
|
||||
online ? `在线 ${online}` : '',
|
||||
].filter(Boolean)
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user