From 1df7b1781a035c37ab907de8c4a7d5177e68f12d Mon Sep 17 00:00:00 2001 From: chenyuan Date: Tue, 4 Aug 2026 16:34:20 +0800 Subject: [PATCH] feat: sync student navigation with task allocation --- src/layout/components/Navbar.vue | 32 +++++++++-- src/layout/components/Sidebar/index.vue | 52 +++++------------ src/router/index.js | 15 +++++ src/utils/studentTrainingNavigation.cjs | 67 ++++++++++++++++++++++ tests/student-training-navigation.test.cjs | 48 ++++++++++++++++ tests/task-publication.static.test.cjs | 4 +- 6 files changed, 174 insertions(+), 44 deletions(-) create mode 100644 src/utils/studentTrainingNavigation.cjs create mode 100644 tests/student-training-navigation.test.cjs diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue index b702ca7..f882979 100644 --- a/src/layout/components/Navbar.vue +++ b/src/layout/components/Navbar.vue @@ -81,7 +81,9 @@ import useAppStore from "@/store/modules/app"; import useUserStore from "@/store/modules/user"; import useSettingsStore from "@/store/modules/settings"; import * as indexApi from "@/api/teacher"; +import { listTrainingTasks } from "@/api/trainingTask"; import { getStudentDemoSession, isStudentDemo } from "@/utils/studentDemo"; +import studentTrainingNavigation from "@/utils/studentTrainingNavigation.cjs"; const { proxy } = getCurrentInstance(); const router = useRouter(); const appStore = useAppStore(); @@ -90,6 +92,8 @@ const settingsStore = useSettingsStore(); const showModel = ref(false); const form = ref({}); const role = computed(() => Number(userStore.userInfo.roleId)); +const { getComprehensiveTopTask } = studentTrainingNavigation; +const studentTopTask = ref(null); const mentList = ref([ { name: "首页", @@ -263,7 +267,7 @@ const roleList = computed(() => { const teacherOrder = ["/index", "/analysis/index", "/ai/teaching-plan"]; return teacherOrder.map((path) => mentList.value.find((item) => item.path === path)).filter(Boolean); } - return mentList.value.filter((item) => { + const items = mentList.value.filter((item) => { if (currentRole === 1) { return item.path === "/index" || item.role === 1; } @@ -273,7 +277,26 @@ const roleList = computed(() => { if (!item.role || item.path === "/index" || item.path === "/analysis/index") return true; return item.role == currentRole; }); + if (currentRole !== 4 || !studentTopTask.value) return items; + const homeIndex = items.findIndex((item) => item.path === "/index"); + return [ + ...items.slice(0, homeIndex + 1), + studentTopTask.value, + ...items.slice(homeIndex + 1), + ]; }); +async function loadStudentTopTask() { + if (role.value !== 4) { + studentTopTask.value = null; + return; + } + try { + const res = await listTrainingTasks({ enabledOnly: true }); + studentTopTask.value = getComprehensiveTopTask(res.data || []); + } catch (error) { + studentTopTask.value = null; + } +} // 获取用户详情 const getUserInfo = () => { if (isStudentDemo()) { @@ -323,9 +346,10 @@ const changePassword = () => { }) .catch(() => {}); }; -onMounted(() => { - getUserInfo(); -}); +onMounted(() => { + getUserInfo(); + loadStudentTopTask(); +});