# 游客模式401问题彻底修复方案 **问题**: 后端返回401错误,导致游客模式下无法看到课程数据 --- ## 🔍 问题诊断 ### 当前状态 1. ✅ 前端已配置游客白名单 2. ✅ 前端已添加 error.silent 检查 3. ✅ 后端WebMvcConfig已排除这些接口 4. ✅ JWT拦截器配置为无token时放行 5. ❌ **但后端仍然返回401错误** ### 控制台日志分析 ``` [Request] 游客模式,白名单接口业务码401,静默失败,不影响页面显示: /api/special-course/list {code: 401, message: "未登录", data: {…}, silent: true} ``` **结论**: 后端确实返回了401错误,说明有其他地方在检查用户登录状态 --- ## 🎯 可能的原因 ### 原因1: Service层检查了用户登录 某些Service方法可能使用了 `@CurrentUser` 注解或手动检查userId ### 原因2: 数据库中没有数据 即使接口正常,如果数据库中没有课程数据,也会显示空列表 ### 原因3: Controller中有隐式的登录检查 虽然没有显式的权限注解,但可能在方法内部检查了userId --- ## ✅ 解决方案 ### 方案1: 检查并修复Service层(推荐) #### 步骤1: 检查Service实现 查看这三个Service的实现,确保没有强制要求userId: - `SpecialCourseService` - `InterestCourseService` - `AssessmentServiceService` #### 步骤2: 修改Service方法 如果Service方法需要userId,改为可选参数: ```java // 修改前 public List getCourseList(Long userId) { if (userId == null) { throw new BusinessException(401, "未登录"); } // ... } // 修改后 public List getCourseList(Long userId) { // userId可以为null,游客模式下不影响查询 // ... } ``` ### 方案2: 创建测试数据 如果数据库中没有数据,创建一些测试数据: ```sql -- 插入专项突破课程测试数据 INSERT INTO special_course (name, category, sub_category, description, price, duration, icon, status, sort_order, created_at, updated_at) VALUES ('数学思维训练', 'math', '逻辑思维', '培养数学逻辑思维能力', 299.00, 60, '🧮', 1, 1, NOW(), NOW()), ('英语口语突破', 'english', '口语表达', '提升英语口语表达能力', 399.00, 90, '🗣️', 1, 2, NOW(), NOW()), ('阅读理解提升', 'language', '阅读理解', '提高阅读理解和分析能力', 199.00, 45, '📖', 1, 3, NOW(), NOW()); -- 插入兴趣培养课程测试数据 INSERT INTO interest_course (name, category, description, price, duration, icon, student_count, rating, status, created_at, updated_at) VALUES ('钢琴入门', '音乐', '从零开始学习钢琴演奏', 599.00, 120, '🎹', 156, 4.8, 1, NOW(), NOW()), ('绘画启蒙', '美术', '培养绘画兴趣和基础技能', 399.00, 90, '🎨', 203, 4.7, 1, NOW(), NOW()), ('编程思维', '科技', '培养计算思维和编程能力', 699.00, 150, '💻', 89, 4.9, 1, NOW(), NOW()); -- 插入测评服务测试数据 INSERT INTO assessment_service (name, category, description, price, duration, icon, assessor_name, assessor_title, rating, appointment_count, status, created_at, updated_at) VALUES ('学业能力测评', '学业', '全面评估学生学业水平', 299.00, 90, '📊', '张老师', '资深教育专家', 4.9, 234, 1, NOW(), NOW()), ('心理健康测评', '心理', '了解学生心理状态', 199.00, 60, '🧠', '李老师', '心理咨询师', 4.8, 178, 1, NOW(), NOW()), ('兴趣特长测评', '兴趣', '发现学生兴趣和特长', 249.00, 75, '🎯', '王老师', '职业规划师', 4.7, 145, 1, NOW(), NOW()); ``` ### 方案3: 后端直接返回空数据而不是401 修改Controller,即使没有userId也返回空列表: ```java @GetMapping("/list") public Result> getCourseList(@CurrentUser(required = false) Long userId, ...) { // userId可以为null,游客模式下返回公开课程 List courses = courseService.getCourseList(userId); return Result.success(courses); } ``` --- ## 🔧 立即执行的修复步骤 ### 步骤1: 检查数据库 运行脚本检查是否有数据: ``` Archive/[一次性]执行检查课程数据-2026-02-01.bat ``` ### 步骤2: 如果没有数据,插入测试数据 创建并执行SQL脚本插入测试数据 ### 步骤3: 重启后端服务 ``` cd peidu/backend mvn clean package -DskipTests java -jar target/peidu-backend.jar ``` ### 步骤4: 测试后端接口 ``` Archive/[一次性]测试后端匿名访问-游客模式-2026-02-01.bat ``` ### 步骤5: 如果还是401,检查Service层 查看Service实现,移除强制的userId检查 --- ## 📝 预期结果 修复后: - ✅ 游客访问课程列表 → 返回200和数据 - ✅ 前端正常显示课程列表 - ✅ 不再显示401错误 - ✅ 游客可以浏览所有公开课程 --- ## 🚨 注意事项 1. **不要在公开接口中检查userId** - 游客模式下userId为null是正常的 - 只在需要用户信息的接口中检查userId 2. **区分公开接口和私有接口** - 公开接口:课程列表、详情、搜索等 - 私有接口:购买、收藏、我的课程等 3. **数据权限控制** - 游客可以看到所有公开课程 - 但不能购买、不能看到价格敏感信息 --- ## 💡 最佳实践 ```java @GetMapping("/list") public Result> getCourseList( @CurrentUser(required = false) Long userId, // ✅ required = false @RequestParam(required = false) String category ) { // 游客模式:userId = null,返回公开课程 // 登录模式:userId != null,可以返回个性化推荐 List courses = courseService.getCourseList(userId, category); return Result.success(courses); } ``` --- ## 🎯 下一步 1. 先运行检查数据脚本,确认是否有数据 2. 如果没有数据,插入测试数据 3. 如果有数据但还是401,检查Service层实现 4. 修改Service层,移除强制的userId检查 5. 重启后端,测试接口