style(mobile): 优化个人中心和站内信界面
This commit is contained in:
@@ -93,6 +93,30 @@ function typeLabel(type: string) {
|
||||
}
|
||||
return map[type] || '系统'
|
||||
}
|
||||
|
||||
function typeIcon(type: string) {
|
||||
const map: Record<string, string> = {
|
||||
order: 'orders-o',
|
||||
handoff: 'logistics',
|
||||
checkout: 'balance-list-o',
|
||||
settlement: 'gold-coin-o',
|
||||
dispute: 'warning-o',
|
||||
arbitration: 'warning-o',
|
||||
timeout: 'clock-o',
|
||||
listing_review: 'certificate',
|
||||
listing_admin: 'shop-o',
|
||||
order_admin: 'service-o',
|
||||
}
|
||||
return map[type] || 'volume-o'
|
||||
}
|
||||
|
||||
function typeTone(type: string) {
|
||||
if (type === 'checkout' || type === 'settlement') return 'money'
|
||||
if (type === 'dispute' || type === 'arbitration' || type === 'timeout') return 'warning'
|
||||
if (type === 'listing_review' || type === 'listing_admin') return 'review'
|
||||
if (type === 'order' || type === 'handoff' || type === 'order_admin') return 'order'
|
||||
return 'system'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -135,32 +159,42 @@ function typeLabel(type: string) {
|
||||
class="notification-item"
|
||||
:class="{ unread: !item.read_at }"
|
||||
>
|
||||
<div class="item-head">
|
||||
<span class="type-chip">{{ typeLabel(item.type) }}</span>
|
||||
<small>{{ formatDateMinute(item.created_at) }}</small>
|
||||
<div class="item-type-icon" :class="`is-${typeTone(item.type)}`">
|
||||
<van-icon :name="typeIcon(item.type)" :size="20" />
|
||||
</div>
|
||||
<h2>{{ item.title }}</h2>
|
||||
<p>{{ item.content }}</p>
|
||||
<div class="item-actions">
|
||||
<van-button
|
||||
v-if="item.biz_id && (item.biz_type === 'order' || item.biz_type === 'listing')"
|
||||
size="small"
|
||||
plain
|
||||
round
|
||||
type="primary"
|
||||
@click="openBiz(item)"
|
||||
<div class="item-body">
|
||||
<div class="item-meta">
|
||||
<span class="type-chip">{{ typeLabel(item.type) }}</span>
|
||||
<span v-if="!item.read_at" class="unread-label">未读</span>
|
||||
<time>{{ formatDateMinute(item.created_at) }}</time>
|
||||
</div>
|
||||
<h2>{{ item.title }}</h2>
|
||||
<p>{{ item.content }}</p>
|
||||
<div
|
||||
v-if="
|
||||
!item.read_at ||
|
||||
(item.biz_id && (item.biz_type === 'order' || item.biz_type === 'listing'))
|
||||
"
|
||||
class="item-actions"
|
||||
>
|
||||
查看详情
|
||||
</van-button>
|
||||
<van-button
|
||||
v-if="!item.read_at"
|
||||
size="small"
|
||||
round
|
||||
type="primary"
|
||||
@click="markRead(item)"
|
||||
>
|
||||
已读
|
||||
</van-button>
|
||||
<button
|
||||
v-if="item.biz_id && (item.biz_type === 'order' || item.biz_type === 'listing')"
|
||||
type="button"
|
||||
class="detail-action"
|
||||
@click.stop="openBiz(item)"
|
||||
>
|
||||
查看详情
|
||||
<van-icon name="arrow" :size="10" />
|
||||
</button>
|
||||
<button
|
||||
v-if="!item.read_at"
|
||||
type="button"
|
||||
class="read-action"
|
||||
@click.stop="markRead(item)"
|
||||
>
|
||||
标为已读
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -186,17 +220,22 @@ function typeLabel(type: string) {
|
||||
.mobile-notifications {
|
||||
min-height: 100dvh;
|
||||
padding: 0 0 calc(64px + env(safe-area-inset-bottom));
|
||||
background: #f6f8fa;
|
||||
background: #f4f6f8;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.mobile-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eef1f5;
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
border-bottom: 1px solid #ffe9db;
|
||||
backdrop-filter: blur(14px);
|
||||
-webkit-backdrop-filter: blur(14px);
|
||||
}
|
||||
|
||||
.header-back {
|
||||
@@ -204,88 +243,202 @@ function typeLabel(type: string) {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
place-items: center;
|
||||
border: none;
|
||||
border: 1px solid #ffe2d1;
|
||||
border-radius: 999px;
|
||||
background: #f3f4f6;
|
||||
color: #374151;
|
||||
background: #fff8f3;
|
||||
color: #d94f00;
|
||||
}
|
||||
|
||||
.mobile-header h1 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
font-size: 19px;
|
||||
line-height: 25px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.mobile-header p {
|
||||
margin: 2px 0 0;
|
||||
margin: 3px 0 0;
|
||||
color: #8a94a6;
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.notification-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
padding: 12px 14px 18px;
|
||||
}
|
||||
|
||||
.notification-item {
|
||||
display: grid;
|
||||
grid-template-columns: 40px minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
padding: 14px;
|
||||
border: 1px solid #eef1f5;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e8edf2;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
box-shadow: 0 4px 14px rgba(15, 23, 42, 0.025);
|
||||
}
|
||||
|
||||
.notification-item.unread {
|
||||
border-color: rgba(255, 106, 0, 0.35);
|
||||
background: #fffaf5;
|
||||
border-color: #ffd6bf;
|
||||
background: #fffdfb;
|
||||
box-shadow:
|
||||
inset 3px 0 #ff6a00,
|
||||
0 4px 14px rgba(255, 106, 0, 0.045);
|
||||
}
|
||||
|
||||
.item-head {
|
||||
.item-type-icon {
|
||||
display: grid;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
border-radius: 11px;
|
||||
background: #fff1e8;
|
||||
color: #ff6a00;
|
||||
}
|
||||
|
||||
.item-type-icon.is-order {
|
||||
background: #eff6ff;
|
||||
color: #2563eb;
|
||||
}
|
||||
|
||||
.item-type-icon.is-money {
|
||||
background: #fff3e8;
|
||||
color: #ea580c;
|
||||
}
|
||||
|
||||
.item-type-icon.is-warning {
|
||||
background: #fff7ed;
|
||||
color: #d97706;
|
||||
}
|
||||
|
||||
.item-type-icon.is-review {
|
||||
background: #f5f3ff;
|
||||
color: #7c3aed;
|
||||
}
|
||||
|
||||
.item-type-icon.is-system {
|
||||
background: #f1f5f9;
|
||||
color: #64748b;
|
||||
}
|
||||
|
||||
.item-body {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.item-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.type-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 22px;
|
||||
padding: 0 8px;
|
||||
height: 20px;
|
||||
padding: 0 7px;
|
||||
border-radius: 999px;
|
||||
background: #eef5ff;
|
||||
color: #2563eb;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
background: #fff1e8;
|
||||
color: #d94f00;
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.item-head small {
|
||||
.unread-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: #e65f00;
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.unread-label::before {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 999px;
|
||||
background: #ff6a00;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.item-meta time {
|
||||
min-width: 0;
|
||||
margin-left: auto;
|
||||
overflow: hidden;
|
||||
color: #9ca3af;
|
||||
font-size: 12px;
|
||||
font-size: 10px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.notification-item h2 {
|
||||
margin: 10px 0 6px;
|
||||
margin: 8px 0 5px;
|
||||
color: #111827;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-weight: 800;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.notification-item p {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
color: #4b5563;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: #5f6b7a;
|
||||
font-size: 12px;
|
||||
line-height: 19px;
|
||||
overflow-wrap: anywhere;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
|
||||
.item-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
margin-top: 10px;
|
||||
padding-top: 9px;
|
||||
border-top: 1px solid #f1f3f6;
|
||||
}
|
||||
|
||||
.detail-action,
|
||||
.read-action {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
min-height: 26px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.detail-action {
|
||||
color: #e65f00;
|
||||
}
|
||||
|
||||
.read-action {
|
||||
margin-left: auto;
|
||||
padding: 0 10px;
|
||||
border-radius: 999px;
|
||||
background: #fff1e8;
|
||||
color: #d94f00;
|
||||
}
|
||||
|
||||
.load-more {
|
||||
margin: 4px 0 12px;
|
||||
}
|
||||
|
||||
@media (min-width: 520px) {
|
||||
.mobile-notifications {
|
||||
max-width: 430px;
|
||||
margin: 0 auto;
|
||||
box-shadow: 0 0 0 1px rgba(23, 35, 61, 0.08);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,29 +1,40 @@
|
||||
.mobile-profile-shell {
|
||||
min-height: 100dvh;
|
||||
background: #f6f8fa;
|
||||
background: #f4f6f8;
|
||||
color: #1a202c;
|
||||
padding: 0 0 calc(64px + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
/* ========== Hero Header ========== */
|
||||
.profile-hero {
|
||||
background: #ffffff;
|
||||
padding: 20px 16px 20px;
|
||||
border-bottom: 1px solid rgba(243, 244, 246, 0.8);
|
||||
padding: 16px 16px 20px;
|
||||
border-bottom: 1px solid #fff1e8;
|
||||
background: linear-gradient(180deg, #fff8f3 0%, #ffffff 82%);
|
||||
}
|
||||
|
||||
.hero-top-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.app-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
font-size: 17px;
|
||||
font-weight: 900;
|
||||
color: #111827;
|
||||
letter-spacing: 0.5px;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.hero-title small {
|
||||
color: #8b95a5;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hero-setting-btn {
|
||||
@@ -31,8 +42,8 @@
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
place-items: center;
|
||||
border: none;
|
||||
background: #f3f4f6;
|
||||
border: 1px solid rgba(255, 214, 191, 0.9);
|
||||
background: rgba(255, 255, 255, 0.88);
|
||||
border-radius: 999px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
@@ -45,7 +56,7 @@
|
||||
.profile-hero-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.avatar-circle {
|
||||
@@ -55,11 +66,12 @@
|
||||
place-items: center;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
background: #eaf2ff;
|
||||
color: #1477ff;
|
||||
background: #fff1e8;
|
||||
color: #ff6a00;
|
||||
font-size: 24px;
|
||||
font-weight: 900;
|
||||
border: 1px solid #e5e7eb;
|
||||
border: 3px solid #fff;
|
||||
box-shadow: 0 0 0 1px #ffd6bf;
|
||||
}
|
||||
|
||||
.avatar-circle img {
|
||||
@@ -76,13 +88,13 @@
|
||||
.name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.user-nickname {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-size: 19px;
|
||||
font-weight: 800;
|
||||
color: #111827;
|
||||
}
|
||||
@@ -107,58 +119,80 @@
|
||||
}
|
||||
|
||||
.user-meta {
|
||||
margin: 4px 0 0;
|
||||
color: #6b7280;
|
||||
margin: 5px 0 0;
|
||||
color: #7b8492;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.growth-card {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin: 12px 16px 0;
|
||||
margin: 10px 16px 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9edf2;
|
||||
border-radius: 14px;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 4px 16px rgba(15, 23, 42, 0.035);
|
||||
}
|
||||
|
||||
.growth-card > div {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
padding: 14px;
|
||||
border: 1px solid rgba(243, 244, 246, 0.9);
|
||||
border-radius: 16px;
|
||||
background: #ffffff;
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.02),
|
||||
0 1px 4px rgba(0, 0, 0, 0.02);
|
||||
padding: 12px 14px 10px;
|
||||
}
|
||||
|
||||
.growth-card span {
|
||||
.growth-card > div + div {
|
||||
border-left: 1px solid #f1f3f6;
|
||||
}
|
||||
|
||||
.growth-card > div span {
|
||||
color: #9ca3af;
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.growth-card strong {
|
||||
color: #7c3aed;
|
||||
font-size: 20px;
|
||||
.growth-card > div strong {
|
||||
color: #c2410c;
|
||||
font-size: 18px;
|
||||
line-height: 1.2;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.growth-card.is-distribution > div {
|
||||
background: #f0fdf4;
|
||||
border-color: rgba(167, 243, 208, 0.6);
|
||||
.growth-more {
|
||||
grid-column: 1 / -1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 30px;
|
||||
padding: 7px 14px;
|
||||
border: 0;
|
||||
border-top: 1px solid #fff1e8;
|
||||
background: #fffaf6;
|
||||
color: #d94f00;
|
||||
font-size: 10px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.growth-card.is-distribution strong {
|
||||
.growth-card.is-distribution {
|
||||
border-color: rgba(167, 243, 208, 0.7);
|
||||
background: #f0fdf4;
|
||||
}
|
||||
|
||||
.growth-card.is-distribution > div {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.growth-card.is-distribution > div strong {
|
||||
color: #059669;
|
||||
}
|
||||
|
||||
/* ========== Balance Card ========== */
|
||||
.balance-card {
|
||||
margin: 12px 16px 14px;
|
||||
padding: 16px;
|
||||
border-radius: 16px;
|
||||
margin: 10px 16px 12px;
|
||||
padding: 14px;
|
||||
border-radius: 14px;
|
||||
background: #ffffff;
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.02),
|
||||
@@ -180,12 +214,12 @@
|
||||
|
||||
.balance-label {
|
||||
color: #9ca3af;
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.balance-value {
|
||||
font-size: 26px;
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
font-family: Inter, system-ui, sans-serif;
|
||||
color: #111827;
|
||||
@@ -193,12 +227,12 @@
|
||||
|
||||
.withdraw-btn {
|
||||
background: transparent;
|
||||
border: 1px solid #1477ff;
|
||||
color: #1477ff;
|
||||
border: 1px solid #ff6a00;
|
||||
color: #ff6a00;
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
padding: 0 16px;
|
||||
height: 26px;
|
||||
padding: 0 14px;
|
||||
border-radius: 999px;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
@@ -207,22 +241,22 @@
|
||||
}
|
||||
|
||||
.withdraw-btn:active {
|
||||
background: #1477ff;
|
||||
background: #ff6a00;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.balance-footer {
|
||||
margin-top: 12px;
|
||||
padding-top: 10px;
|
||||
margin-top: 9px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid #f3f4f6;
|
||||
}
|
||||
|
||||
.detail-btn {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: #1477ff;
|
||||
color: #ff6a00;
|
||||
font-weight: 700;
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
@@ -232,10 +266,10 @@
|
||||
|
||||
/* ========== Menu Cards ========== */
|
||||
.menu-card {
|
||||
margin: 0 16px 14px;
|
||||
margin: 10px 16px 12px;
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
border-radius: 14px;
|
||||
padding: 14px;
|
||||
box-shadow:
|
||||
0 4px 16px rgba(0, 0, 0, 0.02),
|
||||
0 1px 4px rgba(0, 0, 0, 0.02);
|
||||
@@ -247,16 +281,23 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cell-card-title {
|
||||
padding: 12px 16px 6px;
|
||||
color: #697386;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.menu-card .card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 14px;
|
||||
margin-bottom: 11px;
|
||||
}
|
||||
|
||||
.menu-card .card-header h3 {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
color: #111827;
|
||||
}
|
||||
@@ -293,7 +334,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -303,8 +344,8 @@
|
||||
|
||||
.icon-wrap {
|
||||
display: grid;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
place-items: center;
|
||||
border-radius: 12px;
|
||||
transition: transform 0.15s ease;
|
||||
@@ -351,7 +392,7 @@
|
||||
background: transparent;
|
||||
}
|
||||
:deep(.van-cell) {
|
||||
padding: 14px 16px;
|
||||
padding: 12px 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.verified-color {
|
||||
@@ -676,12 +717,13 @@
|
||||
|
||||
.quality-owner-card {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
margin: 10px 12px;
|
||||
padding: 16px;
|
||||
gap: 9px;
|
||||
margin: 10px 16px 0;
|
||||
padding: 14px;
|
||||
border: 1px solid #e9e2fb;
|
||||
border-radius: 14px;
|
||||
background: linear-gradient(135deg, #faf8ff 0%, #ffffff 72%);
|
||||
background: #ffffff;
|
||||
box-shadow: 0 4px 16px rgba(15, 23, 42, 0.035);
|
||||
}
|
||||
|
||||
.mobile-points-entry {
|
||||
@@ -689,36 +731,72 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin: 10px 12px;
|
||||
padding: 14px 16px;
|
||||
margin: 10px 16px 0;
|
||||
padding: 11px 13px;
|
||||
border: 1px solid #ffd6bf;
|
||||
border-radius: 14px;
|
||||
background: #fff8f3;
|
||||
background: linear-gradient(135deg, #fff8f3 0%, #ffffff 78%);
|
||||
box-shadow: 0 4px 16px rgba(15, 23, 42, 0.035);
|
||||
}
|
||||
|
||||
.mobile-points-entry div {
|
||||
.points-entry-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.points-entry-icon {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border-radius: 11px;
|
||||
background: #ffeadf;
|
||||
}
|
||||
|
||||
.mobile-points-entry span {
|
||||
color: #ff6a00;
|
||||
font-size: 10px;
|
||||
font-weight: 900;
|
||||
.points-entry-copy {
|
||||
display: grid;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.mobile-points-entry strong {
|
||||
.points-entry-copy strong {
|
||||
color: #c2410c;
|
||||
font-size: 15px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.mobile-points-entry small {
|
||||
.points-entry-copy small {
|
||||
color: #6b7280;
|
||||
font-size: 10px;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.quality-owner-card.is-active {
|
||||
border-color: #c4b5fd;
|
||||
background: linear-gradient(145deg, #faf8ff 0%, #ffffff 66%);
|
||||
}
|
||||
|
||||
.quality-owner-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.quality-owner-icon {
|
||||
display: grid;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
flex: 0 0 auto;
|
||||
place-items: center;
|
||||
border-radius: 10px;
|
||||
background: #f3e8ff;
|
||||
color: #7c3aed !important;
|
||||
}
|
||||
|
||||
.quality-owner-title > div {
|
||||
display: grid;
|
||||
gap: 1px;
|
||||
}
|
||||
|
||||
.quality-owner-heading,
|
||||
@@ -729,7 +807,6 @@
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.quality-owner-heading > div,
|
||||
.quality-owner-info > div {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
@@ -744,24 +821,30 @@
|
||||
|
||||
.quality-owner-heading strong {
|
||||
color: #312e81;
|
||||
font-size: 15px;
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.quality-owner-info {
|
||||
gap: 8px;
|
||||
gap: 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid #f0ebfb;
|
||||
border-radius: 9px;
|
||||
background: rgba(247, 245, 255, 0.9);
|
||||
}
|
||||
|
||||
.quality-owner-info > div {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
background: rgba(245, 243, 255, 0.85);
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.quality-owner-info > div + div {
|
||||
border-left: 1px solid #eee7fb;
|
||||
}
|
||||
|
||||
.quality-owner-info strong {
|
||||
color: #6d28d9;
|
||||
font-size: 14px;
|
||||
font-size: 13px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
@@ -770,13 +853,35 @@
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.quality-owner-actions :deep(.van-button) {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.quality-owner-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid #f0ecfb;
|
||||
}
|
||||
|
||||
.quality-owner-card p {
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
color: #7b8492;
|
||||
font-size: 11px;
|
||||
font-size: 10px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.quality-owner-actions p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.quality-cancel-btn {
|
||||
flex: 0 0 auto;
|
||||
min-width: 72px;
|
||||
}
|
||||
|
||||
/* ========== 响应式适配 ========== */
|
||||
@media (min-width: 520px) {
|
||||
.mobile-profile-shell {
|
||||
|
||||
@@ -454,10 +454,13 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
<main class="mobile-profile-shell">
|
||||
<!-- 已登录区 -->
|
||||
<template v-if="isLoggedIn">
|
||||
<!-- Hero 顶部蓝色横幅 -->
|
||||
<!-- Hero 顶部账户概览 -->
|
||||
<section class="profile-hero">
|
||||
<div class="hero-top-row">
|
||||
<span class="app-title">个人中心</span>
|
||||
<div class="hero-title">
|
||||
<span class="app-title">个人中心</span>
|
||||
<small>账户、成长与权益管理</small>
|
||||
</div>
|
||||
<button class="hero-setting-btn" @click="showSettings = true">
|
||||
<van-icon name="setting-o" :size="20" color="#374151" />
|
||||
</button>
|
||||
@@ -521,20 +524,29 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
</section>
|
||||
<section v-else class="growth-card">
|
||||
<div>
|
||||
<span>租客成长等级</span>
|
||||
<span>成长等级</span>
|
||||
<strong>{{ session.renterGrowthLevelName }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>累计积分</span>
|
||||
<strong>{{ session.renterGrowthPoints }}</strong>
|
||||
</div>
|
||||
<button type="button" class="growth-more" @click="router.push('/m/benefits')">
|
||||
<span>查看 VIP 与优质号主权益</span>
|
||||
<van-icon name="arrow" :size="11" />
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section class="quality-owner-card" :class="{ 'is-active': qualityOwnerStatus?.active }">
|
||||
<div class="quality-owner-heading">
|
||||
<div>
|
||||
<span>优质号主</span>
|
||||
<strong>{{ qualityOwnerStatus?.active ? '已开通' : '解锁极品专区发布权限' }}</strong>
|
||||
<div class="quality-owner-title">
|
||||
<span class="quality-owner-icon">
|
||||
<van-icon name="award-o" :size="18" />
|
||||
</span>
|
||||
<div>
|
||||
<span>优质号主</span>
|
||||
<strong>{{ qualityOwnerStatus?.active ? '已开通' : '解锁极品专区发布权限' }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<van-tag :type="qualityOwnerStatus?.active ? 'success' : 'default'" round>
|
||||
{{ qualityOwnerStatus?.active ? '优质号主' : '未开通' }}
|
||||
@@ -546,7 +558,7 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
<strong>¥{{ formatCent(qualityOwnerStatus?.required_deposit_cent || 20000) }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>极品专区保险费率</span>
|
||||
<span>极品专区保险</span>
|
||||
<strong
|
||||
>{{
|
||||
((qualityOwnerStatus?.premium_insurance_fee_bps || 400) / 100).toFixed(1)
|
||||
@@ -554,17 +566,28 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="qualityOwnerStatus?.active" class="quality-owner-actions">
|
||||
<div v-if="qualityOwnerStatus?.active" class="quality-owner-footer">
|
||||
<p>
|
||||
<template v-if="qualityOwnerStatus.active_premium_listing_count > 0">
|
||||
极品专区还有 {{ qualityOwnerStatus.active_premium_listing_count }}
|
||||
个进行中账号,需处理后可取消。
|
||||
</template>
|
||||
<template v-else-if="qualityOwnerStatus.deposit_source === 'manual'">
|
||||
已由后台开通优质号主,可随时取消。
|
||||
</template>
|
||||
<template v-else>保证金已冻结,取消后退回可用余额。</template>
|
||||
</p>
|
||||
<van-button
|
||||
block
|
||||
size="small"
|
||||
round
|
||||
plain
|
||||
type="danger"
|
||||
class="quality-cancel-btn"
|
||||
:loading="qualityOwnerCancelling"
|
||||
:disabled="qualityOwnerStatus.active_premium_listing_count > 0"
|
||||
@click="handleCancelQualityOwner"
|
||||
>
|
||||
取消优质号主
|
||||
取消资格
|
||||
</van-button>
|
||||
</div>
|
||||
<div v-else class="quality-owner-actions">
|
||||
@@ -592,24 +615,19 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
>
|
||||
微信 / 支付宝支付开通
|
||||
</van-button>
|
||||
<p>开通后可发布到极品专区,并享受该专区专享保险费率。</p>
|
||||
</div>
|
||||
<p v-if="qualityOwnerStatus?.active">
|
||||
<template v-if="qualityOwnerStatus.active_premium_listing_count > 0">
|
||||
极品专区还有 {{ qualityOwnerStatus.active_premium_listing_count }}
|
||||
个进行中账号,请先下架或完成订单后再取消。
|
||||
</template>
|
||||
<template v-else-if="qualityOwnerStatus.deposit_source === 'manual'">
|
||||
已由后台开通优质号主,可随时取消。
|
||||
</template>
|
||||
<template v-else> 保证金已冻结,取消后可退回可用余额。 </template>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="mobile-points-entry" @click="router.push('/m/points-mall')">
|
||||
<div>
|
||||
<span>积分商城</span>
|
||||
<strong>{{ session.pointsAvailable }} 可用积分</strong>
|
||||
<small>{{ session.renterGrowthLevelName }}等级</small>
|
||||
<div class="points-entry-left">
|
||||
<span class="points-entry-icon">
|
||||
<van-icon name="point-gift-o" :size="22" color="#ff6a00" />
|
||||
</span>
|
||||
<div class="points-entry-copy">
|
||||
<strong>{{ session.pointsAvailable }} 可用积分</strong>
|
||||
<small>积分商城 · {{ session.renterGrowthLevelName }}等级</small>
|
||||
</div>
|
||||
</div>
|
||||
<van-icon name="arrow" />
|
||||
</section>
|
||||
@@ -618,7 +636,7 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
<div class="balance-card">
|
||||
<div class="balance-row">
|
||||
<div class="balance-info">
|
||||
<span class="balance-label">账户可用余额(元)</span>
|
||||
<span class="balance-label">账户可用余额</span>
|
||||
<strong class="balance-value">¥{{ formatCent(availableBalanceCent) }}</strong>
|
||||
</div>
|
||||
<button class="withdraw-btn" @click="handleWithdraw">提现</button>
|
||||
@@ -683,8 +701,9 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 常用功能 Cell Group -->
|
||||
<!-- 消息与公告 -->
|
||||
<div class="menu-card cell-card">
|
||||
<div class="cell-card-title">消息与公告</div>
|
||||
<van-cell-group :border="false">
|
||||
<van-cell title="消息中心" icon="chat-o" is-link to="/m/messages" />
|
||||
<van-cell title="站内信" icon="envelop-o" is-link to="/m/notifications">
|
||||
@@ -695,6 +714,13 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="公告中心" icon="volume-o" is-link to="/m/announcements" />
|
||||
</van-cell-group>
|
||||
</div>
|
||||
|
||||
<!-- 账户与常用服务 -->
|
||||
<div class="menu-card cell-card">
|
||||
<div class="cell-card-title">账户与服务</div>
|
||||
<van-cell-group :border="false">
|
||||
<van-cell title="资料修改" icon="edit" is-link @click="openProfileEditor" />
|
||||
<van-cell title="修改密码" icon="lock" is-link @click="openPasswordEditor" />
|
||||
<van-cell title="实名认证" icon="idcard" is-link to="/m/realname">
|
||||
@@ -711,6 +737,7 @@ function resolveAvatarURL(url: string | undefined | null) {
|
||||
to="/m/invitations"
|
||||
:value="inviteRateText || '阶梯返利'"
|
||||
/>
|
||||
<van-cell title="权益中心" icon="medal-o" is-link to="/m/benefits" />
|
||||
<van-cell title="租后须知" icon="info-o" is-link @click="openPostRentalNotice" />
|
||||
<van-cell title="系统设置" icon="setting-o" is-link @click="showSettings = true" />
|
||||
</van-cell-group>
|
||||
|
||||
Reference in New Issue
Block a user