Files
aiot-uniapp/src/pages-system/menu/index.vue

181 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="min-h-screen bg-[#f5f5f5]">
<!-- 顶部导航栏 -->
<wd-navbar
title="菜单管理"
left-arrow placeholder safe-area-inset-top fixed
@click-left="handleBack"
/>
<!-- 面包屑导航 -->
<Breadcrumb ref="breadcrumbRef" v-model="currentParentId" />
<!-- 菜单列表 -->
<view class="p-24rpx">
<view
v-for="item in currentList"
:key="item.id"
class="mb-24rpx overflow-hidden rounded-12rpx bg-white shadow-sm"
>
<!-- 主内容区域点击进入详情 -->
<view class="p-24rpx" @click="handleDetail(item)">
<!-- 第一行图标名称状态标签 -->
<view class="flex items-center justify-between">
<view class="flex items-center">
<view class="mr-16rpx h-48rpx w-48rpx flex items-center justify-center rounded-8rpx" :class="getTypeIconBg(item.type)">
<wd-icon :name="getTypeIcon(item.type)" size="20px" color="#fff" />
</view>
<view class="text-32rpx text-[#333] font-semibold">
{{ item.name }}
</view>
</view>
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="item.status" />
</view>
<!-- 第二行类型描述子菜单入口 -->
<view class="mt-12rpx flex items-center justify-between pl-64rpx">
<view class="text-24rpx text-[#999]">
{{ getTypeDesc(item) }}
</view>
<view
v-if="item.children && item.children.length > 0"
class="flex items-center"
@click.stop="handleEnterChildren(item)"
>
<text class="text-24rpx text-[#1890ff]">子菜单 ({{ item.children.length }})</text>
<wd-icon name="arrow-right" size="12px" color="#1890ff" />
</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="!loading && currentList.length === 0" class="py-100rpx text-center">
<wd-status-tip image="content" tip="暂无菜单数据" />
</view>
</view>
<!-- 新增按钮 -->
<view
class="fixed bottom-100rpx right-32rpx z-10 h-100rpx w-100rpx flex items-center justify-center rounded-full bg-[#1890ff] shadow-lg"
@click="handleAdd"
>
<wd-icon name="add" size="24px" color="#fff" />
</view>
</view>
</template>
<script lang="ts" setup>
import type { Menu } from '@/api/system/menu'
import { computed, onMounted, ref } from 'vue'
import { getMenuList } from '@/api/system/menu'
import { DICT_TYPE, SystemMenuTypeEnum } from '@/utils/constants'
import { findChildren, handleTree } from '@/utils/tree'
import Breadcrumb from './components/breadcrumb.vue'
definePage({
style: {
navigationBarTitleText: '',
navigationStyle: 'custom',
},
})
const loading = ref(false)
const list = ref<Menu[]>([]) // 完整菜单列表(树形结构)
const currentParentId = ref(0) // 当前层级的父节点编号
const currentList = computed(() => {
if (currentParentId.value === 0) {
return list.value.filter(item => item.parentId === 0)
}
return findChildren(list.value, currentParentId.value)
}) // 当前层级的菜单列表
const breadcrumbRef = ref<InstanceType<typeof Breadcrumb>>()
/** 返回上一页或上一层级 */
function handleBack() {
if (!breadcrumbRef.value?.back()) {
uni.navigateBack()
}
}
/** 获取菜单类型图标 */
function getTypeIcon(type: number): string {
switch (type) {
case SystemMenuTypeEnum.DIR:
return 'folder'
case SystemMenuTypeEnum.MENU:
return 'read'
case SystemMenuTypeEnum.BUTTON:
return 'tips'
default:
return 'folder'
}
}
/** 获取菜单类型图标背景色 */
function getTypeIconBg(type: number): string {
switch (type) {
case SystemMenuTypeEnum.DIR:
return 'bg-[#1890ff]'
case SystemMenuTypeEnum.MENU:
return 'bg-[#52c41a]'
case SystemMenuTypeEnum.BUTTON:
return 'bg-[#faad14]'
default:
return 'bg-[#1890ff]'
}
}
/** 获取菜单类型描述(根据类型展示不同信息) */
function getTypeDesc(item: Menu): string {
switch (item.type) {
case SystemMenuTypeEnum.DIR:
return `路由:${item.path}`
case SystemMenuTypeEnum.MENU:
return `路由:${item.path}`
case SystemMenuTypeEnum.BUTTON:
return `权限:${item.permission}`
default:
return ''
}
}
/** 进入子菜单层级 */
function handleEnterChildren(item: Menu) {
breadcrumbRef.value?.enter({ id: item.id!, name: item.name })
}
/** 查询菜单列表 */
async function getList() {
loading.value = true
try {
const data = await getMenuList()
list.value = handleTree(data)
} finally {
loading.value = false
}
}
/** 新增菜单 */
function handleAdd() {
uni.navigateTo({
url: `/pages-system/menu/form/index?parentId=${currentParentId.value}`,
})
}
/** 查看详情 */
function handleDetail(item: Menu) {
uni.navigateTo({
url: `/pages-system/menu/detail/index?id=${item.id}`,
})
}
/** 初始化 */
onMounted(() => {
getList()
})
</script>
<style lang="scss" scoped>
</style>