peixue-dev/Archive/[一次性]游客模式问题最终诊断-2026-02-01.md

7.7 KiB
Raw Blame History

游客模式问题最终诊断 - 2026-02-01

问题现状

游客模式下,以下三个页面仍然无法显示数据:

  1. 选择陪伴员页面 (/api/teacher/list)
  2. 兴趣培养页面 (/api/interest-course/list)
  3. 专项突破页面 (/api/special-course/list)

后端代码检查结果

TeacherController.java

接口: GET /api/teacher/list

代码分析:

@GetMapping("/list")
public Result<Page<TeacherVO>> getTeacherList(
        @RequestParam(required = false) String keyword,
        @RequestParam(required = false) String teacherName,
        // ... 其他参数
        @RequestParam(defaultValue = "1") Integer page,
        @RequestParam(defaultValue = "10") Integer size) {
    // ✅ 没有使用 userId 参数
    // ✅ 没有从 HttpServletRequest 获取 userId
    // ✅ 直接调用 Service 查询数据
    Page<Teacher> result = teacherService.getTeacherList(...);
    return Result.success((Page) result);
}

结论: 这个接口不需要登录,应该可以正常返回数据

InterestCourseController.java

接口: GET /api/interest-course/list

代码分析:

@GetMapping("/list")
public Result<Page<InterestCourse>> getCourseList(
        @RequestParam(defaultValue = "1") Integer pageNum,
        @RequestParam(defaultValue = "10") Integer pageSize,
        @RequestParam(required = false) String keyword,
        @RequestParam(required = false) String category) {
    // ✅ 没有使用 userId 参数
    // ✅ 没有从 HttpServletRequest 获取 userId
    // ✅ 直接调用 Service 查询数据
    Page<InterestCourse> page = interestCourseService.getCourseList(...);
    return Result.success(page);
}

结论: 这个接口不需要登录,应该可以正常返回数据

SpecialCourseController.java

接口: GET /api/special-course/list

代码分析:

@GetMapping("/list")
public Result<List<SpecialCourse>> getCourseList(
        @RequestParam(required = false) String category,
        @RequestParam(required = false) String subCategory,
        // ... 其他参数
        @RequestParam(required = false) String sortBy) {
    // ✅ 没有使用 userId 参数
    // ✅ 没有从 HttpServletRequest 获取 userId
    // ✅ 直接调用 Service 查询数据
    List<SpecialCourse> list = specialCourseService.list(wrapper);
    return Result.success(list);
}

结论: 这个接口不需要登录,应该可以正常返回数据

JWT拦截器检查

文件: JwtInterceptor.java

当前逻辑:

// ✅ 如果没有token不抛出异常直接放行
if (!StringUtils.hasText(token)) {
    System.out.println("token为空放行请求");
    return true;
}

结论: JWT拦截器已经修改为放行无token请求

WebMvcConfig检查

文件: WebMvcConfig.java

排除路径配置:

.excludePathPatterns(
    "/api/teacher/list",            // ✅ 已排除
    "/api/teacher/detail/**",       // ✅ 已排除
    "/api/teacher/filter-options",  // ✅ 已排除
    "/api/special/**",              // ✅ 已排除(包含 /api/special-course/list)
    "/api/interest/**",             // ✅ 已排除(包含 /api/interest-course/list)
    // ...
)

结论: 这三个接口都已经在排除列表中

前端请求配置检查

文件: request.js

游客白名单:

const GUEST_ALLOWED_URLS = [
  '/api/teacher/list',            // ✅ 已添加
  '/api/teacher/filter-options',  // ✅ 已添加
  '/api/special-course/list',     // ✅ 已添加
  '/api/interest-course/list',    // ❌ 可能缺少这个
  // ...
]

游客模式处理:

// ✅ 游客访问白名单接口时不发送token
if (isGuest && isGuestAllowedUrl(options.url)) {
    console.log('[Request] 游客模式白名单接口返回401静默失败');
    reject({ code: 401, message: '未登录', silent: true });
    return
}

可能的问题点

问题1: 前端白名单可能不完整

检查: request.js 中的 GUEST_ALLOWED_URLS 是否包含:

  • /api/teacher/list
  • /api/interest-course/list (可能缺少)
  • /api/special-course/list (可能缺少)

问题2: 前端URL匹配逻辑

当前匹配逻辑:

function isGuestAllowedUrl(url) {
   return GUEST_ALLOWED_URLS.some(allowedUrl => url.includes(allowedUrl))
}

问题: 使用 includes 可能导致匹配不准确

示例:

  • URL: /api/interest-course/list?page=1&size=10
  • 白名单: /api/interest-course/list
  • 匹配结果: 应该匹配成功

问题3: 前端实际发送的URL

需要确认:

  • 前端实际发送的URL是什么?
  • 是否包含查询参数?
  • 是否与白名单中的URL匹配?

问题4: 后端实际返回的错误

需要确认:

  • 后端是否真的返回401错误?
  • 还是返回其他错误(如500、404)?
  • 错误消息是什么?

诊断步骤

步骤1: 检查前端白名单

打开 peidu/uniapp/src/utils/request.js,检查 GUEST_ALLOWED_URLS 数组:

const GUEST_ALLOWED_URLS = [
   '/api/teacher/list',              // ✅ 必须有
   '/api/teacher/filter-options',    // ✅ 必须有
   '/api/interest-course/list',      // ❓ 检查是否存在
   '/api/special-course/list',       // ❓ 检查是否存在
   // ...
]

步骤2: 检查前端控制台

在微信开发者工具的控制台中查看:

正常日志:

[Request] 当前环境: 生产环境
[Request] BASE_URL: https://px.ddn-ai.cloud
[Request] GET URL: https://px.ddn-ai.cloud/api/teacher/list?page=1&size=10
[Request] 游客模式白名单接口返回401静默失败: /api/teacher/list

异常日志:

[Request] 401 未登录
登录已过期,请重新登录

步骤3: 检查Network请求

在微信开发者工具的Network标签中查看:

请求信息:

  • URL: 完整的请求URL
  • Method: GET
  • Headers: 是否包含 Authorization
  • Status: 实际返回的状态码

响应信息:

  • Status Code: 200? 401? 500?
  • Response Body: 实际返回的数据

步骤4: 检查后端日志

在后端控制台中查看:

正常日志:

=== JWT拦截器执行 ===
请求路径: /api/teacher/list
Authorization Header: null
token为空放行请求
=== JWT拦截器执行完成 ===

异常日志:

=== JWT拦截器执行 ===
请求路径: /api/teacher/list
Authorization Header: null
token验证失败抛出过期异常

下一步行动

方案1: 检查前端白名单(最可能)

如果 GUEST_ALLOWED_URLS 中缺少这两个URL:

  • /api/interest-course/list
  • /api/special-course/list

修复: 添加这两个URL到白名单

方案2: 检查前端URL匹配逻辑

如果URL匹配逻辑有问题:

修复: 改进匹配逻辑,使用更精确的匹配方式

方案3: 检查后端Service层

如果Controller没问题,可能是Service层有问题:

检查:

  • TeacherService.getTeacherList()
  • InterestCourseService.getCourseList()
  • SpecialCourseService.list()

方案4: 检查数据库数据

如果Service没问题,可能是数据库没有数据:

检查:

-- 检查教师数据
SELECT COUNT(*) FROM teacher WHERE deleted = 0;

-- 检查兴趣课程数据
SELECT COUNT(*) FROM interest_course WHERE status = 1;

-- 检查专项课程数据
SELECT COUNT(*) FROM special_course WHERE status = 1;

总结

根据代码检查,后端的三个Controller都不需要userId参数,应该可以正常返回数据。

最可能的问题:

  1. 前端白名单不完整(缺少 /api/interest-course/list/api/special-course/list)
  2. 前端URL匹配逻辑有问题
  3. 数据库中没有数据

建议: 先检查前端的 request.js 文件,确认白名单是否完整。