mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-13 12:28:54 +08:00
feat(buyer): 增强搜索功能并提升用户体验
- 新增 `getStoreById` 接口方法,用于获取包含评分在内的店铺信息 - `Search.vue` 新增搜索建议面板,展示搜索历史和热词,优化搜索体验 - 新增 `SearchSuggest.vue` 组件,用于展示搜索建议和搜索历史 - `App.vue` 根据路由元信息按条件设置页面标题 - 优化多个组件的布局与样式,让整体风格更统一 - 重构多个组件的跳转逻辑,改用路由跳转(`router.push`)替代新开窗口(`window.open`),提升用户体验
This commit is contained in:
@@ -1,35 +1,271 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="userBox">
|
||||
<div class="box">
|
||||
<!-- 我的订单组件 -->
|
||||
<myOrderPage :homePage="true" />
|
||||
</div>
|
||||
<div class="box">
|
||||
<!-- 近期收藏 -->
|
||||
<myFavorites :homePage="true" />
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="member-home">
|
||||
<div class="home-head">
|
||||
<div>
|
||||
<div class="home-hello">你好,{{ displayName }}</div>
|
||||
<div class="home-sub">查看订单进度、优惠券和账户余额</div>
|
||||
</div>
|
||||
<button type="button" class="msg-entry" @click="go('MsgList')">
|
||||
<el-icon :size="18"><Bell /></el-icon>
|
||||
<span>我的消息</span>
|
||||
<i v-if="unreadMsg > 0" class="msg-badge">{{ unreadLabel }}</i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="status-grid">
|
||||
<button
|
||||
v-for="item in orderStats"
|
||||
:key="item.key"
|
||||
type="button"
|
||||
class="stat-card"
|
||||
@click="item.action()"
|
||||
>
|
||||
<span class="stat-count">{{ item.count }}</span>
|
||||
<span class="stat-label">{{ item.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="asset-grid">
|
||||
<button type="button" class="asset-card" @click="go('Coupons')">
|
||||
<div>
|
||||
<div class="asset-label">优惠券</div>
|
||||
<div class="asset-value">{{ couponCount }}<span>张可用</span></div>
|
||||
</div>
|
||||
<span class="asset-link">查看</span>
|
||||
</button>
|
||||
<button type="button" class="asset-card" @click="go('MoneyManagement')">
|
||||
<div>
|
||||
<div class="asset-label">账户余额</div>
|
||||
<div class="asset-value">¥{{ $filters.unitPrice(balance) }}</div>
|
||||
</div>
|
||||
<span class="asset-link">查看</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import myOrderPage from '@/pages/home/orderCenter/MyOrder'
|
||||
import myFavorites from '@/pages/home/memberCenter/Favorites'
|
||||
import { Bell } from "@element-plus/icons-vue";
|
||||
import storage from "@/plugins/storage";
|
||||
import { getOrderList } from "@/api/order";
|
||||
import { afterSaleList, getMembersWallet, memberCouponList } from "@/api/member";
|
||||
import { refreshUnreadMessage } from "@/utils/unreadMessage";
|
||||
|
||||
function totalOf(res) {
|
||||
return res && res.success ? Number(res.result && res.result.total) || 0 : 0;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'main',
|
||||
components: {
|
||||
myOrderPage,
|
||||
myFavorites
|
||||
}
|
||||
}
|
||||
name: "UserCenterHome",
|
||||
components: { Bell },
|
||||
data() {
|
||||
return {
|
||||
displayName: "会员",
|
||||
waitPay: 0,
|
||||
waitShip: 0,
|
||||
waitReceive: 0,
|
||||
afterSale: 0,
|
||||
couponCount: 0,
|
||||
balance: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
unreadMsg() {
|
||||
return Number(this.$store.state.unreadMsg) || 0;
|
||||
},
|
||||
unreadLabel() {
|
||||
return this.unreadMsg > 99 ? "99+" : String(this.unreadMsg);
|
||||
},
|
||||
orderStats() {
|
||||
return [
|
||||
{ key: "pay", label: "待付款", count: this.waitPay, action: () => this.goOrder("WAIT_PAY") },
|
||||
{ key: "ship", label: "待发货", count: this.waitShip, action: () => this.goOrder("WAIT_SHIP") },
|
||||
{ key: "receive", label: "待收货", count: this.waitReceive, action: () => this.goOrder("WAIT_USE") },
|
||||
{ key: "after", label: "售后", count: this.afterSale, action: () => this.go("AfterSale") },
|
||||
];
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.readUser();
|
||||
this.loadSummary();
|
||||
},
|
||||
methods: {
|
||||
readUser() {
|
||||
try {
|
||||
const raw = storage.getItem("userInfo");
|
||||
const user = raw ? JSON.parse(raw) : {};
|
||||
this.displayName = user.nickName || user.username || "会员";
|
||||
} catch {
|
||||
this.displayName = "会员";
|
||||
}
|
||||
},
|
||||
loadSummary() {
|
||||
const page = { pageNumber: 1, pageSize: 1 };
|
||||
Promise.all([
|
||||
getOrderList({ ...page, tag: "WAIT_PAY" }).catch(() => null),
|
||||
getOrderList({ ...page, tag: "WAIT_SHIP" }).catch(() => null),
|
||||
getOrderList({ ...page, tag: "WAIT_USE" }).catch(() => null),
|
||||
afterSaleList({ ...page, sort: "createTime", order: "desc" }).catch(() => null),
|
||||
memberCouponList({ ...page, memberCouponStatus: "NEW" }).catch(() => null),
|
||||
getMembersWallet().catch(() => null),
|
||||
refreshUnreadMessage(),
|
||||
]).then(([pay, ship, receive, afterSale, coupon, wallet]) => {
|
||||
this.waitPay = totalOf(pay);
|
||||
this.waitShip = totalOf(ship);
|
||||
this.waitReceive = totalOf(receive);
|
||||
this.afterSale = totalOf(afterSale);
|
||||
this.couponCount = totalOf(coupon);
|
||||
this.balance = wallet && wallet.success ? wallet.result.memberWallet || 0 : 0;
|
||||
});
|
||||
},
|
||||
go(name) {
|
||||
this.$router.push({ name });
|
||||
},
|
||||
goOrder(tag) {
|
||||
this.$router.push({ name: "MyOrder", query: { tag } });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.userBox {
|
||||
padding: 0 0 20px 0;
|
||||
.member-home {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.home-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding: 4px 4px 8px;
|
||||
}
|
||||
|
||||
.home-hello {
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.home-sub {
|
||||
margin-top: 4px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.msg-entry {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
height: 36px;
|
||||
padding: 0 14px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 18px;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $theme_color;
|
||||
border-color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.msg-badge {
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
padding: 0 4px;
|
||||
border-radius: 8px;
|
||||
background: $theme_color;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.status-grid,
|
||||
.asset-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.status-grid {
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.asset-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.stat-card,
|
||||
.asset-card {
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
border-color: $theme_color;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding: 18px 16px;
|
||||
}
|
||||
|
||||
.stat-count {
|
||||
color: $theme_color;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.asset-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 18px 20px;
|
||||
}
|
||||
|
||||
.asset-label {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.asset-value {
|
||||
margin-top: 4px;
|
||||
color: #333;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
line-height: 28px;
|
||||
|
||||
span {
|
||||
margin-left: 4px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.asset-link {
|
||||
color: $theme_color;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user