diff --git a/frontend/src/features/admin/views/AdminListingsView.vue b/frontend/src/features/admin/views/AdminListingsView.vue
index 964c40f..69f107e 100644
--- a/frontend/src/features/admin/views/AdminListingsView.vue
+++ b/frontend/src/features/admin/views/AdminListingsView.vue
@@ -22,6 +22,7 @@ import {
formatRatio,
getCoinWan,
getDailyLoss,
+ getListingSellerCoinPrice,
getResourceQuantity,
getSkinGroup,
} from '@/shared/utils/listingDisplay'
@@ -135,6 +136,7 @@ const screenshotColumns = [
read: (row: Listing) => characterAndWeaponSkinText(row),
},
{ label: '号主备注', width: 160, read: (row: Listing) => ownerRemarkText(row) },
+ { label: '纯币价格', width: 90, read: (row: Listing) => ownerPureCoinPriceText(row) },
{ label: '租金/押金', width: 96, read: (row: Listing) => rentAndDepositText(row) },
{ label: '比例', width: 64, read: (row: Listing) => formatRatio(row) },
{
@@ -599,6 +601,13 @@ function rentAndDepositText(row: Listing) {
return `${listingPrice(row)}/${formatCentWithSymbol(row.deposit_amount_cent)}`
}
+// 号主纯币价格:号主收号价里的纯币部分(不含额外消耗品),取自发布时固化的价格快照。
+function ownerPureCoinPriceText(row: Listing) {
+ const price = getListingSellerCoinPrice(row)
+ if (price <= 0) return '-'
+ return formatCentWithSymbol(Math.round(price * 100))
+}
+
function estimateTitle(row: Listing) {
const dailyLoss = getDailyLoss(row)
return dailyLoss ? `按哈夫币 ${listingCoinM(row)}、日耗 ${dailyLoss} 估算` : '未配置日耗'
@@ -965,6 +974,14 @@ function formatQuantity(value: number) {
{{ ownerRemarkText(row) }}
+
+
+
+ {{ ownerPureCoinPriceText(row) }}
+
+
+
+
{{ rentAndDepositText(row) }}
diff --git a/frontend/src/shared/utils/__tests__/listingDisplay.spec.ts b/frontend/src/shared/utils/__tests__/listingDisplay.spec.ts
new file mode 100644
index 0000000..41276dc
--- /dev/null
+++ b/frontend/src/shared/utils/__tests__/listingDisplay.spec.ts
@@ -0,0 +1,64 @@
+import { describe, expect, it } from 'vitest'
+
+import { getListingSellerCoinPrice, getListingSellerPrice } from '../listingDisplay'
+import type { PublicListingItem } from '@/features/listings/api/listings'
+
+function buildListing(assetSummary?: Record): PublicListingItem {
+ return {
+ id: 1,
+ listing_no: 'L1',
+ account_id: 1,
+ owner_id: 1,
+ title: '测试商品',
+ description: '',
+ game_name: 'delta',
+ server_region: 'QQ',
+ login_platform: 'PC',
+ rank_level: '钻石',
+ haf_coin_amount: 100_000_000,
+ asset_summary: assetSummary,
+ screenshot_urls: [],
+ cover_url: '',
+ price_cent: 26320,
+ deposit_amount_cent: 15000,
+ in_transaction: false,
+ status: 'published' as PublicListingItem['status'],
+ review_status: 'approved' as PublicListingItem['review_status'],
+ review_reason: '',
+ created_at: '',
+ updated_at: '',
+ }
+}
+
+describe('号主纯币价格读取', () => {
+ it('从价格快照读取 seller_coin_base_price(不含消耗品)', () => {
+ const listing = buildListing({
+ price_breakdown: {
+ seller_coin_base_price: 232.6,
+ consumable_price: 0,
+ seller_total_price: 232.6,
+ },
+ })
+ expect(getListingSellerCoinPrice(listing)).toBe(232.6)
+ })
+
+ it('消耗品单独计价时纯币价格低于号主总收号价', () => {
+ const listing = buildListing({
+ price_breakdown: {
+ seller_coin_base_price: 200,
+ consumable_price: 32.6,
+ seller_total_price: 232.6,
+ },
+ })
+ expect(getListingSellerCoinPrice(listing)).toBe(200)
+ expect(getListingSellerPrice(listing)).toBe(232.6)
+ })
+
+ it('缺少价格快照时返回 0,供调用方展示占位符', () => {
+ expect(getListingSellerCoinPrice(buildListing())).toBe(0)
+ expect(getListingSellerCoinPrice(buildListing({}))).toBe(0)
+ expect(
+ getListingSellerCoinPrice(buildListing({ price_breakdown: { seller_ratio: 43 } }))
+ ).toBe(0)
+ })
+})
diff --git a/frontend/src/shared/utils/listingDisplay.ts b/frontend/src/shared/utils/listingDisplay.ts
index 5474e1d..d17af1d 100644
--- a/frontend/src/shared/utils/listingDisplay.ts
+++ b/frontend/src/shared/utils/listingDisplay.ts
@@ -77,6 +77,11 @@ export function getListingSellerPrice(item: PublicListingItem) {
return getListingDisplayPrice(item)
}
+// 号主纯币价格:不含额外消耗品的纯币部分(快照 seller_coin_base_price,单位元)。
+export function getListingSellerCoinPrice(item: PublicListingItem) {
+ return Math.max(0, roundMoney(readPriceBreakdownNumber(item, 'seller_coin_base_price')))
+}
+
export function getRatioValue(item: PublicListingItem) {
const ratio = readAssetNumber(item, 'publish_ratio')
if (ratio > 0) return ratio