ChatMessageModel.m 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. //
  2. // ChatMessageModel.m
  3. // AIIM
  4. //
  5. // Created by qitewei on 2025/5/14.
  6. //
  7. #import "ChatMessageModel.h"
  8. #import "CryptoAES.h"
  9. #import "ChatsStore.h"
  10. #import "AVFoundation/AVFoundation.h"
  11. #import "FileNetApi.h"
  12. #import <SDWebImage/SDImageCache.h>
  13. @implementation ChatMessageModel
  14. + (instancetype)modelWithDictionary:(NSDictionary *)dict {
  15. ChatMessageModel *model = [[ChatMessageModel alloc] init];
  16. [model setupWithDictionary:dict];
  17. return model;
  18. }
  19. - (void)setupWithDictionary:(NSDictionary *)dict {
  20. NSMutableDictionary * mutableDict = [NSMutableDictionary dictionaryWithDictionary:dict];
  21. [mutableDict jk_each:^(id k, id v) {
  22. if ([v isKindOfClass:[NSNull class]]) {
  23. [mutableDict setObject:@"" forKey:k];
  24. }
  25. }];
  26. //原消息
  27. self.formerMessage = dict;
  28. self.chatId = mutableDict[@"chatId"];
  29. // 消息类型
  30. NSInteger type = [mutableDict[@"messageType"] integerValue];
  31. self.messageType = (ChatMessageType)type;
  32. self.type = [mutableDict[@"type"] integerValue];
  33. self.nickName = mutableDict[@"fromName"]?:@"";
  34. self.avatar = mutableDict[@"fromAvatar"]?:@"";
  35. // 通用内容
  36. // self.content = mutableDict[@"content"] ?: @"";//本地明文存储
  37. self.content =[CryptoAES.shareInstance decryptDataL:mutableDict[@"content"] ?: @""];//本地加密存储
  38. self.msgId = mutableDict[@"id"];
  39. self.fromId = mutableDict[@"fromId"];
  40. // 发送方标识
  41. NSDictionary *userinfo = [UDManager.shareInstance getDDManager:dkuserinfo];
  42. NSString *userId = userinfo[@"id"];
  43. if([self.fromId isEqualToString:userId]){
  44. self.isSender=true;
  45. }
  46. else{
  47. self.isSender=false;
  48. }
  49. // 处理媒体尺寸
  50. CGFloat width = [mutableDict[@"width"] floatValue];
  51. CGFloat height = [mutableDict[@"height"] floatValue];
  52. if (width > 0 && height > 0) {
  53. self.mediaSize = CGSizeMake(width, height);
  54. } else {
  55. // 默认尺寸
  56. self.mediaSize = CGSizeMake(200, 150);
  57. }
  58. self.placeholderImage = kImageMake(@"pictrue_placeholder");
  59. // 文件消息
  60. NSDictionary * extend = [mutableDict[@"extend"] isKindOfClass:NSDictionary.class]?mutableDict[@"extend"]:@{};
  61. self.fileName = extend[@"fileName"] ?: @"未知文件";
  62. self.fileSize = extend[@"size"] ?: @"0KB";
  63. self.url = extend[@"url"] ?: @"";
  64. NSCharacterSet *allowedCharacters = [NSCharacterSet URLQueryAllowedCharacterSet];
  65. self.url = [self.url stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
  66. self.localurl = extend[@"localurl"] ?: @"";
  67. self.quoteMessage = ![extend jk_hasKey:@"quoteMessage"] ?NULL: [ChatMessageModel modelWithDictionary:extend[@"quoteMessage"]];
  68. // 语音消息
  69. NSInteger duration = [extend[@"time"] integerValue];
  70. if (duration<=60) {
  71. self.voiceDuration = duration;
  72. }else{
  73. self.voiceDuration = duration/1000;
  74. }
  75. self.voiceWidth = self.voiceDuration==0?0:[self voiceBubbleWidth];
  76. //文件传输成功或失败
  77. self.fileError = 0;
  78. NSInteger fileError = [extend[@"fileError"] integerValue];
  79. if (fileError!=0) {
  80. self.fileError = fileError;
  81. }
  82. else{
  83. if(self.url.length>0){
  84. self.fileError = 0;
  85. }
  86. }
  87. //合并转发
  88. self.forwardMsgArray = extend[@"messageList"] ?:@[];
  89. // 通话记录
  90. self.callDuration = [mutableDict[@"duration"] integerValue];
  91. self.isCallSuccess = [mutableDict[@"result"] boolValue];
  92. self.isVideo = [mutableDict[@"video"] boolValue];
  93. //@相关
  94. self.atAll = extend[@"atAll"]?[extend[@"atAll"] boolValue]:NO;
  95. self.atUserIds = extend[@"atUserIds"]?:@[];
  96. // 时间戳(如果需要)
  97. self.timestamp = [mutableDict[@"timestamp"] longLongValue];
  98. self.localtime = [mutableDict[@"localtime"] longLongValue];
  99. self.formatterTime = [self timeF:self.timestamp];
  100. // 其他自定义字段...
  101. self.readStatus = [self getReadStatus];
  102. }
  103. - (void)exchangeModelWithModel:(ChatMessageModel *)model{
  104. self.msgId = model.msgId;
  105. self.formerMessage = model.formerMessage;
  106. if(self.messageType!=model.messageType){
  107. self.cellHeight=0;
  108. }
  109. self.messageType = model.messageType;
  110. self.type = model.type;
  111. self.isSender = model.isSender;
  112. self.content = model.content;
  113. self.msgId = model.msgId;
  114. self.mediaSize = model.mediaSize;
  115. self.placeholderImage = model.placeholderImage;
  116. self.fileName = model.fileName;
  117. self.fileSize = model.fileSize;
  118. self.url = model.url;
  119. self.localurl = model.localurl;
  120. //文件传输成功或失败
  121. self.fileError = model.fileError;
  122. // 通话记录
  123. self.callDuration = model.callDuration;
  124. self.isCallSuccess = model.isCallSuccess;
  125. self.isVideo = model.isVideo;
  126. self.avatar = model.avatar;
  127. self.nickName = model.nickName;
  128. //@相关
  129. self.atAll = model.atAll;
  130. self.atUserIds = model.atUserIds;
  131. // 时间戳(如果需要)
  132. self.timestamp = model.timestamp;
  133. self.localtime = model.localtime;
  134. self.formatterTime = model.formatterTime;
  135. // // 其他自定义字段...
  136. // 其他自定义字段...
  137. self.readStatus = [self getReadStatus];
  138. }
  139. -(NSString *)timeF:(NSInteger)time{
  140. //NSLog(@"time:%ld",(long)time);
  141. // 创建日期格式器
  142. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  143. [formatter setDateFormat:@"dd"]; // 设置你想要的日期格式
  144. long long timestamp =(long)time/1000; // 例如:2021-10-01 00:00:00 UTC
  145. // 转换为NSDate
  146. NSDate *date = [NSDate dateWithTimeIntervalSince1970:timestamp];
  147. NSString *dateString = [formatter stringFromDate:date];
  148. NSDate *now = [NSDate date];
  149. NSTimeInterval trt = [now timeIntervalSince1970];
  150. date = [NSDate dateWithTimeIntervalSince1970:trt];
  151. NSString *tdateString = [formatter stringFromDate:date];
  152. NSInteger shijiancha = trt-timestamp;
  153. if(shijiancha<60){
  154. return NSLocalizedString(@"time-oneminint", @"");
  155. }
  156. if(shijiancha>24*3600||dateString.intValue!=tdateString.intValue){
  157. // 假设这是你的时间戳(以秒为单位)
  158. long long timestamp =(long)time/1000; // 例如:2021-10-01 00:00:00 UTC
  159. // 转换为NSDate
  160. NSDate *date = [NSDate dateWithTimeIntervalSince1970:timestamp];
  161. // 创建日期格式器
  162. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  163. [formatter setDateFormat:@"yyyy-MM-dd HH:mm"]; // 设置你想要的日期格式
  164. // 转换为字符串
  165. NSString *dateString = [formatter stringFromDate:date];
  166. return dateString;
  167. }
  168. else{
  169. NSInteger xiaoshi = shijiancha/3600;
  170. NSInteger fenzhong = shijiancha/60;
  171. if(xiaoshi>0){
  172. // 假设这是你的时间戳(以秒为单位)
  173. long long timestamp =(long)time/1000; // 例如:2021-10-01 00:00:00 UTC
  174. // 转换为NSDate
  175. NSDate *date = [NSDate dateWithTimeIntervalSince1970:timestamp];
  176. // 创建日期格式器
  177. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  178. [formatter setDateFormat:@"HH:mm"]; // 设置你想要的日期格式
  179. // 转换为字符串
  180. NSString *dateString = [formatter stringFromDate:date];
  181. return dateString;
  182. }
  183. else{
  184. return [NSString stringWithFormat:@"%ld%@",(long)fenzhong,NSLocalizedString(@"time-outmin", @"")];
  185. }
  186. }
  187. return @"";
  188. }
  189. - (NSString *)getReadStatus{
  190. NSString * readStatus;
  191. self.readstate = 0;
  192. if(self.timestamp == 0){
  193. return @"";
  194. }
  195. if(self.messageType==11||self.messageType==12){
  196. return @"";
  197. }
  198. if(self.type==0){
  199. if (self.localtime != 0 && self.localtime == self.timestamp) {
  200. NSDate *now = [NSDate date];
  201. NSTimeInterval trt = [now timeIntervalSince1970];
  202. NSInteger time = trt*1000;
  203. NSInteger outTime =time-self.localtime;
  204. if(outTime>33000){
  205. if(self.messageType==1||self.messageType==2||self.messageType==5){
  206. readStatus = @"正在发送";
  207. self.readstate = 3;
  208. }else{
  209. readStatus = @"发送失败";
  210. self.readstate = 4;
  211. }
  212. }else{
  213. readStatus = @"正在发送";
  214. self.readstate = 3;
  215. }
  216. }
  217. else{
  218. //判断已读未读
  219. if(self.timestamp>ChatsStore.shareInstance.lastreadTime){
  220. readStatus = @"未读";
  221. self.readstate = 1;
  222. }
  223. else{
  224. readStatus = @"已读";
  225. self.readstate = 2;
  226. }
  227. if(self.fileError==1){
  228. readStatus = @"發送失敗,點擊重發";
  229. self.readstate = 4;
  230. }
  231. }
  232. }else{
  233. return @"";
  234. }
  235. return readStatus;
  236. }
  237. - (void)generateThumbnailWithCompletion:(void(^)(UIImage *thumbnail))completion {
  238. // 如果内存中已有缩略图,直接返回
  239. if (self.videoThumbnailImage) {
  240. if (completion) completion(self.videoThumbnailImage);
  241. return;
  242. }
  243. // 生成缓存 key,优先使用 msgId,如果没有则使用 URL 的 hash
  244. NSString *cacheKey = nil;
  245. if (self.msgId.length > 0) {
  246. cacheKey = [NSString stringWithFormat:@"video_thumbnail_%@", self.msgId];
  247. } else if (self.url.length > 0) {
  248. cacheKey = [NSString stringWithFormat:@"video_thumbnail_%lu", (unsigned long)[self.url hash]];
  249. }
  250. // 从 SDWebImage 缓存中查找
  251. if (cacheKey) {
  252. SDImageCache *imageCache = [SDImageCache sharedImageCache];
  253. UIImage *cachedImage = [imageCache imageFromCacheForKey:cacheKey];
  254. if (cachedImage) {
  255. NSLog(@"从缓存加载缩略图: %@", cacheKey);
  256. self.videoThumbnailImage = cachedImage;
  257. if (completion) completion(cachedImage);
  258. return;
  259. }
  260. }
  261. // 没有缓存,需要生成缩略图
  262. NSURL *videoURL = nil;
  263. if (self.localurl.length != 0 && [[NSFileManager defaultManager] fileExistsAtPath:self.localurl]) {
  264. // 从本地文件生成缩略图
  265. NSLog(@"generateThumbnailWithCompletion localurl:%@",self.localurl);
  266. videoURL = [NSURL fileURLWithPath:self.localurl];
  267. NSString *finalCacheKey = cacheKey;
  268. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  269. AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
  270. AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
  271. generator.appliesPreferredTrackTransform = YES;
  272. CMTime acttime;
  273. NSError *error = nil;
  274. CGImageRef imageRef = [generator copyCGImageAtTime:CMTimeMake(0, 600) actualTime:&acttime error:&error];
  275. NSLog(@"error:%@",error);
  276. if (!error && imageRef) {
  277. UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imageRef];
  278. CGImageRelease(imageRef);
  279. // 缓存到内存
  280. self.videoThumbnailImage = thumbnail;
  281. // 使用 SDWebImage 缓存到磁盘和内存
  282. if (finalCacheKey) {
  283. SDImageCache *imageCache = [SDImageCache sharedImageCache];
  284. [imageCache storeImage:thumbnail forKey:finalCacheKey completion:^{
  285. NSLog(@"缩略图已缓存: %@", finalCacheKey);
  286. }];
  287. }
  288. if (completion){
  289. completion(thumbnail);
  290. }
  291. } else {
  292. if (completion) completion(nil);
  293. }
  294. });
  295. } else {
  296. // 从远程 URL 生成缩略图
  297. NSLog(@"generateThumbnailWithCompletion url");
  298. if (self.url.length == 0){
  299. if (completion) completion(nil);
  300. return;
  301. }
  302. NSDictionary *options = @{AVURLAssetAllowsCellularAccessKey: @YES,
  303. AVURLAssetPreferPreciseDurationAndTimingKey: @YES};
  304. AVURLAsset *asset = [AVURLAsset URLAssetWithURL:getURL(self.url) options:options];
  305. // 创建图像生成器
  306. AVAssetImageGenerator *generator = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
  307. generator.appliesPreferredTrackTransform = YES; // 应用视频的方向
  308. generator.maximumSize = CGSizeMake(320, 0); // 设置最大尺寸,保持宽高比
  309. NSString *finalCacheKey = cacheKey;
  310. // 异步生成缩略图
  311. [generator generateCGImagesAsynchronouslyForTimes:@[[NSValue valueWithCMTime:kCMTimeZero]]
  312. completionHandler:^(CMTime requestedTime, CGImageRef image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error) {
  313. __block UIImage *thumbnail = nil;
  314. // 处理生成结果
  315. if (result == AVAssetImageGeneratorSucceeded && image) {
  316. // 创建UIImage
  317. thumbnail = [UIImage imageWithCGImage:image];
  318. self.videoThumbnailImage = thumbnail;
  319. // 使用 SDWebImage 缓存到磁盘和内存
  320. if (finalCacheKey) {
  321. SDImageCache *imageCache = [SDImageCache sharedImageCache];
  322. [imageCache storeImage:thumbnail forKey:finalCacheKey completion:^{
  323. NSLog(@"缩略图已缓存: %@", finalCacheKey);
  324. }];
  325. }
  326. }
  327. dispatch_async(dispatch_get_main_queue(), ^{
  328. if (completion) completion(thumbnail);
  329. });
  330. }];
  331. }
  332. }
  333. //下载视频文件
  334. -(void)xiazaishipin:(void(^)(NSInteger persent))loading{
  335. NSLog(@"xiazaishipin--------");
  336. if(!self.isSender){
  337. NSString *localFileurl = [self.localurl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
  338. if (self.localurl.length != 0 && [[NSFileManager defaultManager] fileExistsAtPath:localFileurl]){
  339. // NSLog(@"文件已经存在本地");
  340. if (loading) {
  341. loading(100);
  342. }
  343. }
  344. else{
  345. // NSLog(@"文件不存在");
  346. if(self.url&&self.url.length != 0){
  347. NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
  348. NSURL *tempUrl = [NSURL URLWithString:self.url];
  349. NSString *fileName = tempUrl.lastPathComponent;
  350. NSString *fileExtension = [fileName pathExtension];
  351. NSString *newfileName = [NSString stringWithFormat:@"%@.%@", self.msgId,fileExtension];
  352. documentsDirectoryURL = [documentsDirectoryURL URLByAppendingPathComponent:newfileName];
  353. NSLog(@"文件已经存在本地1-:%@",documentsDirectoryURL.path);
  354. if ([[NSFileManager defaultManager] fileExistsAtPath:documentsDirectoryURL.path]){
  355. NSLog(@"文件已经存在本地2-:%@",documentsDirectoryURL.path);
  356. NSMutableDictionary *mutableDict = [self.formerMessage mutableCopy];
  357. NSMutableDictionary *extend = [self.formerMessage[@"extend"] mutableCopy];
  358. [extend setObject:documentsDirectoryURL.path forKey:@"localurl"];
  359. [mutableDict setObject:extend forKey:@"extend"];
  360. self.localurl = documentsDirectoryURL.path;
  361. NSDictionary *NewMsg = [mutableDict copy];
  362. [ChatsStore.shareInstance reciveMsg:NewMsg];
  363. if (loading) {
  364. loading(100);
  365. }
  366. }
  367. else{
  368. [FileNetApi downLoadWToken:getURL(self.url) thrid:self.msgId succ:^(int code, NSDictionary * res) {
  369. if(res!=nil){
  370. NSMutableDictionary *mutableDict = [self.formerMessage mutableCopy];
  371. NSMutableDictionary *extend = [self.formerMessage[@"extend"] mutableCopy];
  372. [extend setObject:res[@"filePath"] forKey:@"localurl"];
  373. [mutableDict setObject:extend forKey:@"extend"];
  374. self.localurl = res[@"filePath"];
  375. NSDictionary *NewMsg = [mutableDict copy];
  376. [ChatsStore.shareInstance reciveMsg:NewMsg];
  377. if (loading) {
  378. loading(100);
  379. }
  380. }
  381. else{
  382. if (code>=0&&code<200) {
  383. if (loading) {
  384. loading(code);
  385. }
  386. }
  387. }
  388. } fail:^(NSError * _Nonnull error) {
  389. NSLog(@"error:%@",error);
  390. }];
  391. }
  392. }
  393. else{
  394. if (loading) {
  395. loading(0);
  396. }
  397. }
  398. }
  399. }
  400. else{
  401. NSLog(@"downLoadWToken xiazaishipin-----");
  402. }
  403. }
  404. -(void)xiazaiwenjian:(void(^)(NSInteger persent))loading{
  405. NSLog(@"xiazaiwenjian---");
  406. if (self.isSender) {
  407. return;
  408. }
  409. else{
  410. // NSLog(@"self.localurl2:%@",self.localurl);
  411. if (self.localurl.length != 0 && [[NSFileManager defaultManager] fileExistsAtPath:self.localurl]){
  412. // NSLog(@"文件已经存在本地");
  413. self.customFileSize = [self getFileSize];
  414. if (loading) {
  415. loading(100);
  416. }
  417. return;
  418. }
  419. else{
  420. if(self.url&&self.url.length != 0){
  421. NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
  422. NSURL *tempUrl = [NSURL URLWithString:self.url];
  423. NSString *fileName = tempUrl.lastPathComponent;
  424. NSString *fileExtension = [fileName pathExtension];
  425. NSString *newfileName = [NSString stringWithFormat:@"%@.%@", self.msgId,fileExtension];
  426. documentsDirectoryURL = [documentsDirectoryURL URLByAppendingPathComponent:newfileName];
  427. NSLog(@"文件已经存在本地1-:%@",documentsDirectoryURL.path);
  428. if ([[NSFileManager defaultManager] fileExistsAtPath:documentsDirectoryURL.path]){
  429. NSLog(@"文件已经存在本地2-:%@",documentsDirectoryURL.path);
  430. NSMutableDictionary *mutableDict = [self.formerMessage mutableCopy];
  431. NSMutableDictionary *extend = [self.formerMessage[@"extend"] mutableCopy];
  432. [extend setObject:documentsDirectoryURL.path forKey:@"localurl"];
  433. [mutableDict setObject:extend forKey:@"extend"];
  434. self.localurl = documentsDirectoryURL.path;
  435. NSDictionary *NewMsg = [mutableDict copy];
  436. [ChatsStore.shareInstance reciveMsg:NewMsg];
  437. self.customFileSize = [self getFileSize];
  438. if (loading) {
  439. loading(100);
  440. }
  441. }
  442. else{
  443. [FileNetApi downLoadWToken:getURL(self.url) thrid:self.msgId succ:^(int code, NSDictionary * res) {
  444. if(res!=nil){
  445. NSMutableDictionary *mutableDict = [self.formerMessage mutableCopy];
  446. NSMutableDictionary *extend = [self.formerMessage[@"extend"] mutableCopy];
  447. [extend setObject:res[@"filePath"] forKey:@"localurl"];
  448. [mutableDict setObject:extend forKey:@"extend"];
  449. self.localurl = res[@"filePath"];
  450. NSDictionary *NewMsg = [mutableDict copy];
  451. [ChatsStore.shareInstance reciveMsg:NewMsg];
  452. self.customFileSize = [self getFileSize];
  453. if (loading) {
  454. loading(100);
  455. }
  456. }
  457. else{
  458. if (code>=0&&code<200) {
  459. if (loading) {
  460. loading(code);
  461. }
  462. }
  463. }
  464. } fail:^(NSError * _Nonnull error) {
  465. NSLog(@"error:%@",error);
  466. }];
  467. }
  468. }
  469. else{
  470. if (loading) {
  471. loading(0);
  472. }
  473. }
  474. }
  475. }
  476. }
  477. -(void)xiazaiyuyin:(void(^)(NSInteger persent))loading{
  478. NSLog(@"xiazaiwenjian---");
  479. if (self.isSender) {
  480. return;
  481. }
  482. else{
  483. // NSLog(@"self.localurl2:%@",self.localurl);
  484. if (self.localurl.length != 0 && [[NSFileManager defaultManager] fileExistsAtPath:self.localurl]){
  485. // NSLog(@"文件已经存在本地");
  486. if (loading) {
  487. loading(100);
  488. }
  489. return;
  490. }
  491. if(self.url&&self.url.length != 0){
  492. NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
  493. NSURL *tempUrl = [NSURL URLWithString:self.url];
  494. NSString *fileName = tempUrl.lastPathComponent;
  495. NSString *fileExtension = [fileName pathExtension];
  496. NSString *newfileName = [NSString stringWithFormat:@"%@.%@", self.msgId,fileExtension];
  497. documentsDirectoryURL = [documentsDirectoryURL URLByAppendingPathComponent:newfileName];
  498. NSLog(@"文件已经存在本地1-:%@",documentsDirectoryURL.path);
  499. if ([[NSFileManager defaultManager] fileExistsAtPath:documentsDirectoryURL.path]){
  500. NSLog(@"文件已经存在本地2-:%@",documentsDirectoryURL.path);
  501. NSMutableDictionary *mutableDict = [self.formerMessage mutableCopy];
  502. NSMutableDictionary *extend = [self.formerMessage[@"extend"] mutableCopy];
  503. [extend setObject:documentsDirectoryURL.path forKey:@"localurl"];
  504. [mutableDict setObject:extend forKey:@"extend"];
  505. self.localurl = documentsDirectoryURL.path;
  506. NSDictionary *NewMsg = [mutableDict copy];
  507. [ChatsStore.shareInstance reciveMsg:NewMsg];
  508. if (loading) {
  509. loading(100);
  510. }
  511. }
  512. else{
  513. [FileNetApi downLoadWToken:getURL(self.url) thrid:self.msgId succ:^(int code, NSDictionary * res) {
  514. if(res!=nil){
  515. NSMutableDictionary *mutableDict = [self.formerMessage mutableCopy];
  516. NSMutableDictionary *extend = [self.formerMessage[@"extend"] mutableCopy];
  517. [extend setObject:res[@"filePath"] forKey:@"localurl"];
  518. [mutableDict setObject:extend forKey:@"extend"];
  519. self.localurl = res[@"filePath"];
  520. NSDictionary *NewMsg = [mutableDict copy];
  521. [ChatsStore.shareInstance reciveMsg:NewMsg];
  522. if (loading) {
  523. loading(100);
  524. }
  525. }
  526. else{
  527. if (code>=0&&code<200) {
  528. if (loading) {
  529. loading(code);
  530. }
  531. }
  532. }
  533. } fail:^(NSError * _Nonnull error) {
  534. NSLog(@"error:%@",error);
  535. }];
  536. }
  537. }
  538. else{
  539. if (loading) {
  540. loading(0);
  541. }
  542. }
  543. }
  544. }
  545. -(void)setuploadPersent:(NSInteger)persent localtime:(NSInteger)localtime{
  546. if(self.uploadPersentChange && localtime==self.localtime){
  547. self.uploadPersentChange(persent,localtime);
  548. }
  549. }
  550. // 根据语音时长计算气泡宽度
  551. - (CGFloat)voiceBubbleWidth {
  552. // 基础宽度
  553. CGFloat minWidth = 60.0f;
  554. CGFloat maxWidth = 200.0f;
  555. // 最大限制时长(如60秒)
  556. NSInteger maxDuration = 60;
  557. NSInteger duration = MIN(self.voiceDuration, maxDuration);
  558. // 线性增长计算
  559. CGFloat width = minWidth + (maxWidth - minWidth) * (duration / (CGFloat)maxDuration);
  560. return width;
  561. }
  562. - (NSString *)getFileSize {
  563. NSString *filePath = self.localurl;
  564. NSFileManager *fileManager = [NSFileManager defaultManager];
  565. // 获取文件属性
  566. NSError *error = nil;
  567. NSDictionary *attributes = [fileManager attributesOfItemAtPath:filePath error:&error];
  568. NSString *string = @"0KB";
  569. if (error) {
  570. NSLog(@"获取文件属性失败: %@", error);
  571. } else {
  572. // 获取文件大小(单位:字节)
  573. unsigned long long fileSize = [attributes fileSize];
  574. NSLog(@"文件大小: %llu 字节", fileSize);
  575. // 可选:转换为 KB、MB
  576. double fileSizeKB = fileSize / 1024.0;
  577. double fileSizeMB = fileSizeKB / 1024.0;
  578. NSLog(@"文件大小: %.2f KB (%.2f MB)", fileSizeKB, fileSizeMB);
  579. string = [NSString stringWithFormat:@"%.2fMB", fileSizeMB];
  580. }
  581. return string;
  582. }
  583. - (NSString *)customFileSize {
  584. if (!_customFileSize) {
  585. _customFileSize = [self getFileSize];
  586. }
  587. return _customFileSize;
  588. }
  589. @end