GDBManager.m 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. //
  2. // GDBManager.m
  3. // TUIContact
  4. //
  5. // Created by gan on 2025/3/24.
  6. //
  7. #import <Foundation/Foundation.h>
  8. #import "GDBManager.h"
  9. #import "UDManager.h"
  10. #import "FMDB.h"
  11. #import "config.h"
  12. @interface GDBManager ()
  13. {
  14. BOOL _isReadey;
  15. }
  16. @property (nonatomic, strong) FMDatabase *db;
  17. @property (nonatomic) BOOL isOpen;
  18. @end
  19. @implementation GDBManager
  20. + (GDBManager *_Nonnull)shareInstance{
  21. static id gShareInstance = nil;
  22. static dispatch_once_t onceToken;
  23. dispatch_once(&onceToken, ^{
  24. gShareInstance = [[self alloc] init];
  25. });
  26. return gShareInstance;
  27. }
  28. - (BOOL)isReadey {
  29. return _isReadey;
  30. }
  31. - (instancetype)init {
  32. if (self = [super init]) {
  33. self.isOpen = false;
  34. }
  35. return self;
  36. }
  37. -(BOOL)initDataBase {
  38. self.isOpen = [self createDatabase];
  39. BOOL msgTable = [self createLocalMSGtable];
  40. BOOL chatTable = [self createChatTable];
  41. BOOL readTable = [self createLastreadTimeTable];
  42. BOOL ret = self.isOpen && msgTable && chatTable && readTable;
  43. _isReadey = ret;
  44. if (ret) {
  45. [[NSNotificationCenter defaultCenter] postNotificationName:kOnDatabaseReadyNotice
  46. object:nil
  47. userInfo:nil];
  48. }
  49. return ret;
  50. }
  51. #pragma mark - Public -
  52. -(BOOL)createDatabase{
  53. // 数据库文件路径,这里使用文档目录下的数据库文件,确保数据持久化
  54. NSString *docsDir;
  55. NSArray *dirPaths;
  56. // 获取文档目录路径
  57. dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  58. docsDir = [dirPaths objectAtIndex:0];
  59. NSString *dbPath = [[docsDir stringByAppendingPathComponent:locateDB] stringByStandardizingPath];
  60. // 创建数据库实例,如果数据库文件不存在,则会自动创建该文件
  61. self.db = [FMDatabase databaseWithPath:dbPath];
  62. if (![self.db open]) {
  63. NSLog(@"数据库打开失败: %@", [self.db lastErrorMessage]);
  64. return NO;
  65. }
  66. self.isOpen = true;
  67. return YES;
  68. }
  69. -(void)closeDB{
  70. [self.db close];
  71. self.isOpen = false;
  72. }
  73. -(void)deleteDB{
  74. // 数据库文件路径,这里使用文档目录下的数据库文件,确保数据持久化
  75. [self closeDB];
  76. NSString *docsDir;
  77. NSArray *dirPaths;
  78. // 获取文档目录路径
  79. dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  80. docsDir = [dirPaths objectAtIndex:0];
  81. NSString *dbPath = [[docsDir stringByAppendingPathComponent:locateDB] stringByStandardizingPath];
  82. NSError *error;
  83. NSFileManager *fileManager = [NSFileManager defaultManager];
  84. BOOL success = [fileManager removeItemAtPath:dbPath error:&error];
  85. if (success) {
  86. NSLog(@"文件删除成功");
  87. self.isOpen = false;
  88. } else {
  89. NSLog(@"文件删除失败: %@", error.localizedDescription);
  90. }
  91. }
  92. -(void)replayAllData{
  93. int lowerBound = 10;
  94. int upperBound = 30;
  95. int randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  96. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  97. for (NSInteger i = 0; i<randomInt; i++) {
  98. [self delLocalmsglistTable:userid];
  99. [self createLocalMSGtable];
  100. NSUUID *uid = [NSUUID UUID];
  101. NSDate *now = [NSDate date];
  102. NSTimeInterval trt = [now timeIntervalSince1970];
  103. NSInteger time = trt*1000;
  104. NSString *strtime = [NSString stringWithFormat:@"%ld",(long)time];
  105. NSDictionary *dic =@{
  106. @"id":strtime,
  107. @"messageType":MessageType_image,
  108. @"chatId":[NSString stringWithFormat:@"%d",randomInt],
  109. @"fromId":userid,
  110. @"fromName":userid,
  111. @"fromAvatar":@"Avatar",
  112. @"reSend":[NSNumber numberWithBool:false],
  113. @"content":uid.UUIDString,
  114. @"type":@"0",
  115. @"localtime":strtime,
  116. @"timestamp":strtime,
  117. @"mine":[NSNumber numberWithBool:YES],
  118. @"extend":@{
  119. @"url":uid.UUIDString,
  120. @"time":strtime,
  121. @"localurl":uid.UUIDString,
  122. }
  123. };
  124. [self insertLocalmsg:dic succ:nil fail:nil];
  125. NSLog(@"delLocalmsglistTable:%ld",(long)i);
  126. }
  127. randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  128. for (NSInteger i = 0; i<randomInt; i++) {
  129. [self delchatlistTable:nil fail:nil];
  130. [self createChatTable];
  131. NSUUID *uid = [NSUUID UUID];
  132. NSDate *now = [NSDate date];
  133. NSTimeInterval trt = [now timeIntervalSince1970];
  134. NSInteger time = trt*1000;
  135. NSString *strtime = [NSString stringWithFormat:@"%ld",(long)time];
  136. NSDictionary *chatD=@{
  137. @"id":strtime,
  138. @"name":userid,
  139. @"avatar":@"avatar",
  140. @"type":@"0",
  141. @"lastMessage":uid.UUIDString,
  142. @"lastTime":strtime,
  143. @"unreadCount":[NSString stringWithFormat:@"%ld",(long)i],
  144. @"loaded":@"",
  145. @"loading":@"",
  146. @"top":@"true",
  147. };
  148. [self insertLocalchat:chatD succ:nil fail:nil];
  149. NSLog(@"delchatlistTable:%ld",(long)i);
  150. }
  151. randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  152. for (NSInteger i = 0; i<randomInt; i++) {
  153. [self createLastreadTimeTable];
  154. [self deleatLastreadtimetable];
  155. NSLog(@"deleatLastreadtimetable:%ld",(long)i);
  156. }
  157. randomInt = lowerBound + arc4random() % (upperBound - lowerBound + 1);
  158. for (NSInteger i = 0; i<randomInt; i++) {
  159. [self deleteDB];
  160. [self createDatabase];
  161. NSLog(@"deleteDB:%ld",(long)i);
  162. }
  163. }
  164. //创建消息表
  165. -(BOOL)createLocalMSGtable{
  166. // 创建表语句
  167. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  168. NSString *sql1=@"create table if not exists lcmsglist_";
  169. NSString *tablejg = @"(id CHAR PRIMARY KEY,chatId CHAR,type CHAR,messageType CHAR,timestamp BIGINT,localtime BIGINT,Message TEXT)";
  170. NSString *sql = [NSString stringWithFormat:@"%@%@ %@",sql1,userid,tablejg];
  171. //NSLog(@"sql:%@",sql);
  172. BOOL success = [self.db executeUpdate:sql];
  173. if (!success) {
  174. NSLog(@"创建消息表失败: %@", [self.db lastErrorMessage]);
  175. } else {
  176. NSLog(@"创建消息表成功");
  177. }
  178. return success;
  179. }
  180. -(void)delLocalmsglistTable:(NSString *)userid{//删除消息表
  181. NSString *sql1=@"DROP TABLE lcmsglist_";
  182. NSString *sql = [NSString stringWithFormat:@"%@%@",sql1,userid];
  183. BOOL success = [self.db executeUpdate:sql];
  184. if (!success) {
  185. NSLog(@"删除消息表失败: %@", [self.db lastErrorMessage]);
  186. } else {
  187. NSLog(@"删除消息表成功");
  188. }
  189. }
  190. -(void)insertLocalmsg:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//插入消息
  191. NSString *vstr = @"insert into lcmsglist_";
  192. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  193. NSDictionary * safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  194. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" ('id','chatId','type','messageType','timestamp','localtime','Message') values ("];
  195. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"id"]];
  196. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"chatId"]];
  197. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"type"]];
  198. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"messageType"]];
  199. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"timestamp"]];
  200. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"localtime"]];
  201. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:msg options:0 error:nil];
  202. NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  203. vstr=[NSString stringWithFormat:@"%@'%@'%@",vstr,jsonString,@")"];
  204. // NSLog(@"vstr:%@",vstr);
  205. BOOL success = [self.db executeUpdate:vstr];
  206. if (!success) {
  207. if(fail){
  208. fail([NSString stringWithFormat:@"插入消息表失败: %@", [self.db lastErrorMessage]]);
  209. }
  210. NSLog(@"插入消息表失败: %@", [self.db lastErrorMessage]);
  211. } else {
  212. NSLog(@"插入消息表成功");
  213. if (succ) {
  214. succ(nil);
  215. }
  216. }
  217. }
  218. -(void)insertRplaceLocalmsg:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//插入消息
  219. if (![self.db isOpen]) {
  220. return;
  221. }
  222. // 1. 参数校验
  223. if (!msg || msg.count == 0) {
  224. if (fail) fail(@"消息内容不能为空");
  225. return;
  226. }
  227. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  228. if (userid.length == 0) {
  229. if (fail) fail(@"用户ID获取失败");
  230. return;
  231. }
  232. NSString *tableName = [NSString stringWithFormat:@"lcmsglist_%@", userid];
  233. NSDictionary *safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  234. // 2. 处理localtime
  235. NSString *localtime = [NSString stringWithFormat:@"%@", safeDict[@"localtime"]];
  236. // if (localtime.length == 0) {
  237. // localtime = safeDict[@"timestamp"];
  238. // }
  239. // 2. 处理图片文件视频消息可能存在乱序问题
  240. NSString *msgtype = safeDict[@"messageType"];
  241. BOOL urlMark = true;
  242. if([msgtype isEqualToString:MessageType_image]||[msgtype isEqualToString:MessageType_file]||[msgtype isEqualToString:MessageType_video]){
  243. // 文件消息
  244. NSDictionary * extend = [safeDict[@"extend"] isKindOfClass:NSDictionary.class]?safeDict[@"extend"]:@{};
  245. NSString *url=extend[@"url"] ?: @"";
  246. if(url.length==0){
  247. urlMark=false;//不是正式真实消息尝试插入,不能删除已有的信息
  248. }
  249. NSString *fileEER = extend[@"fileError"] ?: @"";
  250. if(fileEER.intValue==1){
  251. urlMark=true;//不是正式真实消息尝试插入,不能删除已有的信息
  252. }
  253. }
  254. // 3. 开启事务
  255. [self.db beginTransaction];
  256. BOOL shouldRollback = NO;
  257. @try {
  258. // NSLog(@"删除旧数据(localtime=%@)", localtime);
  259. NSString *selctSQL = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE localtime = %@ AND (messageType='11' OR messageType='12')",tableName,localtime];
  260. FMResultSet *rs = [self.db executeQuery:selctSQL];
  261. BOOL markesel=NO;
  262. while ([rs next]) {
  263. //NSLog(@"rs:%@",rs);
  264. NSString *msg =[rs stringForColumn:@"Message"];
  265. NSLog(@"--------rsmsg:%@",msg);
  266. markesel=YES;
  267. break;
  268. }
  269. [rs close]; // 关闭结果集
  270. if(markesel){
  271. [self.db commit];
  272. return;
  273. }
  274. if(urlMark){//删除旧数据,以便更新信息
  275. NSLog(@"删除旧数据(2localtime=%@)", localtime);
  276. // 4. 删除相同localtime的旧数据
  277. NSString *deleteSQL = [NSString stringWithFormat:
  278. @"DELETE FROM %@ WHERE localtime = ?",
  279. tableName];
  280. if (![self.db executeUpdate:deleteSQL, localtime]) {
  281. NSLog(@"删除旧数据失败(localtime=%@): %@", localtime, [self.db lastErrorMessage]);
  282. // 不终止,继续尝试插入
  283. }
  284. }
  285. // 5. 准备插入数据
  286. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:safeDict options:0 error:nil];
  287. NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  288. NSString *insertSQL = [NSString stringWithFormat:
  289. @"INSERT INTO %@ (id,chatId,type,messageType,timestamp,localtime,Message) VALUES (?,?,?,?,?,?,?)",
  290. tableName];
  291. // 6. 执行插入
  292. BOOL success = [self.db executeUpdate:insertSQL,
  293. safeDict[@"id"],
  294. safeDict[@"chatId"],
  295. safeDict[@"type"],
  296. safeDict[@"messageType"],
  297. safeDict[@"timestamp"],
  298. localtime,
  299. jsonString];
  300. if (!success) {
  301. shouldRollback = YES;
  302. NSString *error = [NSString stringWithFormat:@"插入消息失败: %@", [self.db lastErrorMessage]];
  303. if (fail) fail(error);
  304. } else {
  305. [self.db commit];
  306. if (succ) succ(nil);
  307. // NSLog(@"消息插入成功(ID=%@)", safeDict);
  308. }
  309. }
  310. @catch (NSException *exception) {
  311. shouldRollback = YES;
  312. NSString *error = [NSString stringWithFormat:@"操作异常: %@", exception.reason];
  313. if (fail) fail(error);
  314. }
  315. @finally {
  316. if (shouldRollback) {
  317. [self.db rollback];
  318. }
  319. }
  320. }
  321. - (void)batchInsertLocalMessages:(NSArray<NSDictionary *> *)messages
  322. success:(DBSucc _Nullable)succ
  323. failure:(DBFail _Nullable)fail {
  324. if (![self.db isOpen]) {
  325. return;
  326. }
  327. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  328. NSString *tableName = [NSString stringWithFormat:@"lcmsglist_%@", userid];
  329. // 开启事务
  330. [self.db beginTransaction];
  331. NSMutableArray *failedMessages = [NSMutableArray array];
  332. BOOL hasErrors = NO;
  333. @try {
  334. // 准备SQL语句(使用参数化查询,避免SQL注入)
  335. NSString *insertSQL = [NSString stringWithFormat:
  336. @"INSERT INTO %@ ('id','chatId','type','messageType','timestamp','localtime','Message') VALUES (?,?,?,?,?,?,?)",
  337. tableName];
  338. for (NSDictionary *msg in messages) {
  339. NSDictionary *safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  340. NSString *localtime = [NSString stringWithFormat:@"%@", safeDict[@"localtime"]];
  341. NSString *selctSQL = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE localtime = %@ AND (messageType='11' OR messageType='12')",tableName,localtime];
  342. FMResultSet *rs = [self.db executeQuery:selctSQL];
  343. BOOL markesel=NO;
  344. while ([rs next]) {
  345. //NSLog(@"rs:%@",rs);
  346. NSString *msg =[rs stringForColumn:@"Message"];
  347. // NSLog(@"--------rsmsg:%@",msg);
  348. markesel=YES;
  349. break;
  350. }
  351. [rs close]; // 关闭结果集
  352. if(markesel){
  353. continue;
  354. }
  355. NSString *deleteSQL = [NSString stringWithFormat:
  356. @"DELETE FROM %@ WHERE localtime = ?",
  357. tableName];
  358. if (![self.db executeUpdate:deleteSQL, localtime]) {
  359. // NSLog(@"batchInsertLocalMessages 删除旧数据失败(localtime=%@): %@", localtime, [self.db lastErrorMessage]);
  360. // 不终止,继续尝试插入
  361. }
  362. else{
  363. // NSLog(@"batchInsertLocalMessages 删除旧数据(localtime=%@): %@", localtime, [self.db lastErrorMessage]);
  364. }
  365. // 准备Message字段的JSON字符串
  366. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:safeDict options:0 error:nil];
  367. NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  368. // 执行插入(使用参数化查询)
  369. BOOL success = [self.db executeUpdate:insertSQL,
  370. safeDict[@"id"],
  371. safeDict[@"chatId"],
  372. safeDict[@"type"],
  373. safeDict[@"messageType"],
  374. safeDict[@"timestamp"],
  375. safeDict[@"localtime"],
  376. jsonString];
  377. if (!success) {
  378. hasErrors = YES;
  379. // 记录失败的消息
  380. // 继续下一条
  381. continue;
  382. }
  383. }
  384. // 提交事务
  385. [self.db commit];
  386. NSLog(@"批量插入消息完成,成功 %lu 条,失败 %lu 条",
  387. (unsigned long)(messages.count - failedMessages.count),
  388. (unsigned long)failedMessages.count);
  389. if (succ) {
  390. // 如果有失败记录,返回失败信息
  391. if (failedMessages.count > 0) {
  392. succ(@[@{
  393. @"successCount": @(messages.count - failedMessages.count),
  394. @"failedCount": @(failedMessages.count),
  395. @"failedMessages": failedMessages
  396. }]);
  397. } else {
  398. succ(nil);
  399. }
  400. }
  401. }
  402. @catch (NSException *exception) {
  403. [self.db rollback];
  404. NSString *error = [NSString stringWithFormat:@"批量插入本地异常: %@", exception.reason];
  405. if (fail) {
  406. fail(error);
  407. }
  408. NSLog(@"%@", error);
  409. }
  410. }
  411. -(void)selectLocalmsg:(NSString *_Nonnull)chatId page:(NSInteger)page succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//查询消息
  412. // 查询数据
  413. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  414. NSString *vstr = @"select * from lcmsglist_";
  415. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  416. vstr=[NSString stringWithFormat:@"%@%@",vstr,chatId];
  417. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  418. // NSLog(@"vstr:%@",vstr);
  419. FMResultSet *rs = [self.db executeQuery:vstr];
  420. NSMutableArray *array=[[NSMutableArray alloc] init];
  421. while ([rs next]) {
  422. //NSLog(@"rs:%@",rs);
  423. NSString *msg =[rs stringForColumn:@"Message"];
  424. //NSLog(@"msg:%@",msg);
  425. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  426. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  427. // NSLog(@"%@",jsonDict);
  428. // Message *msgobj = [[Message alloc] init];
  429. // [msgobj setValuesWithDictionary:jsonDict];
  430. [array addObject:jsonDict];
  431. }
  432. [rs close]; // 关闭结果集
  433. if(succ){
  434. succ(array);
  435. }
  436. }
  437. -(void)selectnextmsg:(NSString *_Nonnull)chatId timestp:(NSInteger)timestp succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//查询消息
  438. // 查询数据
  439. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  440. NSString *vstr = @"select * from lcmsglist_";
  441. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  442. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,chatId,@" AND timestamp < "];
  443. vstr=[NSString stringWithFormat:@"%@%ld",vstr,(long)timestp];
  444. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  445. // NSLog(@"vstr:%@",vstr);
  446. FMResultSet *rs = [self.db executeQuery:vstr];
  447. NSMutableArray *array=[[NSMutableArray alloc] init];
  448. while ([rs next]) {
  449. //NSLog(@"rs:%@",rs);
  450. NSString *msg =[rs stringForColumn:@"Message"];
  451. //NSLog(@"msg:%@",msg);
  452. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  453. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  454. // NSLog(@"%@",jsonDict);
  455. // Message *msgobj = [[Message alloc] init];
  456. // [msgobj setValuesWithDictionary:jsonDict];
  457. [array addObject:jsonDict];
  458. }
  459. [rs close]; // 关闭结果集
  460. if(succ){
  461. succ(array);
  462. }
  463. }
  464. -(void)deleteMyLocalmsg:(NSDictionary *)msg{//删除单个消息 DELETE FROM users WHERE id IN (100, 101);
  465. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  466. NSString *vstr = @"DELETE FROM lcmsglist_";
  467. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" WHERE id=="];
  468. vstr=[NSString stringWithFormat:@"%@%@",vstr,msg[@"localtime"]];
  469. BOOL success = [self.db executeUpdate:vstr];
  470. if (!success) {
  471. NSLog(@"删除消息表失败: %@", [self.db lastErrorMessage]);
  472. } else {
  473. NSLog(@"删除消息表成功");
  474. }
  475. }
  476. -(void)deleteLocalmsg:(NSDictionary *_Nullable)msg{
  477. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  478. NSString *vstr = @"DELETE FROM lcmsglist_";
  479. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" WHERE id=="];
  480. vstr=[NSString stringWithFormat:@"%@%@",vstr,msg[@"id"]];
  481. BOOL success = [self.db executeUpdate:vstr];
  482. if (!success) {
  483. NSLog(@"删除指定消息: %@", [self.db lastErrorMessage]);
  484. } else {
  485. NSLog(@"删除指定消息成功");
  486. }
  487. }
  488. //删除数据指定聊天窗消息
  489. -(void)deletechatLocalmsg:(NSString *_Nullable)chatId{
  490. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  491. // 开启事务
  492. [self.db beginTransaction];
  493. @try {
  494. NSString *updataSQL =[NSString stringWithFormat:@"UPDATE lcmsglist_%@ SET Message=? WHERE chatId = ?",userid];
  495. // 执行插入(使用参数化查询)
  496. NSUUID *uid = [NSUUID UUID];
  497. BOOL success = [self.db executeUpdate:updataSQL,
  498. uid.UUIDString,
  499. chatId];
  500. // 提交事务
  501. [self.db commit];
  502. if (!success) {
  503. NSLog(@"更新数据失败: %@", [self.db lastErrorMessage]);
  504. } else {
  505. NSLog(@"更新数据成功");
  506. }
  507. NSString *vstr = [NSString stringWithFormat:@"DELETE FROM lcmsglist_%@ WHERE chatId=%@",userid,chatId];
  508. success = [self.db executeUpdate:vstr];
  509. if (!success) {
  510. NSLog(@"删除指定消息: %@", [self.db lastErrorMessage]);
  511. } else {
  512. NSLog(@"删除指定消息成功");
  513. }
  514. }
  515. @catch (NSException *exception) {
  516. [self.db rollback];
  517. NSString *error = [NSString stringWithFormat:@"lcUserServer插入本地异常: %@", exception.reason];
  518. NSLog(@"%@", error);
  519. }
  520. }
  521. -(void)selectLocalmsgType:(NSString *)chatId messageType:(NSString *)messageType succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//按分类查询消息
  522. // 查询数据
  523. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  524. NSString *vstr = @"select * from lcmsglist_";
  525. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  526. vstr=[NSString stringWithFormat:@"%@%@ AND messageType=",vstr,chatId];
  527. vstr=[NSString stringWithFormat:@"%@%@",vstr,messageType];
  528. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  529. //NSLog(@"vstr:%@",vstr);
  530. FMResultSet *rs = [self.db executeQuery:vstr];
  531. NSMutableArray *array=[[NSMutableArray alloc] init];
  532. while ([rs next]) {
  533. //NSLog(@"rs:%@",rs);
  534. NSString *msg =[rs stringForColumn:@"Message"];
  535. //NSLog(@"msg:%@",msg);
  536. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  537. if (data) {
  538. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  539. [array addObject:jsonDict];
  540. }
  541. }
  542. [rs close]; // 关闭结果集
  543. if(succ){
  544. succ(array);
  545. }
  546. }
  547. -(void)selectNextmsgType:(NSString *_Nullable)chatId messageType:(NSString *_Nullable)messageType timestp:(NSInteger)timestp succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  548. // 查询数据
  549. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  550. NSString *vstr = @"select * from lcmsglist_";
  551. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where chatId = "];
  552. vstr=[NSString stringWithFormat:@"%@%@ AND messageType=",vstr,chatId];
  553. vstr=[NSString stringWithFormat:@"%@%@ AND timestamp < ",vstr,messageType];
  554. vstr=[NSString stringWithFormat:@"%@%ld",vstr,(long)timestp];
  555. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY timestamp DESC LIMIT 16;"];
  556. NSLog(@"vstr:%@",vstr);
  557. FMResultSet *rs = [self.db executeQuery:vstr];
  558. NSMutableArray *array=[[NSMutableArray alloc] init];
  559. while ([rs next]) {
  560. //NSLog(@"rs:%@",rs);
  561. NSString *msg =[rs stringForColumn:@"Message"];
  562. //NSLog(@"msg:%@",msg);
  563. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  564. if (data) {
  565. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  566. [array addObject:jsonDict];
  567. }
  568. }
  569. [rs close]; // 关闭结果集
  570. if(succ){
  571. succ(array);
  572. }
  573. }
  574. //根据本地时间查询本地消息
  575. -(void)selectLocalmsgWithLocaltime:(NSString *_Nullable)localtime succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  576. // 查询数据
  577. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  578. NSString *vstr = @"select * from lcmsglist_";
  579. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" where localtime = "];
  580. vstr=[NSString stringWithFormat:@"%@%@",vstr,localtime];;
  581. NSLog(@"vstr:%@",vstr);
  582. FMResultSet *rs = [self.db executeQuery:vstr];
  583. NSMutableArray *array=[[NSMutableArray alloc] init];
  584. while ([rs next]) {
  585. //NSLog(@"rs:%@",rs);
  586. NSString *msg =[rs stringForColumn:@"Message"];
  587. //NSLog(@"msg:%@",msg);
  588. NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
  589. if (data) {
  590. NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
  591. [array addObject:jsonDict];
  592. }
  593. }
  594. [rs close]; // 关闭结果集
  595. if(succ){
  596. succ(array);
  597. }
  598. }
  599. //聊天窗表lcChatlist_
  600. -(BOOL)createChatTable {
  601. // 创建表语句
  602. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  603. NSString *sql1=@"create table if not exists lcChatlist_";
  604. NSString *tablejg = @"(id CHAR PRIMARY KEY,name CHAR,avatar CHAR,type CHAR,lastMessage TEXT,lastTime BIGINT,unreadCount int,loaded int,loading int,top int)";
  605. NSString *sql = [NSString stringWithFormat:@"%@%@ %@",sql1,userid,tablejg];
  606. BOOL success = [self.db executeUpdate:sql];
  607. if (!success) {
  608. NSLog(@"创建lcChatlist_表失败: %@", [self.db lastErrorMessage]);
  609. } else {
  610. NSLog(@"创建lcChatlist_表成功");
  611. }
  612. return success;
  613. }
  614. -(void)delchatlistTable:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{//删除聊天窗表lcChatlist_
  615. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  616. NSString *sql1=@"DROP TABLE lcChatlist_";
  617. NSString *sql = [NSString stringWithFormat:@"%@%@",sql1,userid];
  618. BOOL success = [self.db executeUpdate:sql];
  619. if (!success) {
  620. NSLog(@"删除lcChatlist_表失败: %@", [self.db lastErrorMessage]);
  621. if(fail){
  622. fail([NSString stringWithFormat:@"创建消息表失败: %@", [self.db lastErrorMessage]]);
  623. }
  624. } else {
  625. NSLog(@"删除lcChatlist_表成功");
  626. if (succ) {
  627. succ(nil);
  628. }
  629. }
  630. }
  631. -(void)insertLocalchat:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  632. NSString *vstr = @"INSERT OR REPLACE INTO lcChatlist_";
  633. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  634. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" ('id','name','avatar','type','lastMessage','lastTime','unreadCount','loaded','loading','top') values ("];
  635. NSDictionary * safeDict = [self replaceNullsWithEmptyStringInDictionary:msg];
  636. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"id"]];
  637. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"name"]];
  638. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"avatar"]];
  639. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"type"]];
  640. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"lastMessage"]];
  641. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"lastTime"]];
  642. vstr=[NSString stringWithFormat:@"%@%@,",vstr,safeDict[@"unreadCount"]];
  643. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"loaded"]];
  644. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,safeDict[@"loading"]];
  645. vstr=[NSString stringWithFormat:@"%@'%@')",vstr,safeDict[@"top"]];
  646. // NSLog(@"vstr:%@",vstr);
  647. BOOL success = [self.db executeUpdate:vstr];
  648. if (!success) {
  649. if(fail){
  650. fail([NSString stringWithFormat:@"插入消息表失败: %@", [self.db lastErrorMessage]]);
  651. }
  652. //NSLog(@"插入消息表失败: %@", [self.db lastErrorMessage]);
  653. } else {
  654. // NSLog(@"插入消息表成功 insertLocalchat");
  655. if (succ) {
  656. succ(nil);
  657. }
  658. }
  659. }
  660. -(void)selectLocalchats:(NSString *)top succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  661. // 查询数据
  662. NSString *vstr = @"select * from lcChatlist_";
  663. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  664. vstr=[NSString stringWithFormat:@"%@%@",vstr,userid];
  665. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"where top="];
  666. vstr=[NSString stringWithFormat:@"%@%@",vstr,top];
  667. vstr=[NSString stringWithFormat:@"%@ %@",vstr,@"ORDER BY 'lastTime' ASC"];
  668. NSLog(@"vstr:%@",vstr);
  669. FMResultSet *rs = [self.db executeQuery:vstr];
  670. NSMutableArray *array=[[NSMutableArray alloc] init];
  671. while ([rs next]) {
  672. NSDictionary *chatD=@{
  673. @"id":[rs stringForColumn:@"id"],
  674. @"name":[rs stringForColumn:@"name"],
  675. @"avatar":[rs stringForColumn:@"avatar"],
  676. @"type":[rs stringForColumn:@"type"],
  677. @"lastMessage":[rs stringForColumn:@"lastMessage"],
  678. @"lastTime":[rs stringForColumn:@"lastTime"],
  679. @"unreadCount":[rs stringForColumn:@"unreadCount"],
  680. @"loaded":[rs stringForColumn:@"loaded"],
  681. @"loading":[rs stringForColumn:@"loading"],
  682. @"top":[rs stringForColumn:@"top"]
  683. };
  684. [array addObject:chatD];
  685. }
  686. [rs close]; // 关闭结果集
  687. if(succ){
  688. succ(array);
  689. }
  690. }
  691. - (void)deleteChatListItem:(NSDictionary *_Nonnull)item succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  692. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  693. NSString *vstr = @"DELETE FROM lcChatlist_";
  694. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" WHERE id="];
  695. vstr=[NSString stringWithFormat:@"%@%@",vstr,item[@"id"]];
  696. BOOL success = [self.db executeUpdate:vstr];
  697. if (!success) {
  698. NSLog(@"删除消息表失败: %@", [self.db lastErrorMessage]);
  699. if(fail){
  700. fail([NSString stringWithFormat:@"删除消息表失败: %@", [self.db lastErrorMessage]]);
  701. }
  702. } else {
  703. int changes = [self.db changes];
  704. if (changes > 0) {
  705. NSLog(@"成功删除 %d 条记录", changes);
  706. if (succ) {
  707. succ(nil);
  708. }
  709. } else {
  710. NSLog(@"没有匹配的记录被删除");
  711. }
  712. }
  713. }
  714. //聊天窗最后已读时间表
  715. -(BOOL)createLastreadTimeTable {
  716. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  717. NSString *sql1=@"create table if not exists lcChatlasttime_";
  718. NSString *tablejg = @"(chatId CHAR PRIMARY KEY,userId CHAR,timestamp BIGINT,type CHAR)";
  719. NSString *sql = [NSString stringWithFormat:@"%@%@ %@",sql1,userid,tablejg];
  720. BOOL success = [self.db executeUpdate:sql];
  721. if (!success) {
  722. NSLog(@"创建lcChatlasttime_表失败: %@", [self.db lastErrorMessage]);
  723. } else {
  724. NSLog(@"创建lcChatlasttime_表成功");
  725. }
  726. return success;
  727. }
  728. -(void)deleatLastreadtimetable{
  729. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  730. NSString *sql1=@"DROP TABLE lcChatlasttime_";
  731. NSString *sql = [NSString stringWithFormat:@"%@%@",sql1,userid];
  732. BOOL success = [self.db executeUpdate:sql];
  733. if (!success) {
  734. NSLog(@"删除lcChatlasttime_表失败: %@", [self.db lastErrorMessage]);
  735. } else {
  736. NSLog(@"删除lcChatlasttime_表成功");
  737. }
  738. }
  739. -(void)insertLastreadtime:(NSDictionary *_Nonnull)msg succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  740. NSString *vstr = @"INSERT OR REPLACE INTO lcChatlasttime_";
  741. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  742. vstr=[NSString stringWithFormat:@"%@%@%@",vstr,userid,@" ('chatId','userId','timestamp','type') values ("];
  743. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,msg[@"chatId"]];
  744. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,msg[@"userId"]];
  745. vstr=[NSString stringWithFormat:@"%@'%@',",vstr,msg[@"timestamp"]];
  746. vstr=[NSString stringWithFormat:@"%@'%@')",vstr,msg[@"type"]];
  747. NSLog(@"vstr:%@",vstr);
  748. BOOL success = [self.db executeUpdate:vstr];
  749. if (!success) {
  750. if(fail){
  751. fail([NSString stringWithFormat:@"插入Lastreadtime表失败: %@", [self.db lastErrorMessage]]);
  752. }
  753. NSLog(@"插入消息表失败: %@", [self.db lastErrorMessage]);
  754. } else {
  755. NSLog(@"插入Lastreadtime表成功 insertLocalchat");
  756. if (succ) {
  757. succ(nil);
  758. }
  759. }
  760. }
  761. -(void)selectchatLastreadtime:(NSString *_Nonnull)chatId succ:(DBSucc _Nullable )succ fail:(DBFail _Nullable )fail{
  762. // 查询数据
  763. NSString *vstr = @"select * from lcChatlasttime_";
  764. NSString *userid = [UDManager.shareInstance getSDManager:dkuserId];
  765. vstr=[NSString stringWithFormat:@"%@%@",vstr,userid];
  766. vstr=[NSString stringWithFormat:@"%@ %@%@",vstr,@"where userId=",chatId];
  767. NSLog(@"vstr:%@",vstr);
  768. FMResultSet *rs = [self.db executeQuery:vstr];
  769. NSMutableArray *array=[[NSMutableArray alloc] init];
  770. while ([rs next]) {
  771. NSDictionary *chatD=@{
  772. @"chatId":[rs stringForColumn:@"chatId"],
  773. @"userId":[rs stringForColumn:@"userId"],
  774. @"timestamp":[rs stringForColumn:@"timestamp"],
  775. @"type":[rs stringForColumn:@"type"]
  776. };
  777. [array addObject:chatD];
  778. }
  779. [rs close]; // 关闭结果集
  780. if(succ){
  781. succ(array);
  782. }
  783. }
  784. // 递归替换字典中的 NSNull 为 @""
  785. - (NSDictionary *)replaceNullsWithEmptyStringInDictionary:(NSDictionary *)dictionary {
  786. NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:dictionary];
  787. for (id key in [mutableDict allKeys]) {
  788. id value = [mutableDict objectForKey:key];
  789. if ([value isKindOfClass:[NSNull class]]) {
  790. [mutableDict setObject:@"" forKey:key];
  791. } else if ([value isKindOfClass:[NSDictionary class]]) {
  792. // 递归处理子字典
  793. [mutableDict setObject:[self replaceNullsWithEmptyStringInDictionary:value] forKey:key];
  794. } else if ([value isKindOfClass:[NSArray class]]) {
  795. // 递归处理数组
  796. [mutableDict setObject:[self replaceNullsWithEmptyStringInArray:value] forKey:key];
  797. }
  798. }
  799. return [NSDictionary dictionaryWithDictionary:mutableDict];
  800. }
  801. // 递归替换数组中的 NSNull 为 @""
  802. - (NSArray *)replaceNullsWithEmptyStringInArray:(NSArray *)array {
  803. NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
  804. for (NSInteger i = 0; i < [mutableArray count]; i++) {
  805. id value = [mutableArray objectAtIndex:i];
  806. if ([value isKindOfClass:[NSNull class]]) {
  807. [mutableArray replaceObjectAtIndex:i withObject:@""];
  808. } else if ([value isKindOfClass:[NSDictionary class]]) {
  809. // 递归处理子字典
  810. [mutableArray replaceObjectAtIndex:i withObject:[self replaceNullsWithEmptyStringInDictionary:value]];
  811. } else if ([value isKindOfClass:[NSArray class]]) {
  812. // 递归处理子数组
  813. [mutableArray replaceObjectAtIndex:i withObject:[self replaceNullsWithEmptyStringInArray:value]];
  814. }
  815. }
  816. return [NSArray arrayWithArray:mutableArray];
  817. }
  818. @end