From 949d5f439d50822fa1291b43c6dca935ac332985 Mon Sep 17 00:00:00 2001 From: yuk255 Date: Fri, 10 Oct 2025 09:50:46 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E5=AD=A6=E5=91=98=E4=B8=AD?= =?UTF-8?q?=E5=BF=83=E8=8F=9C=E5=8D=95=E5=AF=B9=E6=8E=A5=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=9B=E6=95=99=E5=B8=88=E7=AB=AF=E8=8F=9C=E5=8D=95=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=B8=80=E4=B8=AA=E6=98=BE=E7=A4=BA=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/modules/menu.ts | 4 +- src/api/types.ts | 1 + src/components/InstantMessage.vue | 3 + src/views/Profile.vue | 222 +++++++++++++++++++-------- src/views/teacher/AdminDashboard.vue | 7 +- 5 files changed, 169 insertions(+), 68 deletions(-) diff --git a/src/api/modules/menu.ts b/src/api/modules/menu.ts index c2b8690..fe4ce5b 100644 --- a/src/api/modules/menu.ts +++ b/src/api/modules/menu.ts @@ -1,6 +1,6 @@ // 菜单相关API import { ApiRequest } from '../request' -import type { ApiResponse } from '../types' +import type { ApiResponse, ApiResponseWithResult } from '../types' // 菜单项接口定义 export interface MenuItem { @@ -27,7 +27,7 @@ export class MenuApi { /** * 获取学生菜单 */ - static async getStudentMenus(): Promise> { + static async getStudentMenus(): Promise> { return await ApiRequest.get('/aiol/aiolMenu/getStudentMenus') } } diff --git a/src/api/types.ts b/src/api/types.ts index d29d6cc..a02f879 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -13,6 +13,7 @@ export interface ApiResponseWithResult { code: number message: string data: { + code: number result: T } timestamp?: string diff --git a/src/components/InstantMessage.vue b/src/components/InstantMessage.vue index e8707d2..2f24566 100644 --- a/src/components/InstantMessage.vue +++ b/src/components/InstantMessage.vue @@ -3406,6 +3406,9 @@ onUnmounted(() => { justify-content: center; align-items: center; padding: 40px 20px; + position: relative; + height: 100%; + width: 100%; } .loading-text { diff --git a/src/views/Profile.vue b/src/views/Profile.vue index bbb9c21..6f60fac 100644 --- a/src/views/Profile.vue +++ b/src/views/Profile.vue @@ -23,70 +23,27 @@ - -
- - - 我的课程 + +
+ + + {{ menu.name }}
- - -
- - - 我的作业 -
- - -
- - - 我的考试 -
- - -
- - - 我的练习 -
- - -
- - - 我的活动 -
- - -
- - - 我的关注 -
- - -
- - - 我的消息 -
- - -
- - - 我的资料 -
- - -
@@ -1042,6 +999,7 @@ import QuillEditor from '@/components/common/QuillEditor.vue' import InstantMessage from '@/components/InstantMessage.vue' import { useRouter, useRoute } from 'vue-router' import { MessageApi, type BackendMessageItem } from '@/api' +import MenuApi from '@/api/modules/menu' import CourseContent from '@/components/profile/CourseContent.vue' import PracticeContent from '@/components/profile/PracticeContent.vue' import ActivityContent from '@/components/profile/ActivityContent.vue' @@ -3394,7 +3352,47 @@ const submitAssignment = () => { closeUploadModal() } -onMounted(() => { +const menuItems = ref([]) +const getMenu = async () => { + try { + const response = await MenuApi.getStudentMenus() + if (response.data && response.data.code === 200) { + menuItems.value = response.data.result + console.log('✅ 获取菜单成功:', menuItems.value) + } else { + menuItems.value = [] + } + } catch (error) { + console.error('❌ 获取菜单失败:', error) + menuItems.value = [] + } +} + +// 计算可见的菜单项 +const visibleMenuItems = computed(() => { + return menuItems.value + .filter(menu => menu.izVisible === 1) +}) + +// 从路径获取菜单tab key +const getMenuTabKey = (path: string): TabType => { + const pathMatch = path.match(/\/profile\/(.+)/) + return pathMatch ? pathMatch[1] as TabType : 'courses' +} + +// 获取激活状态的图标 +const getActiveIcon = (iconPath: string) => { + if (!iconPath) return iconPath + + const lastDotIndex = iconPath.lastIndexOf('.') + if (lastDotIndex === -1) return iconPath + '-active' + + const fileName = iconPath.substring(0, lastDotIndex) + const extension = iconPath.substring(lastDotIndex) + return fileName + '-active' + extension +} + +onMounted(async () => { // 初始化 // 检查是否需要刷新 const shouldRefresh = sessionStorage.getItem('refreshProfile') @@ -3408,6 +3406,9 @@ onMounted(() => { }, 100) } + // 获取菜单 + await getMenu() + const tabKey = route.params.tabKey || 'courses' handleMenuSelect(tabKey) @@ -9269,4 +9270,97 @@ onActivated(() => { .form-input::placeholder { color: #999; } + +/* 动态菜单样式 */ +[class^="menu-item-"] { + width: 11vw; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + cursor: pointer; + padding: 1.5vh 0 1.5vh 1.8vw; + border-radius: 0.31vw; + transition: all 0.3s ease; + background: transparent; +} + +[class^="menu-item-"]:hover { + background: #eff7fc; +} + +[class^="menu-item-"].active { + background: #eff7fc; +} + +/* 动态菜单图标 */ +[class^="menu-item-"] .menu-icon { + width: 1.04vw; + height: 1.04vw; + margin-right: 0.78vw; + object-fit: contain; + flex-shrink: 0; +} + +/* 动态菜单文字 */ +[class^="menu-item-"] .menu-text { + font-size: 16px; + color: rgba(102, 102, 102, 1); + font-family: 'Microsoft YaHei', Arial, sans-serif; + font-weight: normal; + line-height: 1.46vh; + transition: color 0.3s ease; +} + +/* 激活状态的菜单文字颜色 */ +[class^="menu-item-"].active .menu-text { + color: rgba(2, 134, 206, 1); +} + +/* 悬停状态的菜单文字颜色 */ +[class^="menu-item-"]:hover .menu-text { + color: rgba(2, 134, 206, 1); +} + +/* 动态菜单图标悬停效果 */ +[class^="menu-item-"] .hover-icon { + display: none; +} + +[class^="menu-item-"]:hover .default-icon { + display: none; +} + +[class^="menu-item-"]:hover .hover-icon { + display: block; +} + +/* 激活状态的图标显示 */ +[class^="menu-item-"].active .default-icon { + display: none; +} + +[class^="menu-item-"].active .hover-icon { + display: block; +} + +/* 移动端适配 */ +@media (max-width: 768px) { + [class^="menu-item-"] { + width: 80%; + margin: 1.5vh 0; + padding: 2vh 0 2vh 3vw; + } + + [class^="menu-item-"] .menu-icon { + width: 6vw; + height: 6vw; + margin-right: 4vw; + } + + [class^="menu-item-"] .menu-text { + font-size: 4.5vw; + line-height: 3vh; + } +} \ No newline at end of file diff --git a/src/views/teacher/AdminDashboard.vue b/src/views/teacher/AdminDashboard.vue index 6b18923..aa8b7b8 100644 --- a/src/views/teacher/AdminDashboard.vue +++ b/src/views/teacher/AdminDashboard.vue @@ -296,8 +296,11 @@ const processMenuData = (menuData) => { const menuMap = new Map() const rootMenus = [] + // 过滤只显示 izVisible 为 1 的菜单项 + const visibleMenuData = menuData.filter(menu => menu.izVisible === 1) + // 先创建所有菜单项的映射 - menuData.forEach(menu => { + visibleMenuData.forEach(menu => { menuMap.set(menu.id, { ...menu, children: [] @@ -305,7 +308,7 @@ const processMenuData = (menuData) => { }) // 构建层级关系 - menuData.forEach(menu => { + visibleMenuData.forEach(menu => { if (menu.parentId === null) { // 根级菜单 rootMenus.push(menuMap.get(menu.id))