ChatHistoryController.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. //
  2. // ChatHistoryController.m
  3. // AIIM
  4. //
  5. // Created by gan on 2025/5/2.
  6. //
  7. #import <Foundation/Foundation.h>
  8. #import "ChatHistoryController.h"
  9. #import "config.h"
  10. #import "ChatsStore.h"
  11. #import "CryptoAES.h"
  12. #import "SDWebImage/SDWebImage.h"
  13. #import "FileNetApi.h"
  14. #import "FilePreviewer.h"
  15. #import "HistoryPreloader.h"
  16. #import "chatCellView.h"
  17. @interface ChatHistoryController()<UITextViewDelegate,UITableViewDelegate,UITableViewDataSource,UIScrollViewDelegate,ChatsStoreDelegate>
  18. @property (weak, nonatomic) IBOutlet UILabel *titleLb;
  19. @property (weak, nonatomic) IBOutlet UIScrollView *topScrollV;
  20. @property (weak, nonatomic) IBOutlet UITableView *tableView;
  21. @property (weak, nonatomic) IBOutlet UIImageView *bigImageV;
  22. @property (nonatomic,strong) UITextView *textV;
  23. @property (nonatomic,strong) UIButton *bt1;
  24. @property (nonatomic,strong) UIButton *bt2;
  25. @property (nonatomic,strong) UIButton *bt3;
  26. @property (nonatomic,strong) UIButton *bt4;
  27. @property (nonatomic,strong) UIButton *bt5;
  28. @property (nonatomic,strong) UIButton *bt6;
  29. @property(nonatomic, strong) NSArray *msgList;
  30. @property (nonatomic,strong) NSString *username;
  31. @property (nonatomic,strong) NSString *useravatar;
  32. @property (nonatomic) BOOL canloadhistory;
  33. @property (nonatomic,strong) NSString *ListType;
  34. @property (nonatomic, strong) NSMutableArray * messageArray;
  35. @end
  36. @implementation ChatHistoryController
  37. -(void)viewDidLoad{
  38. [super viewDidLoad];
  39. [self.navigationController setNavigationBarHidden:YES animated:NO];
  40. [_tableView registerClass:chatCellView.class forCellReuseIdentifier:NSStringFromClass(chatCellView.class)];
  41. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  42. _tableView.backgroundColor = [UIColor clearColor];
  43. _tableView.delegate=self;
  44. _tableView.dataSource = self;
  45. ChatsStore.shareInstance.delegate = self;
  46. ChatsStore.shareInstance.chatId = self.chatId;
  47. _titleLb.text = self.titlename;
  48. _textV=[[UITextView alloc] init];
  49. _canloadhistory=true;
  50. [self initTopScrollList];
  51. }
  52. - (void)dealloc {
  53. [[NSNotificationCenter defaultCenter] removeObserver:self];
  54. ChatsStore.shareInstance.delegate = nil;
  55. ChatsStore.shareInstance.chatId = nil;
  56. }
  57. - (IBAction)gotoback:(id)sender {
  58. [self dismissViewControllerAnimated:YES completion:nil];
  59. }
  60. -(void)initTopScrollList{
  61. CGFloat btwidth = 50.0f;
  62. CGFloat btdisten = btwidth+10;
  63. _bt1 = [[UIButton alloc] init];
  64. _bt1 = [[UIButton alloc] init];
  65. _bt1.tag = 1;
  66. _bt1.frame=CGRectMake(btdisten*0, 10, btwidth, 30);
  67. _bt1.backgroundColor =globalColor(GCTypeGreen);
  68. _bt1.layer.cornerRadius = 8;
  69. _bt1.layer.masksToBounds = YES; // 防止子视图超出圆角边界
  70. _bt1.titleLabel.font = [UIFont systemFontOfSize: 14.0];
  71. [_bt1 setTitle:@"全部" forState:UIControlStateNormal];
  72. _bt1.titleLabel.textColor = [UIColor blackColor];
  73. [_bt1 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside];
  74. _bt2 = [[UIButton alloc] init];
  75. _bt2 = [[UIButton alloc] init];
  76. _bt2.tag = 2;
  77. _bt2.frame=CGRectMake(btdisten*1, 10, btwidth, 30);
  78. _bt2.backgroundColor =[UIColor clearColor];
  79. _bt2.layer.cornerRadius = 8;
  80. _bt2.layer.masksToBounds = YES; // 防止子视图超出圆角边界
  81. _bt2.titleLabel.font = [UIFont systemFontOfSize: 14.0];
  82. [_bt2 setTitle:@"文本" forState:UIControlStateNormal];
  83. _bt2.titleLabel.textColor = [UIColor blackColor];
  84. [_bt2 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside];
  85. _bt3 = [[UIButton alloc] init];
  86. _bt3 = [[UIButton alloc] init];
  87. _bt3.tag = 3;
  88. _bt3.frame=CGRectMake(btdisten*2, 10, btwidth, 30);
  89. _bt3.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen);
  90. _bt3.layer.cornerRadius = 8;
  91. _bt3.layer.masksToBounds = YES; // 防止子视图超出圆角边界
  92. _bt3.titleLabel.font = [UIFont systemFontOfSize: 14.0];
  93. [_bt3 setTitle:@"图片" forState:UIControlStateNormal];
  94. _bt3.titleLabel.textColor = [UIColor blackColor];
  95. [_bt3 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside];
  96. _bt4 = [[UIButton alloc] init];
  97. _bt4 = [[UIButton alloc] init];
  98. _bt4.tag = 4;
  99. _bt4.frame=CGRectMake(btdisten*3, 10, btwidth, 30);
  100. _bt4.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen);
  101. _bt4.layer.cornerRadius = 8;
  102. _bt4.layer.masksToBounds = YES; // 防止子视图超出圆角边界
  103. _bt4.titleLabel.font = [UIFont systemFontOfSize: 14.0];
  104. [_bt4 setTitle:@"文件" forState:UIControlStateNormal];
  105. _bt4.titleLabel.textColor = [UIColor blackColor];
  106. [_bt4 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside];
  107. _bt5 = [[UIButton alloc] init];
  108. _bt5 = [[UIButton alloc] init];
  109. _bt5.tag = 5;
  110. _bt5.frame=CGRectMake(btdisten*4, 10, btwidth, 30);
  111. _bt5.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen);
  112. _bt5.layer.cornerRadius = 8;
  113. _bt5.layer.masksToBounds = YES; // 防止子视图超出圆角边界
  114. _bt5.titleLabel.font = [UIFont systemFontOfSize: 14.0];
  115. [_bt5 setTitle:@"语音" forState:UIControlStateNormal];
  116. _bt5.titleLabel.textColor = [UIColor blackColor];
  117. [_bt5 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside];
  118. _bt6 = [[UIButton alloc] init];
  119. _bt6 = [[UIButton alloc] init];
  120. _bt6.tag = 6;
  121. _bt6.frame=CGRectMake(btdisten*5, 10, btwidth, 30);
  122. _bt6.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen);
  123. _bt6.layer.cornerRadius = 8;
  124. _bt6.layer.masksToBounds = YES; // 防止子视图超出圆角边界
  125. _bt6.titleLabel.font = [UIFont systemFontOfSize: 14.0];
  126. [_bt6 setTitle:@"视频" forState:UIControlStateNormal];
  127. _bt6.titleLabel.textColor = [UIColor blackColor];
  128. [_bt6 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside];
  129. [_topScrollV addSubview:_bt1];
  130. [_topScrollV addSubview:_bt2];
  131. [_topScrollV addSubview:_bt3];
  132. [_topScrollV addSubview:_bt4];
  133. [_topScrollV addSubview:_bt5];
  134. [_topScrollV addSubview:_bt6];
  135. [self.messageArray removeAllObjects];
  136. _topScrollV.contentSize = CGSizeMake(60*5+btwidth, 50);
  137. [self loadData:@""];
  138. }
  139. -(void)topBtAct:(UIButton *)bt{
  140. _bt1.backgroundColor =[UIColor clearColor];
  141. _bt2.backgroundColor =[UIColor clearColor];
  142. _bt3.backgroundColor =[UIColor clearColor];
  143. _bt4.backgroundColor =[UIColor clearColor];
  144. _bt5.backgroundColor =[UIColor clearColor];
  145. _bt6.backgroundColor =[UIColor clearColor];
  146. bt.backgroundColor =globalColor(GCTypeGreen);
  147. if(bt.tag==1){
  148. [self.messageArray removeAllObjects];
  149. [self loadData:@""];
  150. return;
  151. }
  152. if(bt.tag==2){
  153. NSString *type =[NSString stringWithFormat:@"%@",MessageType_text];
  154. [self.messageArray removeAllObjects];
  155. [self loadData:type];
  156. return;
  157. }
  158. if(bt.tag==3){
  159. NSString *type =[NSString stringWithFormat:@"%@",MessageType_image];
  160. [self.messageArray removeAllObjects];
  161. [self loadData:type];
  162. return;
  163. }
  164. if(bt.tag==4){
  165. NSString *type =[NSString stringWithFormat:@"%@",MessageType_file];
  166. [self.messageArray removeAllObjects];
  167. [self loadData:type];
  168. return;
  169. }
  170. if(bt.tag==5){
  171. NSString *type =[NSString stringWithFormat:@"%@",MessageType_voice];
  172. [self.messageArray removeAllObjects];
  173. [self loadData:type];
  174. return;
  175. }
  176. if(bt.tag==6){
  177. NSString *type =[NSString stringWithFormat:@"%@",MessageType_video];
  178. [self.messageArray removeAllObjects];
  179. [self loadData:type];
  180. return;
  181. }
  182. }
  183. -(void)loadData:(NSString *)state{
  184. _ListType = state;
  185. if([_ListType isEqualToString:@""]){
  186. [self loadAllData];
  187. }
  188. else{
  189. [self loadDataWithType];
  190. }
  191. }
  192. -(void)loadAllData{
  193. if(self.type==1){
  194. [ChatsStore.shareInstance getGroupHistory:self.chatId type:@""];
  195. }
  196. else{
  197. [ChatsStore.shareInstance reloadData:self.chatId];
  198. }
  199. }
  200. -(void)loadDataWithType{
  201. if(self.type==1){
  202. [ChatsStore.shareInstance getGroupHistory:self.chatId type:_ListType];
  203. }
  204. else{
  205. [ChatsStore.shareInstance reloadDataWithType:self.chatId type:_ListType];
  206. }
  207. }
  208. #pragma mark ChatsStoreDelegate
  209. -(void)ChatsChange:(NSArray *)msgList type:(NSInteger)typpe{
  210. NSInteger oldIndex =self.msgList.count;
  211. self.msgList =msgList;
  212. NSMutableArray * tempArray = [NSMutableArray array];
  213. for (NSDictionary * msg in msgList) {
  214. ChatMessageModel *message = [ChatMessageModel modelWithDictionary:msg];
  215. if (message.avatar.length==0 && message.isSender) {
  216. message.avatar = self.useravatar;
  217. }else if (message.avatar.length==0 && !message.isSender) {
  218. message.avatar = self.avatar;
  219. }
  220. [tempArray addObject:message];
  221. }
  222. [self.messageArray removeAllObjects];
  223. [self.messageArray addObjectsFromArray:tempArray];
  224. // 记录当前滚动位置
  225. CGPoint contentOffset = self.tableView.contentOffset;
  226. CGFloat y =self.tableView.contentSize.height-self.tableView.contentOffset.y;
  227. [self.tableView reloadData];
  228. if(_canloadhistory){
  229. [self movetoBotton];
  230. }
  231. else{
  232. if(oldIndex>0){
  233. contentOffset.y= self.tableView.contentSize.height-y;
  234. self.tableView.contentOffset = contentOffset;
  235. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  236. self->_canloadhistory=true;
  237. });
  238. }
  239. }
  240. }
  241. -(void)movetoBotton{
  242. NSLog(@"movetoBotton----------------------");
  243. if (self.msgList.count>0) {
  244. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  245. NSIndexPath *lastRowIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0];
  246. //NSLog(@"lastRowIndexPath:%ld",(long)lastRowIndexPath.row);
  247. [self.tableView scrollToRowAtIndexPath:lastRowIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
  248. });
  249. }
  250. }
  251. -(void)movetoindex:(NSInteger)index{
  252. NSLog(@"movetoindex----------------------%ld",index);
  253. NSInteger row =self.msgList.count-index;
  254. if (row>0) {
  255. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  256. NSIndexPath *lastRowIndexPath = [NSIndexPath indexPathForRow:(row) inSection:0];
  257. //NSLog(@"lastRowIndexPath:%ld",(long)lastRowIndexPath.row);
  258. [self.tableView scrollToRowAtIndexPath:lastRowIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
  259. });
  260. }
  261. }
  262. #pragma mark UITableViewDelegate,UITableViewDataSource
  263. -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
  264. return 1;
  265. }
  266. -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  267. return self.messageArray.count;
  268. }
  269. -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  270. chatCellView *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(chatCellView.class)];
  271. if (!cell) {
  272. cell = [[chatCellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass(chatCellView.class)];
  273. }
  274. cell.isHistory = YES;
  275. cell.parentViewController = self;
  276. // ChatMessageModel *message = self.messageArray[indexPath.row];
  277. return cell;
  278. }
  279. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  280. ChatMessageModel *message = self.messageArray[indexPath.row];
  281. return [chatCellView cellHeightForMessage:message];
  282. }
  283. - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
  284. chatCellView * currentCell = (chatCellView *)cell;
  285. ChatMessageModel *message = self.messageArray[indexPath.row];
  286. currentCell.messageModel = message;
  287. // currentCell.batchState = self.isBatchMode;
  288. }
  289. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
  290. }
  291. -(CGFloat)getcellHeight:(NSString *)text{
  292. NSString *dcontent = text;//[CryptoAES.shareInstance decryptDataL:text];
  293. _textV.font = [UIFont systemFontOfSize:17];
  294. _textV.layer.masksToBounds = YES; // 防止子视图超出边界
  295. _textV.editable = NO;
  296. _textV.scrollEnabled = NO; // 禁止滚动,使内容自适应高度
  297. CGRect viewFrame = _textV.frame;
  298. viewFrame.origin.y=16;
  299. viewFrame.origin.x = 8;
  300. viewFrame.size.width =self.view.frame.size.width-110;
  301. _textV.frame=viewFrame;
  302. _textV.text =dcontent;
  303. //_textV.text =@"afa faafa faffaf affafafaffa fafafa affafaf faadafafaf afafa aafafafafa afafafafafaf fafafaf afaffa";
  304. [_textV sizeToFit];
  305. viewFrame=_textV.frame;
  306. CGFloat height = viewFrame.size.height+66;
  307. return height;
  308. }
  309. -(CGFloat)getImagCellHeight:(NSDictionary *)extend{
  310. return 232;
  311. }
  312. -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
  313. if (scrollView.contentOffset.y <80) { // 50 是触发加载的额外距离
  314. // 加载更多数据的代码
  315. if(_canloadhistory){
  316. NSLog(@"触发加载更多。。。。:111:%f",scrollView.contentOffset.y);
  317. _canloadhistory=false;
  318. [self loadhistoryData];
  319. }
  320. else{
  321. NSLog(@"触发加载更多。。。。:2");
  322. }
  323. }
  324. else{
  325. if(scrollView.contentOffset.y>500){
  326. NSLog(@"触发加载更多。。。。:3333:%f",scrollView.contentOffset.y);
  327. }
  328. }
  329. }
  330. -(void)loadhistoryData{
  331. if(self.msgList.count>0){
  332. NSLog(@"self.msgList:%lu",(unsigned long)self.msgList.count);
  333. _canloadhistory = false;
  334. NSDictionary *eldata = self.msgList[0];
  335. NSString *timestr = eldata[@"timestamp"];
  336. NSInteger time =timestr.integerValue;
  337. if([_ListType isEqualToString:@""]){
  338. NSLog(@"1-------------------");
  339. [ChatsStore.shareInstance loadNextDataAll:self.chatId timestp:time];
  340. }
  341. else{
  342. NSLog(@"1-------------------");
  343. [ChatsStore.shareInstance loadNextDataWithType:self.chatId type:_ListType timestp:time];
  344. }
  345. }
  346. }
  347. -(NSDictionary *)getgroupuser:(NSString *)userId{
  348. for (NSDictionary *item in ChatsStore.shareInstance.groupUserList) {
  349. NSString *_id = item[@"id"];
  350. if(_id.integerValue == userId.integerValue){
  351. return item;
  352. }
  353. }
  354. return nil;
  355. }
  356. -(void)tableListFileAct:(NSDictionary *)msg{
  357. NSString *messageType=msg[@"messageType"];
  358. if(messageType.intValue==1){//放大展示图片
  359. NSDictionary *extend = msg[@"extend"];
  360. NSString *localurl=extend[@"localurl"];
  361. if([self fileExist:localurl]){
  362. NSURL *imageURL = [NSURL fileURLWithPath:localurl];
  363. [_bigImageV sd_setImageWithURL:imageURL
  364. placeholderImage:nil
  365. options:SDWebImageRetryFailed];
  366. _bigImageV.alpha = 1;
  367. NSLog(@"111111111");
  368. }
  369. else{
  370. NSURL *imgUrl = [NSURL URLWithString:extend[@"url"]];
  371. [_bigImageV sd_setImageWithURL:imgUrl completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
  372. }];
  373. _bigImageV.alpha = 1;
  374. NSLog(@"222222222");
  375. }
  376. }
  377. if(messageType.intValue==2){//文件
  378. NSDictionary *extend = msg[@"extend"];
  379. NSString *localurl=extend[@"localurl"];
  380. NSString *imgUrl = extend[@"url"];
  381. NSString *msgId = msg[@"id"];
  382. if([self fileExist:localurl]){//文件已经下载,打开文件位置
  383. }
  384. else{//下载文件并保存
  385. NSLog(@"imgUrl:%@",imgUrl);
  386. [FileNetApi downLoadWToken:[NSURL URLWithString:imgUrl] thrid:msgId succ:^(int code, NSDictionary * res) {
  387. NSLog(@"code:%d",code);
  388. } fail:^(NSError * _Nonnull error) {
  389. NSLog(@"error:%@",error);
  390. }];
  391. }
  392. }
  393. }
  394. -(BOOL)fileExist:(NSString *)filePath{
  395. NSLog(@"filePath:%@",filePath);
  396. if ([filePath isKindOfClass:NSString.class]) {
  397. if (filePath.length>5) {
  398. // 创建 NSFileManager 实例
  399. NSFileManager *fileManager = [NSFileManager defaultManager];
  400. // 检查文件是否存在
  401. BOOL fileExists = [fileManager fileExistsAtPath:filePath];
  402. if (fileExists) {
  403. NSLog(@"文件存在");
  404. return true;
  405. } else {
  406. NSLog(@"文件不存在");
  407. return false;
  408. }
  409. }
  410. }
  411. return false;
  412. }
  413. - (NSMutableArray *)messageArray{
  414. if (!_messageArray) {
  415. _messageArray = [NSMutableArray array];
  416. }
  417. return _messageArray;
  418. }
  419. #pragma mark statusBar
  420. - (UIStatusBarStyle)preferredStatusBarStyle{
  421. return UIStatusBarStyleLightContent;
  422. }
  423. @end