From 353f62edf05f81dc6cec90d64d4a5ce815b1bdc8 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Mon, 8 Jun 2026 07:26:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=97=E8=A1=A8=E8=B5=84?= =?UTF-8?q?=E4=BA=A7=E5=B1=95=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/views/AdminListingsView.vue | 14 +- .../listings/components/ListingCard.vue | 265 +++++++++++------- .../listings/views/MobileHomeView.css | 6 - .../listings/views/MobileHomeView.vue | 1 - .../seller/composables/usePublishForm.ts | 18 +- frontend/src/shared/utils/listingDisplay.ts | 6 +- frontend/src/utils/listingDisplay.ts | 6 +- 7 files changed, 194 insertions(+), 122 deletions(-) diff --git a/frontend/src/features/admin/views/AdminListingsView.vue b/frontend/src/features/admin/views/AdminListingsView.vue index 769d4b2..5d70dce 100644 --- a/frontend/src/features/admin/views/AdminListingsView.vue +++ b/frontend/src/features/admin/views/AdminListingsView.vue @@ -88,7 +88,7 @@ const screenshotColumns = [ { label: '租期', width: 92, - read: (row: Listing) => `${formatEstimatedRentalDuration(row)}\n日耗 ${getDailyLoss(row)}`, + read: (row: Listing) => rentalPeriodText(row), }, ] as const @@ -376,7 +376,15 @@ function rentAndDepositText(row: Listing) { } function estimateTitle(row: Listing) { - return `按哈夫币 ${listingCoinM(row)}、日耗 ${getDailyLoss(row)} 估算` + const dailyLoss = getDailyLoss(row) + return dailyLoss ? `按哈夫币 ${listingCoinM(row)}、日耗 ${dailyLoss} 估算` : '未配置日耗' +} + +function rentalPeriodText(row: Listing) { + const dailyLoss = getDailyLoss(row) + return [formatEstimatedRentalDuration(row), dailyLoss ? `日耗 ${dailyLoss}` : ''] + .filter(Boolean) + .join('\n') } function formatQuantity(value: number) { @@ -547,7 +555,7 @@ function formatQuantity(value: number) { diff --git a/frontend/src/features/listings/components/ListingCard.vue b/frontend/src/features/listings/components/ListingCard.vue index 63bb7ab..a189ca9 100644 --- a/frontend/src/features/listings/components/ListingCard.vue +++ b/frontend/src/features/listings/components/ListingCard.vue @@ -5,28 +5,78 @@ import type { Listing } from '@/features/listings' import { formatHafCoinM, getCoinWan, + getDailyLoss, getListingDisplayPrice, + getListingResources, getListingTitle, getLoginMethod, + getOnlineTimeText, getServerRegion, + getSkinNames, hasAcceleratedSaleRatio, hasGiftResources, readAssetNumber, readAssetString, - getResourceQuantity, - getOnlineTimeText, - getSkinNames, getRatioValue, - getDailyLoss, + type ListingDisplayResource, } from '@/utils/listingDisplay' interface Props { listing: Listing } +interface ListingCardStat { + label: string + value: string + tone?: 'accent' | 'highlight' + title?: string +} + const props = defineProps() const coverURL = computed(() => props.listing.cover_url || props.listing.screenshot_urls?.[0] || '') +const dailyLoss = computed(() => getDailyLoss(props.listing)) +const skinNames = computed(() => getSkinNames(props.listing)) +const statItems = computed(() => buildStatItems(props.listing)) +const resourceItems = computed(() => getListingResources(props.listing)) + +function buildStatItems(listing: Listing) { + const onlineTime = getOnlineTimeText(listing) + const secretKD = readAssetNumber(listing, 'secret_kd') + const skinText = skinNames.value.slice(0, 2).join('、') + const stats: ListingCardStat[] = [ + { label: '哈夫币', value: formatHafCoinM(getCoinWan(listing)), tone: 'accent' }, + { label: '保险格数', value: readAssetString(listing, 'season_insurance') }, + { label: '体力/负重', value: formatLevelPair(listing) }, + { label: '绝密KD', value: secretKD > 0 ? formatStatNumber(secretKD) : '' }, + { label: '游戏段位', value: listing.rank_level }, + { label: '所属区服', value: getServerRegion(listing) }, + { label: '上号方式', value: getLoginMethod(listing) }, + { label: '方便上号', value: onlineTime }, + { + label: '持有皮肤', + value: skinText, + title: skinNames.value.join('、'), + }, + ] + + return stats.filter(stat => Boolean(stat.value)) +} + +function formatResourceQuantity(resource: ListingDisplayResource) { + const suffix = resource.key === 'awmAmmo' ? '发' : '' + return `${formatStatNumber(resource.quantity)}${suffix}` +} + +function formatLevelPair(listing: Listing) { + const staminaLevel = readAssetString(listing, 'stamina_level') + const loadLevel = readAssetString(listing, 'load_level') + return [staminaLevel, loadLevel].filter(Boolean).join('/') +} + +function formatStatNumber(value: number) { + return Number.isInteger(value) ? String(value) : value.toFixed(1) +}