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

7.2 KiB
Raw Blame History

人设列表实现说明

📦 架构概览

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. 竖向分页滚动

// UICollectionView 配置
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.itemSize = [UIScreen mainScreen].bounds.size; // 每个 cell 占满屏
_collectionView.pagingEnabled = YES; // 开启分页

2. 预加载机制

  • 预加载 3 个 Cell:上一个、当前、下一个
  • 触发时机:滑动超过 30% 时开始预加载
  • 避免重复:用 preloadedIndexes 记录已加载的索引
- (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 标记防止重复请求
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // 接近底部时加载更多
    if (offsetY + scrollView.bounds.size.height >= scrollView.contentSize.height - pageHeight) {
        [self loadMorePersonas];
    }
}

🌐 网络请求

接口地址

POST /ai-companion/page

请求参数

{
  "pageNum": 1,
  "pageSize": 10
}

响应格式

{
  "code": 0,
  "message": "success",
  "data": {
    "records": [
      {
        "id": 1,
        "name": "温柔小姐姐",
        "avatarUrl": "https://...",
        "coverImageUrl": "https://...",
        "shortDesc": "温柔体贴的聊天伙伴",
        "introText": "你好呀,今天过得怎么样?",
        "personalityTags": "温柔,体贴,善解人意",
        ...
      }
    ],
    "total": 100,
    "current": 1,
    "pages": 10
  }
}

使用示例

[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 请求聊天记录接口
  • KBPersonaChatCelltableView 中展示聊天记录

2. 聊天功能

  • 点击输入框发送消息
  • 接收 AI 回复
  • 支持语音消息

3. 错误处理

  • 网络请求失败提示
  • 空数据占位图
  • 加载中状态

4. 性能优化

  • Cell 高度缓存
  • 图片缓存策略
  • 内存管理(清理不可见 Cell 的数据)

📝 使用方式

1. 在其他 VC 中跳转

KBAIHomeVC *homeVC = [[KBAIHomeVC alloc] init];
[self.navigationController pushViewController:homeVC animated:YES];

2. 作为 TabBar 的一个页面

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_bgplaceholder_avatar 图片资源
  3. 线程安全:网络回调后需要回到主线程更新 UI
  4. 内存管理:注意使用 weakSelf 避免循环引用
  5. 字段兼容:后端可能返回 null,已做容错处理

🎯 下一步计划

  1. 接入真实的聊天记录接口
  2. 实现聊天输入和发送功能
  3. 优化 Cell 的聊天记录展示(使用现有的 KBChatTableView
  4. 添加下拉刷新和上拉加载更多
  5. 添加错误提示和空数据占位图