#include "ThreadWriteDBManager.h" #include "GlobalInfo.h" #include "spdlog.h" #include "GlobalInfo.h" #include #include ThreadWriteDBManager::~ThreadWriteDBManager() { } /* 线程工作函数 */ void ThreadWriteDBManager::thread_task() { /* 初始化信息 */ if(!initData()) { SPDLOG_LOGGER_ERROR(m_logger, "写数据库线程初始化数据失败"); return; } /* 设置标志位 */ m_isRunning = true; m_isStop = false; m_threadState = EThreadState::State_Running; SPDLOG_LOGGER_INFO(m_logger, "✉ 写数据库线程开始运行"); /* 运行线程功能 */ task(); /* 清理数据 */ clearData(); m_threadState = EThreadState::State_Stopped; m_isStop = true; SPDLOG_LOGGER_WARN(m_logger, "✉ 写数据库线程结束运行"); } /* 停止线程 */ void ThreadWriteDBManager::thread_stop() { m_isRunning = false; // 设置线程停止标志位 } void ThreadWriteDBManager::thread_stopBlock() { thread_stop(); while(m_threadState != EThreadState::State_Stopped) // 等待线程停止 { std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } /* 添加报警内容 */ void ThreadWriteDBManager::addAlarmInfo(const AlarmInfo_t& alarmInfo) { std::lock_guard lock(m_mutexListAlarm); m_listAlarm.push_back(alarmInfo); } void ThreadWriteDBManager::addAlarmInfo(const std::list& listAlarm) { std::lock_guard lock(m_mutexListAlarm); m_listAlarm.insert(m_listAlarm.end(), listAlarm.begin(), listAlarm.end()); } /* 添加一致性报警信息,键为主通道信息,值为次通道信息 */ void ThreadWriteDBManager::addAlarmInfo(const AlarmInfo_t& mainAlarm, const AlarmInfo_t& subAlarm) { std::lock_guard lock(m_mutexListAlarmConsistency); m_listAlarmConsistency.push_back(std::make_pair(mainAlarm, subAlarm)); } /* 录音文件写入数据库,isNewFile = true 是插入数据库,= false是更新数据库 */ void ThreadWriteDBManager::addRecordFileInfo(std::list& listRecordFile, bool isNewFile) { std::lock_guard lock(m_mutexListRecordFile); m_listRecordFile.insert(m_listRecordFile.end(), listRecordFile.begin(), listRecordFile.end()); m_isRecordFileInsert.store(isNewFile); } /* 线程工作函数 */ void ThreadWriteDBManager::task() { while(m_isRunning.load()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 每100毫秒执行一次 /* 写入普通报警文件 */ alarmInfoToDB(); /* 写入一致性报警文件 */ consistencyAlarmInfoToDB(); /* 写录音文件信息到数据库 */ recordFileInfoToDB(); } } /* 初始化数据 */ bool ThreadWriteDBManager::initData() { if(m_logger == nullptr) { m_logger = spdlog::get("WriteDB"); if(m_logger == nullptr) { fmt::print("Alarm is nullptr"); return false; // 日志记录器获取失败 } } /* 登陆WebAPI */ if(!m_fromWebAPI.initWebApi(GInfo.webAPIUrl(), GInfo.webAPIID(), GInfo.webApiAppType())) { SPDLOG_LOGGER_ERROR(m_logger, "报警信息处理线程登录WebAPI失败"); return false; } SPDLOG_LOGGER_INFO(m_logger, "报警信息处理线程登录WebAPI成功"); /* 获取文件存储的根目录 */ m_strRootPath = GInfo.rootPath(); if(m_strRootPath.endsWith('/')) { m_strRootPath.chop(1); } return true; } /* 清理数据 */ void ThreadWriteDBManager::clearData() { } /* 普通报警写入数据库 */ void ThreadWriteDBManager::alarmInfoToDB() { /* 普通的报警数据写入数据库 */ std::list listAlarm; { std::lock_guard lock(m_mutexListAlarm); if(m_listAlarm.empty()) { return; // 没有报警信息 } listAlarm = std::move(m_listAlarm); // 移动报警信息列表 m_listAlarm.clear(); // 清空报警列表 } /* 处理报警路径 */ for(auto& alarm : listAlarm) { processFilePath(alarm.strAlarmFilePath); } if(!m_fromWebAPI.insertAlarmInfo(listAlarm)) { SPDLOG_LOGGER_ERROR(m_logger, "写入报警信息失败"); } /* 清空报警列表 */ listAlarm.clear(); } /* 一致性报警写入数据库 */ void ThreadWriteDBManager::consistencyAlarmInfoToDB() { /* 写入一致性报警信息 */ std::list> listAlarmConsistency; { std::lock_guard lock(m_mutexListAlarmConsistency); if(m_listAlarmConsistency.empty()) { return; // 没有一致性报警信息 } listAlarmConsistency = std::move(m_listAlarmConsistency); // 移动一致性报警信息列表 m_listAlarmConsistency.clear(); // 清空一致性报警列表 } /* 处理报警路径 */ for(auto it = listAlarmConsistency.begin(); it != listAlarmConsistency.end(); ++it) { processFilePath(it->first.strAlarmFilePath); processFilePath(it->second.strAlarmFilePath); } for(const auto& alarmPair : listAlarmConsistency) { if(!m_fromWebAPI.insertConsistencyAlarmInfo(alarmPair.first, alarmPair.second)) { SPDLOG_LOGGER_ERROR(m_logger, "写入一致性报警信息失败"); } } /* 清空报警信息 */ listAlarmConsistency.clear(); } /* 录音文件写数据库 */ void ThreadWriteDBManager::recordFileInfoToDB() { std::list listRecordFile; { std::lock_guard lock(m_mutexListRecordFile); if(m_listRecordFile.empty()) { return; // 没有录音文件信息 } listRecordFile = std::move(m_listRecordFile); // 移动录音文件信息列表 m_listRecordFile.clear(); } /* 处理录音文件路径 */ for(auto& recordFile : listRecordFile) { processFilePath(recordFile.FilePath); } if(m_isRecordFileInsert.load()) { if(!m_fromWebAPI.insertRecordFileInfo(listRecordFile)) { SPDLOG_LOGGER_ERROR(m_logger, "写入录音文件信息失败"); } } else { if(!m_fromWebAPI.updateRecordFileInfo(listRecordFile)) { SPDLOG_LOGGER_ERROR(m_logger, "更新录音文件信息失败"); } } } /* 处理报警路径,去掉前面的本地路径,只保留服务自己创建的文件夹及之后的路径 */ bool ThreadWriteDBManager::processFilePath(QString& strFilePath) { if(strFilePath.isEmpty()) { return false; } /* 去掉前面的目录,只留下报警文件夹及之后的路径 */ if(strFilePath.startsWith(m_strRootPath)) { strFilePath = strFilePath.mid(m_strRootPath.length()); if(!strFilePath.startsWith('/')) { strFilePath = '/' + strFilePath; } } return true; }