// // ChatListStore.m // AIIM // // Created by gan on 2025/4/1. // #import #import "ChatListStore.h" #import "GDBManager.h" #import "ChatNetApi.h" #import "UserNetApi.h" #import "GroupNetApi.h" #import #import "CryptoAES.h" #import "AppDelegate.h" @interface ChatListStore() @property(nonatomic, strong) NSArray *toparray; @property(nonatomic, strong) NSArray *nmarray; @end @implementation ChatListStore + (ChatListStore *_Nonnull)shareInstance{ static id gShareInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ gShareInstance = [[self alloc] init]; }); return gShareInstance; } - (instancetype)init { if (self = [super init]) { } return self; } -(void)reloadData:(BOOL)mark{ self.chatlist=@[]; [GDBManager.shareInstance selectLocalchats:@"'true'" succ:^(NSArray * _Nullable array) { NSLog(@"array:%@",array); if(array.count>0){ array = [self saveArray:array]; NSMutableOrderedSet *orderedSet = [[NSMutableOrderedSet alloc] initWithArray:array];//去重,顺序不变 NSArray *chats = [orderedSet array]; chats=[self arraysort:chats]; self.chatlist =chats; self.toparray =chats; } else{ self.toparray = @[]; } [self loadnmData:mark]; } fail:^(NSString * _Nullable error) { [self loadnmData:mark]; }]; } -(void)loadnmData:(BOOL)mark{ [GDBManager.shareInstance selectLocalchats:@"'false'" succ:^(NSArray * _Nullable array) { NSLog(@"array:%@",array); if(array.count>0){ array = [self saveArray:array]; NSMutableOrderedSet *orderedSet = [[NSMutableOrderedSet alloc] initWithArray:array];//去重,顺序不变 NSArray *chats = [orderedSet array]; chats=[self arraysort:chats]; self.nmarray = chats; NSArray *reschats; if(self.chatlist.count>0){ reschats=[self.chatlist arrayByAddingObjectsFromArray:chats]; } else{ reschats =chats; } self.chatlist=reschats; if(self.delegate){ [self.delegate ChatListChange:reschats.copy]; } NSInteger unreadCount = 0; for (NSDictionary *item in reschats) { NSString *unreadCountStr = item[@"unreadCount"]; if(unreadCountStr.intValue>0){ unreadCount = unreadCount + unreadCountStr.intValue; } } dispatch_main_async_safe(^{ AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate; [app updateBadgeCount:unreadCount]; }) } else{ self.nmarray =@[]; } if(mark){ [self getnmChatlist]; } } fail:^(NSString * _Nullable error) { if(mark){ [self getnmChatlist]; } }]; } -(void)gettopChatlist{ [ChatNetApi gettopchats:nil succ:^(int code, NSDictionary * res) { NSLog(@"top res:%@",res); self.toparray = res[@"data"]; if(self.toparray.count>0){ self.toparray = [self saveArray:self.toparray]; self.toparray=[self arraysort:self.toparray]; NSMutableOrderedSet *orderedSet = [[NSMutableOrderedSet alloc] initWithArray:self.toparray];//去重,顺序不变 NSArray *chats = [orderedSet array]; [self updatelcDB:chats top:@"true"]; } [self getnmChatlist]; } fail:^(NSError * _Nonnull error) { [self getnmChatlist]; }]; } -(void)getnmChatlist{ NSDictionary *userinfo = [UDManager.shareInstance getDDManager:dkuserinfo]; [ChatNetApi getchats:nil succ:^(int code, NSDictionary * res) { NSLog(@"getnmChatlist res:%@",res); NSArray *netArray = res[@"data"]; [Bugly reportException:[NSException exceptionWithName:[NSString stringWithFormat:@"getnmChatlist:%@",userinfo[@"name"]] reason:[NSString stringWithFormat:@"netArray:%lu",(unsigned long)netArray.count] userInfo:nil]]; if(netArray.count>0){ netArray = [self saveArray:netArray]; netArray=[self arraysort:netArray]; NSMutableOrderedSet *orderedSet = [[NSMutableOrderedSet alloc] initWithArray:netArray];//去重,顺序不变 NSArray *chats = [orderedSet array]; [self doWithNewList:chats]; // [self updatelcDB:chats top:@"false"]; } else{ [Bugly reportException:[NSException exceptionWithName:@"getchats--空" reason:userinfo[@"name"] userInfo:nil]]; } //NSLog(@"self.chatlist:%@",self.chatlist); } fail:^(NSError * _Nonnull error) { [Bugly reportException:[NSException exceptionWithName:@"getchats--失败" reason:[NSString stringWithFormat:@"error:%@",error] userInfo:nil]]; }]; } -(void)updatelcDB:(NSArray *)array top:(NSString *)top{ // NSLog(@"updatelcDB:%@",self.chatlist); BOOL hadChange = NO; for (NSDictionary *item in array) { // NSLog(@"updatelcDB item:%@",item); BOOL mark = true; NSString *newtime =item[@"lastTime"]; if([newtime isKindOfClass:[NSNull class]]){ continue; } NSString *userid =item[@"id"]; if([userid isKindOfClass:[NSNull class]]){ continue; } else{ if(userid.length==0){ continue; } } for (NSDictionary *Ditem in self.chatlist) { if([Ditem[@"id"] isEqualToString:item[@"id"]]){//窗口已经存在 // NSLog(@"item:%@",Ditem); NSString *dtop = Ditem[@"top"]; if([top isEqualToString:dtop]){ NSString *dtime =Ditem[@"lastTime"]; if(![dtime isKindOfClass:[NSNull class]]){ if(newtime.longLongValue=dtime.longLongValue){ NSDictionary *chatD=@{ @"id":item[@"id"], @"name":item[@"name"], @"avatar":item[@"avatar"], @"type":item[@"type"], @"lastMessage":lastMsg, @"lastTime":msg[@"timestamp"], @"unreadCount":countstr, @"loaded":item[@"loaded"], @"loading":item[@"loading"], @"top":item[@"top"]?:@"false" }; [self updateChat:chatD isreload:YES]; [self updataUserInfo:chatD]; } } else{ if(newtime.longLongValue>dtime.longLongValue){ NSDictionary *chatD=@{ @"id":item[@"id"], @"name":item[@"name"], @"avatar":item[@"avatar"], @"type":item[@"type"], @"lastMessage":lastMsg, @"lastTime":msg[@"timestamp"], @"unreadCount":countstr, @"loaded":item[@"loaded"], @"loading":item[@"loading"], @"top":item[@"top"]?:@"false" }; [self updateChat:chatD isreload:YES]; [self updataUserInfo:chatD]; } } return; } } [self addNewChats:msg]; } -(void)updateChat:(NSDictionary *)chat isreload:(BOOL)reload{ chat = [self encodingMsg:chat]; // NSLog(@"1----------updateChat--------------"); NSDictionary *userinfo = [UDManager.shareInstance getDDManager:dkuserinfo]; [GDBManager.shareInstance insertLocalchat:chat succ:^(NSArray * _Nullable array) { NSLog(@"111chat"); if(self.delegate &&reload){ [self reloadData:false]; } } fail:^(NSString * _Nullable error) { NSLog(@"111222chat"); [Bugly reportException:[NSException exceptionWithName:[NSString stringWithFormat:@"insertLocalchat fail:%@",userinfo[@"name"]] reason:[NSString stringWithFormat:@"error:%@",chat] userInfo:nil]]; }]; } -(void)addNewChats:(NSDictionary *_Nonnull)msg{//新增聊天窗 NSInteger addcount = 0; if([msg[@"chatId"] isEqual:self.chatId]){ addcount=0; } else{ addcount=1; } NSString *countstr = [NSString stringWithFormat:@"%ld",(long)addcount]; NSString *lastMsg = [self setLastMsg:msg]; if([msg[@"type"] isEqualToString:@"0"]){//友聊 [UserNetApi getUserinfo_id:msg[@"chatId"] succ:^(int code, NSDictionary * res) { NSDictionary * userinfo=res[@"data"]; if(userinfo){ NSDictionary *chatD=@{ @"id":msg[@"chatId"], @"name":userinfo[@"name"], @"avatar":userinfo[@"avatar"], @"type":msg[@"type"], @"lastMessage":lastMsg, @"lastTime":msg[@"timestamp"], @"unreadCount":countstr, @"loaded":@"false", @"loading":@"false", @"top":@"false" }; [self updateChat:chatD isreload:YES]; } } fail:^(NSError * _Nonnull error) { NSDictionary *chatD=@{ @"id":msg[@"chatId"], @"name":@"loading...", @"avatar":@"avatar", @"type":msg[@"type"], @"lastMessage":lastMsg, @"lastTime":msg[@"timestamp"], @"unreadCount":countstr, @"loaded":@"false", @"loading":@"false", @"top":@"false" }; [self updateChat:chatD isreload:YES]; }]; }else{//群聊 NSLog(@"addNewChats----:%@",msg); [GroupNetApi getGroupInfo:msg[@"chatId"] succ:^(int code, NSDictionary * res) { NSLog(@"getGroupInfo:%@",res); NSDictionary * userinfo=res[@"data"]; if(userinfo){ NSDictionary *chatD=@{ @"id":msg[@"chatId"], @"name":userinfo[@"name"], @"avatar":userinfo[@"avatar"], @"type":msg[@"type"], @"lastMessage":lastMsg, @"lastTime":msg[@"timestamp"], @"unreadCount":countstr, @"loaded":@"false", @"loading":@"false", @"top":@"false" }; [self updateChat:chatD isreload:YES]; } else{ } } fail:^(NSError * _Nonnull error) { NSDictionary *chatD=@{ @"id":msg[@"chatId"], @"name":@"loading...", @"avatar":@"avatar", @"type":msg[@"type"], @"lastMessage":lastMsg, @"lastTime":msg[@"timestamp"], @"unreadCount":countstr, @"loaded":@"false", @"loading":@"false", @"top":@"false" }; [self updateChat:chatD isreload:YES]; }]; } } -(void)updataUserInfo:(NSDictionary *)chatDis{ NSString *type = chatDis[@"type"]; NSString *chatId = chatDis[@"id"]; NSString *oldName = chatDis[@"name"]; NSString *oldavatar = chatDis[@"avatar"]; if([type isEqualToString:@"0"]){//友聊 [UserNetApi getUserinfo_id:chatId succ:^(int code, NSDictionary * res) { NSDictionary * userinfo=res[@"data"]; if(userinfo){ if([oldName isEqualToString:userinfo[@"name"]]&&[oldavatar isEqualToString:userinfo[@"avatar"]]){ return; }else{ NSMutableDictionary *mdic = [chatDis mutableCopy]; [mdic setObject:userinfo[@"name"] forKey:@"name"]; [mdic setObject:userinfo[@"avatar"] forKey:@"avatar"]; [self updateChat:mdic isreload:YES]; } } } fail:^(NSError * _Nonnull error) { }]; } else{ [GroupNetApi getGroupInfo:chatId succ:^(int code, NSDictionary * res) { NSLog(@"getGroupInfo:%@",res); NSDictionary * userinfo=res[@"data"]; if(userinfo){ if([oldName isEqualToString:userinfo[@"name"]]&&[oldavatar isEqualToString:userinfo[@"avatar"]]){ return; }else{ NSMutableDictionary *mdic = [chatDis mutableCopy]; [mdic setObject:userinfo[@"name"] forKey:@"name"]; [mdic setObject:userinfo[@"avatar"] forKey:@"avatar"]; [self updateChat:mdic isreload:YES]; } } else{ } } fail:^(NSError * _Nonnull error) { }]; } } - (void)deleteChat:(NSDictionary *_Nonnull)chat{ weakSelf(self); [GDBManager.shareInstance deleteChatListItem:chat succ:^(NSArray * _Nullable array) { // [GDBManager.shareInstance deleteLocalMessageTable:chat[@"id"]]; NSMutableArray * tempArray = [NSMutableArray arrayWithArray:weakself.chatlist]; [tempArray removeObject:chat]; weakself.chatlist = tempArray; } fail:^(NSString * _Nullable error) { NSLog(@"error:%@",error); }]; [GDBManager.shareInstance deletechatLocalmsg:chat[@"id"]]; } -(NSString *)setLastMsg:(NSDictionary *)msg{ NSString *content = msg[@"content"]?:@""; NSString *magType=msg[@"messageType"]; // NSLog(@"setLastMsg:%@",msg); if(magType.intValue==0){ return content; } // if(magType.intValue==1){ // return @"【图片】"; // } // if(magType.intValue==2){ // return @"【文件】"; // } // if(magType.intValue==3){ // return @"【语音】"; // } // if(magType.intValue==4){ // return @"【撤回】"; // } // if(magType.intValue==5){ // return @"【转发】"; // } if(magType.intValue==7){ BOOL video = msg[@"video"]; if(video){ return @"【视频通话】"; } return @"【语音通话】"; } return content; } -(void)chatDidOpen:(NSDictionary *_Nonnull)chatmsg{ BOOL notHadChat=YES; NSString *chatid = chatmsg[@"chatId"]; for (NSDictionary *item in self.chatlist) { if([chatid isEqualToString:item[@"id"]]){//窗口已经存在 NSLog(@"窗口已经存在:%@",item); notHadChat=NO; NSString *countstr = @"0"; NSDictionary *chatD=@{ @"id":item[@"id"], @"name":item[@"name"], @"avatar":item[@"avatar"], @"type":item[@"type"], @"lastMessage":item[@"lastMessage"], @"lastTime":item[@"lastTime"], @"unreadCount":countstr, @"loaded":item[@"loaded"], @"loading":item[@"loading"], @"top":item[@"top"]?:@"false" }; [self updateChat:chatD isreload:YES]; return; } } if(notHadChat){//还没有窗口,创建一个新的窗口 [self tryToCreateChate:chatmsg]; } } -(void)tryToCreateChate:(NSDictionary *_Nonnull)chatmsg{ NSDictionary *userinfo = [UDManager.shareInstance getDDManager:dkuserinfo]; [Bugly reportException:[NSException exceptionWithName:@"tryToCreateChate" reason:userinfo[@"name"] userInfo:nil]]; NSDate *now = [NSDate date]; NSTimeInterval trt = [now timeIntervalSince1970]; NSInteger time = trt*1000; NSString *strtime = [NSString stringWithFormat:@"%ld",(long)time]; NSDictionary *chatD=@{ @"id":chatmsg[@"chatId"], @"name":chatmsg[@"name"], @"avatar":chatmsg[@"avatar"], @"type":chatmsg[@"type"], @"lastMessage":@"", @"lastTime":strtime, @"unreadCount":@"0", @"loaded":@"", @"loading":@"", @"top":@"false" }; [self updateChat:chatD isreload:YES]; } - (void)topChat:(NSDictionary *_Nonnull)chat{ [self updatelcDB:@[chat] top:@"true"]; } - (void)cancelTopChat:(NSDictionary *_Nonnull)chat{ [self updatelcDB:@[chat] top:@"false"]; } -(NSArray *)arraysort:(NSArray *)array{ NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) { NSString *newtime =obj1[@"lastTime"]; NSString *dtime =obj2[@"lastTime"]; // NSLog(@"newtime:%@",newtime); // NSLog(@"dtime:%@",[dtime class]); if([newtime isKindOfClass:[NSNull class]]){ return NSOrderedDescending; } if([dtime isKindOfClass:[NSNull class]]){ return NSOrderedAscending; } if(newtime.longLongValue0){ for (NSDictionary *item in array) { NSDictionary * safeDict = [self replaceNullsWithEmptyStringInDictionary:item]; mark=YES; NSString *newtime =safeDict[@"lastTime"]; if (newtime.intValue==0) { continue; } for(NSDictionary *oitem in self.toparray){ if([safeDict[@"id"] isEqualToString:oitem[@"id"]]){ mark=NO; NSString *dtime =oitem[@"lastTime"]; if(newtime.longLongValue>=dtime.longLongValue){ NSDictionary *chatD=@{ @"id":oitem[@"id"], @"name":oitem[@"name"]?:@"", @"avatar":oitem[@"avatar"]?:@"", @"type":oitem[@"type"]?:@"", @"lastMessage":safeDict[@"lastMessage"]?:@"", @"lastTime":safeDict[@"lastTime"]?:@"", @"unreadCount":safeDict[@"unreadCount"]?:@"", @"loaded":@"", @"loading":@"", @"top":oitem[@"top"]?:@"false", }; NSLog(@"chatD:%@",chatD); chatD = [self encodingMsg:chatD]; NSInteger index = [self.toparray indexOfObject:oitem]; [topArray replaceObjectAtIndex:index withObject:chatD]; [self updateToDBonly:chatD]; } } } if(mark){ [tempArray addObject:item]; } } } else{ tempArray=[array mutableCopy]; } self.toparray = [topArray copy]; if(tempArray.count>0){ if(nmArray.count>0){ for (NSDictionary *item in tempArray) { NSDictionary * safeDict = [self replaceNullsWithEmptyStringInDictionary:item]; mark=YES; NSString *newtime =safeDict[@"lastTime"]; NSLog(@"000000000"); if (newtime.intValue==0) { continue; } for(NSDictionary *oitem in self.nmarray){ if([safeDict[@"id"] isEqualToString:oitem[@"id"]]){ NSLog(@"1111111111"); mark=NO; NSString *dtime =oitem[@"lastTime"]; if(newtime.longLongValue>=dtime.longLongValue){ NSLog(@"2222222"); NSDictionary *chatD=@{ @"id":oitem[@"id"], @"name":oitem[@"name"]?:@"", @"avatar":oitem[@"avatar"]?:@"", @"type":oitem[@"type"]?:@"", @"lastMessage":safeDict[@"lastMessage"]?:@"", @"lastTime":safeDict[@"lastTime"]?:@"", @"unreadCount":safeDict[@"unreadCount"]?:@"", @"loaded":@"", @"loading":@"", @"top":oitem[@"top"]?:@"false", }; NSLog(@"chatD:%@",chatD); chatD = [self encodingMsg:chatD]; NSInteger index = [self.nmarray indexOfObject:oitem]; [nmArray replaceObjectAtIndex:index withObject:chatD]; [self updateToDBonly:chatD]; } } } if(mark){ NSDictionary *chatD=@{ @"id":safeDict[@"id"], @"name":safeDict[@"name"]?:@"", @"avatar":safeDict[@"avatar"]?:@"", @"type":safeDict[@"type"]?:@"", @"lastMessage":safeDict[@"lastMessage"]?:@"", @"lastTime":safeDict[@"lastTime"]?:@"", @"unreadCount":safeDict[@"unreadCount"]?:@"", @"loaded":@"", @"loading":@"", @"top":@"false", }; chatD = [self encodingMsg:chatD]; [nmArray addObject:chatD]; [self updateToDBonly:chatD]; } } } else{ NSArray *arr= [self replaceNullsWithEmptyStringInArray:tempArray]; // nmArray=[arr mutableCopy]; for (NSDictionary *item in arr) { NSLog(@"3333333"); NSString *lastT =item[@"lastTime"]; if(lastT.intValue==0){ continue; } NSDictionary *chatD=@{ @"id":item[@"id"], @"name":item[@"name"]?:@"", @"avatar":item[@"avatar"]?:@"", @"type":item[@"type"]?:@"", @"lastMessage":item[@"lastMessage"]?:@"", @"lastTime":item[@"lastTime"]?:@"", @"unreadCount":item[@"unreadCount"]?:@"", @"loaded":@"", @"loading":@"", @"top":@"false", }; chatD = [self encodingMsg:chatD]; [nmArray addObject:chatD.copy]; [self updateToDBonly:chatD]; } } } else{ } self.nmarray = [nmArray copy]; [self postdataToView]; } -(void)updateToDBonly:(NSDictionary *)chat{ chat = [self encodingMsg:chat]; [GDBManager.shareInstance insertLocalchat:chat succ:^(NSArray * _Nullable array) { } fail:^(NSString * _Nullable error) { ; }]; } -(void)postdataToView{ NSMutableOrderedSet *toporderedSet = [[NSMutableOrderedSet alloc] initWithArray:self.toparray];//去重,顺序不变 NSArray *topchats = [toporderedSet array]; topchats=[self arraysort:topchats]; NSMutableOrderedSet *orderedSet = [[NSMutableOrderedSet alloc] initWithArray:self.nmarray];//去重,顺序不变 NSArray *chats = [orderedSet array]; chats=[self arraysort:chats]; NSArray *reschats; if(topchats.count>0){ reschats=[topchats arrayByAddingObjectsFromArray:chats]; } else{ reschats =chats; } self.chatlist =reschats.copy; if(self.delegate){ [self.delegate ChatListChange:reschats.copy]; [Bugly reportException:[NSException exceptionWithName:@"postdataToView--1" reason:[NSString stringWithFormat:@"reschats:%lu",(unsigned long)reschats.count] userInfo:nil]]; } else{ [Bugly reportException:[NSException exceptionWithName:@"postdataToView--2" reason:[NSString stringWithFormat:@"reschats:%lu",(unsigned long)reschats.count] userInfo:nil]]; } } // 递归替换字典中的 NSNull 为 @"" - (NSDictionary *)replaceNullsWithEmptyStringInDictionary:(NSDictionary *)dictionary { NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:dictionary]; for (id key in [mutableDict allKeys]) { id value = [mutableDict objectForKey:key]; if ([value isKindOfClass:[NSNull class]]) { [mutableDict setObject:@"" forKey:key]; } else if ([value isKindOfClass:[NSDictionary class]]) { // 递归处理子字典 [mutableDict setObject:[self replaceNullsWithEmptyStringInDictionary:value] forKey:key]; } else if ([value isKindOfClass:[NSArray class]]) { // 递归处理数组 [mutableDict setObject:[self replaceNullsWithEmptyStringInArray:value] forKey:key]; } } return [NSDictionary dictionaryWithDictionary:mutableDict]; } // 递归替换数组中的 NSNull 为 @"" - (NSArray *)replaceNullsWithEmptyStringInArray:(NSArray *)array { NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array]; for (NSInteger i = 0; i < [mutableArray count]; i++) { id value = [mutableArray objectAtIndex:i]; if ([value isKindOfClass:[NSNull class]]) { [mutableArray replaceObjectAtIndex:i withObject:@""]; } else if ([value isKindOfClass:[NSDictionary class]]) { // 递归处理子字典 [mutableArray replaceObjectAtIndex:i withObject:[self replaceNullsWithEmptyStringInDictionary:value]]; } else if ([value isKindOfClass:[NSArray class]]) { // 递归处理子数组 [mutableArray replaceObjectAtIndex:i withObject:[self replaceNullsWithEmptyStringInArray:value]]; } } return [NSArray arrayWithArray:mutableArray]; } //信息解密存储 -(NSDictionary *)encodingMsg:(NSDictionary *)msg{ NSMutableDictionary *temp = [msg mutableCopy]; NSString *content = msg[@"lastMessage"]; content = [CryptoAES.shareInstance decryptDataL:content?: @""]; [temp setObject:content forKey:@"lastMessage"]; return [temp copy]; } @end