Files
medical-mall/layouts/admin/defaults.uvue

453 lines
11 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.
<!-- CRMEB Admin Defaults布局 - uni-app版本 -->
<template>
<view class="layout-container">
<!-- 侧边栏 -->
<AdminAside
:is-collapsed="isCollapsed"
:menu-list="menuList"
:active-menu="activeMenu"
@toggle-collapse="handleToggleCollapse"
@menu-click="handleMenuClick"
/>
<!-- 主内容区域 -->
<view class="main-container" :class="{ 'main-collapsed': isCollapsed }">
<!-- 顶部导航栏 -->
<AdminHeader
:is-collapsed="isCollapsed"
:current-page-title="currentPageTitle"
@toggle-collapse="handleToggleCollapse"
/>
<!-- 页面内容 -->
<view class="page-content">
<scroll-view
class="content-scroll"
scroll-y="true"
:style="{ height: contentHeight }"
>
<slot></slot>
</scroll-view>
</view>
<!-- 返回顶部按钮 -->
<view
class="back-top"
v-if="showBackTop"
@click="scrollToTop"
>
<text class="iconfont icon-top"></text>
</view>
</view>
<!-- 移动端遮罩 -->
<view
class="mobile-overlay"
v-if="showOverlay"
@click="closeSidebar"
></view>
</view>
</template>
<script>
import AdminAside from './aside.uvue'
import AdminHeader from './header.uvue'
import type { MenuItem } from './types.uts'
export default {
name: 'AdminDefaults',
components: {
AdminAside,
AdminHeader
},
props: {
currentPage: {
type: String,
required: true
}
},
data() {
return {
isCollapsed: false,
showOverlay: false,
showBackTop: false,
activeMenu: '',
openMenus: [] as string[],
menuList: [] as MenuItem[],
contentHeight: '100vh',
scrollTop: 0
}
},
computed: {
currentPageTitle() {
const findMenuTitle = (menus: MenuItem[]): string => {
for (const menu of menus) {
if (menu.id === this.activeMenu) {
return menu.title
}
if (menu.children) {
const subTitle = findMenuTitle(menu.children)
if (subTitle) return subTitle
}
}
return '管理后台'
}
return findMenuTitle(this.menuList)
}
},
onLoad() {
this.initLayout()
this.initMenuData()
this.updateActiveMenu()
},
onShow() {
this.updateActiveMenu()
},
methods: {
// 初始化布局
initLayout() {
// 获取侧边栏状态
const collapsed = uni.getStorageSync('admin_sidebar_collapsed')
this.isCollapsed = collapsed === true
// 获取展开的菜单
const openMenus = uni.getStorageSync('admin_open_menus')
if (openMenus) {
this.openMenus = openMenus
}
// 设置内容高度
this.setContentHeight()
},
// 初始化菜单数据
initMenuData() {
// 这里应该从配置或API获取菜单数据
// 暂时使用静态数据实际项目中应该从配置文件或API获取
this.menuList = [
{
id: 'dashboard',
title: '首页',
icon: 'icon-shujutongji',
path: '/pages/mall/admin/index'
},
{
id: 'user',
title: '用户管理',
icon: 'icon-yonghuguanli',
children: [
{
id: 'user-list',
title: '用户列表',
icon: 'icon-yonghuguanli',
path: '/pages/mall/admin/user-management'
},
{
id: 'user-detail',
title: '用户详情',
icon: 'icon-yonghuguanli',
path: '/pages/mall/admin/user-detail'
}
]
},
{
id: 'merchant',
title: '商家管理',
icon: 'icon-shangjiaguanli',
children: [
{
id: 'merchant-list',
title: '商家列表',
icon: 'icon-shangjiaguanli',
path: '/pages/mall/admin/merchant-management'
},
{
id: 'merchant-review',
title: '商家审核',
icon: 'icon-shenhe',
path: '/pages/mall/admin/merchant-review'
}
]
},
{
id: 'product',
title: '商品管理',
icon: 'icon-shangpinguanli',
children: [
{
id: 'product-list',
title: '商品列表',
icon: 'icon-shangpinguanli',
path: '/pages/mall/admin/product-management'
},
{
id: 'product-review',
title: '商品审核',
icon: 'icon-shenhe',
path: '/pages/mall/admin/product-review'
}
]
},
{
id: 'order',
title: '订单管理',
icon: 'icon-dingdanguanli',
path: '/pages/mall/admin/order-management'
},
{
id: 'finance',
title: '财务管理',
icon: 'icon-caiwuguanli',
path: '/pages/mall/admin/finance-management'
},
{
id: 'marketing',
title: '营销管理',
icon: 'icon-yingxiaoguanli',
children: [
{
id: 'coupon',
title: '优惠券',
icon: 'icon-youhuiquan',
path: '/pages/mall/admin/coupon-management'
},
{
id: 'marketing-main',
title: '营销活动',
icon: 'icon-yingxiaoguanli',
path: '/pages/mall/admin/marketing-management'
}
]
},
{
id: 'delivery',
title: '配送管理',
icon: 'icon-dingdanguanli',
path: '/pages/mall/admin/delivery-management'
},
{
id: 'subscription',
title: '订阅管理',
icon: 'icon-gongnengdaohang',
children: [
{
id: 'plan-management',
title: '方案管理',
icon: 'icon-gongnengdaohang',
path: '/pages/mall/admin/subscription/plan-management'
},
{
id: 'user-subscriptions',
title: '用户订阅',
icon: 'icon-gongnengdaohang',
path: '/pages/mall/admin/subscription/user-subscriptions'
}
]
},
{
id: 'review',
title: '审核管理',
icon: 'icon-shenhe',
children: [
{
id: 'product-review',
title: '商品审核',
icon: 'icon-shenhe',
path: '/pages/mall/admin/product-review'
},
{
id: 'merchant-review',
title: '商家审核',
icon: 'icon-shenhe',
path: '/pages/mall/admin/merchant-review'
},
{
id: 'refund-review',
title: '退款处理',
icon: 'icon-shenhe',
path: '/pages/mall/admin/refund-review'
}
]
},
{
id: 'complaints',
title: '投诉处理',
icon: 'icon-tousu',
path: '/pages/mall/admin/complaints'
},
{
id: 'notification',
title: '通知中心',
icon: 'icon-notification',
path: '/pages/mall/admin/notifications'
},
{
id: 'activity-log',
title: '活动日志',
icon: 'icon-rizhi',
path: '/pages/mall/admin/activity-log'
},
{
id: 'layout-test',
title: '布局测试',
icon: 'icon-kaifa',
path: '/pages/mall/admin/layout-test'
},
{
id: 'system',
title: '系统设置',
icon: 'icon-xitongshezhi',
path: '/pages/mall/admin/system-settings'
}
]
},
// 更新当前激活的菜单
updateActiveMenu() {
// 使用传入的currentPage prop来设置激活菜单
if (this.currentPage) {
this.activeMenu = this.currentPage
}
},
// 处理侧边栏切换
handleToggleCollapse() {
this.isCollapsed = !this.isCollapsed
uni.setStorageSync('admin_sidebar_collapsed', this.isCollapsed)
// 移动端处理
if (this.isMobile() && !this.isCollapsed) {
this.showOverlay = true
} else {
this.showOverlay = false
}
},
// 处理菜单点击
handleMenuClick(menu: MenuItem) {
if (menu.children && menu.children.length > 0) {
// 有子菜单,切换展开状态
const index = this.openMenus.indexOf(menu.id)
if (index > -1) {
this.openMenus.splice(index, 1)
} else {
this.openMenus.push(menu.id)
}
uni.setStorageSync('admin_open_menus', this.openMenus)
} else if (menu.path) {
// 叶子节点,跳转页面
this.activeMenu = menu.id
uni.navigateTo({
url: menu.path,
fail: () => {
// 如果navigateTo失败尝试switchTab
uni.switchTab({
url: menu.path
})
}
})
}
},
// 关闭侧边栏(移动端)
closeSidebar() {
if (this.isMobile()) {
this.isCollapsed = true
this.showOverlay = false
uni.setStorageSync('admin_sidebar_collapsed', true)
}
},
// 设置内容高度
setContentHeight() {
const systemInfo = uni.getSystemInfoSync()
// 减去顶部导航栏高度约88rpx和底部安全区域
this.contentHeight = `calc(${systemInfo.windowHeight}px - 88rpx)`
},
// 滚动到顶部
scrollToTop() {
this.scrollTop = 0
},
// 判断是否为移动端
isMobile(): boolean {
const systemInfo = uni.getSystemInfoSync()
return systemInfo.windowWidth < 768
}
}
}
</script>
<style lang="scss">
.layout-container {
display: flex;
height: 100vh;
background-color: #f0f2f5;
}
/* 主内容区域 */
.main-container {
flex: 1;
display: flex;
flex-direction: column;
transition: margin-left 0.3s ease;
background-color: #f0f2f5;
}
.main-collapsed {
margin-left: 80rpx;
}
/* 页面内容 */
.page-content {
flex: 1;
overflow: hidden;
}
.content-scroll {
height: 100%;
padding: 20rpx;
}
/* 返回顶部按钮 */
.back-top {
position: fixed;
right: 40rpx;
bottom: 40rpx;
width: 80rpx;
height: 80rpx;
background-color: #1890ff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 32rpx;
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.3);
z-index: 1000;
}
.back-top:active {
transform: scale(0.95);
}
/* 移动端遮罩 */
.mobile-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 999;
}
/* 响应式设计 */
@media screen and (max-width: 768rpx) {
.main-collapsed {
margin-left: 0 !important;
}
}
</style>