feat(admin-listing): 商品管理列表在租金/押金左侧展示号主纯币价格

- listingDisplay 新增 getListingSellerCoinPrice,读取价格快照 seller_coin_base_price
  (号主收号价中的纯币部分,不含额外消耗品)
- 商品管理表格新增「纯币价格」列并置于「租金/押金」左侧,悬停显示完整说明
- 快照缺失(旧数据/无定价快照)时展示 -,与相邻列风格一致
- PNG 导出列定义同步新增该列,保持导出与页面一致
- 补 listingDisplay 单测:纯币价读取、消耗品单独计价时与号主总价区分、缺快照兜底
This commit is contained in:
yml2213
2026-09-17 17:32:00 +08:00
parent 8e167bc12b
commit 4d05fa2c4c
3 changed files with 86 additions and 0 deletions
@@ -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<string, unknown>): 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)
})
})
@@ -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