Commit d0f828aa by qinjianhui

feat: 调整页面顶部菜单栏

parent 48f06c8d
...@@ -55,6 +55,7 @@ declare module 'vue' { ...@@ -55,6 +55,7 @@ declare module 'vue' {
ElTag: typeof import('element-plus/es')['ElTag'] ElTag: typeof import('element-plus/es')['ElTag']
ElTimeline: typeof import('element-plus/es')['ElTimeline'] ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem'] ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTooltip: typeof import('element-plus/es')['ElTooltip'] ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree'] ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
...@@ -63,6 +64,7 @@ declare module 'vue' { ...@@ -63,6 +64,7 @@ declare module 'vue' {
ImageView: typeof import('./src/components/ImageView.vue')['default'] ImageView: typeof import('./src/components/ImageView.vue')['default']
LogList: typeof import('./src/components/LogList.vue')['default'] LogList: typeof import('./src/components/LogList.vue')['default']
NavMenu: typeof import('./src/components/NavMenu.vue')['default'] NavMenu: typeof import('./src/components/NavMenu.vue')['default']
NavMenuItem: typeof import('./src/components/NavMenuItem.vue')['default']
RenderColumn: typeof import('./src/components/RenderColumn.vue')['default'] RenderColumn: typeof import('./src/components/RenderColumn.vue')['default']
RightClickMenu: typeof import('./src/components/RightClickMenu.vue')['default'] RightClickMenu: typeof import('./src/components/RightClickMenu.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
......
<template>
<router-link
v-if="!hasChildren"
:to="item.index"
class="nav-menu-item"
:class="{ 'is-active': isActive }"
>
{{ item.label }}
</router-link>
<div
v-else
class="nav-menu-item has-children"
:class="{ 'is-active': isActive }"
@mouseenter="onMouseEnter"
@mouseleave="onMouseLeave"
>
<span class="nav-menu-item-label">{{ item.label }}</span>
<div v-show="panelVisible" class="mega-panel">
<div v-for="group in item.children" :key="group.id" class="mega-group">
<div class="mega-group-title">{{ group.label }}</div>
<div class="mega-group-items">
<router-link
v-for="child in group.children"
:key="child.id"
:to="child.index"
class="mega-item"
@click="panelVisible = false"
>
<span class="mega-item-text" :title="child.label">{{
child.label
}}</span>
</router-link>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useRoute } from 'vue-router'
import type { MenuItem } from '@/router/menu'
const props = defineProps<{
item: MenuItem
}>()
const route = useRoute()
const panelVisible = ref(false)
const hasChildren = computed(
() => !!props.item.children && props.item.children.length > 0,
)
const isRouteIndex = (index: string) => index.startsWith('/')
const isActive = computed(() => {
return checkActive(props.item)
})
function checkActive(menuItem: MenuItem): boolean {
if (isRouteIndex(menuItem.index) && route.path === menuItem.index) {
return true
}
if (menuItem.children) {
return menuItem.children.some((child) => checkActive(child))
}
return false
}
const onMouseEnter = () => {
panelVisible.value = true
}
const onMouseLeave = () => {
panelVisible.value = false
}
</script>
<style lang="scss" scoped>
.nav-menu-item {
display: flex;
align-items: center;
height: 100%;
padding: 0 16px;
color: #fff;
font-size: 14px;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
transition: all 0.2s;
position: relative;
&:hover .nav-menu-item-label {
color: #409eff;
font-weight: 500;
}
&.is-active {
color: #409eff;
position: relative;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 2px;
background-color: #409eff;
}
}
&.is-active .nav-menu-item-label {
font-weight: 500;
}
}
.has-children {
> span {
pointer-events: none;
}
}
.mega-panel {
position: absolute;
top: 100%;
left: 50%;
transform: translate(-50%, 0);
background: #fff;
border-radius: 4px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
padding: 12px 0;
z-index: 2000;
min-width: 280px;
width: 580px;
}
.mega-group {
display: flex;
align-items: flex-start;
padding: 8px 20px;
& + & {
border-top: 1px solid #f0f0f0;
}
}
.mega-group-title {
font-weight: bold;
color: #303133;
font-size: 14px;
white-space: nowrap;
min-width: 80px;
line-height: 32px;
}
.mega-group-items {
flex: 1;
min-width: 0;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.mega-item {
display: block;
min-width: 0;
padding: 6px 12px;
color: #333;
font-size: 14px;
text-decoration: none;
border-radius: 4px;
transition: all 0.2s;
&:hover {
color: #409eff;
}
&.router-link-exact-active {
color: #409eff;
font-weight: 600;
}
}
.mega-item-text {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
...@@ -441,7 +441,7 @@ watch(getLogisticDrawer, async (value: boolean) => { ...@@ -441,7 +441,7 @@ watch(getLogisticDrawer, async (value: boolean) => {
<style lang="scss" scoped> <style lang="scss" scoped>
.tool_warper { .tool_warper {
position: absolute; position: absolute;
top: 50px; top: 60px;
right: 0; right: 0;
bottom: 0; bottom: 0;
width: 40px; width: 40px;
......
# 顶部菜单修改
## 菜单
### 概览
### 物流
- 物流管理
- 物流公司
- 物流方式
- 物流分区
- 物流报价
- 运费试算
- 物流跟踪
- 发货地址
- 规则设置
- 申报规则
- 分拣配置
### 库存
- 库存管理
- 入库申请单
- 仓库预警
- 入库单
- 出库单
- 备货计划
- 仓库管理
- 仓库管理
- 库位管理
- 仓库规则
- 仓库规则
- 共享库存设置
### 订单
- 订单处理
- 定制订单
- POD 订单
- POD 订单(CN)
- POD 订单(US)
- 工厂订单(NEW)
- 取消后订单处理
- 订单查询
- POD(CN)订单跟踪
- POD(US)订单跟踪
- 订单规则
- POD(US)派单规则
- 配货分拣规则
### 供应
- 采购生产
- 备货计划
- 备货订单
- 打版管理
- 供应管理
- 供应商管理
### 财务
- 对账管理
- 定制对账单
- POD(CN)对账单
- POD(US)对账单
### 发货单
- 发货单查询
- 定制发货单
- POD 发货单
### 系统
- 系统管理
- 用户管理
- 功能角色管理
- 系统设置
- 工厂设置
- 下载生产客户端
其中菜单的数据结构为
```ts
interface MenuItem {
index: string
id: number
label: string
children?: MenuItem[]
}
// 菜单数据结构
const menu = [
{
route: 'xxx', // 路由地址
path: 'xxx', // 菜单路径
url: 'xxx', // 菜单url
id: 1, // 菜单id
pid: 0, // 父级id
type: 0, // 菜单类型 0: 菜单 1: 按钮
sortNo: 1, // 排序
enable: true, // 是否启用,用于权限控制
includeNamespace: '', // 包含命名空间
excludeNamespace: '', // 排除命名空间,用于权限控制
children: [
{
route: 'xxx', // 二级菜单不可点击 路由为空
path: 'xxx', // 二级菜单路径
url: 'xxx', // 二级菜单url
id: 1, // 菜单id
pid: 0, // 父级id
type: 0, // 菜单类型 0: 菜单 1: 按钮
sortNo: 1, // 排序
enable: true, // 是否启用,用于权限控制
children: [], // 三级菜单 结构与二级菜单相同
label: 'xxx', // 菜单名称
},
], //二级菜单
label: 'xxx', // 菜单名称
},
]
```
如果有菜单有子级的话,不可点击
\ No newline at end of file
...@@ -12,249 +12,245 @@ const menu: MenuItem[] = [ ...@@ -12,249 +12,245 @@ const menu: MenuItem[] = [
label: '概览', label: '概览',
}, },
{ {
index: '4', index: 'logistics',
id: 7, id: 2,
label: '物流', label: '物流',
children: [ children: [
{ {
index: '/logistics/logisticsCompany', index: 'logistics-manage',
id: 11, id: 21,
label: '物流公司', label: '物流管理',
}, children: [
{ { index: '/logistics/logisticsCompany', id: 211, label: '物流公司' },
index: '/logistics/logisticsMethod', { index: '/logistics/logisticsMethod', id: 212, label: '物流方式' },
id: 1,
label: '物流方式',
},
{ {
index: '/logistics/shippingAddress', index: '/logistics/logisticsPartition',
id: 2, id: 213,
label: '发货地址', label: '物流分区',
}, },
{ {
index: '/logistics/logisticsQuotation', index: '/logistics/logisticsQuotation',
id: 3, id: 214,
label: '物流报价', label: '物流报价',
}, },
{ {
index: '/logistics/declarationRule',
id: 4,
label: '申报规则',
},
{
index: '/logistics/logisticsPartition',
id: 5,
label: '物流分区',
},
{
index: '/logistics/logisticsCalculate', index: '/logistics/logisticsCalculate',
id: 6, id: 215,
label: '运费试算', label: '运费试算',
}, },
{ index: '/logistics/logisticsTracking', id: 216, label: '物流跟踪' },
{ index: '/logistics/shippingAddress', id: 217, label: '发货地址' },
],
},
{
index: 'logistics-rules',
id: 22,
label: '规则设置',
children: [
{ index: '/logistics/declarationRule', id: 221, label: '申报规则' },
{ {
index: '/logistics/sortingConfiguration', index: '/logistics/sortingConfiguration',
id: 7, id: 222,
label: '分拣配置', label: '分拣配置',
}, },
{ ],
index: '/logistics/logisticsTracking',
id: 8,
label: '物流跟踪',
}, },
], ],
}, },
{ {
index: '13', index: 'warehouse',
id: 13, id: 3,
label: '库存', label: '库存',
children: [ children: [
{ {
index: 'warehouse-inventory',
id: 31,
label: '库存管理',
children: [
{
index: '/warehouse/stocking-application', index: '/warehouse/stocking-application',
id: 126, id: 311,
label: '入库申请单', label: '入库申请单',
}, },
{ { index: '/warehouse/warning', id: 312, label: '仓库预警' },
index: '/warehouse/warning', { index: '/warehouse/receipt-doc', id: 313, label: '入库单' },
id: 125, { index: '/warehouse/issue-doc', id: 314, label: '出库单' },
label: '仓库预警', { index: '/warehouse/stocking-plan', id: 315, label: '备货计划' },
}, ],
{
index: '/warehouse/receipt-doc',
id: 123,
label: '入库单',
},
{
index: '/warehouse/issue-doc',
id: 124,
label: '出库单',
}, },
{ {
index: '/warehouse/manage', index: 'warehouse-manage',
id: 121, id: 32,
label: '仓库管理', label: '仓库管理',
children: [
{ index: '/warehouse/manage', id: 321, label: '仓库管理' },
{ index: '/warehouse/position', id: 322, label: '库位管理' },
],
}, },
{ {
index: '/warehouse/position', index: 'warehouse-rules',
id: 122, id: 33,
label: '库位管理', label: '仓库规则',
}, children: [
{ {
index: '/warehouse/stocking-plan', index: '/warehouse/warehouse-rule-setting',
id: 124, id: 331,
label: '备货计划', label: '共享库存设置',
},
],
}, },
], ],
}, },
{ {
index: '1', index: 'order',
id: 2, id: 4,
label: '订单', label: '订单',
children: [ children: [
{ {
index: '/order/list', index: 'order-process',
id: 1, id: 41,
label: '定制订单', label: '订单处理',
}, children: [
{ index: '/order/list', id: 411, label: '定制订单' },
{ index: '/pod-order/list', id: 412, label: 'POD订单' },
{ index: '/pod-cn-order/list', id: 413, label: 'POD订单(CN)' },
{ index: '/pod-us-order/list', id: 414, label: 'POD订单(US)' },
{ {
index: '/pod-order/list', index: '/order/factory-order-new',
id: 7, id: 415,
label: 'POD订单', label: '工厂订单(NEW)',
}, },
{ {
index: '/pod-cn-order/list', index: '/order/cancel-order-process',
id: 6, id: 416,
label: 'POD订单(CN)', label: '取消后订单处理',
}, },
{ ],
index: '/pod-us-order/list',
id: 8,
label: 'POD订单(US)',
}, },
{ {
index: 'order-query',
id: 42,
label: '订单查询',
children: [
{
index: '/pod-cn-order/orderTracking', index: '/pod-cn-order/orderTracking',
id: 9, id: 421,
label: 'POD(CN)订单跟踪', label: 'POD(CN)订单跟踪',
}, },
{ {
index: '/pod-us-order/orderTracking', index: '/pod-us-order/orderTracking',
id: 10, id: 422,
label: 'POD(US)订单跟踪', label: 'POD(US)订单跟踪',
}, },
{ ],
index: '/pod-us-order/podUsSchedulingRules',
id: 11,
label: 'POD(US)排单规则',
}, },
{ {
index: '/order/factory-order-new', index: 'order-rules',
id: 12, id: 43,
label: '工厂订单(NEW)', label: '订单规则',
}, children: [
{ {
index: '/order/cancel-order-process', index: '/pod-us-order/podUsSchedulingRules',
id: 13, id: 431,
label: '取消后订单处理', label: 'POD(US)派单规则',
}, },
{ {
index: '/order/allocation-sorting-rule', index: '/order/allocation-sorting-rule',
id: 14, id: 432,
label: '配货分拣规则', label: '配货分拣规则',
}, },
], ],
}, },
],
},
{ {
index: '14', index: 'supply',
id: 14, id: 5,
label: '供应', label: '供应',
children: [ children: [
{ {
label: '缺货统计', index: 'supply-production',
id: 51,
label: '采购生产',
children: [
{
index: '/supply/out-of-stock-statistics', index: '/supply/out-of-stock-statistics',
id: 1, id: 511,
label: '缺货统计',
}, },
{ { index: '/supply/stocking-order', id: 512, label: '备货订单' },
label: '备货订单', { index: '/typesetting-management/list', id: 513, label: '打版管理' },
index: '/supply/stocking-order', ],
id: 2,
}, },
{ {
index: '/supply/supplierManagement', index: 'supply-manage',
id: 3, id: 52,
label: '供应商管理', label: '供应管理',
children: [
{ index: '/supply/supplierManagement', id: 521, label: '供应商管理' },
],
}, },
], ],
}, },
{ {
index: '11', index: 'finance',
id: 3, id: 6,
label: '对账单', label: '财务',
children: [ children: [
{ {
index: '/account/statement-note', index: 'finance-reconciliation',
id: 1, id: 61,
label: '定制对账单', label: '对账管理',
}, children: [
{ { index: '/account/statement-note', id: 611, label: '定制对账单' },
index: '/account/pod-bill-order', { index: '/account/pod-bill-order', id: 612, label: 'POD(CN)对账单' },
id: 2,
label: 'POD(CN)对账单',
},
{ {
index: '/account/pod-us-bill-order', index: '/account/pod-us-bill-order',
id: 3, id: 613,
label: 'POD(US)对账单', label: 'POD(US)对账单',
}, },
], ],
}, },
],
},
{ {
index: '2', index: 'delivery',
id: 4, id: 7,
label: '发货单', label: '发货单',
children: [ children: [
{ {
index: '/system/delivery-note', index: 'delivery-query',
id: 1, id: 71,
label: '定制发货单', label: '发货单查询',
}, children: [
{ { index: '/system/delivery-note', id: 711, label: '定制发货单' },
index: '/pod-delivery-note/list', { index: '/pod-delivery-note/list', id: 712, label: 'POD发货单' },
id: 2,
label: 'POD发货单',
},
], ],
}, },
],
{
index: '/typesetting-management/list',
id: 5,
label: '打版管理',
}, },
{ {
index: '3', index: 'system',
id: 6, id: 8,
label: '系统设置', label: '系统',
children: [ children: [
{ {
index: '/system/user', index: 'system-manage',
id: 4, id: 81,
label: '用户管理', label: '系统管理',
}, children: [
{ { index: '/system/user', id: 811, label: '用户管理' },
index: '/system/downloadClient', { index: '/system/role-manage', id: 812, label: '功能角色管理' },
id: 4, ],
label: '下载生产客户端',
},
{
index: '/system/customers',
id: 6,
label: '客户管理',
}, },
{ {
index: '/setting/settingIndex', index: 'system-settings',
id: 8, id: 82,
label: '工厂设置', label: '系统设置',
children: [
{ index: '/setting/settingIndex', id: 821, label: '工厂设置' },
{ index: '/system/downloadClient', id: 822, label: '下载生产客户端' },
],
}, },
], ],
}, },
......
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
<div class="container"> <div class="container">
<RouterView /> <RouterView />
</div> </div>
<SideBar />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import NavMenu from '@/components/NavMenu.vue' import NavMenu from '@/components/NavMenu.vue'
import SideBar from '@/components/SideBar.vue'
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.home { .home {
......
...@@ -8,12 +8,8 @@ ...@@ -8,12 +8,8 @@
</div> </div>
<div class="cardBox"> <div class="cardBox">
<div class="card-box-item-container"> <div class="card-box-item-container">
<div <template v-for="(item, index) in formList" :key="index">
v-for="(item, index) in formList" <div v-if="item.type === 'RIIN'" class="card-box-item">
:key="index"
class="card-box-item"
>
<template v-if="item.type === 'RIIN'">
<div class="formBox"> <div class="formBox">
<div class="form-item"> <div class="form-item">
<span>转至RIIN生产</span> <span>转至RIIN生产</span>
...@@ -65,8 +61,8 @@ ...@@ -65,8 +61,8 @@
@click="saveConfiguration(item, index)" @click="saveConfiguration(item, index)"
>保存配置</ElButton >保存配置</ElButton
> >
</template> </div>
<template v-if="item.type === 'TRACK'"> <div v-if="item.type === 'TRACK'" class="card-box-item">
<div class="formBox"> <div class="formBox">
<div class="form-item"> <div class="form-item">
<span>物流轨迹跟踪</span> <span>物流轨迹跟踪</span>
...@@ -118,8 +114,8 @@ ...@@ -118,8 +114,8 @@
@click="saveConfiguration(item, index)" @click="saveConfiguration(item, index)"
>保存配置</ElButton >保存配置</ElButton
> >
</template>
</div> </div>
</template>
<div class="card-box-item"> <div class="card-box-item">
<div class="formBox"> <div class="formBox">
<div class="form-item"> <div class="form-item">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment