Files
medical-mall/layouts/admin/index-simple.uvue

351 lines
6.3 KiB
Plaintext

<template>
<view class="admin-layout">
<!-- 左侧侧边栏 -->
<view class="admin-sider" :class="{ 'sider-collapsed': isCollapsed }">
<view class="sider-header">
<view class="logo">
<text class="logo-text">{{ isCollapsed ? 'M' : 'Mall Admin' }}</text>
</view>
<view class="collapse-trigger" @click="toggleCollapse">
<text class="iconfont">{{ isCollapsed ? 'icon-menu-unfold' : 'icon-menu-fold' }}</text>
</view>
</view>
<!-- 一级菜单 -->
<scroll-view class="menu-scroll" scroll-y="true">
<view class="menu-list">
<view
v-for="menu in menuList"
:key="menu.id"
class="menu-item"
:class="{ 'menu-active': activeMenu === menu.id }"
@click="handleMenuClick(menu)"
>
<view class="menu-icon">
<text class="iconfont">{{ menu.icon }}</text>
</view>
<view class="menu-content" v-if="!isCollapsed">
<text class="menu-text">{{ menu.title }}</text>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 主内容区 -->
<view class="admin-main" :class="{ 'main-collapsed': isCollapsed }">
<!-- 顶部头部 -->
<view class="admin-header">
<view class="header-left">
<view class="breadcrumb">
<text class="breadcrumb-item">{{ currentPageTitle }}</text>
</view>
</view>
<view class="header-right">
<view class="header-action" @click="handleSearch">
<text class="iconfont icon-search"></text>
</view>
<view class="header-user">
<text class="user-name">管理员</text>
</view>
</view>
</view>
<!-- 页面内容 -->
<scroll-view class="page-content" scroll-y="true">
<view class="page-wrapper">
<slot></slot>
</view>
</scroll-view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, computed } from 'vue'
// Props
const props = defineProps<{
currentPage: string
}>()
// 响应式数据
const isCollapsed = ref(false)
const activeMenu = ref('dashboard')
// 菜单数据
const menuList = ref([
{
id: 'dashboard',
title: '首页',
icon: 'icon-dashboard',
path: '/pages/mall/admin/index'
},
{
id: 'user',
title: '用户管理',
icon: 'icon-user',
path: '/pages/mall/admin/user-management'
},
{
id: 'product',
title: '商品管理',
icon: 'icon-shopping',
path: '/pages/mall/admin/product-management'
},
{
id: 'order',
title: '订单管理',
icon: 'icon-order',
path: '/pages/mall/admin/order-management'
},
{
id: 'finance',
title: '财务管理',
icon: 'icon-finance',
path: '/pages/mall/admin/finance-management'
},
{
id: 'system',
title: '系统设置',
icon: 'icon-setting',
path: '/pages/mall/admin/system-settings'
}
])
// 计算属性
const currentPageTitle = computed(() => {
const menu = menuList.value.find(m => m.id === props.currentPage)
return menu ? menu.title : '管理后台'
})
// 方法
const toggleCollapse = () => {
isCollapsed.value = !isCollapsed.value
}
const handleMenuClick = (menu: any) => {
activeMenu.value = menu.id
uni.navigateTo({
url: menu.path
})
}
const handleSearch = () => {
uni.showToast({
title: '搜索功能',
icon: 'none'
})
}
</script>
<style lang="scss">
.admin-layout {
display: flex;
height: 100vh;
background: #f0f2f5;
}
// 侧边栏
.admin-sider {
width: 240rpx;
background: #001529;
transition: width 0.3s;
display: flex;
flex-direction: column;
&.sider-collapsed {
width: 80rpx;
}
}
.sider-header {
height: 120rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24rpx;
border-bottom: 1rpx solid #002140;
}
.logo {
display: flex;
align-items: center;
}
.logo-text {
color: #fff;
font-size: 32rpx;
font-weight: bold;
}
.collapse-trigger {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
color: #fff;
border-radius: 6rpx;
transition: background-color 0.3s;
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
}
.menu-scroll {
flex: 1;
}
.menu-list {
padding: 16rpx 0;
}
.menu-item {
display: flex;
align-items: center;
height: 80rpx;
padding: 0 24rpx;
cursor: pointer;
color: rgba(255, 255, 255, 0.65);
transition: all 0.3s;
&:hover {
background-color: #1890ff;
color: #fff;
}
&.menu-active {
background-color: #1890ff;
color: #fff;
}
}
.menu-icon {
width: 40rpx;
text-align: center;
margin-right: 16rpx;
}
.menu-content {
flex: 1;
}
.menu-text {
font-size: 28rpx;
}
// 主内容区
.admin-main {
flex: 1;
display: flex;
flex-direction: column;
transition: margin-left 0.3s;
}
// 头部
.admin-header {
height: 120rpx;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
border-bottom: 1rpx solid #e8e8e8;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
}
.header-left {
display: flex;
align-items: center;
}
.breadcrumb {
font-size: 28rpx;
color: #666;
}
.breadcrumb-item {
color: #1890ff;
}
.header-right {
display: flex;
align-items: center;
gap: 24rpx;
}
.header-action {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
color: #666;
border-radius: 6rpx;
transition: all 0.3s;
&:hover {
background-color: #f5f5f5;
color: #1890ff;
}
}
.header-user {
display: flex;
align-items: center;
gap: 12rpx;
cursor: pointer;
padding: 8rpx 16rpx;
border-radius: 6rpx;
transition: background-color 0.3s;
&:hover {
background-color: #f5f5f5;
}
}
.user-name {
font-size: 28rpx;
color: #666;
}
// 页面内容
.page-content {
flex: 1;
background: #f0f2f5;
}
.page-wrapper {
padding: 32rpx;
min-height: calc(100vh - 120rpx);
}
// 响应式设计
@media screen and (max-width: 768rpx) {
.admin-sider {
width: 200rpx;
&.sider-collapsed {
width: 0;
overflow: hidden;
}
}
.admin-header {
padding: 0 16rpx;
}
.page-wrapper {
padding: 16rpx;
}
}
.iconfont {
font-family: 'iconfont';
font-size: 24rpx;
}
</style>