增加消息界面 删除我的界面无用的图标

This commit is contained in:
yml
2026-05-22 21:32:44 +08:00
parent 13bb77f89b
commit 36f54d2380
7 changed files with 305 additions and 254 deletions
+1 -9
View File
@@ -14,22 +14,14 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
VanButton: typeof import('vant/es')['Button'] VanButton: typeof import('vant/es')['Button']
VanCell: typeof import('vant/es')['Cell']
VanCellGroup: typeof import('vant/es')['CellGroup']
VanCheckbox: typeof import('vant/es')['Checkbox'] VanCheckbox: typeof import('vant/es')['Checkbox']
VanDropdownItem: typeof import('vant/es')['DropdownItem'] VanEmpty: typeof import('vant/es')['Empty']
VanDropdownMenu: typeof import('vant/es')['DropdownMenu']
VanField: typeof import('vant/es')['Field'] VanField: typeof import('vant/es')['Field']
VanGrid: typeof import('vant/es')['Grid']
VanGridItem: typeof import('vant/es')['GridItem']
VanIcon: typeof import('vant/es')['Icon'] VanIcon: typeof import('vant/es')['Icon']
VanImage: typeof import('vant/es')['Image']
VanLoading: typeof import('vant/es')['Loading'] VanLoading: typeof import('vant/es')['Loading']
VanNoticeBar: typeof import('vant/es')['NoticeBar'] VanNoticeBar: typeof import('vant/es')['NoticeBar']
VanPullRefresh: typeof import('vant/es')['PullRefresh'] VanPullRefresh: typeof import('vant/es')['PullRefresh']
VanSearch: typeof import('vant/es')['Search'] VanSearch: typeof import('vant/es')['Search']
VanTabbar: typeof import('vant/es')['Tabbar']
VanTabbarItem: typeof import('vant/es')['TabbarItem']
VanTag: typeof import('vant/es')['Tag'] VanTag: typeof import('vant/es')['Tag']
} }
} }
+6
View File
@@ -36,6 +36,12 @@ const router = createRouter({
component: () => import("@/views/mobile/MobileRegisterView.vue"), component: () => import("@/views/mobile/MobileRegisterView.vue"),
meta: { layout: "blank" }, meta: { layout: "blank" },
}, },
{
path: "/m/messages",
name: "mobile-messages",
component: () => import("@/views/mobile/MobileMessagesView.vue"),
meta: { layout: "blank" },
},
{ {
path: "/m/profile", path: "/m/profile",
name: "mobile-profile", name: "mobile-profile",
+45 -11
View File
@@ -246,7 +246,11 @@ function formatRatio(item: Listing) {
<!-- 数据背书面板 --> <!-- 数据背书面板 -->
<div class="trust-panel" aria-label="交易数据背书"> <div class="trust-panel" aria-label="交易数据背书">
<div v-for="item in platformStats" :key="item.label" class="trust-item"> <div
v-for="item in platformStats"
:key="item.label"
class="trust-item"
>
<span class="trust-icon">{{ item.icon }}</span> <span class="trust-icon">{{ item.icon }}</span>
<strong>{{ item.value }}</strong> <strong>{{ item.value }}</strong>
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
@@ -305,14 +309,28 @@ function formatRatio(item: Listing) {
<em>可租</em> <em>可租</em>
</div> </div>
<div class="card-tags"> <div class="card-tags">
<van-tag type="primary" size="medium" plain>{{ item.server_region }}</van-tag> <van-tag type="primary" size="medium" plain>{{
<van-tag type="primary" size="medium" plain>{{ item.login_platform }}</van-tag> item.server_region
<van-tag v-if="item.rank_level" type="primary" size="medium" plain>{{ item.rank_level }}</van-tag> }}</van-tag>
<van-tag type="primary" size="medium" plain>{{
item.login_platform
}}</van-tag>
<van-tag
v-if="item.rank_level"
type="primary"
size="medium"
plain
>{{ item.rank_level }}</van-tag
>
</div> </div>
<div class="card-footer"> <div class="card-footer">
<div class="price-col"> <div class="price-col">
<strong>¥{{ item.price_hourly }}<small>/小时</small></strong> <strong>¥{{ item.price_hourly }}<small>/小时</small></strong>
<span class="rent-sub">日租¥{{ item.price_daily || "--" }} · 周租¥{{ item.price_weekly || "--" }}</span> <span class="rent-sub"
>日租¥{{ item.price_daily || "--" }} · 周租¥{{
item.price_weekly || "--"
}}</span
>
</div> </div>
<div class="coin-badge"> <div class="coin-badge">
{{ formatCoin(item.haf_coin_amount) }}哈夫币 {{ formatCoin(item.haf_coin_amount) }}哈夫币
@@ -325,23 +343,39 @@ function formatRatio(item: Listing) {
<!-- ========== 底部导航原生App风格手写不用 van-tabbar ========== --> <!-- ========== 底部导航原生App风格手写不用 van-tabbar ========== -->
<nav class="bottom-nav"> <nav class="bottom-nav">
<RouterLink to="/m" class="nav-item" :class="{ active: isNavActive('/m') }"> <RouterLink
to="/m"
class="nav-item"
:class="{ active: isNavActive('/m') }"
>
<van-icon name="home-o" :size="22" /> <van-icon name="home-o" :size="22" />
<span>首页</span> <span>首页</span>
</RouterLink> </RouterLink>
<RouterLink to="/m/listings" class="nav-item" :class="{ active: isNavActive('/m/listings') }"> <RouterLink
<van-icon name="search" :size="22" /> to="/m/messages"
<span>租号</span> class="nav-item"
:class="{ active: isNavActive('/m/messages') }"
>
<van-icon name="chat-o" :size="22" />
<span>消息</span>
</RouterLink> </RouterLink>
<RouterLink to="/m/seller/listings/create" class="nav-item nav-publish"> <RouterLink to="/m/seller/listings/create" class="nav-item nav-publish">
<div class="publish-pill">+</div> <div class="publish-pill">+</div>
<span>发布</span> <span>发布</span>
</RouterLink> </RouterLink>
<RouterLink to="/m/orders" class="nav-item" :class="{ active: isNavActive('/m/orders') }"> <RouterLink
to="/m/orders"
class="nav-item"
:class="{ active: isNavActive('/m/orders') }"
>
<van-icon name="orders-o" :size="22" /> <van-icon name="orders-o" :size="22" />
<span>订单</span> <span>订单</span>
</RouterLink> </RouterLink>
<RouterLink to="/m/profile" class="nav-item" :class="{ active: isNavActive('/m/profile') }"> <RouterLink
to="/m/profile"
class="nav-item"
:class="{ active: isNavActive('/m/profile') }"
>
<van-icon name="manager-o" :size="22" /> <van-icon name="manager-o" :size="22" />
<span>我的</span> <span>我的</span>
</RouterLink> </RouterLink>
@@ -0,0 +1,143 @@
<script setup lang="ts">
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
const route = useRoute();
function isNavActive(path: string) {
if (path === "/m") return route.path === "/m";
return route.path.startsWith(path);
}
</script>
<template>
<main class="mobile-messages">
<header class="page-header">
<button class="back-btn" @click="router.back()">
<van-icon name="arrow-left" :size="20" />
</button>
<h1>消息</h1>
<span class="header-spacer"></span>
</header>
<!-- 空状态 -->
<van-empty description="暂无消息" image="search" />
<!-- 底部导航 -->
<nav class="bottom-nav">
<RouterLink to="/m" class="nav-item" :class="{ active: isNavActive('/m') }">
<van-icon name="home-o" :size="22" />
<span>首页</span>
</RouterLink>
<RouterLink to="/m/messages" class="nav-item" :class="{ active: isNavActive('/m/messages') }">
<van-icon name="chat-o" :size="22" />
<span>消息</span>
</RouterLink>
<RouterLink to="/m/seller/listings/create" class="nav-item nav-publish">
<div class="publish-pill">+</div>
<span>发布</span>
</RouterLink>
<RouterLink to="/m/orders" class="nav-item" :class="{ active: isNavActive('/m/orders') }">
<van-icon name="orders-o" :size="22" />
<span>订单</span>
</RouterLink>
<RouterLink to="/m/profile" class="nav-item" :class="{ active: isNavActive('/m/profile') }">
<van-icon name="manager-o" :size="22" />
<span>我的</span>
</RouterLink>
</nav>
</main>
</template>
<style scoped>
.mobile-messages {
min-height: 100dvh;
background: #f5f7fa;
padding-bottom: 56px;
}
/* ========== 顶部导航 ========== */
.page-header {
position: sticky;
top: 0;
z-index: 10;
display: flex;
align-items: center;
height: 48px;
padding: 0 12px;
background: #fff;
border-bottom: 1px solid #eee;
}
.page-header h1 {
flex: 1;
margin: 0;
font-size: 17px;
font-weight: 700;
text-align: center;
}
.back-btn {
display: grid;
width: 36px;
height: 36px;
place-items: center;
border: none;
background: none;
color: #333;
cursor: pointer;
}
.header-spacer {
width: 36px;
}
/* ========== 底部导航 ========== */
.bottom-nav {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
display: flex;
height: 50px;
background: #fff;
border-top: 1px solid #eee;
}
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 2px;
color: #999;
font-size: 10px;
text-decoration: none;
}
.nav-item.active {
color: #1477ff;
}
.nav-item span {
font-weight: 600;
}
.publish-pill {
width: 36px;
height: 26px;
display: grid;
place-items: center;
border-radius: 13px;
background: #ff6a00;
color: #fff;
font-size: 18px;
font-weight: 900;
}
.nav-publish span {
color: #ff6a00;
}
</style>
@@ -168,12 +168,12 @@ function goDetail(id: number) {
<span>首页</span> <span>首页</span>
</RouterLink> </RouterLink>
<RouterLink <RouterLink
to="/m/listings" to="/m/messages"
class="nav-item" class="nav-item"
:class="{ active: isNavActive('/m/listings') }" :class="{ active: isNavActive('/m/messages') }"
> >
<van-icon name="search" :size="22" /> <van-icon name="chat-o" :size="22" />
<span>租号</span> <span>消息</span>
</RouterLink> </RouterLink>
<RouterLink to="/m/seller/listings/create" class="nav-item nav-publish"> <RouterLink to="/m/seller/listings/create" class="nav-item nav-publish">
<div class="publish-pill">+</div> <div class="publish-pill">+</div>
+93 -217
View File
@@ -26,31 +26,6 @@ const maskedPhone = computed(() =>
: "登录后查看手机号" : "登录后查看手机号"
); );
const sellerOrders = [
{ label: "商品管理", icon: "🛍️", to: "/m/seller/listings/create" },
{ label: "交易中", icon: "📦", to: "/m/orders" },
{ label: "已完成", icon: "✈️", to: "/m/orders" },
{ label: "退款/售后", icon: "💴", to: "/m/orders" },
];
const buyerOrders = [
{ label: "未支付", icon: "💳", to: "/m/orders" },
{ label: "交易中", icon: "🪙", to: "/m/orders" },
{ label: "已完成", icon: "☑️", to: "/m/orders" },
{ label: "退款/售后", icon: "🧾", to: "/m/orders" },
];
const serviceItems = [
"收款账户",
"余额明细",
"提现记录",
"商务合作",
"我的代练",
"我的代肝",
"我的收藏",
"我的打赏",
"我的邀请",
];
const serviceIcons = ["👥", "🪙", "💸", "💼", "⚔️", "💎", "⭐", "💰", "🎁"];
function logout() { function logout() {
session.logout(); session.logout();
} }
@@ -87,32 +62,32 @@ function goToLogin() {
<!-- 已登录区 --> <!-- 已登录区 -->
<template v-else> <template v-else>
<!-- 头像区 --> <!-- Hero 顶部蓝色横幅 -->
<section class="profile-header"> <section class="profile-hero">
<van-image round width="64px" height="64px" src="" class="avatar-image"> <div class="hero-bg"></div>
<template #error> <div class="profile-hero-content">
<div class="avatar-fallback">👤</div> <div class="avatar-wrap">
</template> <div class="avatar-circle">👤</div>
</van-image> </div>
<div class="profile-user"> <div class="hero-user">
<h1>{{ displayName }}<span class="edit-icon"></span></h1> <h1>{{ displayName }}</h1>
<p>ID: {{ displayId }} · {{ maskedPhone }}</p> <p>ID: {{ displayId }} · {{ maskedPhone }}</p>
</div> </div>
<van-icon name="setting-o" size="24" class="setting-icon" /> </div>
</section> </section>
<!-- 余额卡片 - 两行结构 --> <!-- 余额卡片 - 白色浮层 -->
<van-cell-group inset class="balance-group"> <div class="balance-card">
<van-cell center class="balance-main"> <div class="balance-row">
<template #title> <div class="balance-info">
<span class="balance-label">账户余额()</span> <span class="balance-label">账户余额()</span>
</template>
<template #value>
<strong class="balance-value">¥0.00</strong> <strong class="balance-value">¥0.00</strong>
</template> </div>
</van-cell> <van-button type="primary" size="small" round class="withdraw-btn"
<van-cell class="balance-actions"> >提现</van-button
<template #title> >
</div>
<div class="balance-footer">
<van-button <van-button
size="mini" size="mini"
plain plain
@@ -121,74 +96,17 @@ function goToLogin() {
class="detail-btn" class="detail-btn"
>查看明细</van-button >查看明细</van-button
> >
</div>
</div>
</template> </template>
<template #value>
<van-button type="primary" size="small" round class="withdraw-btn"
>提现</van-button
>
</template>
</van-cell>
</van-cell-group>
</template>
<!-- 订单菜单 -->
<section class="menu-section">
<h2>我的订单</h2>
<van-grid :column-num="4" :border="false" class="order-grid">
<van-grid-item
v-for="item in sellerOrders"
:key="item.label"
:to="item.to"
>
<template #icon>
<span class="menu-icon">{{ item.icon }}</span>
</template>
<template #text>
<span class="menu-text">{{ item.label }}</span>
</template>
</van-grid-item>
</van-grid>
</section>
<!-- 我买的 -->
<section class="menu-section">
<h2>我买的</h2>
<van-grid :column-num="4" :border="false" class="order-grid">
<van-grid-item
v-for="item in buyerOrders"
:key="item.label"
:to="item.to"
>
<template #icon>
<span class="menu-icon">{{ item.icon }}</span>
</template>
<template #text>
<span class="menu-text">{{ item.label }}</span>
</template>
</van-grid-item>
</van-grid>
</section>
<!-- 服务菜单 -->
<van-cell-group inset class="service-group">
<van-grid :column-num="4" :border="false" class="service-grid">
<van-grid-item v-for="(item, index) in serviceItems" :key="item">
<template #icon>
<span class="menu-icon">{{ serviceIcons[index] }}</span>
</template>
<template #text>
<span class="menu-text">{{ item }}</span>
</template>
</van-grid-item>
</van-grid>
</van-cell-group>
<!-- 退出登录 --> <!-- 退出登录 -->
<van-button <van-button
v-if="isLoggedIn" v-if="isLoggedIn"
plain plain
type="danger" type="danger"
block size="small"
round
class="logout-btn" class="logout-btn"
@click="logout" @click="logout"
> >
@@ -206,12 +124,12 @@ function goToLogin() {
<span>首页</span> <span>首页</span>
</RouterLink> </RouterLink>
<RouterLink <RouterLink
to="/m/listings" to="/m/messages"
class="nav-item" class="nav-item"
:class="{ active: isNavActive('/m/listings') }" :class="{ active: isNavActive('/m/messages') }"
> >
<van-icon name="search" :size="22" /> <van-icon name="chat-o" :size="22" />
<span>租号</span> <span>消息</span>
</RouterLink> </RouterLink>
<RouterLink to="/m/seller/listings/create" class="nav-item nav-publish"> <RouterLink to="/m/seller/listings/create" class="nav-item nav-publish">
<div class="publish-pill">+</div> <div class="publish-pill">+</div>
@@ -242,14 +160,14 @@ function goToLogin() {
min-height: 100vh; min-height: 100vh;
background: #f5f6f8; background: #f5f6f8;
color: #1a202c; color: #1a202c;
padding: 28px 12px 60px; padding: 0 0 60px;
} }
/* ========== 未登录区 - 自定义卡片 ========== */ /* ========== 未登录区 - 自定义卡片 ========== */
.guest-card { .guest-card {
text-align: center; text-align: center;
padding: 34px 26px; padding: 34px 26px;
margin: 0 2px; margin: 12px;
border-radius: 16px; border-radius: 16px;
background: #fff; background: #fff;
box-shadow: 0 8px 26px rgba(24, 30, 45, 0.06); box-shadow: 0 8px 26px rgba(24, 30, 45, 0.06);
@@ -303,100 +221,103 @@ function goToLogin() {
font-weight: 800; font-weight: 800;
} }
/* ========== 已登录头像区 ========== */ /* ========== 已登录区 - Hero蓝色横幅 ========== */
.profile-header { .profile-hero {
position: relative;
padding: 28px 20px 40px;
border-radius: 0 0 24px 24px;
overflow: hidden;
}
.hero-bg {
position: absolute;
inset: 0;
background: #1479ff;
z-index: 0;
}
.profile-hero-content {
position: relative;
z-index: 1;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 14px; gap: 14px;
min-height: 120px;
} }
.avatar-image { .avatar-wrap {
flex: 0 0 auto; flex: 0 0 auto;
} }
.avatar-fallback { .avatar-circle {
display: grid; display: grid;
width: 64px; width: 54px;
height: 64px; height: 54px;
place-items: center; place-items: center;
background: #fff;
border-radius: 50%; border-radius: 50%;
font-size: 32px; background: rgba(255, 255, 255, 0.2);
box-shadow: 0 10px 24px rgba(24, 30, 45, 0.08); font-size: 28px;
} }
.profile-user { .hero-user {
min-width: 0; min-width: 0;
flex: 1; flex: 1;
} }
.profile-user h1 { .hero-user h1 {
overflow: hidden; overflow: hidden;
margin: 0; margin: 0;
font-size: 20px; font-size: 18px;
font-weight: 800;
color: #fff;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.edit-icon { .hero-user p {
margin-left: 4px; margin: 4px 0 0;
color: #b7bcc6; color: rgba(255, 255, 255, 0.75);
font-size: 14px; font-size: 12px;
} }
.profile-user p { /* ========== 余额卡片 - 白色浮层 ========== */
margin: 7px 0 0; .balance-card {
color: #666f7c; position: relative;
font-size: 13px; margin: -24px 12px 0;
} padding: 18px 16px 14px;
.setting-icon {
color: #8b8f99;
cursor: pointer;
}
/* ========== 余额卡片 - 两行结构 ========== */
.balance-group {
margin-top: 10px;
border-radius: 16px; border-radius: 16px;
overflow: hidden; background: #fff;
box-shadow: 0 8px 26px rgba(24, 30, 45, 0.06); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
} }
.balance-main :deep(.van-cell__title) { .balance-row {
flex: none; display: flex;
align-items: center;
justify-content: space-between;
} }
.balance-main :deep(.van-cell__value) { .balance-info {
flex: 1; display: flex;
text-align: right; flex-direction: column;
gap: 4px;
} }
.balance-label { .balance-label {
color: #8b8f99; color: #8b8f99;
font-size: 13px; font-size: 12px;
font-weight: 700; font-weight: 600;
} }
.balance-value { .balance-value {
font-size: 32px; font-size: 26px;
line-height: 1; line-height: 1;
color: #1a202c; color: #1a202c;
font-weight: 900;
} }
.balance-actions { .balance-footer {
padding-top: 4px !important; margin-top: 10px;
padding-bottom: 12px !important; padding-top: 10px;
} border-top: 1px solid #f0f0f0;
.balance-actions :deep(.van-cell__title) {
flex: none;
}
.balance-actions :deep(.van-cell__value) {
flex: 1;
text-align: right;
} }
.detail-btn { .detail-btn {
@@ -414,60 +335,15 @@ function goToLogin() {
padding: 0 20px; padding: 0 20px;
} }
/* ========== 订单菜单 ========== */
.menu-section {
margin-top: 12px;
border-radius: 16px;
background: #fff;
padding: 16px 14px;
box-shadow: 0 8px 26px rgba(24, 30, 45, 0.06);
}
.menu-section h2 {
margin: 0 0 12px;
font-size: 18px;
}
.order-grid :deep(.van-grid-item__content) {
padding: 8px 4px;
background: transparent;
}
.menu-icon {
font-size: 25px;
line-height: 1;
}
.menu-text {
font-size: 13px;
font-weight: 700;
color: #5f6671;
}
/* ========== 服务菜单 ========== */
.service-group {
margin-top: 12px;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 8px 26px rgba(24, 30, 45, 0.06);
}
.service-group :deep(.van-cell-group) {
margin: 0;
}
.service-grid :deep(.van-grid-item__content) {
padding: 14px 4px;
background: #fff;
}
/* ========== 退出登录 ========== */ /* ========== 退出登录 ========== */
.logout-btn { .logout-btn {
margin-top: 14px; display: block;
border-radius: 14px; margin: 20px auto;
font-weight: 900; padding: 0 24px;
height: 48px; border-radius: 20px;
font-size: 16px; font-weight: 700;
height: 32px;
font-size: 13px;
} }
/* ========== 底部导航 - 手写原生 ========== */ /* ========== 底部导航 - 手写原生 ========== */
@@ -297,12 +297,12 @@ function readError(error: unknown, fallback: string) {
<span>首页</span> <span>首页</span>
</RouterLink> </RouterLink>
<RouterLink <RouterLink
to="/m/listings" to="/m/messages"
class="nav-item" class="nav-item"
:class="{ active: isNavActive('/m/listings') }" :class="{ active: isNavActive('/m/messages') }"
> >
<van-icon name="search" :size="22" /> <van-icon name="chat-o" :size="22" />
<span>租号</span> <span>消息</span>
</RouterLink> </RouterLink>
<RouterLink to="/m/seller/listings/create" class="nav-item nav-publish"> <RouterLink to="/m/seller/listings/create" class="nav-item nav-publish">
<div class="publish-pill">+</div> <div class="publish-pill">+</div>