优化租号的详情界面

This commit is contained in:
yml2213
2026-06-02 07:26:32 +08:00
parent 2d883eb2cb
commit 275294ed1c
3 changed files with 202 additions and 25 deletions
@@ -12,14 +12,15 @@ import {
formatRatio,
getCoinWan,
getDailyLoss,
getListingConsumablePrice,
getListingChips,
getListingDisplayPrice,
getListingRentPrice,
getListingResources,
getListingSubtitle,
getListingTitle,
getLoginMethod,
getServerRegion,
readAssetNumber,
readAssetString,
} from "@/utils/listingDisplay";
@@ -46,14 +47,27 @@ const orderTotal = computed(() => {
return `${Math.round(getListingDisplayPrice(listing.value))}`;
});
const orderPriceBreakdown = computed(() => {
if (!listing.value) {
return {
rent: 0,
consumable: 0,
};
}
return {
rent: getListingRentPrice(listing.value),
consumable: getListingConsumablePrice(listing.value),
};
});
const detailMetrics = computed(() => {
if (!listing.value) return [];
const totalAssetWan = readAssetNumber(listing.value, "total_asset_wan");
const dailyLoss = getDailyLoss(listing.value);
return [
{ label: "纯币", value: formatHafCoinM(getCoinWan(listing.value)), tone: "coin" },
{
label: "总资产",
value: totalAssetWan > 0 ? formatHafCoinM(totalAssetWan) : "--",
label: "日损耗",
value: dailyLoss ? `${dailyLoss}/天` : "--",
tone: "coin",
},
{ label: "价格", value: `¥${getListingDisplayPrice(listing.value)}`, tone: "price" },
@@ -215,14 +229,6 @@ function isNavActive(path: string) {
<van-tag v-if="listing.rank_level" plain size="medium">{{
listing.rank_level
}}</van-tag>
<van-tag
v-if="getDailyLoss(listing)"
color="#fff7ed"
text-color="#ea580c"
size="medium"
>
损耗 {{ getDailyLoss(listing) }}
</van-tag>
</div>
<h2 class="detail-title">{{ getListingTitle(listing) }}</h2>
<p class="detail-desc">{{ getListingSubtitle(listing) }}</p>
@@ -271,7 +277,12 @@ function isNavActive(path: string) {
>
<span>{{ resource.label }}</span>
<strong>{{ resource.quantity }}</strong>
<em>{{ resource.mode }}</em>
<em>
<b>{{ resource.mode || "--" }}</b>
<small v-if="resource.amount > 0">¥{{ resource.amount }}</small>
<small v-else-if="resource.mode === '收费'">{{ resource.price || "¥0" }}</small>
<small v-else>无额外收费</small>
</em>
</div>
</div>
</div>
@@ -312,6 +323,10 @@ function isNavActive(path: string) {
<span class="price-label">价格</span>
<span class="price-amount">¥{{ orderTotal }}</span>
</div>
<div class="order-price-detail">
<span>租金 ¥{{ orderPriceBreakdown.rent }}</span>
<span>额外 ¥{{ orderPriceBreakdown.consumable }}</span>
</div>
</div>
<van-button
type="primary"
@@ -580,13 +595,28 @@ function isNavActive(path: string) {
}
.resource-pill em {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
grid-column: 1 / -1;
color: #ff7900;
font-size: 11px;
font-style: normal;
font-weight: 800;
}
.resource-pill em b {
color: #ff7900;
}
.resource-pill em small {
min-width: 0;
color: #17233d;
font-size: 11px;
font-weight: 800;
text-align: right;
}
.skin-detail-group + .skin-detail-group {
margin-top: 12px;
}
@@ -669,6 +699,16 @@ function isNavActive(path: string) {
color: #ff5f00;
}
.order-price-detail {
display: flex;
flex-wrap: wrap;
gap: 4px 8px;
color: #8a5a12;
font-size: 10px;
font-weight: 700;
line-height: 1.3;
}
.order-btn {
flex-shrink: 0;
padding: 0 20px;
+110 -9
View File
@@ -13,8 +13,10 @@ import {
formatRatio,
getCoinWan,
getDailyLoss,
getListingConsumablePrice,
getListingChips,
getListingDisplayPrice,
getListingRentPrice,
getListingResources,
getListingSubtitle,
getListingTitle,
@@ -46,6 +48,21 @@ const orderTotal = computed(() => {
return `${Math.round(getListingDisplayPrice(listing.value))}`;
});
const orderPriceBreakdown = computed(() => {
if (!listing.value) {
return {
rent: 0,
consumable: 0,
total: 0,
};
}
return {
rent: getListingRentPrice(listing.value),
consumable: getListingConsumablePrice(listing.value),
total: Math.round(getListingDisplayPrice(listing.value)),
};
});
const coverURL = computed(() => {
if (!listing.value) return "";
return listing.value.cover_url || listing.value.screenshot_urls?.[0] || "";
@@ -53,12 +70,12 @@ const coverURL = computed(() => {
const detailMetrics = computed(() => {
if (!listing.value) return [];
const totalAssetWan = readAssetNumber(listing.value, "total_asset_wan");
const dailyLoss = getDailyLoss(listing.value);
return [
{ label: "纯币", value: formatHafCoinM(getCoinWan(listing.value)), tone: "coin" },
{
label: "总资产",
value: totalAssetWan > 0 ? formatHafCoinM(totalAssetWan) : "--",
label: "日损耗",
value: dailyLoss ? `${dailyLoss}/天` : "--",
tone: "coin",
},
{ label: "价格", value: `¥${orderTotal.value}`, tone: "price" },
@@ -167,7 +184,6 @@ function listingPrice(item: Listing) {
<span>{{ getServerRegion(listing) }}</span>
<span v-if="getLoginMethod(listing)">{{ getLoginMethod(listing) }}</span>
<span v-if="listing.rank_level">{{ listing.rank_level }}</span>
<span v-if="getDailyLoss(listing)">损耗 {{ getDailyLoss(listing) }}</span>
</div>
<h1>{{ getListingTitle(listing) }}</h1>
<p>{{ getListingSubtitle(listing) }}</p>
@@ -209,7 +225,12 @@ function listingPrice(item: Listing) {
<div v-for="resource in getListingResources(listing)" :key="resource.key" class="detail-resource-card">
<span>{{ resource.label }}</span>
<strong>{{ resource.quantity }}</strong>
<em>{{ resource.mode }}</em>
<em>
<b>{{ resource.mode || "--" }}</b>
<small v-if="resource.amount > 0">¥{{ resource.amount }}</small>
<small v-else-if="resource.mode === '收费'">{{ resource.price || "¥0" }}</small>
<small v-else>无额外收费</small>
</em>
</div>
</div>
</section>
@@ -256,9 +277,21 @@ function listingPrice(item: Listing) {
<p class="order-safe-text">平台托管订单与押金,按平台交接流程完成账号使用。</p>
<el-form label-position="top">
<div class="order-total-box">
<span>价格</span>
<strong>¥{{ listingPrice(listing) }}</strong>
<em>押金 ¥{{ listing.deposit_amount }}</em>
<div class="order-total-head">
<span>租赁价格</span>
<strong>¥{{ listingPrice(listing) }}</strong>
</div>
<div class="order-price-breakdown">
<div>
<span>基础租金</span>
<strong>¥{{ orderPriceBreakdown.rent }}</strong>
</div>
<div>
<span>额外物品</span>
<strong>¥{{ orderPriceBreakdown.consumable }}</strong>
</div>
</div>
<em>押金另付 ¥{{ listing.deposit_amount }}</em>
</div>
<dl class="order-check-list">
<div>
@@ -520,13 +553,25 @@ function listingPrice(item: Listing) {
}
.detail-resource-card em {
display: flex;
align-items: center;
justify-content: space-between;
grid-column: 1 / -1;
color: #ff6a00;
font-size: 12px;
font-style: normal;
font-weight: 900;
}
.detail-resource-card em b {
color: #ff6a00;
}
.detail-resource-card em small {
color: #17233d;
font-size: 13px;
font-weight: 900;
}
.skin-groups {
display: grid;
gap: 16px;
@@ -580,6 +625,62 @@ function listingPrice(item: Listing) {
margin-bottom: 14px;
}
.order-total-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
padding-bottom: 12px;
border-bottom: 1px solid rgba(217, 119, 6, 0.14);
}
.order-total-head span {
color: #92400e;
font-size: 14px;
font-weight: 900;
}
.order-total-head strong {
margin: 0;
color: #ef4444;
font-size: 32px;
line-height: 1;
}
.order-price-breakdown {
display: grid;
gap: 8px;
padding: 12px 0;
}
.order-price-breakdown div {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.order-price-breakdown span {
color: #8a5a12;
font-size: 13px;
font-weight: 900;
}
.order-price-breakdown strong {
margin: 0;
color: #17233d;
font-size: 16px;
line-height: 1.2;
}
.order-total-box > em {
padding-top: 10px;
border-top: 1px solid rgba(217, 119, 6, 0.14);
color: #92400e;
font-size: 13px;
font-weight: 900;
}
.order-check-list {
display: grid;
gap: 10px;