feat(buyer): 增强搜索功能并提升用户体验

- 新增 `getStoreById` 接口方法,用于获取包含评分在内的店铺信息
- `Search.vue` 新增搜索建议面板,展示搜索历史和热词,优化搜索体验
- 新增 `SearchSuggest.vue` 组件,用于展示搜索建议和搜索历史
- `App.vue` 根据路由元信息按条件设置页面标题
- 优化多个组件的布局与样式,让整体风格更统一
- 重构多个组件的跳转逻辑,改用路由跳转(`router.push`)替代新开窗口(`window.open`),提升用户体验
This commit is contained in:
pikachu1995@126.com
2026-10-02 15:26:58 +08:00
parent 4777eb2dd6
commit 8410179885
44 changed files with 2116 additions and 674 deletions

View File

@@ -24,17 +24,25 @@
<p>{{ userInfo.nickName }}</p>
</div>
<el-menu-item index="UserCenter">
<el-icon><House /></el-icon>
<span>我的主页</span>
</el-menu-item>
<template v-for="(menu, index) in menuList" :key="index">
<el-sub-menu v-if="menu.display" :index="menu.title">
<template #title>
<el-icon><Location /></el-icon>
<el-icon><component :is="menuIcon(menu.icon)" /></el-icon>
<span>{{ menu.title }}</span>
</template>
<el-menu-item
v-for="(chlidren, i) in menu.menus"
:key="i"
:index="chlidren.path"
>{{ chlidren.title }}</el-menu-item>
>
<el-icon><component :is="menuIcon(chlidren.icon)" /></el-icon>
<span>{{ chlidren.title }}</span>
<span v-if="chlidren.path === 'MsgList' && unreadMsg > 0" class="menu-badge">{{ unreadLabel }}</span>
</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
@@ -48,12 +56,51 @@
</template>
<script>
import { Location, User } from '@element-plus/icons-vue';
import {
Bell,
ChatDotRound,
Clock,
Coin,
Goods,
House,
List,
Location,
Lock,
Present,
RefreshLeft,
Star,
Ticket,
Trophy,
User,
Wallet,
Warning,
} from '@element-plus/icons-vue';
import menuList from "./menu";
import Storage from "@/plugins/storage.js";
import { refreshUnreadMessage } from "@/utils/unreadMessage";
const MENU_ICONS = {
Bell,
ChatDotRound,
Clock,
Coin,
Goods,
House,
List,
Location,
Lock,
Present,
RefreshLeft,
Star,
Ticket,
Trophy,
User,
Wallet,
Warning,
};
export default {
components: { Location, User },
components: { House, User },
name: "Home",
data() {
return {
@@ -67,14 +114,24 @@ export default {
}
return {};
},
unreadMsg() {
return Number(this.$store.state.unreadMsg) || 0;
},
unreadLabel() {
return this.unreadMsg > 99 ? "99+" : String(this.unreadMsg);
},
},
mounted() {
document.body.classList.add("buyer-user-center");
refreshUnreadMessage();
},
beforeUnmount() {
document.body.classList.remove("buyer-user-center");
},
methods: {
menuIcon(name) {
return MENU_ICONS[name] || Goods;
},
onSelect(name) {
this.$router.push({ name });
},
@@ -134,6 +191,38 @@ export default {
overflow: hidden;
}
.side-menu {
:deep(.el-menu-item),
:deep(.el-sub-menu__title) {
display: flex;
align-items: center;
}
:deep(.el-menu-item .el-icon),
:deep(.el-sub-menu__title .el-icon) {
margin-right: 6px;
}
}
.menu-badge {
margin-left: auto;
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;
}
/* 选中项会把文字设成主题红。角标用 span,避免 i 继承成红底红字 */
.side-menu :deep(.el-menu-item.is-active) .menu-badge {
color: #fff;
}
.layout-footer-center {
padding: 0px 15px;
padding-bottom: 15px;