ThreadWriteDBManager.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include "ThreadWriteDBManager.h"
  2. #include "GlobalInfo.h"
  3. #include "spdlog.h"
  4. #include "GlobalInfo.h"
  5. #include <mutex>
  6. #include <thread>
  7. ThreadWriteDBManager::~ThreadWriteDBManager()
  8. {
  9. }
  10. /* 线程工作函数 */
  11. void ThreadWriteDBManager::thread_task()
  12. {
  13. /* 初始化信息 */
  14. if(!initData())
  15. {
  16. SPDLOG_LOGGER_ERROR(m_logger, "写数据库线程初始化数据失败");
  17. return;
  18. }
  19. /* 设置标志位 */
  20. m_isRunning = true;
  21. m_isStop = false;
  22. m_threadState = EThreadState::State_Running;
  23. SPDLOG_LOGGER_INFO(m_logger, "✉ 写数据库线程开始运行");
  24. /* 运行线程功能 */
  25. task();
  26. /* 清理数据 */
  27. clearData();
  28. m_threadState = EThreadState::State_Stopped;
  29. m_isStop = true;
  30. SPDLOG_LOGGER_WARN(m_logger, "✉ 写数据库线程结束运行");
  31. }
  32. /* 停止线程 */
  33. void ThreadWriteDBManager::thread_stop()
  34. {
  35. m_isRunning = false; // 设置线程停止标志位
  36. }
  37. void ThreadWriteDBManager::thread_stopBlock()
  38. {
  39. thread_stop();
  40. while(m_threadState != EThreadState::State_Stopped) // 等待线程停止
  41. {
  42. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  43. }
  44. }
  45. /* 添加报警内容 */
  46. void ThreadWriteDBManager::addAlarmInfo(const AlarmInfo_t& alarmInfo)
  47. {
  48. std::lock_guard<std::mutex> lock(m_mutexListAlarm);
  49. m_listAlarm.push_back(alarmInfo);
  50. }
  51. void ThreadWriteDBManager::addAlarmInfo(const std::list<AlarmInfo_t>& listAlarm)
  52. {
  53. std::lock_guard<std::mutex> lock(m_mutexListAlarm);
  54. m_listAlarm.insert(m_listAlarm.end(), listAlarm.begin(), listAlarm.end());
  55. }
  56. /* 添加一致性报警信息,键为主通道信息,值为次通道信息 */
  57. void ThreadWriteDBManager::addAlarmInfo(const AlarmInfo_t& mainAlarm, const AlarmInfo_t& subAlarm)
  58. {
  59. std::lock_guard<std::mutex> lock(m_mutexListAlarmConsistency);
  60. m_listAlarmConsistency.push_back(std::make_pair(mainAlarm, subAlarm));
  61. }
  62. /* 录音文件写入数据库,isNewFile = true 是插入数据库,= false是更新数据库 */
  63. void ThreadWriteDBManager::addRecordFileInfo(std::list<RecordFileInfo_t>& listRecordFile, bool isNewFile)
  64. {
  65. std::lock_guard<std::mutex> lock(m_mutexListRecordFile);
  66. m_listRecordFile.insert(m_listRecordFile.end(), listRecordFile.begin(), listRecordFile.end());
  67. m_isRecordFileInsert.store(isNewFile);
  68. }
  69. /* 线程工作函数 */
  70. void ThreadWriteDBManager::task()
  71. {
  72. while(m_isRunning.load())
  73. {
  74. std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 每100毫秒执行一次
  75. /* 写入普通报警文件 */
  76. alarmInfoToDB();
  77. /* 写入一致性报警文件 */
  78. consistencyAlarmInfoToDB();
  79. /* 写录音文件信息到数据库 */
  80. recordFileInfoToDB();
  81. }
  82. }
  83. /* 初始化数据 */
  84. bool ThreadWriteDBManager::initData()
  85. {
  86. if(m_logger == nullptr)
  87. {
  88. m_logger = spdlog::get("WriteDB");
  89. if(m_logger == nullptr)
  90. {
  91. fmt::print("Alarm is nullptr");
  92. return false; // 日志记录器获取失败
  93. }
  94. }
  95. /* 登陆WebAPI */
  96. if(!m_fromWebAPI.initWebApi(GInfo.webAPIUrl(), GInfo.webAPIID(), GInfo.webApiAppType()))
  97. {
  98. SPDLOG_LOGGER_ERROR(m_logger, "报警信息处理线程登录WebAPI失败");
  99. return false;
  100. }
  101. SPDLOG_LOGGER_INFO(m_logger, "报警信息处理线程登录WebAPI成功");
  102. /* 获取文件存储的根目录 */
  103. m_strRootPath = GInfo.rootPath();
  104. if(m_strRootPath.endsWith('/'))
  105. {
  106. m_strRootPath.chop(1);
  107. }
  108. return true;
  109. }
  110. /* 清理数据 */
  111. void ThreadWriteDBManager::clearData()
  112. {
  113. }
  114. /* 普通报警写入数据库 */
  115. void ThreadWriteDBManager::alarmInfoToDB()
  116. {
  117. /* 普通的报警数据写入数据库 */
  118. std::list<AlarmInfo_t> listAlarm;
  119. {
  120. std::lock_guard<std::mutex> lock(m_mutexListAlarm);
  121. if(m_listAlarm.empty())
  122. {
  123. return; // 没有报警信息
  124. }
  125. listAlarm = std::move(m_listAlarm); // 移动报警信息列表
  126. m_listAlarm.clear(); // 清空报警列表
  127. }
  128. /* 处理报警路径 */
  129. for(auto& alarm : listAlarm)
  130. {
  131. processFilePath(alarm.strAlarmFilePath);
  132. }
  133. if(!m_fromWebAPI.insertAlarmInfo(listAlarm))
  134. {
  135. SPDLOG_LOGGER_ERROR(m_logger, "写入报警信息失败");
  136. }
  137. /* 清空报警列表 */
  138. listAlarm.clear();
  139. }
  140. /* 一致性报警写入数据库 */
  141. void ThreadWriteDBManager::consistencyAlarmInfoToDB()
  142. {
  143. /* 写入一致性报警信息 */
  144. std::list<std::pair<AlarmInfo_t, AlarmInfo_t>> listAlarmConsistency;
  145. {
  146. std::lock_guard<std::mutex> lock(m_mutexListAlarmConsistency);
  147. if(m_listAlarmConsistency.empty())
  148. {
  149. return; // 没有一致性报警信息
  150. }
  151. listAlarmConsistency = std::move(m_listAlarmConsistency); // 移动一致性报警信息列表
  152. m_listAlarmConsistency.clear(); // 清空一致性报警列表
  153. }
  154. /* 处理报警路径 */
  155. for(auto it = listAlarmConsistency.begin(); it != listAlarmConsistency.end(); ++it)
  156. {
  157. processFilePath(it->first.strAlarmFilePath);
  158. processFilePath(it->second.strAlarmFilePath);
  159. }
  160. for(const auto& alarmPair : listAlarmConsistency)
  161. {
  162. if(!m_fromWebAPI.insertConsistencyAlarmInfo(alarmPair.first, alarmPair.second))
  163. {
  164. SPDLOG_LOGGER_ERROR(m_logger, "写入一致性报警信息失败");
  165. }
  166. }
  167. /* 清空报警信息 */
  168. listAlarmConsistency.clear();
  169. }
  170. /* 录音文件写数据库 */
  171. void ThreadWriteDBManager::recordFileInfoToDB()
  172. {
  173. std::list<RecordFileInfo_t> listRecordFile;
  174. {
  175. std::lock_guard<std::mutex> lock(m_mutexListRecordFile);
  176. if(m_listRecordFile.empty())
  177. {
  178. return; // 没有录音文件信息
  179. }
  180. listRecordFile = std::move(m_listRecordFile); // 移动录音文件信息列表
  181. m_listRecordFile.clear();
  182. }
  183. /* 处理录音文件路径 */
  184. for(auto& recordFile : listRecordFile)
  185. {
  186. processFilePath(recordFile.FilePath);
  187. }
  188. if(m_isRecordFileInsert.load())
  189. {
  190. if(!m_fromWebAPI.insertRecordFileInfo(listRecordFile))
  191. {
  192. SPDLOG_LOGGER_ERROR(m_logger, "写入录音文件信息失败");
  193. }
  194. } else
  195. {
  196. if(!m_fromWebAPI.updateRecordFileInfo(listRecordFile))
  197. {
  198. SPDLOG_LOGGER_ERROR(m_logger, "更新录音文件信息失败");
  199. }
  200. }
  201. }
  202. /* 处理报警路径,去掉前面的本地路径,只保留服务自己创建的文件夹及之后的路径 */
  203. bool ThreadWriteDBManager::processFilePath(QString& strFilePath)
  204. {
  205. if(strFilePath.isEmpty())
  206. {
  207. return false;
  208. }
  209. /* 去掉前面的目录,只留下报警文件夹及之后的路径 */
  210. if(strFilePath.startsWith(m_strRootPath))
  211. {
  212. strFilePath = strFilePath.mid(m_strRootPath.length());
  213. if(!strFilePath.startsWith('/'))
  214. {
  215. strFilePath = '/' + strFilePath;
  216. }
  217. }
  218. return true;
  219. }