feat(system): 菜单增加图标选择功能

- 在菜单查询中添加 icon 字段
- 在菜单对话框中添加图标选择功能
- 在侧边栏中根据路由图标进行分类显示
- 添加知识库相关图标
This commit is contained in:
du.meimei
2025-04-25 14:30:15 +08:00
parent 19024c50d4
commit a7a5260a78
5 changed files with 109 additions and 28 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -13,10 +13,21 @@
@click="selectParentMenu(route)"
>
<i
v-if="route.meta && route.meta.icon"
class="iconfont fs22"
:class="route.meta.icon"
v-if="route.icon"
:class="[
route.icon,
{ iconfont: !route.icon.includes('el-icon') },
{ mb5: route.icon.includes('el-icon') }
]"
class=" fs22"
></i>
<img
v-else
:src="activeParent === route.url ? knowledgeActive : knowledge"
alt=""
class="mb5"
style="width: 20px"
/>
<span class="menu-title">{{ route.menuName }}</span>
</div>
</div>
@@ -43,9 +54,12 @@
@click="navigateTo(subItem.url)"
>
<i
v-if="subItem.meta && subItem.meta.icon"
class="iconfont mr10"
:class="subItem.meta.icon"
v-if="subItem.icon"
class="mr10"
:class="[
subItem.icon,
{ iconfont: !subItem.icon.includes('el-icon') }
]"
/>
<span>{{ subItem.menuName }}</span>
</div>
@@ -57,15 +71,22 @@
</template>
<script>
import Cookies from 'js-cookie'
import { mapGetters, mapActions } from 'vuex'
import Logo from './Logo'
import variables from '@/assets/sass/variables.scss'
import Personal from '@/views/app/layout/components/Sidebar/personal.vue'
import knowledge from '@/assets/images/knowledge.png'
import knowledgeActive from '@/assets/images/knowledgeActive.png'
export default {
components: { Personal, Logo },
computed: {
knowledge() {
return knowledge
},
knowledgeActive() {
return knowledgeActive
},
...mapGetters(['sidebar', 'sidebarList']),
routes() {
return this.$router.options.routes
@@ -91,8 +112,6 @@ export default {
currentSubmenu() {
if (!this.activeParent) return []
const parent = this.menuList.find(item => item.url === this.activeParent)
console.log('Parent found:', parent)
console.log('Children:', parent ? parent.children : 'No children')
return parent ? parent.children || [] : []
},
currentParentTitle() {
@@ -115,8 +134,6 @@ export default {
menu.map(item => {
if (parentPath) {
item.url = '/' + parentPath + '/' + item.url
} else {
item.url = item.url
}
if (item.otherInfo1 == 0) {
item.name = item.menuName
@@ -138,7 +155,6 @@ export default {
},
selectParentMenu(route) {
this.activeParent = route.url
console.log(Cookies.get('sidebarStatus'))
// this.$store.dispatch('app/toggleSideBar')
// If this parent has children, don't navigate
if (route.children && route.children.length > 0) {
@@ -189,24 +205,14 @@ export default {
created() {
if (sessionStorage.token !== 'MockToken') {
// 获取路由数据
let data = this.$store.state.app.sidebarList
console.log('sidebarList')
console.log(data)
// 通过检查路由结构来确定顶级菜单
const topLevelRoutes = data.filter(route => {
// 如果路由有 meta 和 children则认为它是顶级菜单
return route.meta && route.children && !route.hidden
})
this.menuList = data
this.menuList = this.$store.state.app.sidebarList
} else {
// 从路由配置中获取顶级路由
const topLevelRoutes = this.routes.filter(route => {
this.menuList = this.routes.filter(route => {
// 只显示有 meta 和 children 的路由,并且不是隐藏的
return route.meta && route.children && !route.hidden
})
this.menuList = topLevelRoutes
}
// 根据当前路由设置活动的父菜单
@@ -246,7 +252,6 @@ export default {
border-right: 1px solid #ebeef2;
overflow-y: auto;
background-color: #fff;
padding: 0 10px;
text-align: center;
display: flex;
flex-direction: column;

View File

@@ -81,6 +81,32 @@
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="菜单icon" prop="icon">
<el-select
v-model="form.icon"
size="medium"
filterable
placeholder="请选择图标"
>
<el-option label="全部" value=""></el-option>
<el-option
v-for="icon in iconList"
:key="icon"
:label="icon"
:value="icon"
>
<div class="flex align-items-c">
<i
:class="[icon, { iconfont: !icon.includes('el-icon') }]"
class="mr10"
></i>
<span>{{ icon }}</span>
</div>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer" v-if="!isView">
@@ -147,7 +173,55 @@ export default {
type: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }]
},
typeOptions: [{ value: 0, label: '菜单' }, { value: 1, label: '接口' }],
loading: false
loading: false,
iconList: [
'el-icon-user-solid',
'el-icon-bangzhu',
'el-icon-orange',
'el-icon-lock',
'el-icon-setting',
'el-icon-camera-solid',
'el-icon-video-camera-solid',
'el-icon-bell',
'el-icon-map-location',
'el-icon-picture-outline',
'el-icon-picture',
'el-icon-document',
'el-icon-document-add',
'el-icon-printer',
'el-icon-share',
'el-icon-delete-solid',
'el-icon-delete',
'el-icon-search',
'el-icon-edit',
'el-icon-edit-outline',
'el-icon-refresh',
'el-icon-refresh-left',
'el-icon-refresh-right',
'el-icon-circle-plus',
'el-icon-circle-plus-outline',
'el-icon-remove',
'el-icon-remove-outline',
'el-icon-circle-check',
'el-icon-circle-check-solid',
'el-icon-circle-close',
'el-icon-circle-close-solid',
'el-icon-top',
'el-icon-bottom',
'el-icon-right',
'el-icon-back',
'el-icon-d-arrow-left',
'el-icon-d-arrow-right',
'el-icon-sort',
'el-icon-sort-up',
'el-icon-sort-down',
'icon-zhuye',
'icon-dingwei',
'icon-notebook',
'el-icon-s-custom',
'icon-dengpao1',
'icon-guizeshezhi'
]
}
},
watch: {
@@ -220,7 +294,7 @@ export default {
this.form = {}
}
})
.catch(error => {
.catch(() => {
this.$message.error(this.isEdit ? '修改菜单出错' : '添加菜单出错')
})
.finally(() => {

View File

@@ -85,7 +85,8 @@ export default {
queryParams: {
menuCodeLike: '',
menuNameLike: '',
type: null
type: null,
icon: ''
},
typeOptions: [{ value: 0, label: '菜单' }, { value: 1, label: '接口' }],
// 表格配置项
@@ -188,6 +189,7 @@ export default {
this.queryParams.menuNameLike = ''
this.queryParams.menuCodeLike = ''
this.queryParams.type = null
this.queryParams.icon = ''
this.handleQuery()
},
handleSubmit() {