diff --git a/src/views/studentDemo/index.vue b/src/views/studentDemo/index.vue
index cb09e39..d908a8c 100644
--- a/src/views/studentDemo/index.vue
+++ b/src/views/studentDemo/index.vue
@@ -7,6 +7,23 @@ import { exchangeStudentDemoSession } from "@/api/studentDemo";
import { saveStudentDemoSession } from "@/utils/studentDemo";
import useUserStore from "@/store/modules/user";
+// 学生端演示登录态的角色:固定为学生 (roleId === 4),避免后端返回
+// 教师身份导致跳转到教师首页。后端若返回 demoTeachingClassId,会被
+// 透传保留,登录页/Navbar/AppMain 可据此识别为"演示学生"。
+const STUDENT_DEMO_ROLE_ID = "4";
+
+function unwrapDemoPayload(payload) {
+ if (!payload || typeof payload !== "object") {
+ return { userInfo: { roleId: STUDENT_DEMO_ROLE_ID }, token: "" };
+ }
+ // 兼容两种返回结构:
+ // 1) { token, roleId, userId, ... } —— 扁平结构
+ // 2) { token, userInfo: { roleId, ... } } —— userInfo 嵌套
+ const inner = payload.userInfo && typeof payload.userInfo === "object" ? payload.userInfo : payload;
+ const token = inner.token || payload.token || "";
+ return { userInfo: { ...inner, token, roleId: STUDENT_DEMO_ROLE_ID }, token };
+}
+
const userStore = useUserStore();
const message = ref("正在连接教师演示会话…");
let readyTimer;
@@ -15,15 +32,36 @@ function notifyReady() {
if (window.opener) window.opener.postMessage({ type: "STUDENT_DEMO_READY" }, window.location.origin);
}
+function applyDemoSession(demoPayload) {
+ const { userInfo, token } = unwrapDemoPayload(demoPayload);
+ // 保存到 sessionStorage(getUserInfo/getToken 优先从这里读取)
+ // 注意:演示 session 只放在新窗口的 sessionStorage,避免覆盖
+ // 教师主窗口的 cookie/sessionStorage 而把教师侧误切到学生身份。
+ saveStudentDemoSession(userInfo);
+ // 立即更新 Pinia,避免 reload 之前出现教师内容闪烁
+ userStore.token = token;
+ userStore.userInfo = userInfo;
+}
+
function receiveTicket(event) {
if (event.origin !== window.location.origin || event.source !== window.opener || event.data?.type !== "STUDENT_DEMO_TICKET") return;
exchangeStudentDemoSession(event.data.ticket).then((res) => {
- saveStudentDemoSession(res.data);
- userStore.token = res.data.token;
- userStore.userInfo = res.data;
+ if (!res || !res.data) {
+ message.value = "演示服务返回数据为空,请稍后重试";
+ return;
+ }
+ applyDemoSession(res.data);
window.clearInterval(readyTimer);
window.removeEventListener("message", receiveTicket);
- window.location.hash = "#/index";
+ // 跳转学生端基础课首页 #/foundation/new-product-survey:
+ // roleId 已被改写为 4,filterDynamicRoutes 会加载 student 路由,
+ // 避开 /index 的角色分发逻辑(role==='3' 会落到
上传案例资料,配置实训步骤