Files
medical-mall/components/analytics/AnalyticsSidebarMenu.uvue
2026-01-23 16:33:11 +08:00

276 lines
6.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 数据分析侧边栏菜单组件 -->
<template>
<view>
<!-- 侧边栏菜单 -->
<view class="sidebar-menu" :class="{ active: showMenu, 'always-visible': isWideScreen }" @click.stop>
<view class="sidebar-content">
<view
v-for="item in menuItems"
:key="item.path"
class="menu-item"
:class="{ active: currentPath === item.path }"
@click="navigateToPage(item.path)"
>
<text class="menu-icon">{{ item.icon }}</text>
<text class="menu-text">{{ item.title }}</text>
</view>
</view>
</view>
<!-- 遮罩层(仅窄屏时显示) -->
<view class="sidebar-overlay" v-if="showMenu && !isWideScreen" @click="closeMenu"></view>
</view>
</template>
<script lang="uts">
// 菜单项类型
type MenuItem = {
path: string
title: string
icon: string
}
// 菜单配置
const MENU_ITEMS: Array<MenuItem> = [
{ path: '/pages/mall/analytics/index', title: '数据分析中心', icon: '📊' },
{ path: '/pages/mall/analytics/profile', title: '个人中心', icon: '👤' },
{ path: '/pages/mall/analytics/sales-report', title: '销售报表', icon: '💰' },
{ path: '/pages/mall/analytics/user-analysis', title: '用户分析', icon: '👥' },
{ path: '/pages/mall/analytics/product-insights', title: '商品洞察', icon: '📦' },
{ path: '/pages/mall/analytics/delivery-analysis', title: '配送效率分析', icon: '🚚' },
{ path: '/pages/mall/analytics/coupon-analysis', title: '优惠券效果分析', icon: '🎫' },
{ path: '/pages/mall/analytics/market-trends', title: '市场趋势', icon: '📈' },
{ path: '/pages/mall/analytics/custom-report', title: '自定义报表', icon: '📋' },
{ path: '/pages/mall/analytics/report-detail', title: '报表详情', icon: '📄' },
{ path: '/pages/mall/analytics/data-detail', title: '数据分析详情', icon: '🔍' },
{ path: '/pages/mall/analytics/insight-detail', title: '数据洞察详情', icon: '💡' }
]
export default {
props: {
// 是否显示菜单
visible: {
type: Boolean,
default: false
},
// 当前页面路径
currentPath: {
type: String,
default: ''
}
},
emits: ['visible-change'],
data() {
return {
showMenu: false,
menuItems: MENU_ITEMS,
isWideScreen: false,
screenWidth: 0
}
},
watch: {
visible(newVal: boolean) {
// 宽屏时自动显示,窄屏时根据 visible 控制
if (this.isWideScreen) {
this.showMenu = true
} else {
this.showMenu = newVal
}
},
showMenu(newVal: boolean) {
// 同步到父组件(仅窄屏时)
if (!this.isWideScreen) {
this.$emit('visible-change', newVal)
}
}
},
onLoad() {
this.checkScreenSize()
},
onShow() {
// 每次显示时检查屏幕尺寸
this.checkScreenSize()
},
methods: {
checkScreenSize() {
// 获取屏幕宽度
const systemInfo = uni.getSystemInfoSync()
this.screenWidth = systemInfo.windowWidth || systemInfo.screenWidth
// 宽屏阈值960px与页面响应式断点一致
this.isWideScreen = this.screenWidth >= 960
// 宽屏时自动显示菜单
if (this.isWideScreen) {
this.showMenu = true
}
},
closeMenu() {
// 宽屏时不允许关闭
if (this.isWideScreen) {
return
}
this.showMenu = false
this.$emit('visible-change', false)
},
navigateToPage(path: string) {
if (this.currentPath === path) {
// 窄屏时关闭菜单
if (!this.isWideScreen) {
this.closeMenu()
}
return
}
uni.navigateTo({
url: path,
fail: () => {
uni.showToast({ title: '页面跳转失败', icon: 'none' })
}
})
// 窄屏时关闭菜单
if (!this.isWideScreen) {
this.closeMenu()
}
}
}
}
</script>
<style>
/* 侧边栏菜单 */
.sidebar-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 998;
animation: fadeIn 0.3s ease;
}
.sidebar-menu {
position: fixed;
top: 0;
left: 0;
width: 280px;
height: 100vh;
background: #fff;
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
z-index: 999;
transform: translateX(-100%);
transition: transform 0.3s ease;
display: flex;
flex-direction: column;
}
/* 窄屏:抽屉效果 */
.sidebar-menu.active {
transform: translateX(0);
}
/* 宽屏:固定显示在左侧 */
.sidebar-menu.always-visible {
position: relative;
transform: translateX(0);
box-shadow: none;
border-right: 1px solid rgba(0, 0, 0, 0.06);
z-index: 1;
}
.sidebar-header {
display: flex;
flex-direction: row !important;
justify-content: flex-end;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}
.sidebar-close {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border-radius: 6px;
transition: background 0.2s;
}
.sidebar-close:hover {
background: rgba(0, 0, 0, 0.05);
}
.sidebar-close .icon {
font-size: 20px;
color: #666;
}
.sidebar-content {
flex: 1;
overflow-y: auto;
padding: 8px 0;
}
.menu-item {
display: flex;
flex-direction: row !important;
align-items: center;
gap: 12px;
padding: 12px 16px;
cursor: pointer;
transition: background 0.2s;
}
.menu-item:hover {
background: rgba(0, 0, 0, 0.03);
}
.menu-item.active {
background: rgba(59, 130, 246, 0.1);
border-left: 3px solid #3b82f6;
}
.menu-item.active .menu-text {
color: #3b82f6;
font-weight: 600;
}
.menu-icon {
font-size: 20px;
width: 24px;
text-align: center;
}
.menu-text {
font-size: 15px;
color: #333;
flex: 1;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
/* 响应式:宽屏时固定显示 */
@media screen and (min-width: 960px) {
.sidebar-menu {
position: relative;
transform: translateX(0);
box-shadow: none;
border-right: 1px solid rgba(0, 0, 0, 0.06);
z-index: 1;
}
.sidebar-overlay {
display: none;
}
}
</style>