feat: 完善商品筛选、发布配置与优质号主流程

This commit is contained in:
yml2213
2026-11-05 19:00:37 +08:00
parent 88beae4c96
commit f01329e049
19 changed files with 1256 additions and 180 deletions
@@ -320,7 +320,7 @@ async function handleSave() {
<div class="editor-block">
<div class="editor-block-title">
<strong>押金与价格提示</strong>
<strong>押金、专区与价格提示</strong>
</div>
<el-form-item label="押金提示">
<el-input
@@ -344,6 +344,14 @@ async function handleSave() {
placeholder="支持换行,发布页点击或悬停押金旁的说明图标时展示"
/>
</el-form-item>
<el-form-item label="极品专区说明">
<el-input
v-model="publishOptionsDraft.price_config.premium_zone_tooltip"
type="textarea"
:rows="10"
placeholder="支持换行,发布页悬停或点击极品专区旁的说明图标时展示"
/>
</el-form-item>
<el-form-item label="赔付方案说明">
<el-input
v-model="publishOptionsDraft.price_config.compensation_note"
@@ -32,6 +32,8 @@ const filters = reactive<AdminListingQuery>({
owner_id: '',
status: '',
review_status: '',
compensation_plan: '',
zone: '',
insurance: '',
stamina: '',
load: '',
@@ -178,6 +180,8 @@ function resetFilters() {
filters.owner_id = ''
filters.status = ''
filters.review_status = ''
filters.compensation_plan = ''
filters.zone = ''
filters.min_coin = undefined
filters.max_coin = undefined
filters.min_deposit = undefined
@@ -797,6 +801,18 @@ function formatQuantity(value: number) {
<el-option label="已拒绝" value="rejected" />
</el-select>
</el-form-item>
<el-form-item class="filter-select" label="赔付方案">
<el-select v-model="filters.compensation_plan" clearable placeholder="全部方案">
<el-option label="无忧保险" value="insurance" />
<el-option label="普通赔付" value="normal" />
</el-select>
</el-form-item>
<el-form-item class="filter-select" label="专区">
<el-select v-model="filters.zone" clearable placeholder="全部专区">
<el-option label="普通专区" value="normal" />
<el-option label="极品专区" value="premium" />
</el-select>
</el-form-item>
<el-form-item class="filter-select" label="资产">
<el-popover
:visible="activeFilterPopover === 'asset'"
File diff suppressed because it is too large Load Diff
@@ -17,6 +17,7 @@ describe('mergeListingPublishOptions', () => {
deposit_placeholder: '',
deposit_hint: '',
deposit_tooltip: '自定义押金说明',
premium_zone_tooltip: '',
price_placeholder: '',
ratio_description: '',
},
@@ -31,6 +32,7 @@ describe('mergeListingPublishOptions', () => {
deposit_placeholder: '',
deposit_hint: '',
deposit_tooltip: '',
premium_zone_tooltip: '',
compensation_note: '自定义赔付方案说明',
price_placeholder: '',
ratio_description: '',
@@ -39,4 +41,20 @@ describe('mergeListingPublishOptions', () => {
expect(options.price_config.compensation_note).toBe('自定义赔付方案说明')
})
it('读取后台配置的极品专区说明', () => {
const options = mergeListingPublishOptions({
price_config: {
deposit_placeholder: '',
deposit_hint: '',
deposit_tooltip: '',
premium_zone_tooltip: '自定义极品专区说明',
compensation_note: '',
price_placeholder: '',
ratio_description: '',
},
})
expect(options.price_config.premium_zone_tooltip).toBe('自定义极品专区说明')
})
})
@@ -33,6 +33,7 @@ export interface PublishPriceConfig {
deposit_placeholder: string
deposit_hint: string
deposit_tooltip: string
premium_zone_tooltip: string
compensation_note: string
price_placeholder: string
ratio_description: string
@@ -148,6 +149,14 @@ const defaultDepositTooltip = `1. 系统推荐押金(基础覆盖)
若您在设置足额押金后仍感不放心,可选择购买平台提供的《全额包赔服务》。一旦发生封号损失,将获得账号市场价值的全额赔付,让您的出租过程后顾无忧。`
const defaultPremiumZoneTooltip = `极品专区是面向优质号主和高价值账号的专属展示区。
1. 发布条件:仅已认证且有效的优质号主可以开启;未开通时需先缴纳平台要求的信用保证金并完成优质号主认证。
2. 专区展示:商品审核通过后将在首页“极品专区”展示,获得更聚焦的高端账号曝光。
3. 价格规则:系统会按后台配置在基础比例上计算极品专区专享比例,审核页展示的最终价格通过后不再改价。
4. 保险服务:可选择无忧租号保险,服务费率按优质号主及极品专区的当前配置执行,并从卖家实际到手租金中扣除。
5. 责任说明:开启专区不会免除商品审核、资料真实性及发布协议中的责任,请如实填写账号资产与出租条件。`
export const emptyListingPublishOptions: ListingPublishOptions = {
schema_version: 2,
unlock_demulan_enabled: false,
@@ -169,6 +178,7 @@ export const emptyListingPublishOptions: ListingPublishOptions = {
deposit_placeholder: '',
deposit_hint: '租客缴纳,封号必赔付',
deposit_tooltip: defaultDepositTooltip,
premium_zone_tooltip: defaultPremiumZoneTooltip,
compensation_note:
'普通赔付方案如下:账号在租期内或祖期外出现封禁,追回、洗号等情况,最高可获赔全款相金+押金\n\n无忧保险赔付方案:按账号市场价值进行赔付(可参照螃蟹,盼之等主流交易平台)。注:选择此方案,需额外抽取订单佣金的8.0%作为服务费:押金须达到推荐押金方可购买。',
price_placeholder: '',
@@ -360,6 +370,10 @@ function normalizePriceConfig(value?: unknown): PublishPriceConfig {
typeof row.deposit_tooltip === 'string' && row.deposit_tooltip.trim()
? row.deposit_tooltip.trim()
: emptyListingPublishOptions.price_config.deposit_tooltip,
premium_zone_tooltip:
typeof row.premium_zone_tooltip === 'string' && row.premium_zone_tooltip.trim()
? row.premium_zone_tooltip.trim()
: emptyListingPublishOptions.price_config.premium_zone_tooltip,
compensation_note:
typeof row.compensation_note === 'string' && row.compensation_note.trim()
? row.compensation_note.trim()
@@ -186,6 +186,8 @@ export interface AdminListingQuery {
owner_id?: string
status?: ListingStatus | ''
review_status?: ListingReviewStatus | ''
compensation_plan?: 'normal' | 'insurance' | ''
zone?: 'normal' | 'premium' | ''
insurance?: string
stamina?: string
load?: string
@@ -139,6 +139,16 @@ function showDepositGuide() {
})
}
function showPremiumZoneGuide() {
if (!priceConfig.value.premium_zone_tooltip) return
void showDialog({
title: '极品专区说明',
message: priceConfig.value.premium_zone_tooltip,
messageAlign: 'left',
confirmButtonText: '我知道了',
})
}
function selectRadio<T extends string>(value: T, setter: (value: T) => void) {
setter(value)
}
@@ -887,6 +897,15 @@ const screenshotGuides: Record<string, string> = {
<div class="premium-zone-copy">
<div class="premium-zone-title">
<strong>极品专区</strong>
<button
v-if="priceConfig.premium_zone_tooltip"
type="button"
class="deposit-guide-trigger"
aria-label="查看极品专区说明"
@click.prevent.stop="showPremiumZoneGuide"
>
<van-icon name="info-o" />
</button>
<em v-if="isQualityOwner">优质号主已认证</em>
<em v-else class="is-locked">优质号主专享</em>
</div>
@@ -711,6 +711,26 @@ function selectDailyLoss(value: string | number) {
<div class="premium-zone-copy">
<div class="premium-zone-title">
<strong>极品专区</strong>
<el-popover
v-if="priceConfig.premium_zone_tooltip"
placement="top-start"
:width="560"
trigger="hover"
popper-class="deposit-guide-popper"
>
<template #reference>
<button
type="button"
class="deposit-guide-trigger"
aria-label="查看极品专区说明"
>
<el-icon><InfoFilled /></el-icon>
</button>
</template>
<div class="deposit-guide-content">
{{ priceConfig.premium_zone_tooltip }}
</div>
</el-popover>
<em v-if="isQualityOwner">优质号主已认证</em>
<em v-else class="is-locked">优质号主专享</em>
</div>