支持号主与租客查看自己的发布/订单详情
新增卖家商品详情页;订单详情底部增加可折叠账号快照,已完成订单展示结账明细。
This commit is contained in:
@@ -0,0 +1,503 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import type { Order } from '@/features/orders/api/orders'
|
||||
import {
|
||||
getSnapshotHafCoinM,
|
||||
quantity,
|
||||
readAssetSummary,
|
||||
readSnapshot,
|
||||
readSnapshotResources,
|
||||
} from '@/features/orders/composables/useOrderSnapshot'
|
||||
import AuthImage from '@/shared/components/business/AuthImage.vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
order: Order
|
||||
variant?: 'desktop' | 'mobile'
|
||||
}>(),
|
||||
{ variant: 'desktop' }
|
||||
)
|
||||
|
||||
/** 默认折叠 */
|
||||
const expanded = ref(false)
|
||||
const mobileActive = ref<string[]>([])
|
||||
|
||||
const snapshot = computed(() => readSnapshot(props.order))
|
||||
const asset = computed(() => readAssetSummary(props.order) || {})
|
||||
const resources = computed(() => readSnapshotResources(props.order))
|
||||
const coinM = computed(() => getSnapshotHafCoinM(props.order))
|
||||
|
||||
function asRecord(value: unknown): Record<string, unknown> | null {
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: null
|
||||
}
|
||||
|
||||
function asStringList(value: unknown): string[] {
|
||||
if (!Array.isArray(value)) return []
|
||||
return value.filter((item): item is string => typeof item === 'string' && Boolean(item.trim()))
|
||||
}
|
||||
|
||||
function formatScalar(value: unknown): string {
|
||||
if (value === null || value === undefined || value === '') return '--'
|
||||
if (typeof value === 'boolean') return value ? '是' : '否'
|
||||
if (typeof value === 'number') {
|
||||
if (!Number.isFinite(value)) return '--'
|
||||
return Number.isInteger(value) ? String(value) : String(Math.round(value * 100) / 100)
|
||||
}
|
||||
if (typeof value === 'string') return value.trim() || '--'
|
||||
return '--'
|
||||
}
|
||||
|
||||
function formatRatioNumber(value: unknown): string {
|
||||
const n = typeof value === 'number' ? value : Number(value)
|
||||
if (!Number.isFinite(n) || n <= 0) return '--'
|
||||
const rounded = Math.round(n * 10) / 10
|
||||
return `1:${Number.isInteger(rounded) ? rounded : rounded.toFixed(1)}`
|
||||
}
|
||||
|
||||
function formatOnlineTime(value: unknown): string {
|
||||
const row = asRecord(value)
|
||||
if (!row) return '--'
|
||||
const start = String(row.start || '')
|
||||
const end = String(row.end || '')
|
||||
if (!start && !end) return '--'
|
||||
if (start === '全天' || end === '全天' || (start === '00:00' && end === '23:59')) return '全天'
|
||||
if (start && end) return `${start.replace(':00', '')}-${end.replace(':00', '')}点`
|
||||
return [start, end].filter(Boolean).join(' ~ ')
|
||||
}
|
||||
|
||||
const primaryRows = computed(() => {
|
||||
const s = snapshot.value || {}
|
||||
const a = asset.value
|
||||
const ratio = a.display_ratio ?? a.publish_ratio
|
||||
const regions = asStringList(a.common_regions)
|
||||
|
||||
return [
|
||||
{ label: '商品标题', value: formatScalar(s.title || props.order.title) },
|
||||
{ label: '商品编号', value: formatScalar(s.listing_no || props.order.listing_no) },
|
||||
{ label: '区服', value: formatScalar(s.server_region || props.order.server_region) },
|
||||
{ label: '上号方式', value: formatScalar(s.login_platform || props.order.login_platform) },
|
||||
{ label: '游戏段位', value: formatScalar(s.rank_level) },
|
||||
{ label: '游戏名称', value: formatScalar(s.game_name) },
|
||||
{ label: '纯币', value: coinM.value > 0 ? `${quantity(coinM.value)}M` : '--' },
|
||||
{ label: 'M单价/比例', value: formatRatioNumber(ratio) },
|
||||
{
|
||||
label: '日损耗',
|
||||
value: Number(a.daily_loss_m) > 0 ? `${formatScalar(a.daily_loss_m)}M/天` : '--',
|
||||
},
|
||||
{
|
||||
label: '烽火等级',
|
||||
value: a.fire_level != null && a.fire_level !== '' ? `${formatScalar(a.fire_level)}级` : '--',
|
||||
},
|
||||
{ label: '绝密KD', value: formatScalar(a.secret_kd) },
|
||||
{ label: '体力等级', value: formatScalar(a.stamina_level) },
|
||||
{ label: '负重等级', value: formatScalar(a.load_level) },
|
||||
{ label: '赛季保险', value: formatScalar(a.season_insurance) },
|
||||
{ label: '方便上号时段', value: formatOnlineTime(a.online_time) },
|
||||
{ label: '常用登录地', value: regions.length ? regions.join('、') : '--' },
|
||||
{ label: '人脸归属', value: formatScalar(a.face_owner) },
|
||||
{ label: '是否解锁赛季', value: formatScalar(a.unlock_said) },
|
||||
{
|
||||
label: '封禁记录',
|
||||
value: formatScalar(a.ban_record) === '--' ? '无' : formatScalar(a.ban_record),
|
||||
},
|
||||
{
|
||||
label: '备注',
|
||||
value: formatScalar(s.description || a.remark || a.note),
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
/** 未在主表列出、但仍可展示的扁平字段 */
|
||||
const extraRows = computed(() => {
|
||||
const known = new Set([
|
||||
'face_owner',
|
||||
'secret_kd',
|
||||
'fire_level',
|
||||
'daily_loss_m',
|
||||
'publish_ratio',
|
||||
'display_ratio',
|
||||
'reference_ratio',
|
||||
'display_total_price',
|
||||
'display_coin_base_price',
|
||||
'consumable_price',
|
||||
'daily_loss_ratio_adjustment',
|
||||
'accelerated_sale_ratio',
|
||||
'seller_ratio',
|
||||
'buyer_ratio',
|
||||
'seller_total_price',
|
||||
'buyer_total_price',
|
||||
'seller_coin_base_price',
|
||||
'buyer_coin_base_price',
|
||||
'seller_reference_ratio',
|
||||
'platform_markup_amount',
|
||||
'platform_rule_type',
|
||||
'season_insurance',
|
||||
'stamina_level',
|
||||
'load_level',
|
||||
'resources',
|
||||
'skin_groups',
|
||||
'screenshot_groups',
|
||||
'online_time',
|
||||
'unlock_said',
|
||||
'ban_record',
|
||||
'common_regions',
|
||||
'remark',
|
||||
'note',
|
||||
'price_breakdown',
|
||||
])
|
||||
const rows: { label: string; value: string }[] = []
|
||||
for (const [key, value] of Object.entries(asset.value)) {
|
||||
if (known.has(key)) continue
|
||||
if (value === null || value === undefined || value === '') continue
|
||||
if (typeof value === 'object') {
|
||||
// 复杂对象单独区块处理;其余跳过避免噪音
|
||||
continue
|
||||
}
|
||||
rows.push({ label: key, value: formatScalar(value) })
|
||||
}
|
||||
return rows
|
||||
})
|
||||
|
||||
const skinGroups = computed(() => {
|
||||
const groups = asset.value.skin_groups
|
||||
if (typeof groups !== 'object' || groups === null) return []
|
||||
const titles: Record<string, string> = {
|
||||
melee: '近战皮肤',
|
||||
operator: '干员皮肤',
|
||||
operatorGold: '干员金皮',
|
||||
operatorRed: '干员红皮',
|
||||
weapon: '武器皮肤',
|
||||
}
|
||||
return Object.entries(groups as Record<string, unknown>)
|
||||
.map(([key, value]) => ({
|
||||
key,
|
||||
title: titles[key] || key,
|
||||
options: asStringList(value),
|
||||
}))
|
||||
.filter(g => g.options.length)
|
||||
})
|
||||
|
||||
const screenshots = computed(() => {
|
||||
const groups = asset.value.screenshot_groups
|
||||
if (typeof groups === 'object' && groups !== null) {
|
||||
const slots = [
|
||||
{ key: 'coin', label: '纯币截图' },
|
||||
{ key: 'gameId', label: '游戏ID截图' },
|
||||
{ key: 'totalAsset', label: '总资产截图' },
|
||||
{ key: 'tencentSecurity', label: '腾讯安全中心截图' },
|
||||
{ key: 'skin', label: '皮肤截图' },
|
||||
]
|
||||
return slots.flatMap(slot => {
|
||||
const urls = (groups as Record<string, unknown>)[slot.key]
|
||||
if (!Array.isArray(urls)) return []
|
||||
const valid = urls.filter((u): u is string => typeof u === 'string' && Boolean(u))
|
||||
return valid.map((url, i) => ({
|
||||
label: valid.length > 1 ? `${slot.label}${i + 1}` : slot.label,
|
||||
url,
|
||||
}))
|
||||
})
|
||||
}
|
||||
const list = snapshot.value?.screenshot_urls
|
||||
if (!Array.isArray(list)) return []
|
||||
return list
|
||||
.filter((u): u is string => typeof u === 'string' && Boolean(u))
|
||||
.map((url, i) => ({ label: `截图${i + 1}`, url }))
|
||||
})
|
||||
const screenshotUrls = computed(() => screenshots.value.map(s => s.url))
|
||||
|
||||
const hasContent = computed(() => Boolean(snapshot.value))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Mobile:默认折叠 -->
|
||||
<section v-if="props.variant === 'mobile'" class="card-section">
|
||||
<van-collapse v-model="mobileActive" :border="false">
|
||||
<van-collapse-item name="snapshot" title="订单账号信息" :label="hasContent ? '下单时账号快照(点击展开)' : '暂无快照'">
|
||||
<template v-if="hasContent">
|
||||
<div class="kv-list">
|
||||
<div v-for="row in primaryRows" :key="row.label" class="kv-row">
|
||||
<span>{{ row.label }}</span>
|
||||
<em>{{ row.value }}</em>
|
||||
</div>
|
||||
<div v-for="row in extraRows" :key="'x-' + row.label" class="kv-row">
|
||||
<span>{{ row.label }}</span>
|
||||
<em>{{ row.value }}</em>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="resources.length" class="sub-block">
|
||||
<strong>额外消耗品</strong>
|
||||
<div v-for="r in resources" :key="r.key" class="pill">
|
||||
{{ r.label }} · {{ r.quantity }} · {{ r.mode || '收费' }}
|
||||
<template v-if="r.price"> · {{ r.price }}</template>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="skinGroups.length" class="sub-block">
|
||||
<strong>皮肤</strong>
|
||||
<div v-for="g in skinGroups" :key="g.key" class="skin-group">
|
||||
<p>{{ g.title }}</p>
|
||||
<span v-for="skin in g.options" :key="skin" class="chip">{{ skin }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="screenshots.length" class="sub-block">
|
||||
<strong>账号截图</strong>
|
||||
<div class="shot-grid">
|
||||
<figure v-for="(shot, index) in screenshots" :key="shot.url + index">
|
||||
<AuthImage
|
||||
:source="shot.url"
|
||||
:alt="shot.label"
|
||||
image-class="shot-img"
|
||||
fit="cover"
|
||||
:preview-src-list="screenshotUrls"
|
||||
:preview-initial-index="index"
|
||||
/>
|
||||
<figcaption>{{ shot.label }}</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="empty">暂无账号快照(下单时未固化账号信息)</div>
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
</section>
|
||||
|
||||
<!-- Desktop:默认折叠 -->
|
||||
<div v-else class="snapshot-section">
|
||||
<button type="button" class="collapse-head" @click="expanded = !expanded">
|
||||
<div>
|
||||
<h2>订单账号信息</h2>
|
||||
<span>下单时账号快照 · 仅本单双方可见 · {{ expanded ? '点击收起' : '点击展开' }}</span>
|
||||
</div>
|
||||
<em :class="{ open: expanded }">›</em>
|
||||
</button>
|
||||
<div v-show="expanded" class="collapse-body">
|
||||
<template v-if="hasContent">
|
||||
<div class="kv-grid">
|
||||
<div v-for="row in primaryRows" :key="row.label" class="kv-item">
|
||||
<span>{{ row.label }}</span>
|
||||
<strong>{{ row.value }}</strong>
|
||||
</div>
|
||||
<div v-for="row in extraRows" :key="'x-' + row.label" class="kv-item">
|
||||
<span>{{ row.label }}</span>
|
||||
<strong>{{ row.value }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="resources.length" class="sub-block">
|
||||
<h3>额外消耗品</h3>
|
||||
<div class="pill-row">
|
||||
<span v-for="r in resources" :key="r.key" class="pill">
|
||||
{{ r.label }} · {{ r.quantity }} · {{ r.mode || '收费' }}
|
||||
<template v-if="r.price"> · {{ r.price }}</template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="skinGroups.length" class="sub-block">
|
||||
<h3>皮肤</h3>
|
||||
<div v-for="g in skinGroups" :key="g.key" class="skin-group">
|
||||
<p>{{ g.title }}</p>
|
||||
<span v-for="skin in g.options" :key="skin" class="chip">{{ skin }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="screenshots.length" class="sub-block">
|
||||
<h3>账号截图</h3>
|
||||
<div class="shot-grid desktop">
|
||||
<figure v-for="(shot, index) in screenshots" :key="shot.url + index">
|
||||
<AuthImage
|
||||
:source="shot.url"
|
||||
:alt="shot.label"
|
||||
image-class="shot-img"
|
||||
fit="cover"
|
||||
:preview-src-list="screenshotUrls"
|
||||
:preview-initial-index="index"
|
||||
/>
|
||||
<figcaption>{{ shot.label }}</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="empty">暂无账号快照(下单时未固化账号信息)</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.snapshot-section {
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
.collapse-head {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 14px 16px;
|
||||
border: 0;
|
||||
background: #fbfcfe;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
.collapse-head h2 {
|
||||
margin: 0 0 4px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #1f2937;
|
||||
}
|
||||
.collapse-head span {
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
}
|
||||
.collapse-head em {
|
||||
font-style: normal;
|
||||
font-size: 22px;
|
||||
color: #94a3b8;
|
||||
transform: rotate(90deg);
|
||||
transition: transform 0.15s ease;
|
||||
line-height: 1;
|
||||
}
|
||||
.collapse-head em.open {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
.collapse-body {
|
||||
padding: 16px;
|
||||
border-top: 1px solid #eef1f5;
|
||||
}
|
||||
.kv-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 10px 16px;
|
||||
}
|
||||
.kv-item {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 8px;
|
||||
background: #f8fafc;
|
||||
}
|
||||
.kv-item span {
|
||||
color: #94a3b8;
|
||||
font-size: 12px;
|
||||
}
|
||||
.kv-item strong {
|
||||
color: #0f172a;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
word-break: break-word;
|
||||
}
|
||||
.sub-block {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.sub-block h3,
|
||||
.sub-block strong {
|
||||
display: block;
|
||||
margin: 0 0 8px;
|
||||
font-size: 14px;
|
||||
color: #334155;
|
||||
}
|
||||
.pill-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.pill {
|
||||
display: inline-block;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
background: #fff7ed;
|
||||
color: #9a3412;
|
||||
font-size: 12px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.skin-group {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.skin-group p {
|
||||
margin: 0 0 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #475569;
|
||||
}
|
||||
.chip {
|
||||
display: inline-block;
|
||||
margin: 0 6px 6px 0;
|
||||
padding: 4px 8px;
|
||||
border-radius: 999px;
|
||||
background: #f1f5f9;
|
||||
color: #334155;
|
||||
font-size: 12px;
|
||||
}
|
||||
.shot-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
.shot-grid.desktop {
|
||||
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
|
||||
}
|
||||
.shot-grid figure {
|
||||
margin: 0;
|
||||
}
|
||||
.shot-img {
|
||||
width: 100%;
|
||||
height: 110px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
background: #e5e7eb;
|
||||
}
|
||||
.shot-grid figcaption {
|
||||
margin-top: 4px;
|
||||
text-align: center;
|
||||
color: #94a3b8;
|
||||
font-size: 11px;
|
||||
}
|
||||
.empty {
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
color: #94a3b8;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.card-section {
|
||||
margin: 12px 12px 0;
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.kv-list {
|
||||
display: grid;
|
||||
gap: 0;
|
||||
}
|
||||
.kv-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #f1f5f9;
|
||||
font-size: 13px;
|
||||
}
|
||||
.kv-row:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
.kv-row span {
|
||||
color: #94a3b8;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.kv-row em {
|
||||
font-style: normal;
|
||||
color: #0f172a;
|
||||
text-align: right;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.kv-grid {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,7 @@
|
||||
// Orders 模块统一导出
|
||||
export * from './api/orders'
|
||||
export * from './composables/useOrderSnapshot'
|
||||
export { default as OrderAccountSnapshot } from './components/OrderAccountSnapshot.vue'
|
||||
export { default as OrderCheckoutSummary } from './components/OrderCheckoutSummary.vue'
|
||||
export { default as OrderHandoffTimeline } from './components/OrderHandoffTimeline.vue'
|
||||
export { default as OrderResourceUsageEditor } from './components/OrderResourceUsageEditor.vue'
|
||||
|
||||
@@ -8,13 +8,9 @@ import MobilePayWaySelectPopup from '@/features/orders/components/MobilePayWaySe
|
||||
import { useOrderActions, CONFIRMABLE_ACTIONS } from '@/features/orders/composables/useOrderActions'
|
||||
import { useMobilePaymentCashier } from '@/features/orders/composables/useMobilePaymentCashier'
|
||||
import { useMobilePayWaySelect } from '@/features/orders/composables/useMobilePayWaySelect'
|
||||
import { amountYuan, money } from '@/features/orders/composables/useOrderSnapshot'
|
||||
import {
|
||||
amountYuan,
|
||||
money,
|
||||
readAssetSummary as readOrderAssetSummary,
|
||||
readSnapshot as readOrderSnapshot,
|
||||
} from '@/features/orders/composables/useOrderSnapshot'
|
||||
import {
|
||||
OrderAccountSnapshot,
|
||||
OrderCheckoutSummary,
|
||||
OrderHandoffTimeline,
|
||||
OrderResourceUsageEditor,
|
||||
@@ -116,20 +112,11 @@ const {
|
||||
onCreateDisputeSuccess: () => (showDisputePopup.value = false),
|
||||
})
|
||||
|
||||
// Mobile 独有 UI 状态:折叠面板、各类 popup 显隐。
|
||||
const activeNames = ref<string[]>([])
|
||||
// Mobile 独有 UI 状态:各类 popup 显隐。
|
||||
const showDisputePopup = ref(false)
|
||||
const showCounterPopup = ref(false)
|
||||
const showRejectPopup = ref(false)
|
||||
|
||||
// 账号快照展示(PC 不用,保留在本视图)。
|
||||
function readSnapshot() {
|
||||
return readOrderSnapshot(order.value) as Record<string, any> | null
|
||||
}
|
||||
function readAssetSummary() {
|
||||
return readOrderAssetSummary(order.value) as Record<string, any> | null
|
||||
}
|
||||
|
||||
// 状态颜色映射(vant 标签主题)。
|
||||
function getStatusTagType(status: string) {
|
||||
if (['completed', 'received'].includes(status)) return 'success'
|
||||
@@ -336,11 +323,16 @@ async function copyListingCode() {
|
||||
@submit="handleSubmitCheckout"
|
||||
/>
|
||||
|
||||
<!-- Checkout Details Display -->
|
||||
<!-- Checkout Details Display(结账中 / 已完成均可查看) -->
|
||||
<OrderCheckoutSummary
|
||||
v-if="
|
||||
order.checkout &&
|
||||
['pending_checkout_confirm', 'pending_checkout_accept'].includes(order.status)
|
||||
[
|
||||
'pending_checkout_confirm',
|
||||
'pending_checkout_accept',
|
||||
'checkout_disputing',
|
||||
'completed',
|
||||
].includes(order.status)
|
||||
"
|
||||
variant="mobile"
|
||||
:order="order"
|
||||
@@ -421,32 +413,7 @@ async function copyListingCode() {
|
||||
</van-button>
|
||||
</section>
|
||||
|
||||
<!-- Snapshot Account Details Accordion -->
|
||||
<section class="card-section">
|
||||
<van-collapse v-model="activeNames">
|
||||
<van-collapse-item title="查看订单账号快照信息" name="snapshot">
|
||||
<template v-if="readSnapshot()">
|
||||
<van-cell-group :border="false">
|
||||
<van-cell title="区服" :value="order.server_region" />
|
||||
<van-cell title="登录平台" :value="order.login_platform" />
|
||||
<van-cell title="烽火等级" :value="readAssetSummary()?.fire_level || '--'" />
|
||||
<van-cell title="绝密KD" :value="readAssetSummary()?.secret_kd || '--'" />
|
||||
<van-cell
|
||||
title="常用登录地区"
|
||||
:value="readAssetSummary()?.common_regions?.join('、') || '--'"
|
||||
/>
|
||||
<van-cell title="封禁记录" :value="readAssetSummary()?.ban_record || '无'" />
|
||||
<van-cell title="体力等级" :value="readAssetSummary()?.stamina_level || '--'" />
|
||||
<van-cell title="负重等级" :value="readAssetSummary()?.load_level || '--'" />
|
||||
<van-cell title="账号备注" :label="readSnapshot()?.description || '无'" />
|
||||
</van-cell-group>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="no-snapshot-hint">暂无快照数据</div>
|
||||
</template>
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
</section>
|
||||
<OrderAccountSnapshot v-if="order" :order="order" variant="mobile" />
|
||||
</template>
|
||||
|
||||
<div v-else class="empty-wrap">
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ChatDotRound, CopyDocument, Loading, Service } from '@element-plus/icon
|
||||
import {
|
||||
amountYuan,
|
||||
money,
|
||||
OrderAccountSnapshot,
|
||||
OrderCheckoutSummary,
|
||||
OrderHandoffTimeline,
|
||||
OrderResourceUsageEditor,
|
||||
@@ -467,7 +468,12 @@ watch([() => route.query.focus, order, loading], () => {
|
||||
v-if="
|
||||
order &&
|
||||
order.checkout &&
|
||||
['pending_checkout_confirm', 'pending_checkout_accept'].includes(order.status)
|
||||
[
|
||||
'pending_checkout_confirm',
|
||||
'pending_checkout_accept',
|
||||
'checkout_disputing',
|
||||
'completed',
|
||||
].includes(order.status)
|
||||
"
|
||||
:order="order"
|
||||
:is-owner="isOwner"
|
||||
@@ -569,6 +575,9 @@ watch([() => route.query.focus, order, loading], () => {
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 账号快照放最下方,默认折叠 -->
|
||||
<OrderAccountSnapshot v-if="order" :order="order" variant="desktop" />
|
||||
</div>
|
||||
|
||||
<!-- 右侧悬浮操作区 -->
|
||||
|
||||
Reference in New Issue
Block a user