Files
keyboard/keyBoard/Class/AiTalk/人设列表实现说明.md
2026-01-26 18:17:02 +08:00

265 lines
7.2 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.

# 人设列表实现说明
## 📦 架构概览
```
KBAIHomeVC (人设列表容器)
├─ UICollectionView (竖向分页滚动)
│ └─ KBPersonaChatCell (每个人设占满屏)
│ ├─ 背景图coverImageUrl
│ ├─ 头像avatarUrl
│ ├─ 人设名称name
│ ├─ 简介shortDesc
│ └─ UITableView (聊天记录 - 待实现)
└─ KBVoiceInputBar (底部语音输入栏)
├─ 毛玻璃背景
├─ 状态标签
└─ 录音按钮
```
---
## 📂 文件结构
### Model 层keyBoard/Class/AiTalk/M/
- **KBPersonaModel.h/m**:人设模型
- 包含personaId、name、avatarUrl、coverImageUrl、shortDesc、introText 等
- 扩展属性tagsArray、isEnabled、isPublic
- **KBPersonaPageModel.h/m**:分页数据模型
- 包含records人设数组、total、current、pages、hasMore
### View 层keyBoard/Class/AiTalk/V/
- **KBPersonaChatCell.h/m**:人设聊天 Cell
- 展示:背景图、头像、名称、简介
- 支持:预加载数据
### VM 层keyBoard/Class/AiTalk/VM/
- **AiVM.h/m**:网络请求管理
- 新增接口:`fetchPersonasWithPageNum:pageSize:completion:`
- 请求地址:`POST /ai-companion/page`
### VC 层keyBoard/Class/AiTalk/VC/
- **KBAIHomeVC.h/m**:人设列表容器
- 功能:分页加载、竖向翻页、预加载相邻 Cell
---
## 🔧 核心功能
### 1. 竖向分页滚动
```objc
// UICollectionView 配置
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.itemSize = [UIScreen mainScreen].bounds.size; // 每个 cell 占满屏
_collectionView.pagingEnabled = YES; // 开启分页
```
### 2. 预加载机制
- **预加载 3 个 Cell**:上一个、当前、下一个
- **触发时机**:滑动超过 30% 时开始预加载
- **避免重复**:用 `preloadedIndexes` 记录已加载的索引
```objc
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageHeight = scrollView.bounds.size.height;
CGFloat offsetY = scrollView.contentOffset.y;
NSInteger currentPage = offsetY / pageHeight;
// 滑动超过 30% 就预加载
if (fmod(offsetY, pageHeight) > pageHeight * 0.3) {
[self preloadAdjacentCellsForIndex:currentPage + 1];
}
}
```
### 3. 分页加载
- **首次加载**pageNum=1, pageSize=10
- **加载更多**:接近底部时自动加载下一页
- **防重复**:用 `isLoading` 标记防止重复请求
```objc
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 接近底部时加载更多
if (offsetY + scrollView.bounds.size.height >= scrollView.contentSize.height - pageHeight) {
[self loadMorePersonas];
}
}
```
---
## 🌐 网络请求
### 接口地址
```
POST /ai-companion/page
```
### 请求参数
```json
{
"pageNum": 1,
"pageSize": 10
}
```
### 响应格式
```json
{
"code": 0,
"message": "success",
"data": {
"records": [
{
"id": 1,
"name": "温柔小姐姐",
"avatarUrl": "https://...",
"coverImageUrl": "https://...",
"shortDesc": "温柔体贴的聊天伙伴",
"introText": "你好呀,今天过得怎么样?",
"personalityTags": "温柔,体贴,善解人意",
...
}
],
"total": 100,
"current": 1,
"pages": 10
}
}
```
### 使用示例
```objc
[self.aiVM fetchPersonasWithPageNum:1
pageSize:10
completion:^(KBPersonaPageModel *pageModel, NSError *error) {
if (error) {
NSLog(@"加载失败:%@", error.localizedDescription);
return;
}
[self.personas addObjectsFromArray:pageModel.records];
self.hasMore = pageModel.hasMore;
[self.collectionView reloadData];
}];
```
---
## 🎨 UI 布局
### KBPersonaChatCell 布局
```
┌─────────────────────────────┐
│ 背景图coverImageUrl
│ ┌─────────────────────┐ │
│ │ 半透明遮罩(黑色 0.3 │ │
│ │ │ │
│ │ ┌───┐ │ │
│ │ │头像│ │ │
│ │ └───┘ │ │
│ │ 人设名称 │ │
│ │ 简短描述 │ │
│ │ │ │
│ │ ┌───────────────┐ │ │
│ │ │ 聊天记录列表 │ │ │
│ │ │ (待实现) │ │ │
│ │ └───────────────┘ │ │
│ └─────────────────────┘ │
└─────────────────────────────┘
```
---
## ✅ 已完成功能
1. ✅ Model 层KBPersonaModel、KBPersonaPageModel
2. ✅ VM 层AiVM 新增人设列表接口
3. ✅ View 层KBPersonaChatCell基础 UI
4. ✅ VC 层KBAIHomeVC分页加载、竖向翻页、预加载
5. ✅ MJExtension 配置JSON 自动转 Model
6. ✅ 懒加载:所有控件使用懒加载
7. ✅ Masonry 布局:纯代码布局
---
## 🚧 待实现功能
### 1. 聊天记录展示
- 需要后端提供 `chatId` 字段
-`chatId` 请求聊天记录接口
-`KBPersonaChatCell``tableView` 中展示聊天记录
### 2. 聊天功能
- 点击输入框发送消息
- 接收 AI 回复
- 支持语音消息
### 3. 错误处理
- 网络请求失败提示
- 空数据占位图
- 加载中状态
### 4. 性能优化
- Cell 高度缓存
- 图片缓存策略
- 内存管理(清理不可见 Cell 的数据)
---
## 📝 使用方式
### 1. 在其他 VC 中跳转
```objc
KBAIHomeVC *homeVC = [[KBAIHomeVC alloc] init];
[self.navigationController pushViewController:homeVC animated:YES];
```
### 2. 作为 TabBar 的一个页面
```objc
KBAIHomeVC *homeVC = [[KBAIHomeVC alloc] init];
homeVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"AI聊天"
image:[UIImage imageNamed:@"tab_ai"]
selectedImage:[UIImage imageNamed:@"tab_ai_sel"]];
```
---
## 🐛 调试日志
### 网络请求日志
```
[AiVM] /ai-companion/page request: {pageNum: 1, pageSize: 10}
[AiVM] /ai-companion/page response: {...}
加载成功:当前 10 条,总共 100 条,还有更多:是
```
### 预加载日志
```
预加载第 0 个人设
预加载第 1 个人设
预加载第 2 个人设
当前在第 1 个人设:温柔小姐姐
```
---
## 📌 注意事项
1. **接口地址**:需要在 `KBAPI.h` 中定义 `/ai-companion/page`
2. **图片占位图**:需要添加 `placeholder_bg``placeholder_avatar` 图片资源
3. **线程安全**:网络回调后需要回到主线程更新 UI
4. **内存管理**:注意使用 `weakSelf` 避免循环引用
5. **字段兼容**:后端可能返回 `null`,已做容错处理
---
## 🎯 下一步计划
1. 接入真实的聊天记录接口
2. 实现聊天输入和发送功能
3. 优化 Cell 的聊天记录展示(使用现有的 KBChatTableView
4. 添加下拉刷新和上拉加载更多
5. 添加错误提示和空数据占位图