Commit d0f828aa by qinjianhui

feat: 调整页面顶部菜单栏

parent 48f06c8d
......@@ -55,6 +55,7 @@ declare module 'vue' {
ElTag: typeof import('element-plus/es')['ElTag']
ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
......@@ -63,6 +64,7 @@ declare module 'vue' {
ImageView: typeof import('./src/components/ImageView.vue')['default']
LogList: typeof import('./src/components/LogList.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']
RightClickMenu: typeof import('./src/components/RightClickMenu.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
......
......@@ -2,39 +2,21 @@
<div>
<div class="nav-menu">
<div class="header-logo">
<img src="../assets/images/factory-logo.png" alt="logo" />
<img
style="vertical-align: middle"
src="../assets/images/factory-logo.png"
alt="logo"
/>
</div>
<!-- 导航栏 -->
<el-menu
class="el-menu-demo"
mode="horizontal"
background-color="#001529"
text-color="#fff"
style="border-bottom: none"
:default-active="defaultActive"
router
>
<template v-for="item in menuList">
<el-menu-item
v-if="!item.children"
:key="item.id"
:index="item.index"
>{{ item.label }}</el-menu-item
>
<el-sub-menu v-else :key="item.index" :index="item.index">
<template #title>
<span class="label">{{ item.label }}</span>
</template>
<el-menu-item
v-for="sub in item.children"
:key="sub.id"
:index="sub.index"
>{{ sub.label }}</el-menu-item
>
</el-sub-menu>
</template>
</el-menu>
<SideBar />
<nav class="mega-nav">
<NavMenuItem
v-for="item in displayMenuList"
:key="item.id"
:item="item"
/>
</nav>
<div v-if="userInfo" class="user-info">
<span class="user-avatar" style="color: #fff; font-size: 14px">
工厂: {{ userInfo.factoryCode }}
......@@ -63,6 +45,20 @@
</div>
</div>
<div ref="tabsContainer" class="nav-tabs">
<div
class="tabs-node tabs-node--fixed"
:class="{ 'is-active': activeTab === DASHBOARD_PATH }"
:style="{
backgroundColor: activeTab === DASHBOARD_PATH ? '#409EFF' : '',
color: activeTab === DASHBOARD_PATH ? '#fff' : '',
}"
@click="activeTab = DASHBOARD_PATH"
>
<div class="nav-tabs-node_label">
<span>{{ DASHBOARD_TITLE }}</span>
</div>
</div>
<el-icon
v-if="showScrollArrows"
class="nav-tabs-arrow left"
......@@ -71,19 +67,17 @@
<ArrowLeft />
</el-icon>
<div
ref="tabsWrapper"
class="tabs-scroll-container"
:style="{ width: showScrollArrows ? 'calc(100% - 80px)' : '100%' }"
>
<div ref="tabsScrollContainer" class="tabs-scroll-container">
<div
ref="tabsInnerWrapper"
class="tabs-wrapper"
:style="{ transform: `translateX(${scrollOffset}px)` }"
>
<div
v-for="item in tabs"
v-for="item in scrollableTabs"
:key="item.name"
class="tabs-node"
:class="{ 'is-active': item.name === activeTab }"
:style="{
backgroundColor: item.name === activeTab ? '#409EFF' : '',
color: item.name === activeTab ? '#fff' : '',
......@@ -92,12 +86,7 @@
>
<div class="nav-tabs-node_label">
<span>{{ item.title }}</span>
<!-- 首页不可删除 -->
<el-icon
v-if="item.path != '/dashboard' && tabs.length > 1"
class="el-icon-close"
@click.stop="removeTab(item.name)"
>
<el-icon class="el-icon-close" @click.stop="removeTab(item.name)">
<CircleClose />
</el-icon>
</div>
......@@ -171,14 +160,14 @@ import {
import {
ref,
reactive,
watch,
computed,
watch,
nextTick,
onMounted,
onUnmounted,
} from 'vue'
import { useRoute, useRouter } from 'vue-router'
import Menu from '@/router/menu'
import Menu, { type MenuItem } from '@/router/menu'
import userUserStore from '@/store/user'
import type { FormRules } from 'element-plus'
......@@ -187,13 +176,16 @@ import { useValue } from '@/utils/hooks/useValue'
import { changePasswordApi } from '@/api/auth'
import { ElMessage } from 'element-plus'
import SideBar from './SideBar.vue'
import NavMenuItem from './NavMenuItem.vue'
interface MenuItem {
index: string
id: number
label: string
children?: MenuItem[]
const removeMenuItemByIndex = (items: MenuItem[], indexToRemove: string) => {
for (let i = items.length - 1; i >= 0; i--) {
if (items[i].index === indexToRemove) {
items.splice(i, 1)
} else if (items[i].children?.length) {
removeMenuItemByIndex(items[i].children!, indexToRemove)
}
}
}
interface PasswordForm {
oldPwd: string
......@@ -201,14 +193,13 @@ interface PasswordForm {
confirmPwd?: string
}
const route = useRoute()
// 使用 computed 替代直接赋值
const defaultActive = computed({
get: () => route.path,
set: (val) => {
router.push(val)
},
})
const menuList = reactive(Menu)
const DASHBOARD_PATH = '/dashboard'
const DASHBOARD_TITLE = '概览'
const displayMenuList = computed(() =>
menuList.filter((item) => item.index !== DASHBOARD_PATH),
)
const userStore = userUserStore()
const userInfo = userStore.user
......@@ -285,9 +276,18 @@ const tabs = ref<Array<{ name: string; title: string; path: string }>>([])
const activeTab = ref('')
const router = useRouter()
// 添加标签页
const scrollableTabs = computed(() =>
tabs.value.filter((tab) => tab.path !== DASHBOARD_PATH),
)
const addTab = () => {
const { path, meta } = route
if (path === DASHBOARD_PATH) {
activeTab.value = DASHBOARD_PATH
return
}
const existingTab = tabs.value.find((tab) => tab.path === path)
if (!existingTab) {
......@@ -302,105 +302,94 @@ const addTab = () => {
activeTab.value = path
}
// 移除标签页
const removeTab = (targetName: string) => {
const tabIndex = tabs.value.findIndex((tab) => tab.name === targetName)
if (tabIndex !== -1) {
tabs.value.splice(tabIndex, 1)
// 如果关闭的是当前激活的标签,则切换到最后一个标签
if (activeTab.value === targetName) {
const lastTab = tabs.value[tabs.value.length - 1]
if (lastTab) {
nextTick(() => {
nextTick(() => {
if (lastTab) {
activeTab.value = lastTab.name
router.push(lastTab.path)
})
}
} else {
activeTab.value = DASHBOARD_PATH
router.push(DASHBOARD_PATH)
}
})
}
}
}
const tabsContainer = ref<HTMLDivElement | null>(null)
const tabsWrapper = ref<HTMLDivElement | null>(null)
const tabsScrollContainer = ref<HTMLDivElement | null>(null)
const tabsInnerWrapper = ref<HTMLDivElement | null>(null)
const scrollOffset = ref(0)
const scrollStep = 200 // 每次滚动的像素数
const scrollStep = 200
const showScrollArrows = ref(false)
// 检查是否需要显示滚动箭头
const checkScrollArrows = () => {
nextTick(() => {
if (!tabsContainer.value || !tabsWrapper.value) return
const containerWidth = tabsContainer.value.clientWidth
const wrapperWidth = tabsWrapper.value.scrollWidth
const clampScrollOffset = () => {
if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return
// 如果包装器宽度大于容器宽度,显示箭头
showScrollArrows.value = wrapperWidth > containerWidth
const containerWidth = tabsScrollContainer.value.clientWidth
const innerWidth = tabsInnerWrapper.value.scrollWidth
const maxScroll = Math.min(0, containerWidth - innerWidth)
// 调整滚动位置,确保不会超出边界
if (showScrollArrows.value) {
const maxScroll = -(wrapperWidth - containerWidth)
scrollOffset.value = Math.min(0, Math.max(maxScroll, scrollOffset.value))
}
// 如果当前滚动位置已经超出最大可滚动范围,重新调整
if (scrollOffset.value < maxScroll) {
scrollOffset.value = maxScroll
}
const checkScrollArrows = () => {
nextTick(() => {
if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return
// 确保不会滚动到容器左侧之外
if (scrollOffset.value > 0) {
scrollOffset.value = 0
}
} else {
// 如果不需要滚动,重置滚动位置
scrollOffset.value = 0
}
const containerWidth = tabsScrollContainer.value.clientWidth
const innerWidth = tabsInnerWrapper.value.scrollWidth
showScrollArrows.value = innerWidth > containerWidth
clampScrollOffset()
ensureActiveTabVisible()
})
}
// 添加窗口大小监听器
const resizeObserver = new ResizeObserver(checkScrollArrows)
const scrollTabs = (direction: 'left' | 'right') => {
if (!tabsContainer.value || !tabsWrapper.value) return
if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return
const containerWidth = tabsContainer.value.clientWidth
const wrapperWidth = tabsWrapper.value.scrollWidth
const containerWidth = tabsScrollContainer.value.clientWidth
const innerWidth = tabsInnerWrapper.value.scrollWidth
const maxScroll = Math.min(0, containerWidth - innerWidth)
if (direction === 'left') {
// 向左滚动(显示前面的标签)
scrollOffset.value = Math.min(0, scrollOffset.value + scrollStep)
} else {
// 向右滚动(显示后面的标签)
const maxScroll = -(wrapperWidth - containerWidth)
scrollOffset.value = Math.max(maxScroll, scrollOffset.value - scrollStep)
}
}
// 确保活动标签始终在可视范围内
const ensureActiveTabVisible = () => {
nextTick(() => {
if (!tabsContainer.value || !tabsWrapper.value) return
const activeTab = tabsWrapper.value.querySelector(
'.tabs-node[style*="background-color: rgb(64, 158, 255)"]',
) as HTMLElement
if (!activeTab) return
const containerRect = tabsContainer.value.getBoundingClientRect()
const activeTabRect = activeTab.getBoundingClientRect()
const wrapperRect = tabsWrapper.value.getBoundingClientRect()
// 计算活动标签相对于包装器的位置
const relativeLeft = activeTabRect.left - wrapperRect.left
const relativeRight = activeTabRect.right - wrapperRect.left
// 如果标签部分或完全在容器外
if (relativeLeft < 0 || relativeRight > containerRect.width) {
// 调整滚动位置,使活动标签居中
const centerOffset = containerRect.width / 2 - activeTabRect.width / 2
scrollOffset.value = -relativeLeft + centerOffset
// 重新检查滚动边界
checkScrollArrows()
if (!tabsScrollContainer.value || !tabsInnerWrapper.value) return
const activeTabEl = tabsScrollContainer.value.querySelector(
'.tabs-node.is-active',
) as HTMLElement | null
if (!activeTabEl) return
const containerWidth = tabsScrollContainer.value.clientWidth
const tabLeft = activeTabEl.offsetLeft
const tabRight = tabLeft + activeTabEl.offsetWidth
const visibleLeft = -scrollOffset.value
const visibleRight = visibleLeft + containerWidth
if (tabLeft < visibleLeft) {
scrollOffset.value = -tabLeft
} else if (tabRight > visibleRight) {
scrollOffset.value = -(tabRight - containerWidth)
}
clampScrollOffset()
})
}
......@@ -418,12 +407,10 @@ watch(activeTab, (newTab) => {
if (newTab) {
router.push(newTab)
}
// 监听活动标签变化时调整滚动
ensureActiveTabVisible()
checkScrollArrows()
})
watch(tabs, checkScrollArrows)
// 初始化时确保活动标签可见
watch(scrollableTabs, checkScrollArrows)
onMounted(() => {
let showCustomerManagement = false
const userJson = localStorage.getItem('user')
......@@ -438,22 +425,17 @@ onMounted(() => {
}
}
if (!showCustomerManagement) {
const systemSettingsMenu = menuList.find(
(item: MenuItem) => item.label === '系统设置',
)
if (systemSettingsMenu && systemSettingsMenu.children) {
systemSettingsMenu.children = systemSettingsMenu.children.filter(
(child: MenuItem) => child.index !== '/system/customers',
)
}
removeMenuItemByIndex(menuList, '/system/customers')
}
// 初始检查
checkScrollArrows()
// 监听容器大小变化
if (tabsContainer.value) {
resizeObserver.observe(tabsContainer.value)
}
if (tabsScrollContainer.value) {
resizeObserver.observe(tabsScrollContainer.value)
}
})
const toDownload = () => {
......@@ -461,21 +443,23 @@ const toDownload = () => {
}
onUnmounted(() => {
// 清理监听器
resizeObserver.disconnect()
})
</script>
<style lang="scss" scoped>
.nav-tabs {
background-color: #f5f5f5;
padding: 10px 20px;
padding: 10px 50px 10px 20px;
font-size: 14px;
display: flex;
align-items: center;
position: relative;
z-index: 1;
}
.tabs-scroll-container {
overflow: hidden;
flex-grow: 1;
flex: 1;
min-width: 0;
}
.tabs-wrapper {
......@@ -483,12 +467,16 @@ onUnmounted(() => {
align-items: center;
gap: 10px;
transition: transform 0.3s ease;
pointer-events: none;
}
.nav-tabs-arrow {
cursor: pointer;
color: #409eff;
font-size: 20px;
flex-shrink: 0;
position: relative;
z-index: 2;
&.left {
margin-right: 10px;
......@@ -509,9 +497,20 @@ onUnmounted(() => {
transition: all 0.3s;
box-shadow: var(--el-box-shadow-light);
background-color: #fff;
pointer-events: auto;
flex-shrink: 0;
&--fixed {
margin-right: 10px;
}
&:hover {
background-color: #c6e2ff;
}
&.is-active:hover {
background-color: #409eff;
}
}
.nav-tabs-node_label {
display: flex;
......@@ -525,28 +524,21 @@ onUnmounted(() => {
display: flex;
align-items: center;
padding: 0 40px;
:deep(.el-sub-menu .el-sub-menu__icon-arrow) {
display: none;
}
}
.el-menu-demo {
.mega-nav {
flex: 1;
height: 100%;
border-bottom: none;
margin-left: 20px;
:deep(.el-menu-item) {
border-bottom: none !important;
}
:deep(.el-menu-item.is-active) {
background-color: #409eff !important;
color: #fff !important;
border: none !important;
}
display: flex;
align-items: center;
margin-left: 60px;
}
.user-info {
display: flex;
align-items: center;
}
.header-logo {
margin-left: 120px;
}
</style>
<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) => {
<style lang="scss" scoped>
.tool_warper {
position: absolute;
top: 50px;
top: 60px;
right: 0;
bottom: 0;
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[] = [
label: '概览',
},
{
index: '4',
id: 7,
index: 'logistics',
id: 2,
label: '物流',
children: [
{
index: '/logistics/logisticsCompany',
id: 11,
label: '物流公司',
},
{
index: '/logistics/logisticsMethod',
id: 1,
label: '物流方式',
},
{
index: '/logistics/shippingAddress',
id: 2,
label: '发货地址',
},
{
index: '/logistics/logisticsQuotation',
id: 3,
label: '物流报价',
},
{
index: '/logistics/declarationRule',
id: 4,
label: '申报规则',
},
{
index: '/logistics/logisticsPartition',
id: 5,
label: '物流分区',
},
{
index: '/logistics/logisticsCalculate',
id: 6,
label: '运费试算',
},
{
index: '/logistics/sortingConfiguration',
id: 7,
label: '分拣配置',
},
{
index: '/logistics/logisticsTracking',
id: 8,
label: '物流跟踪',
index: 'logistics-manage',
id: 21,
label: '物流管理',
children: [
{ index: '/logistics/logisticsCompany', id: 211, label: '物流公司' },
{ index: '/logistics/logisticsMethod', id: 212, label: '物流方式' },
{
index: '/logistics/logisticsPartition',
id: 213,
label: '物流分区',
},
{
index: '/logistics/logisticsQuotation',
id: 214,
label: '物流报价',
},
{
index: '/logistics/logisticsCalculate',
id: 215,
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',
id: 222,
label: '分拣配置',
},
],
},
],
},
{
index: '13',
id: 13,
index: 'warehouse',
id: 3,
label: '库存',
children: [
{
index: '/warehouse/stocking-application',
id: 126,
label: '入库申请单',
},
{
index: '/warehouse/warning',
id: 125,
label: '仓库预警',
},
{
index: '/warehouse/receipt-doc',
id: 123,
label: '入库单',
},
{
index: '/warehouse/issue-doc',
id: 124,
label: '出库单',
},
{
index: '/warehouse/manage',
id: 121,
index: 'warehouse-inventory',
id: 31,
label: '库存管理',
children: [
{
index: '/warehouse/stocking-application',
id: 311,
label: '入库申请单',
},
{ index: '/warehouse/warning', id: 312, label: '仓库预警' },
{ index: '/warehouse/receipt-doc', id: 313, label: '入库单' },
{ index: '/warehouse/issue-doc', id: 314, label: '出库单' },
{ index: '/warehouse/stocking-plan', id: 315, label: '备货计划' },
],
},
{
index: 'warehouse-manage',
id: 32,
label: '仓库管理',
},
{
index: '/warehouse/position',
id: 122,
label: '库位管理',
},
{
index: '/warehouse/stocking-plan',
id: 124,
label: '备货计划',
children: [
{ index: '/warehouse/manage', id: 321, label: '仓库管理' },
{ index: '/warehouse/position', id: 322, label: '库位管理' },
],
},
{
index: 'warehouse-rules',
id: 33,
label: '仓库规则',
children: [
{
index: '/warehouse/warehouse-rule-setting',
id: 331,
label: '共享库存设置',
},
],
},
],
},
{
index: '1',
id: 2,
index: 'order',
id: 4,
label: '订单',
children: [
{
index: '/order/list',
id: 1,
label: '定制订单',
},
{
index: '/pod-order/list',
id: 7,
label: 'POD订单',
},
{
index: '/pod-cn-order/list',
id: 6,
label: 'POD订单(CN)',
},
{
index: '/pod-us-order/list',
id: 8,
label: 'POD订单(US)',
},
{
index: '/pod-cn-order/orderTracking',
id: 9,
label: 'POD(CN)订单跟踪',
},
{
index: '/pod-us-order/orderTracking',
id: 10,
label: 'POD(US)订单跟踪',
},
{
index: '/pod-us-order/podUsSchedulingRules',
id: 11,
label: 'POD(US)排单规则',
},
{
index: '/order/factory-order-new',
id: 12,
label: '工厂订单(NEW)',
},
{
index: '/order/cancel-order-process',
id: 13,
label: '取消后订单处理',
},
{
index: '/order/allocation-sorting-rule',
id: 14,
label: '配货分拣规则',
index: 'order-process',
id: 41,
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: '/order/factory-order-new',
id: 415,
label: '工厂订单(NEW)',
},
{
index: '/order/cancel-order-process',
id: 416,
label: '取消后订单处理',
},
],
},
{
index: 'order-query',
id: 42,
label: '订单查询',
children: [
{
index: '/pod-cn-order/orderTracking',
id: 421,
label: 'POD(CN)订单跟踪',
},
{
index: '/pod-us-order/orderTracking',
id: 422,
label: 'POD(US)订单跟踪',
},
],
},
{
index: 'order-rules',
id: 43,
label: '订单规则',
children: [
{
index: '/pod-us-order/podUsSchedulingRules',
id: 431,
label: 'POD(US)派单规则',
},
{
index: '/order/allocation-sorting-rule',
id: 432,
label: '配货分拣规则',
},
],
},
],
},
{
index: '14',
id: 14,
index: 'supply',
id: 5,
label: '供应',
children: [
{
label: '缺货统计',
index: '/supply/out-of-stock-statistics',
id: 1,
},
{
label: '备货订单',
index: '/supply/stocking-order',
id: 2,
},
{
index: '/supply/supplierManagement',
id: 3,
label: '供应商管理',
index: 'supply-production',
id: 51,
label: '采购生产',
children: [
{
index: '/supply/out-of-stock-statistics',
id: 511,
label: '缺货统计',
},
{ index: '/supply/stocking-order', id: 512, label: '备货订单' },
{ index: '/typesetting-management/list', id: 513, label: '打版管理' },
],
},
{
index: 'supply-manage',
id: 52,
label: '供应管理',
children: [
{ index: '/supply/supplierManagement', id: 521, label: '供应商管理' },
],
},
],
},
{
index: '11',
id: 3,
label: '对账单',
index: 'finance',
id: 6,
label: '财务',
children: [
{
index: '/account/statement-note',
id: 1,
label: '定制对账单',
},
{
index: '/account/pod-bill-order',
id: 2,
label: 'POD(CN)对账单',
},
{
index: '/account/pod-us-bill-order',
id: 3,
label: 'POD(US)对账单',
index: 'finance-reconciliation',
id: 61,
label: '对账管理',
children: [
{ index: '/account/statement-note', id: 611, label: '定制对账单' },
{ index: '/account/pod-bill-order', id: 612, label: 'POD(CN)对账单' },
{
index: '/account/pod-us-bill-order',
id: 613,
label: 'POD(US)对账单',
},
],
},
],
},
{
index: '2',
id: 4,
index: 'delivery',
id: 7,
label: '发货单',
children: [
{
index: '/system/delivery-note',
id: 1,
label: '定制发货单',
},
{
index: '/pod-delivery-note/list',
id: 2,
label: 'POD发货单',
index: 'delivery-query',
id: 71,
label: '发货单查询',
children: [
{ index: '/system/delivery-note', id: 711, label: '定制发货单' },
{ index: '/pod-delivery-note/list', id: 712, label: 'POD发货单' },
],
},
],
},
{
index: '/typesetting-management/list',
id: 5,
label: '打版管理',
},
{
index: '3',
id: 6,
label: '系统设置',
index: 'system',
id: 8,
label: '系统',
children: [
{
index: '/system/user',
id: 4,
label: '用户管理',
},
{
index: '/system/downloadClient',
id: 4,
label: '下载生产客户端',
},
{
index: '/system/customers',
id: 6,
label: '客户管理',
},
{
index: '/setting/settingIndex',
id: 8,
label: '工厂设置',
index: 'system-manage',
id: 81,
label: '系统管理',
children: [
{ index: '/system/user', id: 811, label: '用户管理' },
{ index: '/system/role-manage', id: 812, label: '功能角色管理' },
],
},
{
index: 'system-settings',
id: 82,
label: '系统设置',
children: [
{ index: '/setting/settingIndex', id: 821, label: '工厂设置' },
{ index: '/system/downloadClient', id: 822, label: '下载生产客户端' },
],
},
],
},
......
......@@ -5,10 +5,12 @@
<div class="container">
<RouterView />
</div>
<SideBar />
</div>
</template>
<script setup lang="ts">
import NavMenu from '@/components/NavMenu.vue'
import SideBar from '@/components/SideBar.vue'
</script>
<style lang="scss" scoped>
.home {
......
......@@ -8,12 +8,8 @@
</div>
<div class="cardBox">
<div class="card-box-item-container">
<div
v-for="(item, index) in formList"
:key="index"
class="card-box-item"
>
<template v-if="item.type === 'RIIN'">
<template v-for="(item, index) in formList" :key="index">
<div v-if="item.type === 'RIIN'" class="card-box-item">
<div class="formBox">
<div class="form-item">
<span>转至RIIN生产</span>
......@@ -65,8 +61,8 @@
@click="saveConfiguration(item, index)"
>保存配置</ElButton
>
</template>
<template v-if="item.type === 'TRACK'">
</div>
<div v-if="item.type === 'TRACK'" class="card-box-item">
<div class="formBox">
<div class="form-item">
<span>物流轨迹跟踪</span>
......@@ -118,8 +114,8 @@
@click="saveConfiguration(item, index)"
>保存配置</ElButton
>
</template>
</div>
</div>
</template>
<div class="card-box-item">
<div class="formBox">
<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