Files
klp-oa/klp-ui/src/views/redirectMenu.vue

253 lines
5.8 KiB
Vue
Raw Normal View History

<template>
<div class="submenu-page">
<div class="submenu-page__header">
<span class="submenu-page__parent-title">{{ parentTitle }}</span>
</div>
<div v-if="tree.length" class="submenu-page__list">
<div v-for="group in tree" :key="group._ownPath" class="submenu-group">
<div class="submenu-group__title" @click="goTo(group)">
<span class="submenu-group__icon">
<svg-icon v-if="group.meta && group.meta.icon" :icon-class="group.meta.icon" />
<i v-else class="el-icon-folder-opened" />
</span>
<span class="submenu-group__text">{{ group._title }}</span>
<span v-if="group._hasChildren" class="submenu-group__count">{{ group._children.length }}</span>
<i v-if="group._hasChildren" class="el-icon-arrow-right submenu-group__arrow" />
</div>
<div v-if="group._hasChildren" class="submenu-group__items">
<div
v-for="child in group._children"
:key="child._ownPath"
class="submenu-item"
:class="{ 'submenu-item--leaf': !child._hasChildren }"
@click="goTo(child)"
>
<i v-if="child._hasChildren" class="el-icon-folder submenu-item__folder" />
<i v-else class="el-icon-document submenu-item__doc" />
<span class="submenu-item__text">{{ child._title }}</span>
<i v-if="child._hasChildren" class="el-icon-arrow-right submenu-item__arrow" />
</div>
</div>
</div>
</div>
<div v-else class="submenu-page__empty">暂无可访问的菜单</div>
</div>
</template>
<script>
import path from 'path'
export default {
name: 'RedirectMenu',
computed: {
parentPath() {
return this.$route.query.parent || ''
},
parentTitle() {
return this.$route.query.title || this.parentPath
},
tree() {
const sidebarRouters = this.$store.state.permission.sidebarRouters
const children = this.findChildren(sidebarRouters, this.parentPath, '')
if (!children) return []
return this.buildTree(children, this.parentPath)
}
},
methods: {
findChildren(routes, targetPath, basePath) {
for (const route of routes) {
if (route.hidden) continue
const fullPath = basePath ? path.resolve(basePath, route.path) : route.path
if (fullPath === targetPath) {
return route.children || []
}
if (route.children && route.children.length > 0) {
const result = this.findChildren(route.children, targetPath, fullPath)
if (result) return result
}
}
return null
},
buildTree(children, parentPath) {
return children
.filter(c => !c.hidden)
.map(c => {
const ownPath = c.path.startsWith('/') ? c.path : path.resolve(parentPath, c.path)
const title = (c.meta && c.meta.title) || c.name || c.path || ''
const hasChildren = c.children && c.children.length > 0 && c.children.some(gc => !gc.hidden)
const item = {
...c,
_ownPath: ownPath,
_fullPath: ownPath,
_title: title,
_hasChildren: hasChildren
}
if (hasChildren) {
item._children = this.buildTree(c.children, ownPath)
}
return item
})
},
goTo(item) {
if (item._hasChildren) {
this.$router.push({
path: '/redirect/subMenu',
query: { parent: item._ownPath, title: item._title }
})
} else if (item.path) {
this.$router.push(item._fullPath)
}
}
}
}
</script>
<style lang="scss" scoped>
.submenu-page {
padding: 16px 20px;
max-width: 900px;
margin: 0 auto;
}
.submenu-page__header {
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #ebeef5;
}
.submenu-page__parent-title {
font-size: 16px;
font-weight: 600;
color: #303133;
}
.submenu-page__list {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.submenu-page__empty {
text-align: center;
padding: 40px 0;
color: #909399;
font-size: 14px;
}
.submenu-group {
width: calc(50% - 6px);
min-width: 280px;
background: #fafbfc;
border: 1px solid #ebeef5;
border-radius: 6px;
overflow: hidden;
transition: border-color 0.2s;
&:hover {
border-color: #c0c4cc;
}
}
.submenu-group__title {
display: flex;
align-items: center;
padding: 12px 16px;
cursor: pointer;
background: #fff;
border-bottom: 1px solid #f0f0f0;
transition: background 0.15s;
&:hover {
background: #f5f7fa;
}
}
.submenu-group__icon {
font-size: 16px;
color: var(--current-color, #409EFF);
margin-right: 8px;
flex-shrink: 0;
}
.submenu-group__text {
font-size: 14px;
font-weight: 500;
color: #303133;
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.submenu-group__count {
font-size: 11px;
color: #909399;
margin-right: 6px;
flex-shrink: 0;
}
.submenu-group__arrow {
font-size: 12px;
color: #c0c4cc;
flex-shrink: 0;
}
.submenu-group__items {
padding: 4px 0;
}
.submenu-item {
display: flex;
align-items: center;
padding: 8px 16px 8px 24px;
cursor: pointer;
transition: background 0.15s;
&:hover {
background: #f0f2f5;
}
&:not(:last-child) {
border-bottom: 1px solid #f5f5f5;
}
}
.submenu-item__folder {
font-size: 13px;
color: #e6a23c;
margin-right: 8px;
flex-shrink: 0;
}
.submenu-item__doc {
font-size: 13px;
color: #909399;
margin-right: 8px;
flex-shrink: 0;
}
.submenu-item__text {
font-size: 13px;
color: #606266;
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.submenu-item__arrow {
font-size: 12px;
color: #c0c4cc;
flex-shrink: 0;
margin-left: 4px;
}
.submenu-item--leaf {
.submenu-item__doc {
color: #c0c4cc;
}
}
</style>