7.7 KiB
游客模式问题最终诊断 - 2026-02-01
问题现状
游客模式下,以下三个页面仍然无法显示数据:
- 选择陪伴员页面 (
/api/teacher/list) - 兴趣培养页面 (
/api/interest-course/list) - 专项突破页面 (
/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参数,应该可以正常返回数据。
最可能的问题:
- ❓ 前端白名单不完整(缺少
/api/interest-course/list和/api/special-course/list) - ❓ 前端URL匹配逻辑有问题
- ❓ 数据库中没有数据
建议: 先检查前端的 request.js 文件,确认白名单是否完整。