// // FavoritesController.m // AIIM // // Created by qitewei on 2025/4/29. // #import "FavoritesController.h" #import "FavoritesAudioCell.h" #import "FavoritesPictrueCell.h" #import "FavoritesTextCell.h" #import "UserNetApi.h" #import "FilePreviewer.h" #import "QuoteDetailController.h" #import "CryptoAES.h" #import "FileNetApi.h" #import "AVFoundation/AVFoundation.h" @interface FavoritesController () @property (nonatomic, strong) UIButton * rightBtn; @property (nonatomic, strong) UITextField * searchTextfield; @property (nonatomic, strong) UIStackView * buttonStackView; @property (nonatomic, strong) UIButton * allBtn; @property (nonatomic, strong) UIButton * textBtn; @property (nonatomic, strong) UIButton * pictrueBtn; @property (nonatomic, strong) UIButton * fileBtn; @property (nonatomic, strong) UIButton * audioBtn; @property (nonatomic, strong) UIView * bottomCube; @property (nonatomic, strong) UITableView * tableView; @property (nonatomic, strong) AVPlayer * player; @property (nonatomic, strong) NSMutableArray * dataArray; @end @implementation FavoritesController #pragma mark lifecircle - (void)viewDidLoad { [super viewDidLoad]; [self configUI]; [self getFavoritesWithType:@""]; } #pragma mark UI - (void)configUI{ [self setNavigationBarHidden:NO animated:YES]; [self setNavigationTitle:NSLocalizedString(@"userCenter-shoucjia", @"")]; // 设置导航栏背景色 [self setNavigationBarBackgroundColor:UIColor.clearColor]; [self setNavigationBarTransparent:YES]; // 设置标题颜色和字体 [self setNavigationTitleColor:[UIColor whiteColor] font:[UIFont boldSystemFontOfSize:18]]; // 设置返回按钮 [self setBackButtonTitle:@""]; [self setBackButtonColor:[UIColor whiteColor]]; // self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.rightBtn]; // [self.view addSubview:self.searchTextfield]; // [self.searchTextfield mas_makeConstraints:^(MASConstraintMaker *make) { // make.height.mas_equalTo(36); // make.top.mas_equalTo(SCREEN_TOP+10); // make.left.mas_equalTo(20); // make.right.mas_equalTo(-20); // }]; UIImageView * bgImageView = [[UIImageView alloc] initWithImage:kImageMake(@"loginBG")]; [self.view addSubview:bgImageView]; [bgImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.bottom.mas_equalTo(0); }]; [self.view addSubview:self.buttonStackView]; [self.buttonStackView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(SCREEN_TOP+10); make.height.mas_equalTo(36); make.left.mas_equalTo(20); make.right.mas_equalTo(-20); }]; [self.view addSubview:self.bottomCube]; [self.bottomCube mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake((SCREEN_WIDTH-40)/4, 4)); make.top.mas_equalTo(self.buttonStackView.mas_bottom); make.centerX.mas_equalTo(self.allBtn.mas_centerX); }]; [self.view addSubview:self.tableView]; [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.bottom.left.right.mas_equalTo(0); make.top.mas_equalTo(self.bottomCube.mas_bottom).offset(5); }]; } #pragma mark api - (void)getFavoritesWithType:(NSString *)type{ [UserNetApi favoritesListWithType:type succ:^(int code, NSDictionary * _Nullable result) { if ([result jk_hasKey:@"code"] && [result[@"code"] isEqual:@200]) { NSLog(@"--------result:%@",result); NSArray * data = [self replaceNullsWithEmptyStringInArray:result[@"data"]]; [self.dataArray removeAllObjects]; [self.dataArray addObjectsFromArray:data]; [self.tableView reloadData]; } } fail:^(NSError * _Nonnull error) { NSLog(@"%@",error); }]; } - (void)deleteFavoritesWithId:(NSString *)msgId{ [UserNetApi deleteFavoritesWithId:msgId succ:^(int code, NSDictionary * _Nullable result) { if ([result jk_hasKey:@"code"] && [result[@"code"] isEqual:@200]) { [MBProgressHUD showWithText:result[@"msg"]]; } } fail:^(NSError * _Nonnull error) { NSLog(@"error:%@",error); }]; } #pragma mark event - (void)categoryButtonClicked:(UIButton *)sender{ for (UIButton * button in @[self.allBtn,self.textBtn,self.pictrueBtn,self.fileBtn,self.audioBtn]) { if (button == sender) { button.selected = YES; }else{ button.selected = NO; } } [self.bottomCube mas_remakeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake((SCREEN_WIDTH-40)/4, 4)); make.top.mas_equalTo(self.buttonStackView.mas_bottom); make.centerX.mas_equalTo(sender.mas_centerX); }]; NSString * favoritesType; if (sender == self.allBtn) { favoritesType = @""; }else if (sender == self.textBtn){ favoritesType = @"0"; }else if (sender == self.pictrueBtn){ favoritesType = @"1"; }else if (sender == self.fileBtn){ favoritesType = @"2"; }else if (sender == self.audioBtn){ favoritesType = @"3"; } [self getFavoritesWithType:favoritesType]; } #pragma mark private - (void)playerItemDidReachEnd:(NSNotification *)notification { // 播放结束时的处理代码 NSLog(@"播放结束:%@",notification); [[UIDevice currentDevice] setProximityMonitoringEnabled:NO]; //建议在播放之前设置yes,播放结束设置NO。这个功能是开启红外感应 [[NSNotificationCenter defaultCenter] removeObserver:self name:notification.name object:notification.object]; //可以执行继续播放下一条操作 } // 递归替换字典中的 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]; } #pragma mark tableView delegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 1; } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return self.dataArray.count; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 0; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ return nil; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ NSDictionary * dict = self.dataArray[indexPath.section]; if ([dict[@"messageType"] isEqualToString:@"0"]) { //文本 FavoritesTextCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(FavoritesTextCell.class) forIndexPath:indexPath]; [cell setMsg:dict]; return cell; } if ([dict[@"messageType"] isEqualToString:@"1"]) { //图片 FavoritesPictrueCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(FavoritesPictrueCell.class) forIndexPath:indexPath]; [cell setMsg:dict]; return cell; } FavoritesAudioCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(FavoritesAudioCell.class) forIndexPath:indexPath]; [cell setMsg:dict]; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSDictionary * dict = self.dataArray[indexPath.section]; NSString *extend = dict[@"extend"]; NSData *data = [extend dataUsingEncoding:NSUTF8StringEncoding]; NSError *error; NSDictionary *extendDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if ([dict[@"messageType"] isEqualToString:@"1"] || [dict[@"messageType"] isEqualToString:@"5"]) { NSLog(@"extendDict:%@",extendDict); if([extendDict jk_hasKey:@"url"]){ [FilePreviewer.shared previewFileWithLocalPath:extendDict[@"localurl"]?:@"" remoteURL:getURL(extendDict[@"url"]) fromViewController:self]; }else{ [MBProgressHUD showWithText:NSLocalizedString(@"AppLock_fail", @"操作失败")]; } }else if ([dict[@"messageType"] isEqualToString:@"0"]) { NSLog(@"dict:%@",dict); QuoteDetailController * quoteDetailVc = [[QuoteDetailController alloc] init]; quoteDetailVc.quotedContent = [CryptoAES.shareInstance decryptDataL:dict[@"content"]]; quoteDetailVc.quotedSenderName = dict[@"formName"]; UINavigationController * navi = [[UINavigationController alloc] initWithRootViewController:quoteDetailVc]; navi.modalPresentationStyle = UIModalPresentationFullScreen; [self presentViewController:navi animated:YES completion:nil]; }else if ([dict[@"messageType"] isEqualToString:@"3"]) { //语音 if (self.player) { AVPlayerItem *playerItem = self.player.currentItem; CMTime currentTime = playerItem.currentTime; CMTime duration = playerItem.duration; if (self.player.rate == 0.0) { if (CMTimeCompare(currentTime, duration) == 0 || CMTimeCompare(currentTime, duration) == 1) { // 播放完毕 NSLog(@"Playback finished"); } else { // 暂停 NSLog(@"Playback paused"); [self.player play]; return; } } else { // 正在播放 NSLog(@"Playback in progress"); [self.player pause]; return; } } if([extendDict jk_hasKey:@"url"]){ NSString *urlstr = extendDict[@"url"]; AVAudioSession *audioSession = [AVAudioSession sharedInstance]; [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; [audioSession setActive:YES error:nil]; NSURL *Url = [NSURL URLWithString:urlstr]; AVPlayerItem *pitem = [[AVPlayerItem alloc] initWithURL:Url]; _player = [AVPlayer playerWithPlayerItem:pitem]; [[UIDevice currentDevice] setProximityMonitoringEnabled:YES]; //建议在播放之前设置yes,播放结束设置NO。这个功能是开启红外感应 [_player play]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:pitem]; } }else if ([dict[@"messageType"] isEqualToString:@"5"]) { //文件(保存到本地) // [AlertHelper showAlertWithTitle:@"提示" message:[NSString stringWithFormat:@" 是否保存%@到本地",extendDict[@"fileName"]] cancelButtonTitle:@"取消" confirmButtonTitle:@"确定" completion:^(NSInteger buttonIndex) { // if (buttonIndex == 0) { // // }else{ // [FileNetApi downLoadWToken:getURL(extendDict[@"url"]) succ:^(int code, NSDictionary * _Nullable result) { // // } fail:^(NSError * _Nonnull error) { // // }]; // } // }]; } } - (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath { // 创建删除操作 UIContextualAction *deleteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:NSLocalizedString(@"GroupCtr-yichu", @"") handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) { // 删除数据 NSDictionary * dict = self.dataArray[indexPath.section]; [self deleteFavoritesWithId:dict[@"id"]]; [self.dataArray removeObjectAtIndex:indexPath.section]; // 更新表格 [tableView reloadData]; // 告诉系统操作已完成 completionHandler(YES); }]; // 设置删除按钮颜色 deleteAction.backgroundColor = [UIColor redColor]; // 创建配置并返回 UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteAction]]; config.performsFirstActionWithFullSwipe = YES; // 完全滑动直接执行删除 return config; } #pragma mark lazy - (UIButton *)rightBtn{ if (!_rightBtn) { _rightBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_rightBtn setImage:[UIImage imageNamed:@"more_btn"] forState:UIControlStateNormal]; } return _rightBtn; } - (UITextField *)searchTextfield{ if (!_searchTextfield) { _searchTextfield = [[UITextField alloc] init]; _searchTextfield.textColor = globalColor(GCTypeWhite); _searchTextfield.font = SYSFONT(14); _searchTextfield.borderStyle = UITextBorderStyleNone; _searchTextfield.backgroundColor = globalColor(GCTypeDark6); _searchTextfield.leftViewMode = UITextFieldViewModeAlways; UIView * leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 36)]; UIImageView * searchIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"search_icon"]]; [leftView addSubview:searchIcon]; [searchIcon mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(15, 15)); make.left.mas_equalTo(20); make.top.mas_equalTo(11); }]; _searchTextfield.leftView = leftView; _searchTextfield.layer.cornerRadius = 5.f; _searchTextfield.layer.masksToBounds = YES; } return _searchTextfield; } - (UIButton *)allBtn{ if (!_allBtn) { _allBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_allBtn setTitle:NSLocalizedString(@"Favorites_type_all", @"") forState:UIControlStateNormal]; [_allBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [_allBtn setTitleColor:globalColor(GCTypeGreen) forState:UIControlStateSelected]; _allBtn.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightRegular]; _allBtn.selected = YES; [_allBtn addTarget:self action:@selector(categoryButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; } return _allBtn; } - (UIButton *)textBtn{ if (!_textBtn) { _textBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_textBtn setTitle:NSLocalizedString(@"Favorites_type_text", @"") forState:UIControlStateNormal]; [_textBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [_textBtn setTitleColor:globalColor(GCTypeGreen) forState:UIControlStateSelected]; _textBtn.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightRegular]; [_textBtn addTarget:self action:@selector(categoryButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; } return _textBtn; } - (UIButton *)pictrueBtn{ if (!_pictrueBtn) { _pictrueBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_pictrueBtn setTitle:NSLocalizedString(@"Favorites_type_pictrue", @"") forState:UIControlStateNormal]; [_pictrueBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [_pictrueBtn setTitleColor:globalColor(GCTypeGreen) forState:UIControlStateSelected]; _pictrueBtn.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightRegular]; [_pictrueBtn addTarget:self action:@selector(categoryButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; } return _pictrueBtn; } - (UIButton *)fileBtn{ if (!_fileBtn) { _fileBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_fileBtn setTitle:NSLocalizedString(@"Favorites_type_file", @"") forState:UIControlStateNormal]; [_fileBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [_fileBtn setTitleColor:globalColor(GCTypeGreen) forState:UIControlStateSelected]; _fileBtn.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightRegular]; [_fileBtn addTarget:self action:@selector(categoryButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; } return _fileBtn; } - (UIButton *)audioBtn{ if (!_audioBtn) { _audioBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_audioBtn setTitle:NSLocalizedString(@"Favorites_type_audio", @"") forState:UIControlStateNormal]; [_audioBtn setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; [_audioBtn setTitleColor:globalColor(GCTypeGreen) forState:UIControlStateSelected]; _audioBtn.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightRegular]; [_audioBtn addTarget:self action:@selector(categoryButtonClicked:) forControlEvents:UIControlEventTouchUpInside]; } return _audioBtn; } - (UIStackView *)buttonStackView{ if (!_buttonStackView) { _buttonStackView = [[UIStackView alloc] initWithArrangedSubviews:@[self.allBtn,self.textBtn,self.pictrueBtn,self.fileBtn,self.audioBtn]]; _buttonStackView.axis = UILayoutConstraintAxisHorizontal; _buttonStackView.alignment = UIStackViewAlignmentFill; _buttonStackView.distribution = UIStackViewDistributionFillEqually; } return _buttonStackView; } - (UIView *)bottomCube{ if (!_bottomCube) { _bottomCube = [[UIView alloc] init]; _bottomCube.backgroundColor = globalColor(GCTypeGreen); _bottomCube.layer.cornerRadius = 2.f; _bottomCube.layer.masksToBounds = YES; } return _bottomCube; } - (UITableView *)tableView{ if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleInsetGrouped]; _tableView.backgroundColor = UIColor.clearColor; _tableView.delegate = self; _tableView.dataSource = self; // 启用编辑模式 _tableView.allowsSelectionDuringEditing = YES; [_tableView registerClass:FavoritesTextCell.class forCellReuseIdentifier:NSStringFromClass(FavoritesTextCell.class)]; [_tableView registerClass:FavoritesPictrueCell.class forCellReuseIdentifier:NSStringFromClass(FavoritesPictrueCell.class)]; [_tableView registerClass:FavoritesAudioCell.class forCellReuseIdentifier:NSStringFromClass(FavoritesAudioCell.class)]; } return _tableView; } - (NSMutableArray *)dataArray{ if (!_dataArray) { _dataArray = [NSMutableArray array]; } return _dataArray; } #pragma mark statusBar - (UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } @end