完善页面布局
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<view class="aside">
|
||||
<view
|
||||
class="aside"
|
||||
:style="{ width: asideWidth + 'px' }"
|
||||
>
|
||||
<view class="aside-header">
|
||||
<view class="logo">
|
||||
<text class="logo-text">{{ collapsed ? '商' : '商城后台' }}</text>
|
||||
@@ -31,6 +34,7 @@ defineProps<{
|
||||
collapsed: boolean
|
||||
menuList: MenuItem[]
|
||||
activeMenuId: string
|
||||
asideWidth:number
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
@@ -41,7 +45,6 @@ defineEmits<{
|
||||
|
||||
<style>
|
||||
.aside{
|
||||
width: 96px;
|
||||
background: #1f2a37;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
|
||||
@@ -34,13 +34,20 @@ defineEmits<{
|
||||
background:#fff;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
|
||||
align-items:center;
|
||||
justify-content: space-between;
|
||||
padding: 0 16px;
|
||||
}
|
||||
.crumb{ color:#374151; font-size:14px; }
|
||||
|
||||
.header-right{ display:flex; align-items:center; gap: 10px; }
|
||||
.header-right{
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
align-items:center;
|
||||
gap: 10px;
|
||||
}
|
||||
.hbtn{
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
<template>
|
||||
<view class="sub-sider" v-if="groups && groups.length > 0">
|
||||
<view
|
||||
class="sub-sider"
|
||||
v-if="groups && groups.length > 0"
|
||||
:style="{ left: props.asideWidth + 'px', width: props.siderWidth + 'px' }"
|
||||
>
|
||||
<view class="sub-header">
|
||||
<text class="sub-title">{{ activeMenuTitle }}</text>
|
||||
<view class="sub-collapse" @click="collapsed = !collapsed">
|
||||
<text class="sub-collapse-text">{{ collapsed ? '›' : '‹' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="sub-body" scroll-y="true">
|
||||
<view v-for="(g, gi) in groups" :key="gi" class="group">
|
||||
<view class="group-title" @click="toggleGroup(g.title)">
|
||||
<view
|
||||
v-for="g in groups"
|
||||
:key="groupKey(g)"
|
||||
class="group"
|
||||
>
|
||||
<view class="group-title" @click="toggleGroup(groupKey(g))">
|
||||
<text class="group-title-text">{{ g.title }}</text>
|
||||
<text class="group-arrow">{{ isGroupOpen(g.title) ? '˄' : '˅' }}</text>
|
||||
<text class="group-arrow" :class="{ open: isGroupOpen(groupKey(g)) }">v</text>
|
||||
</view>
|
||||
|
||||
<view v-if="isGroupOpen(g.title)">
|
||||
<view v-show="isGroupOpen(groupKey(g))" class="group-children">
|
||||
<view
|
||||
v-for="c in g.children"
|
||||
:key="c.id"
|
||||
class="sub-item"
|
||||
:class="{ active: activeSubId === c.id }"
|
||||
@click="$emit('sub-click', c)"
|
||||
:class="{ active: resolvedActiveId === c.id }"
|
||||
@click.stop="handleClick(c)"
|
||||
>
|
||||
<text class="sub-item-text" :class="{ activeText: activeSubId === c.id }">
|
||||
<text class="sub-item-text" :class="{ activeText: resolvedActiveId === c.id }">
|
||||
{{ c.title }}
|
||||
</text>
|
||||
</view>
|
||||
@@ -33,91 +38,312 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import type { MenuGroup, MenuChild } from '../types.uts'
|
||||
|
||||
const props = defineProps<{
|
||||
activeMenuTitle: string
|
||||
groups: MenuGroup[]
|
||||
activeSubId: string
|
||||
asideWidth: number
|
||||
siderWidth: number
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
(e:'sub-click', child: MenuChild): void
|
||||
const emit = defineEmits<{
|
||||
(e: 'sub-click', child: MenuChild): void
|
||||
}>()
|
||||
|
||||
const collapsed = ref(false)
|
||||
const openGroups = ref<string[]>([])
|
||||
/** 只展开一个分组(更像 CRMEB) */
|
||||
const openGroupKey = ref<string>('')
|
||||
|
||||
const isGroupOpen = (title: string): boolean => {
|
||||
// 默认展开第一个分组 + 当前高亮分组(简单策略)
|
||||
if (openGroups.value.length === 0 && props.groups && props.groups.length > 0) return props.groups[0].title === title
|
||||
return openGroups.value.includes(title)
|
||||
/** 给 group 一个稳定 key:优先用 id(如果你 types 里没有 id,就用 title) */
|
||||
const groupKey = (g: MenuGroup): string => {
|
||||
// @ts-ignore - 允许 g.id 可选
|
||||
const anyG: any = g as any
|
||||
return (anyG.id && (anyG.id as string)) ? (anyG.id as string) : g.title
|
||||
}
|
||||
|
||||
const toggleGroup = (title: string) => {
|
||||
if (openGroups.value.includes(title)) {
|
||||
openGroups.value = openGroups.value.filter(t => t !== title)
|
||||
} else {
|
||||
openGroups.value = [...openGroups.value, title]
|
||||
const normalizePath = (p: string): string => {
|
||||
if (!p) return ''
|
||||
// 统一去掉开头 /
|
||||
const s = p.startsWith('/') ? p.slice(1) : p
|
||||
// 去掉 query
|
||||
const q = s.indexOf('?')
|
||||
return q >= 0 ? s.slice(0, q) : s
|
||||
}
|
||||
|
||||
/** 扁平查找:id -> child */
|
||||
const findChildById = (id: string): MenuChild | null => {
|
||||
if (!id) return null
|
||||
for (const g of props.groups) {
|
||||
for (const c of g.children) {
|
||||
if (c.id === id) return c
|
||||
// 兼容未来有更深层 children(递归)
|
||||
// @ts-ignore
|
||||
const anyC: any = c as any
|
||||
// @ts-ignore
|
||||
if (anyC.children && (anyC.children as MenuChild[]).length > 0) {
|
||||
// @ts-ignore
|
||||
const hit = findFirstMatchInChildren(id, anyC.children as MenuChild[])
|
||||
if (hit) return hit
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const findFirstMatchInChildren = (id: string, list: MenuChild[]): MenuChild | null => {
|
||||
for (const n of list) {
|
||||
if (n.id === id) return n
|
||||
// @ts-ignore
|
||||
const anyN: any = n as any
|
||||
// @ts-ignore
|
||||
if (anyN.children && (anyN.children as MenuChild[]).length > 0) {
|
||||
// @ts-ignore
|
||||
const hit = findFirstMatchInChildren(id, anyN.children as MenuChild[])
|
||||
if (hit) return hit
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const findChildByPath = (path: string): MenuChild | null => {
|
||||
const target = normalizePath(path)
|
||||
if (!target) return null
|
||||
for (const g of props.groups) {
|
||||
for (const c of g.children) {
|
||||
if (normalizePath(c.path) === target) return c
|
||||
// 兼容更深层 children(递归)
|
||||
// @ts-ignore
|
||||
const anyC: any = c as any
|
||||
// @ts-ignore
|
||||
if (anyC.children && (anyC.children as MenuChild[]).length > 0) {
|
||||
// @ts-ignore
|
||||
const hit = findFirstMatchByPath(target, anyC.children as MenuChild[])
|
||||
if (hit) return hit
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const findFirstMatchByPath = (targetNorm: string, list: MenuChild[]): MenuChild | null => {
|
||||
for (const n of list) {
|
||||
if (normalizePath(n.path) === targetNorm) return n
|
||||
// @ts-ignore
|
||||
const anyN: any = n as any
|
||||
// @ts-ignore
|
||||
if (anyN.children && (anyN.children as MenuChild[]).length > 0) {
|
||||
// @ts-ignore
|
||||
const hit = findFirstMatchByPath(targetNorm, anyN.children as MenuChild[])
|
||||
if (hit) return hit
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/** 找到某个 child 属于哪个 group,用于自动展开该组 */
|
||||
const findGroupKeyByChildId = (id: string): string => {
|
||||
for (const g of props.groups) {
|
||||
for (const c of g.children) {
|
||||
if (c.id === id) return groupKey(g)
|
||||
// @ts-ignore
|
||||
const anyC: any = c as any
|
||||
// @ts-ignore
|
||||
if (anyC.children && (anyC.children as MenuChild[]).length > 0) {
|
||||
// 深层命中也算这个 group
|
||||
// @ts-ignore
|
||||
const hit = findFirstMatchInChildren(id, anyC.children as MenuChild[])
|
||||
if (hit) return groupKey(g)
|
||||
}
|
||||
}
|
||||
}
|
||||
// fallback:第一个 group
|
||||
return props.groups.length > 0 ? groupKey(props.groups[0]) : ''
|
||||
}
|
||||
|
||||
/** 递归取第一个 leaf 菜单:你要求的“默认打开第一个页面(递归)” */
|
||||
const firstLeaf = (): MenuChild | null => {
|
||||
if (!props.groups || props.groups.length === 0) return null
|
||||
const g0 = props.groups[0]
|
||||
if (!g0.children || g0.children.length === 0) return null
|
||||
|
||||
const c0: any = g0.children[0] as any
|
||||
if (c0.children && (c0.children as MenuChild[]).length > 0) {
|
||||
// @ts-ignore
|
||||
return findFirstLeafInChildren(c0.children as MenuChild[])
|
||||
}
|
||||
return g0.children[0]
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const findFirstLeafInChildren = (list: MenuChild[]): MenuChild | null => {
|
||||
if (!list || list.length === 0) return null
|
||||
const n: any = list[0] as any
|
||||
if (n.children && (n.children as MenuChild[]).length > 0) {
|
||||
// @ts-ignore
|
||||
return findFirstLeafInChildren(n.children as MenuChild[])
|
||||
}
|
||||
return list[0]
|
||||
}
|
||||
|
||||
/**
|
||||
* 高亮兜底:如果 activeSubId 没同步(你现在遇到的“点了不高亮”),
|
||||
* 就按当前页面 route/path 再匹配一次。
|
||||
* uni-app-x 的 getCurrentPages() 返回页面对象,page.route 可取当前路由。:contentReference[oaicite:3]{index=3}
|
||||
*/
|
||||
const resolvedActiveId = computed((): string => {
|
||||
const byId = findChildById(props.activeSubId)
|
||||
if (byId) return byId.id
|
||||
|
||||
try {
|
||||
const pages = getCurrentPages()
|
||||
if (pages && pages.length > 0) {
|
||||
// @ts-ignore
|
||||
const cur: any = pages[pages.length - 1]
|
||||
// @ts-ignore
|
||||
const route: string = cur.route ? (cur.route as string) : ''
|
||||
const hit = findChildByPath(route)
|
||||
if (hit) return hit.id
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
return props.activeSubId || ''
|
||||
})
|
||||
|
||||
const isGroupOpen = (key: string): boolean => {
|
||||
if (!openGroupKey.value) {
|
||||
// 初始默认展开第一个组
|
||||
return props.groups && props.groups.length > 0 ? groupKey(props.groups[0]) === key : false
|
||||
}
|
||||
return openGroupKey.value === key
|
||||
}
|
||||
|
||||
const toggleGroup = (key: string) => {
|
||||
openGroupKey.value = (openGroupKey.value === key) ? '' : key
|
||||
}
|
||||
|
||||
const handleClick = (c: MenuChild) => {
|
||||
// 点击就让该组展开(用户体验更 CRMEB)
|
||||
openGroupKey.value = findGroupKeyByChildId(c.id)
|
||||
emit('sub-click', c)
|
||||
}
|
||||
|
||||
/** 自动:当 groups 变了/activeSubId 无效时,默认跳第一个 leaf(递归)并展开对应 group */
|
||||
const ensureDefault = () => {
|
||||
if (!props.groups || props.groups.length === 0) return
|
||||
|
||||
// activeSubId 有效:展开它所在组
|
||||
const hit = findChildById(props.activeSubId)
|
||||
if (hit) {
|
||||
openGroupKey.value = findGroupKeyByChildId(hit.id)
|
||||
return
|
||||
}
|
||||
|
||||
// activeSubId 无效/空:默认递归选第一个 leaf
|
||||
const first = firstLeaf()
|
||||
if (first) {
|
||||
openGroupKey.value = findGroupKeyByChildId(first.id)
|
||||
emit('sub-click', first)
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.groups,
|
||||
() => { ensureDefault() },
|
||||
{ immediate: true, deep: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.activeSubId,
|
||||
() => { ensureDefault() },
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.sub-sider{
|
||||
width: 240px;
|
||||
background:#ffffff;
|
||||
border-right: 1px solid #e5e7eb;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
left: 96px; /* 紧贴主侧边栏 */
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 900;
|
||||
}
|
||||
|
||||
.sub-header{
|
||||
height: 56px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content: space-between;
|
||||
padding: 0 16px;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
}
|
||||
.sub-title{ font-size:16px; font-weight:600; color:#111827; }
|
||||
.sub-collapse{ width:28px; height:28px; display:flex; align-items:center; justify-content:center; }
|
||||
.sub-collapse-text{ color:#6b7280; }
|
||||
.sub-title{
|
||||
font-size:16px;
|
||||
font-weight:700;
|
||||
color:#111827;
|
||||
}
|
||||
|
||||
.sub-body{ height: calc(100vh - 56px); }
|
||||
.sub-body{
|
||||
height: calc(100vh - 56px);
|
||||
}
|
||||
|
||||
/* CRMEB 风格:分组“块”更明显 */
|
||||
.group{ padding: 8px 0; }
|
||||
|
||||
.group-title{
|
||||
height: 44px;
|
||||
padding: 0 16px;
|
||||
height: 42px;
|
||||
margin: 8px 12px 6px 12px;
|
||||
padding: 0 14px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content: space-between;
|
||||
background: #f6f7fb;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.group-title-text{
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color:#111827;
|
||||
}
|
||||
.group-title-text{ font-size:15px; font-weight:600; }
|
||||
.group-arrow{ color:#6b7280; }
|
||||
|
||||
.group-arrow{
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
.group-arrow.open{
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.group-children{
|
||||
padding: 0 12px 6px 12px;
|
||||
}
|
||||
|
||||
/* 子菜单:缩进 + 更小高度 */
|
||||
.sub-item{
|
||||
height: 44px;
|
||||
padding: 0 16px;
|
||||
height: 34px;
|
||||
margin: 4px 0;
|
||||
padding: 0 14px 0 28px; /* 体现层级 */
|
||||
display:flex;
|
||||
align-items:center;
|
||||
background: transparent;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.sub-item.active{
|
||||
background: #eaf2ff;
|
||||
}
|
||||
|
||||
.sub-item-text{
|
||||
font-size:14px;
|
||||
color:#111827;
|
||||
font-size: 13px;
|
||||
color:#374151;
|
||||
}
|
||||
.sub-item-text.activeText{
|
||||
color:#1677ff;
|
||||
font-weight:600;
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -39,11 +39,13 @@ defineEmits<{
|
||||
background:#fff;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
align-items:center;
|
||||
}
|
||||
.tags-scroll{ width: 100%; height: 44px; }
|
||||
.tags-row{
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
align-items:center;
|
||||
gap: 8px;
|
||||
padding: 0 12px;
|
||||
@@ -69,6 +71,7 @@ defineEmits<{
|
||||
height: 16px;
|
||||
border-radius: 8px;
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
:activeMenuId="activeMenuId"
|
||||
@toggle="toggleCollapse"
|
||||
@menu-click="onMenuClick"
|
||||
:asideWidth='ASIDE_W'
|
||||
/>
|
||||
|
||||
<!-- 二级侧边栏:固定在内容区左侧(独立层级) -->
|
||||
@@ -15,13 +16,15 @@
|
||||
:activeMenuTitle="activeMenuTitle"
|
||||
:groups="activeGroups"
|
||||
:activeSubId="activeSubId"
|
||||
:asideWidth="ASIDE_W"
|
||||
:siderWidth="SUB_W"
|
||||
@sub-click="onSubClick"
|
||||
/>
|
||||
|
||||
<!-- 右侧内容区(Header + Tags + 内容展示区 + Footer) -->
|
||||
<view
|
||||
class="main"
|
||||
:style="{ marginLeft: activeGroups.length > 0 ? '336px' : '96px' }"
|
||||
:style="{ marginLeft: mainLeft }"
|
||||
>
|
||||
<AdminHeader
|
||||
:breadcrumb="breadcrumb"
|
||||
@@ -74,6 +77,14 @@ const hasNotification = ref(true)
|
||||
const activeMenuId = ref('home')
|
||||
const activeSubId = ref('')
|
||||
|
||||
// 二级侧边栏
|
||||
const ASIDE_W = 96
|
||||
const SUB_W = 200 // 你想更像 CRMEB,就把这改小:160~180 都行
|
||||
|
||||
const mainLeft = computed(() => {
|
||||
return (activeGroups.value.length > 0 ? (ASIDE_W + SUB_W) : ASIDE_W) + 'px'
|
||||
})
|
||||
|
||||
// tabs
|
||||
const tabs = ref<TabItem[]>([
|
||||
{ id: 'home', title: '首页', path: '/pages/mall/admin/homePage/index' }
|
||||
@@ -122,6 +133,26 @@ const toggleCollapse = () => {
|
||||
isCollapsed.value = !isCollapsed.value
|
||||
}
|
||||
|
||||
// 递归取第一个 leaf(你要求的“递归默认打开第一个页面”)
|
||||
const firstLeafOfMenu = (m: MenuItem): MenuChild | null => {
|
||||
if (!m.groups || m.groups.length === 0) return null
|
||||
const g0 = m.groups[0]
|
||||
if (!g0.children || g0.children.length === 0) return null
|
||||
|
||||
const c0: any = g0.children[0] as any
|
||||
// 兼容未来 children 还能再嵌套
|
||||
if (c0.children && (c0.children as MenuChild[]).length > 0) {
|
||||
const walk = (list: MenuChild[]): MenuChild | null => {
|
||||
if (!list || list.length === 0) return null
|
||||
const n: any = list[0] as any
|
||||
if (n.children && (n.children as MenuChild[]).length > 0) return walk(n.children as MenuChild[])
|
||||
return list[0]
|
||||
}
|
||||
return walk(c0.children as MenuChild[])
|
||||
}
|
||||
return g0.children[0]
|
||||
}
|
||||
|
||||
const go = (url: string) => {
|
||||
// 你明确要用 navigateTo:页面栈会增长(这是正常行为):contentReference[oaicite:4]{index=4}
|
||||
uni.navigateTo({ url })
|
||||
@@ -138,9 +169,9 @@ const onMenuClick = (menuId: string) => {
|
||||
go(m.path)
|
||||
}
|
||||
|
||||
const onSubClick = (child: any) => {
|
||||
activeSubId.value = child.id
|
||||
go(child.path)
|
||||
const onSubClick = (c: MenuChild) => {
|
||||
activeSubId.value = c.id
|
||||
go(c.path)
|
||||
}
|
||||
|
||||
const onTabClick = (tab: TabItem) => {
|
||||
@@ -177,7 +208,7 @@ const onNotify = () => uni.showToast({ title: '通知', icon: 'none' })
|
||||
.main{
|
||||
min-height: 100vh;
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
flex-direction: rowe;
|
||||
}
|
||||
|
||||
/* 展示区 */
|
||||
|
||||
@@ -18,6 +18,7 @@ export type MenuChild = {
|
||||
}
|
||||
|
||||
export type MenuGroup = {
|
||||
id?:string
|
||||
title: string
|
||||
children: MenuChild[]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export const menuList: MenuItem[] = [
|
||||
title: '首页',
|
||||
icon: '/static/homepage.svg',
|
||||
path: '/pages/mall/admin/homePage/index',
|
||||
groups: []
|
||||
groups: [],
|
||||
},
|
||||
{
|
||||
id: 'user',
|
||||
@@ -15,14 +15,15 @@ export const menuList: MenuItem[] = [
|
||||
path: '/pages/mall/admin/user-management',
|
||||
groups: [
|
||||
{
|
||||
id:'user-management',
|
||||
title: '用户管理',
|
||||
children: [
|
||||
{ id: 'user-list', title: '用户列表', path: '/pages/mall/admin/user-management' },
|
||||
{ id: 'user-add', title: '添加用户', path: '/pages/mall/admin/user-management?action=add' },
|
||||
{ id: 'user-statistics', title: '用户统计 ', path: '/pages/mall/admin/user-statistics' },
|
||||
]
|
||||
}
|
||||
]
|
||||
{ id: 'user-statistics', title: '用户统计', path: '/pages/mall/admin/user-statistics' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'order',
|
||||
@@ -31,12 +32,13 @@ export const menuList: MenuItem[] = [
|
||||
path: '/pages/mall/admin/order-management',
|
||||
groups: [
|
||||
{
|
||||
id:'order-management',
|
||||
title: '订单管理',
|
||||
children: [
|
||||
{ id: 'order-list', title: '订单列表', path: '/pages/mall/admin/order-management' }
|
||||
]
|
||||
}
|
||||
]
|
||||
{ id: 'order-list', title: '订单列表', path: '/pages/mall/admin/order-management' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'product',
|
||||
@@ -45,13 +47,14 @@ export const menuList: MenuItem[] = [
|
||||
path: '/pages/mall/admin/product-management',
|
||||
groups: [
|
||||
{
|
||||
id:'product-management',
|
||||
title: '商品管理',
|
||||
children: [
|
||||
{ id: 'product-list', title: '商品列表', path: '/pages/mall/admin/product-management' },
|
||||
{ id: 'product-add', title: '添加商品', path: '/pages/mall/admin/product-management?action=add' }
|
||||
]
|
||||
}
|
||||
]
|
||||
{ id: 'product-add', title: '添加商品', path: '/pages/mall/admin/product-management?action=add' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'marketing',
|
||||
@@ -60,28 +63,29 @@ export const menuList: MenuItem[] = [
|
||||
path: '/pages/mall/admin/marketing-management',
|
||||
groups: [
|
||||
{
|
||||
id:'coupon',
|
||||
title: '优惠券活动',
|
||||
children: [
|
||||
{ id: 'coupon-list', title: '优惠券列表', path: '/pages/mall/admin/marketing/coupon/list' }
|
||||
{ id: 'coupon-receive', title: '领取情况', path: '/pages/mall/admin/marketing/coupon/receive' }
|
||||
|
||||
]
|
||||
{ id: 'coupon-list', title: '优惠券列表', path: '/pages/mall/admin/marketing/coupon/list' },
|
||||
{ id: 'coupon-receive', title: '领取情况', path: '/pages/mall/admin/marketing/coupon/receive' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id:'points',
|
||||
title: '积分',
|
||||
children: [
|
||||
{ id: 'points', title: '积分管理', path: '/pages/mall/admin/marketing/points/index' }
|
||||
]
|
||||
{ id: 'points-management', title: '积分管理', path: '/pages/mall/admin/marketing/points/index' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id:'signin',
|
||||
title: '签到',
|
||||
children: [
|
||||
{ id: 'rule', title: '签到规则', path: '/pages/mall/admin/marketing/signin/rule' }
|
||||
{ id: 'record', title: '记录', path: '/pages/mall/admin/marketing/signin/record' }
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
{ id: 'rule', title: '签到规则', path: '/pages/mall/admin/marketing/signin/rule' },
|
||||
{ id: 'record', title: '记录', path: '/pages/mall/admin/marketing/signin/record' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'system',
|
||||
@@ -90,12 +94,17 @@ export const menuList: MenuItem[] = [
|
||||
path: '/pages/mall/admin/system-settings',
|
||||
groups: [
|
||||
{
|
||||
id:'system-settings',
|
||||
title: '系统设置',
|
||||
children: [
|
||||
{ id: 'basic', title: '基本设置', path: '/pages/mall/admin/system-settings' },
|
||||
{ id: 'security', title: '安全设置', path: '/pages/mall/admin/system-settings?tab=security' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{ id: 'security', title: '安全设置', path: '/pages/mall/admin/system-settings?tab=security' },
|
||||
{ id: 'email', title: '邮件设置', path: '/pages/mall/admin/system-settings?tab=security' },
|
||||
{ id: 'payment', title: '支付设置', path: '/pages/mall/admin/system-settings?tab=security' },
|
||||
{ id: 'other', title: '其他设置', path: '/pages/mall/admin/system-settings?tab=security' },
|
||||
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user