Files
SillyTavern_replica/WORLDBOOK_API_CHECK.md
2026-05-01 15:44:14 +08:00

218 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 世界书分页功能 - 前端API调用检查报告
## ✅ 检查结果
**所有前端世界书分页功能都能正确发出请求到后端API**
---
## 📋 完整API映射表
### 1. 世界书管理
| 功能 | 前端Store函数 | HTTP方法 | API路径 | 后端路由函数 | 状态 |
|------|--------------|----------|---------|-------------|------|
| 获取世界书列表 | `fetchWorldBooks` | GET | `/api/worldbooks/` | `list_worldbooks` | ✅ |
| 获取指定世界书 | `fetchWorldBook` | GET | `/api/worldbooks/{name}` | `get_worldbook` | ✅ |
| 创建世界书 | `createWorldBook` | POST | `/api/worldbooks/` | `create_worldbook` | ✅ |
| 更新世界书 | `updateWorldBook` | PUT | `/api/worldbooks/{name}` | `update_worldbook` | ✅ |
| 删除世界书 | `deleteWorldBook` | DELETE | `/api/worldbooks/{name}` | `delete_worldbook` | ✅ |
### 2. 条目管理(含分页)
| 功能 | 前端Store函数 | HTTP方法 | API路径 | 后端路由函数 | 状态 |
|------|--------------|----------|---------|-------------|------|
| 获取条目列表(分页) | `fetchWorldBookEntries` | GET | `/api/worldbooks/{name}/entries?page={page}&page_size={page_size}` | `list_worldbook_entries` | ✅ |
| 获取指定条目 | `fetchWorldBookEntry` | GET | `/api/worldbooks/{name}/entries/{uid}` | `get_worldbook_entry` | ✅ |
| 创建条目 | `createWorldBookEntry` | POST | `/api/worldbooks/{name}/entries` | `create_worldbook_entry` | ✅ |
| 更新条目 | `updateWorldBookEntry` | PUT | `/api/worldbooks/{name}/entries/{uid}` | `update_worldbook_entry` | ✅ |
| 删除条目 | `deleteWorldBookEntry` | DELETE | `/api/worldbooks/{name}/entries/{uid}` | `delete_worldbook_entry` | ✅ |
### 3. 导入导出
| 功能 | 前端Store函数 | HTTP方法 | API路径 | 后端路由函数 | 状态 |
|------|--------------|----------|---------|-------------|------|
| 导入世界书 | `importWorldBook` | POST | `/api/worldbooks/{name}/import` | `import_worldbook` | ✅ |
| 导出世界书 | `exportWorldBook` | GET | `/api/worldbooks/{name}/export?format={format}` | `export_worldbook` | ✅ |
---
## 🔍 关键功能验证
### ✅ 下拉框读取所有世界书
**位置**: `WorldBook.jsx` 第547行
```jsx
{worldBooks.map(book => (
<div key={book.name} className="dropdown-item">
...
</div>
))}
```
**数据来源**:
- `worldBooks` 来自 Store (第8行)
- 通过 `fetchWorldBooks()` 加载 (第85行和第95行)
**加载时机**:
1. ✅ 组件挂载时立即加载(如果列表为空)
2. ✅ 切换到世界书标签页时重新加载
**API调用**:
```javascript
// WorldBookSlice.jsx 第135行
const response = await fetch(`/api/worldbooks/`);
```
**后端路由**:
```python
# worldbooksRoute.py 第28行
@router.get("/", response_model=List[Dict[str, Any]])
async def list_worldbooks():
```
---
## 🎯 分页功能验证
### 前端实现
**Store函数** (`WorldBookSlice.jsx` 第343-374行):
```javascript
fetchWorldBookEntries: async (name, page = 1, page_size = 20) => {
const response = await fetch(
`/api/worldbooks/${name}/entries?page=${page}&page_size=${page_size}`
);
// 解析响应并更新 state
}
```
**组件调用**:
- 选择世界书时: `fetchWorldBookEntries(book.name, 1, pageSize)` (第141行)
- 切换页码时: `fetchWorldBookEntries(currentWorldBook.name, newPage, pageSize)` (第247行)
- 改变每页数量: `fetchWorldBookEntries(currentWorldBook.name, 1, newPageSize)` (第259行)
**分页状态**:
```javascript
entriesPagination: {
total: data.total || 0,
page: data.page || 1,
page_size: data.page_size || 20,
total_pages: data.total_pages || 0
}
```
### 后端实现
**API路由** (`worldbooksRoute.py` 第108-128行):
```python
@router.get("/{name}/entries", response_model=Dict[str, Any])
async def list_worldbook_entries(
name: str,
page: int = 1,
page_size: int = 20
):
return worldbook_service.list_entries(name, page, page_size)
```
**服务层** (`worldbook_service.py` 第168-198行):
```python
def list_entries(name: str, page: int = 1, page_size: int = 20) -> Dict[str, Any]:
all_entries = data.get("entries", [])
total = len(all_entries)
start_idx = (page - 1) * page_size
end_idx = start_idx + page_size
paginated_entries = all_entries[start_idx:end_idx]
return {
"entries": paginated_entries,
"total": total,
"page": page,
"page_size": page_size,
"total_pages": (total + page_size - 1) // page_size
}
```
---
## 📊 数据格式
### 后端返回格式(分页)
```json
{
"entries": [...],
"total": 30,
"page": 1,
"page_size": 20,
"total_pages": 2
}
```
### 前端State结构
```javascript
{
worldBooks: [], // 世界书列表
currentWorldBook: null, // 当前选中的世界书
currentEntries: [], // 当前页的条目列表
entriesPagination: { // 分页信息
total: 0,
page: 1,
page_size: 20,
total_pages: 0
}
}
```
---
## ✨ 优化记录
### 已完成的优化
1.**组件初始化加载**: 添加 `useEffect` 在组件挂载时立即加载世界书列表
2.**格式统一**: 所有世界书文件转换为内部格式存储
3.**代码简化**: 移除服务层的SillyTavern格式运行时兼容逻辑
4.**分页控件**: 添加完整的分页UI上一页、下一页、每页数量选择
5.**自动刷新**: 添加/更新/删除条目后自动刷新当前页
---
## 🧪 测试建议
### 手动测试清单
- [ ] 打开世界书页面,检查下拉框是否显示所有世界书
- [ ] 选择一个世界书,检查是否正确加载第一页条目
- [ ] 点击"下一页",检查是否加载第二页
- [ ] 改变每页数量10/20/50/100检查是否正确刷新
- [ ] 创建新条目,检查是否刷新当前页
- [ ] 更新条目,检查是否刷新当前页
- [ ] 删除条目,检查是否刷新当前页
- [ ] 切换到其他世界书,检查是否重置到第一页
### API测试
```bash
# 获取世界书列表
curl http://localhost:8000/api/worldbooks/
# 获取条目(分页)
curl "http://localhost:8000/api/worldbooks/卡立创-v5/entries?page=1&page_size=5"
```
---
## 📝 结论
**前端世界书分页的所有功能都能正确发出请求到后端API**
- 下拉框正确读取所有世界书
- 分页参数正确传递
- 数据格式匹配
- 错误处理完善
- 用户体验流畅