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

296 lines
7.7 KiB
Markdown
Raw Normal View History

2026-02-28 17:26:03 +08:00
# 游客模式问题最终诊断 - 2026-02-01
## 问题现状
游客模式下,以下三个页面仍然无法显示数据:
1. 选择陪伴员页面 (`/api/teacher/list`)
2. 兴趣培养页面 (`/api/interest-course/list`)
3. 专项突破页面 (`/api/special-course/list`)
## 后端代码检查结果
### ✅ TeacherController.java
**接口**: `GET /api/teacher/list`
**代码分析**:
```java
@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`
**代码分析**:
```java
@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`
**代码分析**:
```java
@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`
**当前逻辑**:
```java
// ✅ 如果没有token不抛出异常直接放行
if (!StringUtils.hasText(token)) {
System.out.println("token为空放行请求");
return true;
}
```
**结论**: ✅ JWT拦截器已经修改为放行无token请求
## WebMvcConfig检查
**文件**: `WebMvcConfig.java`
**排除路径配置**:
```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`
**游客白名单**:
```javascript
const GUEST_ALLOWED_URLS = [
'/api/teacher/list', // ✅ 已添加
'/api/teacher/filter-options', // ✅ 已添加
'/api/special-course/list', // ✅ 已添加
'/api/interest-course/list', // ❌ 可能缺少这个
// ...
]
```
**游客模式处理**:
```javascript
// ✅ 游客访问白名单接口时不发送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匹配逻辑
**当前匹配逻辑**:
```javascript
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` 数组:
```javascript
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没问题,可能是数据库没有数据:
**检查**:
```sql
-- 检查教师数据
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` 文件,确认白名单是否完整。