| | |
| | | <template> |
| | | <!-- <ScrollContainer> --> |
| | | <PageWrapper dense contentFullHeight fixedHeight> |
| | | <a-card style="height: 100vh; border-inline-end: 1px solid rgb(5 5 5 / 6%)"> |
| | | <div style="height: 100vh; border-inline-end: 1px solid rgb(5 5 5 / 6%)"> |
| | | <div style="height: 15vh; padding: 20px 40px; text-align: center"> |
| | | <span style="display: flex; justify-content: space-around"> |
| | | <a-button shape="circle" size="large"> |
| | | <template #icon> |
| | | <MailOutlined /> |
| | | </template> |
| | | <MailOutlined /> |
| | | </a-button> |
| | | <a-button shape="circle" size="large"> |
| | | <template #icon> |
| | | <UserOutlined /> |
| | | </template> |
| | | <UserOutlined /> |
| | | </a-button> |
| | | </span> |
| | | <a-button |
| | |
| | | size="large" |
| | | shape="round" |
| | | @click="$router.push('/email/edit')" |
| | | >写信</a-button |
| | | > |
| | | 写信 |
| | | </a-button> |
| | | </div> |
| | | <a-menu |
| | | id="email-left-nav" |
| | | v-model:openKeys="openKeys" |
| | | v-model:selectedKeys="selectedKeys" |
| | | mode="inline" |
| | | :items="items" |
| | | @click="handleClick" |
| | | > |
| | | </a-menu> |
| | | </a-card> |
| | | |
| | | <div class="menu-container"> |
| | | <a-menu |
| | | id="email-left-nav" |
| | | v-model:open-keys="openKeys" |
| | | v-model:selected-keys="selectedKeys" |
| | | mode="inline" |
| | | :popupClassName="popupClassName" |
| | | > |
| | | <template v-for="item in items" :key="item.key"> |
| | | <a-sub-menu v-if="item.children" :key="item.key"> |
| | | <template #title> |
| | | <div class="my-display"> |
| | | <span>{{ item.title }}</span |
| | | ><span class="my-left" v-if="item.total > 0">{{ item.total }}</span> |
| | | </div> |
| | | </template> |
| | | <a-menu-item |
| | | style="display: flex; justify-content: space-between; padding-left: 28px" |
| | | v-for="(child, index) in item.children" |
| | | :key="index" |
| | | @click="handleClick(child)" |
| | | > |
| | | <div class="my-display"> |
| | | <span>{{ child.title }}</span> |
| | | <span v-if="item.total > 0"> {{ child.total }}</span> |
| | | </div> |
| | | </a-menu-item> |
| | | </a-sub-menu> |
| | | <a-menu-item v-else :key="item.key" @click="handleClick(item)"> |
| | | <div class="my-display"> |
| | | <span>{{ item.title }}</span |
| | | ><span class="my-left" v-if="item.total > 0">{{ item.total }}</span> |
| | | </div> |
| | | </a-menu-item> |
| | | </template> |
| | | </a-menu> |
| | | </div> |
| | | </div> |
| | | </PageWrapper> |
| | | <!-- </ScrollContainer> --> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref } from 'vue'; |
| | | import type { MenuProps } from 'ant-design-vue'; |
| | | import { Menu } from 'ant-design-vue'; |
| | | import { useEmailRouterStoreWithout } from '@/store/modules/emailRouter'; |
| | | import { ref, onMounted } from 'vue'; |
| | | import { PageWrapper } from '@/components/Page'; |
| | | import { MailOutlined, UserOutlined } from '@ant-design/icons-vue'; |
| | | import { getEmailModuleApi } from '@/api/email/userList'; |
| | | import { useRouter } from 'vue-router'; |
| | | |
| | | const selectedKeys = ref<string[]>(['Index']); |
| | | const openKeys = ref<string[]>(['index']); |
| | | const openKeys = ref<string[]>(['Inbox']); |
| | | const items = ref([]); // 定义 items 类型 |
| | | |
| | | const AMenu = Menu; |
| | | const fnGetEmailModule = async () => { |
| | | try { |
| | | const res = await getEmailModuleApi(); |
| | | items.value = convertRoutesToMenuItems(res.data); |
| | | } catch (error) { |
| | | console.error('获取邮箱模块失败:', error); // 处理错误 |
| | | } |
| | | }; |
| | | |
| | | function convertRoutesToMenuItems(routes) { |
| | | return routes.map((route) => { |
| | | // 检查是否有子路由 |
| | | if (route.children && route.children.length > 0) { |
| | | return { |
| | | key: route.name, // 作为 Menu 组件的 key |
| | | label: route.meta?.title || route.name, // 显示的标签名称 |
| | | title: route.meta?.title || route.name, // title 属性(可选) |
| | | children: convertRoutesToMenuItems(route.children), // 递归处理子路由 |
| | | }; |
| | | } else { |
| | | if (!route.meta?.hideMenu) { |
| | | const convertRoutesToMenuItems = (routes: any[]) => { |
| | | return routes |
| | | .map((route) => { |
| | | if (route.children && route.children.length > 0) { |
| | | return { |
| | | key: route.name, // 如果没有子路由,直接返回 key 和 label |
| | | label: route.meta?.title || route.name, |
| | | title: route.meta?.title || route.name, |
| | | key: route.key, |
| | | title: route.mailName, |
| | | total: route.total, |
| | | children: convertRoutesToMenuItems(route.children), |
| | | }; |
| | | } |
| | | if (!route.hideMenu) { |
| | | return { |
| | | key: route.key, |
| | | title: route.mailName, |
| | | total: route.total, |
| | | }; |
| | | } |
| | | }) |
| | | .filter(Boolean); // 过滤掉 undefined |
| | | }; |
| | | |
| | | // 生命周期钩子,加载菜单数据 |
| | | onMounted(() => { |
| | | fnGetEmailModule(); |
| | | }); |
| | | const routesConfig = { |
| | | InboxPage1: '/email/index', |
| | | receiver: '/email/Inbox/list', |
| | | }; |
| | | // 点击事件处理 |
| | | const router = useRouter(); |
| | | const handleClick = (e: any) => { |
| | | console.log(e, '------4'); |
| | | let matched = false; |
| | | const route = router.getRoutes() || []; |
| | | route.forEach((item) => { |
| | | if (item.name === e.key) { |
| | | router.push(item.path); |
| | | matched = true; |
| | | return; // 跳出当前循环 |
| | | } |
| | | |
| | | if (!matched) { |
| | | switch (e.key) { |
| | | case 'InboxPage1': |
| | | router.push(routesConfig[e.key]); |
| | | matched = true; |
| | | return; // 跳出当前循环 |
| | | case 'receiver': |
| | | router.push(`${routesConfig[e.key]}?${e.title}`); |
| | | matched = true; |
| | | return; // 跳出当前循环 |
| | | default: |
| | | // 处理默认情况,例如记录日志或抛出警告 |
| | | console.warn(`Unknown key: ${e.key}`); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | const emailRouter = useEmailRouterStoreWithout(); |
| | | const items = ref(convertRoutesToMenuItems(emailRouter.$state.children)); |
| | | import { useRouter } from 'vue-router'; |
| | | const router = useRouter(); |
| | | const handleClick: MenuProps['onClick'] = (e) => { |
| | | console.log('click', router.getRoutes()); |
| | | router.getRoutes().map((item) => { |
| | | if (item.name === e.key) { |
| | | router.push(item.path); |
| | | } |
| | | }); |
| | | }; |
| | | const popupClassName = { |
| | | display: 'flex', |
| | | 'align-items': 'center', |
| | | 'justify-content': 'space-between', |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped> |
| | | :deep(.ant-menu-inline) { |
| | | border-inline-end: 0 solid rgb(5 5 5 / 6%) !important; |
| | | } |
| | | |
| | | .menu-container { |
| | | height: 70vh; |
| | | overflow: auto; |
| | | } |
| | | |
| | | .my-display { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | .my-left { |
| | | margin-left: 5px; |
| | | } |
| | | </style> |