feat: 新增模块首页、国际化适配与菜单重载功能

1. 为菜单数据新增remark字段并设置默认值
2. 全量替换硬编码文本为国际化多语言支持
3. 新增生产配置模块首页组件与路由
4. 新增菜单重载action,支持语言切换后重载菜单
5. 补充简体中文、英文、日文、繁体中文语言包
This commit is contained in:
sheng
2026-05-28 15:47:19 +08:00
parent 05bfa95bfe
commit 3149ffb932
22 changed files with 1132 additions and 72 deletions

View File

@@ -0,0 +1,174 @@
<template>
<div class="d2-navi">
<d2-scrollbar>
<el-collapse v-model="activeNames">
<el-collapse-item
v-for="(item, index) in menuData"
:key="`parent${index}`"
:name="item.menu_id">
<template slot="title">
<span class="d2-navi__title">
<d2-icon v-if="item.icon" class="iconfont__mini" :name="item.icon"/>
<i v-else class="el-icon-folder"/>
</span>
<span>{{ $t(item.title) }}</span>
</template>
<div class="flex-wrap">
<div
v-for="(sub, key) in item.children"
:key="`sub${key}`"
class="d2-navi__block"
@click="handleMenuSelect(sub.path)">
<div class="d2-navi__content">
<span class="d2-navi__icon">
<d2-icon v-if="sub.icon" class="iconfont__medium" :name="sub.icon"/>
<i v-else class="el-icon-document"/>
</span>
<div class="d2-navi__info">
<p class="d2-navi__sub_title">
<i v-if="sub.type" class="el-icon-link d2-pr-5"/>
<span>{{ $t(sub.title) }}</span>
</p>
<p class="d2-navi__desc" :title="$t(sub.remark)">
{{ $t(sub.remark) }}</p>
</div>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</d2-scrollbar>
</div>
</template>
<script>
import { mapState } from 'vuex'
import menuMixin from '@/layout/header-aside/components/mixin/menu'
export default {
name: 'module-index',
mixins: [
menuMixin
],
data () {
return {
activeNames: []
}
},
computed: {
...mapState('d2admin/menu', [
'aside'
]),
rootPath () {
return this.$route.meta.root || this.$route.path
},
menuData () {
// eslint-disable-next-line no-unused-expressions
this.$i18n.locale
const key = this.aside.findIndex(item => item.path === this.rootPath)
if (key === -1 || !this.aside[key].children) {
return []
}
return this.aside[key].children.filter(item => {
const title = item.title || ''
if (title.indexOf('首页') !== -1) return false
if (item.icon === 'home') return false
if (this.$route.path === item.path) return false
return true
})
}
},
watch: {
menuData: {
handler (val) {
this.activeNames = val.map(item => item.menu_id)
},
immediate: true
}
}
}
</script>
<style lang="scss">
.d2-navi {
height: calc(100vh - 160px);
padding: 20px;
background-color: #FFF;
.d2-navi__title {
display: inline-block;
width: 20px;
margin-right: 6px;
color: $color-info;
font-size: 16px;
text-align: center;
vertical-align: middle;
}
.iconfont__mini {
font-size: 20px;
}
.iconfont__medium {
font-size: 40px;
}
.flex-wrap {
display: flex;
flex-wrap: wrap;
margin: -15px auto -10px;
}
.d2-navi__block {
width: 20%;
box-sizing: border-box;
padding: 0 7.5px;
margin-top: 15px;
}
.d2-navi__content {
display: flex;
cursor: pointer;
color: $color-info;
border-radius: 4px;
background-color: #F5F7FA;
padding: 10px;
overflow: hidden;
}
.d2-navi__icon {
display: flex;
justify-content: center;
align-items: center;
min-width: 60px;
font-size: 32px;
}
.d2-navi__info {
min-width: 0;
p {
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.d2-navi__sub_title {
color: $color-text-main;
height: 24px;
font-size: 14px;
font-weight: bold;
line-height: 24px;
}
.d2-navi__desc {
font-size: 12px;
height: 23px;
line-height: 23px;
}
}
</style>