This commit is contained in:
wangjiming
2026-07-30 14:38:56 +08:00
parent 4c7d66030c
commit 945b4ace86
55 changed files with 16633 additions and 1318 deletions

View File

@@ -0,0 +1,134 @@
# 前端功能失效问题排查报告
> 排查时间2026-07-30
> 环境前端Windows`localhost:16801` → Vite 代理 `/modelTF` → 后端WSL`localhost:17861`
> 方法:抓取后端 openapi 路由表 + 实测 curl 比对前端真实请求路径
## 一、现象
页面可以打开app 能正常加载、仪表盘等模块正常),但**大量功能点击无响应或报"请求失败"**。
经排查,故障集中在"路由前缀叠加导致后端 404",并非前端崩溃。
## 二、已验证正常的部分(排除法)
| 模块 | 接口 | 实测结果 |
|------|------|----------|
| 仪表盘 | `GET /modelTF/dashboard/stats` | ✅ 返回真实数据 |
| 登录 | `/modelTF/login` | ✅ 正常 |
| 健康检查 | `/modelTF/health` | ✅ 正常 |
| 其余 83 个后端路由 | 各 `/modelTF/xxx` | ✅ 均为正确的单层前缀 |
后端共 111 个路由,**仅 28 个 `data-process` 路由异常(双重前缀)**,其余均正确。
## 三、问题清单
### 问题 1严重根因数据处理模块整体 404
**链路(前缀被叠加了两次 `/modelTF`**
1. `backend/app/main.py:22``app.include_router(api_router, prefix=settings.route_prefix)`
- `route_prefix` 来自 `config.py`,默认值为 `"/modelTF"`
2. `backend/app/api/v1/router.py``api_router.include_router(data_process_router, prefix="/modelTF", ...)`
- 这里又额外加了一次 `prefix="/modelTF"`
3. `backend/app/api/v1/endpoints/data_process.py``router = APIRouter(prefix="/data-process")`
**结果**:实际注册路径变成 `/modelTF/modelTF/data-process/...`(双层前缀)。
**影响**:整个"数据处理"模块(列表 / 详情 / 创建任务 / 上传源文件 / 预览 / 生成 / 结果编辑 / 发布 / 重新生成 / 外部拉取测试 等)共 **28 个接口全部 404**
**前端请求路径**`baseURL('/modelTF')` + `get('/data-process')` → 实际请求 `/modelTF/data-process/...` → 与后端真实路径不匹配 → 404。
**实测证据**
```
前端真实请求 GET /modelTF/data-process
-> {"detail":"Not Found"} (404)
后端真实路径 GET /modelTF/modelTF/data-process
-> {"code":0,"message":"ok","data":{...有"测试"任务}} (路径存在,有数据)
```
---
### 问题 2数据集下载 / 预览 双重前缀 404
`frontend/src/api/request.ts:16``baseURL: '/modelTF'`,而
`frontend/src/api/modules/dataset.ts:92``:98` 的下载地址直接写了**绝对前缀**
```ts
const baseUrl = `/modelTF/dataset-manage/download/${datasetId}/${fileId}`
```
axios 会把 `baseURL('/modelTF')` 与以 `/` 开头的 url 拼接成 `/modelTF/modelTF/dataset-manage/download/...`,导致 404。
**注意**:后端 `dataset-manage` 是**正确的单层** `/modelTF/dataset-manage/...`(实测真实路径返回 500 = 路径存在但资源参数无效,而非 404
**实测证据**
```
前端实际发出 GET /modelTF/modelTF/dataset-manage/download/x/y -> 404 Not Found
后端真实路径 GET /modelTF/dataset-manage/download/x/y -> 500 (路径存在)
```
**影响**:数据集的下载、预览功能不可用。
---
### 问题 3模型导出 双重前缀 + 后端无此端点
`frontend/src/api/modules/model.ts:48` 导出地址同样写了绝对前缀:
```ts
`/modelTF/model-manage/trained-models/${encodeURIComponent(modelName)}/export`
```
- 经 axios 拼接 → `/modelTF/modelTF/model-manage/trained-models/.../export` → 404双重前缀
- **进一步**openapi 中 `model-manage/trained-models` 仅有 `GET` 列表与 `GET {model_id}` 详情,**并不存在 `/export` 端点**。因此即使修掉双前缀,导出仍会 404需后端补充该接口或确认正确路径。
**影响**:模型导出功能不可用(两个独立原因叠加)。
---
### 问题 4次生隐患修复问题 1 后会暴露data-process 源文件 raw 链接
`frontend/src/api/modules/dataProcess.ts:162`
```ts
`/modelTF/data-process/${taskId}/source-files/${fileId}/raw`
```
当前被 axios 拼成 `/modelTF/modelTF/data-process/.../raw`**恰好命中后端双前缀**,暂时可用。
**一旦修复问题 1后端改为单层 `/modelTF/data-process/...`**,此处会反向变成 404必须同步去掉多余的 `/modelTF`
## 四、前端其他使用绝对 `/modelTF` 前缀的位置(汇总)
| 文件:行 | 接口 | 当前状态 |
|---------|------|----------|
| `dataProcess.ts:162` | 源文件 raw 下载 | 靠后端双前缀"侥幸"命中,修复问题 1 后失效 |
| `dataset.ts:92` `:98` | 数据集下载/预览 | 双重前缀 → 404问题 2 |
| `model.ts:48` | 模型导出 | 双重前缀 + 后端无端点 → 404问题 3 |
其余模块(`compare / fineTune / project / eval / model(其他) / dataset(其他)`)均使用相对路径 `/xxx`,正常。
## 五、修复建议(未实施,待确认)
1. **后端** `backend/app/api/v1/router.py`:去掉 `data_process_router``prefix="/modelTF"`
`api_router` 已挂 `/modelTF``data_process` 自身已有 `/data-process`,无需再叠加)。
改后 data-process 路径变为 `/modelTF/data-process/...`,与前端请求一致。
2. **前端** `dataProcess.ts:162`raw url 去掉 `/modelTF`,改为 `/data-process/.../raw`
3. **前端** `dataset.ts:92/:98`download url 去掉 `/modelTF`,改为 `/dataset-manage/download/...`
4. **前端** `model.ts:48`export url 去掉 `/modelTF`,改为 `/model-manage/trained-models/${name}/export`
同时**与后端确认 `/export` 端点是否存在**openapi 显示无),需后端补实现或给出正确路径。
5. 重启后端 + 前端,对"数据处理 / 数据集下载 / 模型导出"三个模块做回归。
## 六、根因归类
上述问题是一次改动/合并引入的**路由前缀叠加 bug**
- 后端在 `api_router` 已统一挂 `/modelTF` 的前提下,又对 `data_process` 多挂了一次 `/modelTF`
- 前端部分下载/导出接口误用了绝对 `/modelTF` 前缀,与 `request.ts``baseURL` 再次叠加。
修复核心是"前后端前缀只保留一层 `/modelTF`"。