Sfoglia il codice sorgente

V1.3
1、修复了所有的bug,提交了测试

Apple 2 settimane fa
parent
commit
66ec909823

+ 3 - 0
SQL/ACAServer.sql

@@ -157,3 +157,6 @@ FROM tACASoundCardPCMChannels;
 UPDATE tACASoundCardPCMChannels
 SET SoundCardDriver = @soundCardDriver, PCMName = @pcmName, PCMDesc = @pcmDesc, SoundCardNum = @soundCardNum, SoundCardName = @soundCardName, SoundCardRoadNum = @soundCardRoadNum
 WHERE PKID = @pkid;
+
+DELETE FROM tACACompareItems
+WHERE ItemID = :itemID;

+ 2 - 2
SQL/CreateProcedures.sqlbook

@@ -69,7 +69,7 @@ BEGIN
         ItemID, ItemName, AlarmType, SoundCardName, SoundCardPCMName, CompareRoadNum, CompareRoadName, CompareRoadType,
         AlarmStartTime, AlarmEndTime, AlarmDuration, AlarmFilePath, FileAlarmStartPos, FileState
     ) VALUES (
-        itemID1, itemName1, alarmType1, soundCardPCMName1, soundCardRoadNum1, compareRoadNum1, compareRoadName1, compareRoadType1,
+        itemID1, itemName1, alarmType1, soundCardName1, soundCardPCMName1, compareRoadNum1, compareRoadName1, compareRoadType1,
         alarmStartTime1, alarmEndTime1, alarmDuration1, alarmFilePath1, fileAlarmStartPos1, fileState1
     );
     SELECT MAX(PKID) INTO pkid FROM tACAAlarmInfo;
@@ -77,7 +77,7 @@ BEGIN
         ItemID, ItemName, AlarmType, SoundCardName, SoundCardPCMName, CompareRoadNum, CompareRoadName, CompareRoadType,
         AlarmStartTime, AlarmEndTime, AlarmDuration, AlarmFilePath, FileAlarmStartPos, MainRoadPKID, FileState
     ) VALUES (
-        itemID2, itemName2, alarmType2, soundCardName2, soundCardRoadNum2, soundCardPCMName2, compareRoadName2, compareRoadType2,
+        itemID2, itemName2, alarmType2, soundCardName2, soundCardPCMName2, compareRoadNum2, compareRoadName2, compareRoadType2,
         alarmStartTime2, alarmEndTime2, alarmDuration2, alarmFilePath2, fileAlarmStartPos2, pkid, fileState2
     );
 END

+ 27 - 31
SQL/CreateTable-GBase.sqlbook

@@ -142,21 +142,20 @@ CREATE TABLE tACAAlarmInfo
     PKID SERIAL NOT NULL,
     ItemID INTEGER NOT NULL,
     ItemName VARCHAR(64) NOT NULL,
-    AlarmType INTEGER NOT NULL, -- 报警类型,1-静音,2-过载,3-反相,4-噪音,5-不一致
-    SoundCardName VARCHAR(64), -- 声卡名称
-    SoundCardPCMName VARCHAR(64) NOT NULL, -- 声卡PCM通道名称
-    CompareRoadNum INTEGER NOT NULL, -- 对比通道编号
-    CompareRoadName VARCHAR(64), -- 对比通道名称
-    CompareRoadType INTEGER, -- 通道类型:1、主输出,2、空收,3、主输出空收
-    AlarmStartTime VARCHAR(32), -- 报警开始时间 (格式:YYYY-MM-DD HH:MM:SS)
-    AlarmEndTime VARCHAR(32), -- 报警结束时间 (格式:YYYY-MM-DD HH:MM:SS)
-    AlarmDuration INTEGER, -- 报警持续时间(秒数)
-    AlarmFilePath VARCHAR(256), -- 报警录音文件路径
-    FileAlarmStartPos INTEGER, -- 在报警录音文件中报警开始的时间
-    MainRoadPKID INTEGER, -- 主通道的PKID
-    FileState INTEGER DEFAULT 0, -- 报警文件状态,1-录音中,2-已录音,3-已删除
-    CONSTRAINT tACAAlarmInfo PRIMARY KEY (PKID),
-    FOREIGN KEY (ItemID) REFERENCES tACACompareItems(ItemID)
+    AlarmType INTEGER NOT NULL,             -- 报警类型,1-静音,2-过载,3-反相,4-不一致,5-噪音
+    SoundCardName VARCHAR(64),              -- 声卡名称
+    SoundCardPCMName VARCHAR(64) NOT NULL,  -- 声卡PCM通道名称
+    CompareRoadNum INTEGER NOT NULL,        -- 对比通道编号
+    CompareRoadName VARCHAR(64),            -- 对比通道名称
+    CompareRoadType INTEGER,                -- 通道类型:1、主输出,2、空收,3、主输出空收
+    AlarmStartTime DATETIME YEAR TO FRACTION(5), -- 报警开始时间 (格式:YYYY-MM-DD HH:MM:SS)
+    AlarmEndTime DATETIME YEAR TO FRACTION(5), -- 报警结束时间 (格式:YYYY-MM-DD HH:MM:SS)
+    AlarmDuration INTEGER,                  -- 报警持续时间(秒数)
+    AlarmFilePath VARCHAR(256),             -- 报警录音文件路径
+    FileAlarmStartPos INTEGER,              -- 在报警录音文件中报警开始的时间
+    MainRoadPKID INTEGER,                   -- 主通道的PKID
+    FileState INTEGER DEFAULT 0,            -- 报警文件状态,1-录音中,2-已录音,3-已删除
+    CONSTRAINT tACAAlarmInfo PRIMARY KEY (PKID)
 )
 -- 表注释
 COMMENT ON TABLE tACAAlarmInfo IS 'ACA报警记录表';
@@ -164,7 +163,7 @@ COMMENT ON TABLE tACAAlarmInfo IS 'ACA报警记录表';
 COMMENT ON COLUMN tACAAlarmInfo.PKID IS '主键ID';
 COMMENT ON COLUMN tACAAlarmInfo.ItemID IS '对比项ID';
 COMMENT ON COLUMN tACAAlarmInfo.ItemName IS '对比项名称';
-COMMENT ON COLUMN tACAAlarmInfo.AlarmType IS '报警类型,1-静音,2-过载,3-反相,4-噪音,5-不一致';
+COMMENT ON COLUMN tACAAlarmInfo.AlarmType IS '报警类型,1-静音,2-过载,3-反相,4-不一致,5-噪音';
 COMMENT ON COLUMN tACAAlarmInfo.SoundCardName IS '声卡名称';
 COMMENT ON COLUMN tACAAlarmInfo.SoundCardPCMName IS '声卡PCM通道名称';
 COMMENT ON COLUMN tACAAlarmInfo.CompareRoadNum IS '对比通道编号';
@@ -188,21 +187,18 @@ CREATE INDEX idx_tACAAlarmInfo_AlarmEndTime ON tACAAlarmInfo (AlarmEndTime);
 CREATE TABLE tACARecordFile
 (
     PKID SERIAL NOT NULL,
-    ItemID INTEGER NOT NULL,                -- 对比项ID
-    ItemName VARCHAR(64) NOT NULL,    -- 对比项名称
-    ItemRoadNum INTEGER NOT NULL,           -- 通道编号
-    ItemRoadName VARCHAR(64) NOT NULL, -- 通道名称
-    SoundCardName VARCHAR(64) ,          -- 声卡名称
-    SoundCardPCMName VARCHAR(64) NOT NULL,      -- 声卡PCM通道名称
-    FileStartTime VARCHAR(32) NOT NULL, -- 录音开始时间 (格式:YYYY-MM-DD HH:MM:SS)
-    FileEndTime VARCHAR(32) NOT NULL,   -- 录音结束时间 (格式: YYYY-MM-DD HH:MM:SS)
-    FileDuration INTEGER NOT NULL,          -- 录音文件持续时间(秒数)
-    FilePath VARCHAR(256) NOT NULL,     -- 录音文件路径
-    FileState INTEGER DEFAULT 0,            -- 录音文件状态,0-未知状态,1-正在录音,2-录音完成,3-文件已删除
-
-    PRIMARY KEY (PKID),
-    FOREIGN KEY (ItemID) REFERENCES tACACompareItems(ItemID)
-        ON DELETE CASCADE
+    ItemID INTEGER NOT NULL,                            -- 对比项ID
+    ItemName VARCHAR(64) NOT NULL,                      -- 对比项名称
+    ItemRoadNum INTEGER NOT NULL,                       -- 通道编号
+    ItemRoadName VARCHAR(64) NOT NULL,                  -- 通道名称
+    SoundCardName VARCHAR(64) ,                         -- 声卡名称
+    SoundCardPCMName VARCHAR(64) NOT NULL,              -- 声卡PCM通道名称
+    FileStartTime DATETIME YEAR TO FRACTION(5) NOT NULL, -- 录音开始时间 (格式:YYYY-MM-DD HH:MM:SS)
+    FileEndTime DATETIME YEAR TO FRACTION(5) NOT NULL,   -- 录音结束时间 (格式: YYYY-MM-DD HH:MM:SS)
+    FileDuration INTEGER NOT NULL,                      -- 录音文件持续时间(秒数)
+    FilePath VARCHAR(256) NOT NULL,                     -- 录音文件路径
+    FileState INTEGER DEFAULT 0,                        -- 录音文件状态,0-未知状态,1-正在录音,2-录音完成,3-文件已删除
+    PRIMARY KEY (PKID)
 );
 
 -- 表注释

+ 27 - 25
SQL/CreateTable-达梦.sqlbook

@@ -48,10 +48,16 @@ COMMENT ON COLUMN tACACompareItems.PhaseSensitivity IS '反相灵敏度';
 -- CREATE INDEX idx_tACACompareItems_ItemName ON tACACompareItems (ItemName);
 
 -- SQLBook: Code
+-- Active: 1752718919967@@192.1.2.61@5236@EQM_CESHI
 #删除 tACACompareItems
 DROP TABLE IF EXISTS "EQM_CESHI".tACACompareItems;
+
+#删除 tACAAlarmInfo
+DROP TABLE IF EXISTS "EQM_CESHI".tACAAlarmInfo;
+
+#删除 tACARecordFile
+DROP TABLE IF EXISTS "EQM_CESHI".tACARecordFile;
 -- SQLBook: Code
--- Active: 1752920752747@@192.1.2.61@5236@EQM_CESHI
 
 #创建 tACACompareItemRoad
 #这里设置了级联删除,当 tACACompareItems 表中的某个对比项被删除时,tACACompareItemRoad 中对应的通道也会被删除。
@@ -139,6 +145,7 @@ COMMENT ON COLUMN tACADetectPeriod.ApplyNoise IS '是否应用噪音检测';
 -- 创建索引
 CREATE INDEX idx_tACADetectPeriod_ItemID ON tACADetectPeriod (ItemID);
 -- SQLBook: Code
+-- Active: 1752718919967@@192.1.2.61@5236@EQM_CESHI
 -- Active: 1752920752747@@192.1.2.61@5236@EQM_CESHI
 #创建报警记录表
 CREATE TABLE tACAAlarmInfo
@@ -146,20 +153,20 @@ CREATE TABLE tACAAlarmInfo
     PKID INT PRIMARY KEY AUTO_INCREMENT,
     ItemID INT NOT NULL,
     ItemName VARCHAR(64) NOT NULL,
-    AlarmType INT NOT NULL, -- 报警类型,1-静音,2-过载,3-反相,4-噪音,5-不一致
-    SoundCardName VARCHAR(64), -- 声卡名称
+    AlarmType INT NOT NULL,             -- 报警类型,1-静音,2-过载,3-反相,4-不一致,5-噪音
+    SoundCardName VARCHAR(64),          -- 声卡名称
     SoundCardPCMName VARCHAR(64) NOT NULL, -- 声卡PCM通道名称
-    CompareRoadNum INT NOT NULL, -- 对比通道编号
-    CompareRoadName VARCHAR(64), -- 对比通道名称
-    CompareRoadType INT, -- 通道类型:1、主输出,2、空收,3、主输出空收
-    AlarmStartTime VARCHAR(32), -- 报警开始时间 (格式:YYYY-MM-DD HH:MM:SS)
-    AlarmEndTime VARCHAR(32), -- 报警结束时间 (格式:YYYY-MM-DD HH:MM:SS)
-    AlarmDuration INT, -- 报警持续时间(秒数)
-    AlarmFilePath VARCHAR(256), -- 报警录音文件路径
-    FileAlarmStartPos int, -- 在报警录音文件中报警开始的时间
-    MainRoadPKID INT, -- 主通道的PKID
-    FileState INT DEFAULT 0, -- 报警文件状态,1-录音中,2-已录音,3-已删除
-    FOREIGN KEY (ItemID) REFERENCES tACACompareItems(ItemID)
+    CompareRoadNum INT NOT NULL,        -- 对比通道编号
+    CompareRoadName VARCHAR(64),        -- 对比通道名称
+    CompareRoadType INT,                -- 通道类型:1、主输出,2、空收,3、主输出空收
+    AlarmStartTime TIMESTAMP(6),        -- 报警开始时间 (格式:YYYY-MM-DD HH:MM:SS)
+    AlarmEndTime TIMESTAMP(6),          -- 报警结束时间 (格式:YYYY-MM-DD HH:MM:SS)
+    AlarmDuration INT,                  -- 报警持续时间(秒数)
+    AlarmFilePath VARCHAR(256),         -- 报警录音文件路径
+    FileAlarmStartPos int,              -- 在报警录音文件中报警开始的时间
+    MainRoadPKID INT,                   -- 主通道的PKID
+    FileState INT DEFAULT 0             -- 报警文件状态,1-录音中,2-已录音,3-已删除
+    -- FOREIGN KEY (ItemID) REFERENCES tACACompareItems(ItemID)
 )
 
 -- 表注释
@@ -168,7 +175,7 @@ COMMENT ON TABLE tACAAlarmInfo IS 'ACA报警记录表';
 COMMENT ON COLUMN tACAAlarmInfo.PKID IS '主键ID';
 COMMENT ON COLUMN tACAAlarmInfo.ItemID IS '对比项ID';
 COMMENT ON COLUMN tACAAlarmInfo.ItemName IS '对比项名称';
-COMMENT ON COLUMN tACAAlarmInfo.AlarmType IS '报警类型,1-静音,2-过载,3-反相,4-噪音,5-不一致';
+COMMENT ON COLUMN tACAAlarmInfo.AlarmType IS '报警类型,1-静音,2-过载,3-反相,4-不一致,5-噪音';
 COMMENT ON COLUMN tACAAlarmInfo.SoundCardName IS '声卡名称';
 COMMENT ON COLUMN tACAAlarmInfo.SoundCardPCMName IS '声卡PCM通道名称';
 COMMENT ON COLUMN tACAAlarmInfo.CompareRoadNum IS '对比通道编号';
@@ -188,10 +195,7 @@ CREATE INDEX idx_tACAAlarmInfo_AlarmType ON tACAAlarmInfo (AlarmType);
 CREATE INDEX idx_tACAAlarmInfo_CompareRoadNum ON tACAAlarmInfo (CompareRoadNum);
 CREATE INDEX idx_tACAAlarmInfo_AlarmStartTime ON tACAAlarmInfo (AlarmStartTime);
 CREATE INDEX idx_tACAAlarmInfo_AlarmEndTime ON tACAAlarmInfo (AlarmEndTime);
-
 -- SQLBook: Code
--- Active: 1752920752747@@192.1.2.61@5236@EQM_CESHI
--- Active: 1752718919967@@192.1.2.61@5236@EQM_CESHI
 #创建记录录音文件的表格
 CREATE TABLE tACARecordFile
 (
@@ -202,14 +206,13 @@ CREATE TABLE tACARecordFile
     ItemRoadName VARCHAR(64) NOT NULL,      -- 通道名称
     SoundCardName VARCHAR(64) NOT NULL,     -- 声卡名称
     SoundCardPCMName VARCHAR(64) NOT NULL,  -- 声卡PCM通道编号
-    FileStartTime VARCHAR(32) NOT NULL,     -- 录音开始时间 (格式:YYYY-MM-DD HH:MM:SS)
-    FileEndTime VARCHAR(32) NOT NULL,       -- 录音结束时间 (格式: YYYY-MM-DD HH:MM:SS)
+    FileStartTime TIMESTAMP(6) NOT NULL,     -- 录音开始时间 (格式:YYYY-MM-DD HH:MM:SS)
+    FileEndTime TIMESTAMP(6) NOT NULL,       -- 录音结束时间 (格式: YYYY-MM-DD HH:MM:SS)
     FileDuration INT NOT NULL,              -- 录音文件持续时间(秒数)
     FilePath VARCHAR(256) NOT NULL,         -- 录音文件路径
-    FileState INT DEFAULT 0,                -- 录音文件状态,0-未知状态,1-正在录音,2-录音完成,3-文件已删除
-
-    FOREIGN KEY (ItemID) REFERENCES tACACompareItems(ItemID)
-        ON DELETE CASCADE
+    FileState INT DEFAULT 0                 -- 录音文件状态,0-未知状态,1-正在录音,2-录音完成,3-文件已删除
+    -- FOREIGN KEY (ItemID) REFERENCES tACACompareItems(ItemID)
+    --     ON DELETE CASCADE
 );
 
 -- 表注释
@@ -235,7 +238,6 @@ CREATE INDEX idx_tACARecordFile_FileEndTime ON tACARecordFile (FileEndTime);
 CREATE INDEX idx_tACARecordFile_FileDuration ON tACARecordFile (FileDuration);
 
 
-
 -- SQLBook: Code
 #创建存储声卡PCM通道的表格
 CREATE TABLE tACASoundCardPCMChannels

+ 2 - 5
Server/CMakeLists.txt

@@ -32,7 +32,6 @@ file(GLOB LOCAL_SRC
     ${CMAKE_SOURCE_DIR}/common/Network/*.cpp
     ${CMAKE_SOURCE_DIR}/common/GlobalInfo/*.cpp
 
-    ${CMAKE_SOURCE_DIR}/External/common/WebAPI/*.cpp
     ${CMAKE_SOURCE_DIR}/External/common/Thread/*.cpp
 
     ${CMAKE_SOURCE_DIR}/External/module/Logs/*.cpp
@@ -40,7 +39,7 @@ file(GLOB LOCAL_SRC
     ${CMAKE_SOURCE_DIR}/External/module/mqtt/*.cpp
     
     
-    ${LHHTTPAPI_SOURCE_DIRS}/*.cpp
+    ${LHHTTPAPI_SOURCE_DIRS}
     ${LHQLog_SOURCE_DIRS}/*.cpp
 )
 
@@ -82,7 +81,6 @@ target_include_directories(${this_exe} PRIVATE
     ${CMAKE_SOURCE_DIR}/common/GlobalInfo
     
     ${CMAKE_SOURCE_DIR}/External/common
-    ${CMAKE_SOURCE_DIR}/External/common/WebAPI
     ${CMAKE_SOURCE_DIR}/External/common/Thread
     
     ${CMAKE_SOURCE_DIR}/External/module
@@ -95,7 +93,6 @@ target_include_directories(${this_exe} PRIVATE
     ${CMAKE_SOURCE_DIR}/ThreeLib/signalstats/include
     
 
-    ${spdlog_INCLUDE_DIR}
     ${LHQLog_INCLUDE_DIRS}
     ${LHHTTPAPI_INCLUDE_DIRS}
     ${qmqtt_INCLUDE_DIR}
@@ -113,8 +110,8 @@ target_link_libraries(${this_exe} PRIVATE
 )
 
 target_link_libraries(${this_exe} PRIVATE 
-    ${spdlog_LIBRARY}
     ${qmqtt_LIBRARY}
+    External::spdlog
     libsignalstats.so
     asound
 )

+ 134 - 2
Server/ThreadCalculate/CalculateDBThread.cpp

@@ -96,8 +96,14 @@ void CalculateDBThread::task()
         return;
     }
     SPDLOG_LOGGER_INFO(m_logger, " ★ {} 开启计算静音、过载和反相等报警的线程 ", m_logBase);
-    while(m_isRunning)
+    while(true)
     {
+        /* 先判断是否退出线程 */
+        if(m_isRunning == false)
+        {
+            endAllAlarm();
+            break;
+        }
         std::this_thread::sleep_for(std::chrono::milliseconds(10));
 
         // std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
@@ -128,7 +134,7 @@ void CalculateDBThread::task()
     /* 清理数据 */
     clearData();
 
-    SPDLOG_LOGGER_INFO(m_logger, "★ {} 计算静音、过载和反相等报警的线程结束 ", m_logBase);
+    SPDLOG_LOGGER_WARN(m_logger, "★ {} 计算静音、过载和反相等报警的线程结束 ", m_logBase);
 }
 
 /* 初始化数据 */
@@ -576,6 +582,131 @@ void CalculateDBThread::processPhase()
 }
 
 
+/* 结束静音报警 */
+void CalculateDBThread::endSilenceAlarm()
+{
+    /* 这次不是静音,判断静音报警是否已经开启 */
+    if(m_alarmSilence.isAlarm)
+    {
+        /* 静音报警已经开启,结束静音报警 */
+        if(m_silentEndPos > 0)
+        {
+            auto endData = m_caculateDBData.ringQueue.at(m_silentEndPos);
+            if(endData != nullptr)
+            {
+                m_alarmSilence.EndTime = endData->endTime.addSecs(- m_volumeParam.GetSilentDuration());
+            }
+        }else 
+        {
+            m_alarmSilence.EndTime = m_currSecondData.endTime.addSecs(- m_volumeParam.GetSilentDuration());
+        }
+        /* 保存报警信息 */
+        // m_alarmLastSilence = m_alarmSilence;
+        
+        /* 停止录制报警音频 */
+        if(!m_threadCreateAlarmFile->stopRecordAlarmFile(m_alarmSilence))
+        {
+            SPDLOG_LOGGER_WARN(m_logger, "{} 停止录制静音报警音频失败", m_logBase);
+        }
+        /* 设置录音状态 */
+        m_alarmSilence.fileState = eRecordState::eRS_RecordCompleted;
+        /* 将报警信息发送给写入报警信息的线程 */
+        WriteDB.addAlarmInfo(m_alarmSilence);
+        /* 打印日志 */
+        SPDLOG_LOGGER_INFO(m_logger, "{} 静音报警结束,开始时间:{},结束时间:{}",
+            m_logBase, 
+            m_alarmSilence.StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(),
+            m_alarmSilence.EndTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
+        /* 清空报警信息 */
+        m_alarmSilence = AlarmInfo_t();
+    }
+}
+
+/* 结束过载报警 */
+void CalculateDBThread::endOverloadAlarm()
+{
+    /* 这次不是过载,判断过载报警是否已经开启 */
+    if(m_alarmOverload.isAlarm)
+    {
+        /* 过载报警已经开启,结束过载报警 */
+        if(m_overloadEndPos > 0)
+        {
+            auto endData = m_caculateDBData.ringQueue.at(m_overloadEndPos);
+            if(endData != nullptr)
+            {
+                m_alarmOverload.EndTime = endData->endTime.addSecs(- m_volumeParam.GetOverloadDuration());
+            }
+        }else 
+        {
+            m_alarmOverload.EndTime = m_currSecondData.endTime.addSecs(- m_volumeParam.GetOverloadDuration());
+        }
+        /* 保存报警信息 */
+        // m_alarmLastOverload = m_alarmOverload;
+        
+        /* 停止录制报警音频 */
+        if(!m_threadCreateAlarmFile->stopRecordAlarmFile(m_alarmOverload))
+        {
+            SPDLOG_LOGGER_WARN(m_logger, "{} 停止录制过载报警音频失败", m_logBase);
+        }
+        /* 设置录音状态 */
+        m_alarmOverload.fileState = eRecordState::eRS_RecordCompleted;
+        /* 将报警信息发送给写入报警信息的线程 */
+        WriteDB.addAlarmInfo(m_alarmOverload);
+        /* 打印日志 */
+        SPDLOG_LOGGER_INFO(m_logger, "{} 过载报警结束,开始时间:{},结束时间:{}",
+            m_logBase, 
+            m_alarmOverload.StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(),
+            m_alarmOverload.EndTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
+        
+        /* 清空报警信息 */
+        m_alarmOverload = AlarmInfo_t();
+    }
+}
+
+/* 结束反相报警 */
+void CalculateDBThread::endPhaseAlarm()
+{
+    /* 这次不是反相,判断反相报警是否已经开启 */
+    if(m_alarmPhase.isAlarm)
+    {
+        /* 反相报警已经开启,结束反相报警 */
+        if(m_phaseEndPos > 0)
+        {
+            auto endData = m_caculateDBData.ringQueue.at(m_phaseEndPos);
+            if(endData != nullptr)
+            {
+                m_alarmPhase.EndTime = endData->endTime.addSecs(- m_volumeParam.GetPhaseDuration());
+            }
+        }else 
+        {
+            m_alarmPhase.EndTime = m_currSecondData.endTime.addSecs(- m_volumeParam.GetPhaseDuration());
+        }
+        /* 保存报警信息 */
+        // m_alarmLastPhase = m_alarmPhase;
+        
+        /* 停止录制报警音频 */
+        if(!m_threadCreateAlarmFile->stopRecordAlarmFile(m_alarmPhase))
+        {
+            SPDLOG_LOGGER_WARN(m_logger, "{} 停止录制反相报警音频失败", m_logBase);
+        }
+        /* 设置录音状态 */
+        m_alarmPhase.fileState = eRecordState::eRS_RecordCompleted;
+        /* 将报警信息发送给写入报警信息的线程 */
+        WriteDB.addAlarmInfo(m_alarmPhase);
+
+        /* 打印日志 */
+        SPDLOG_LOGGER_INFO(m_logger, "{} 反相报警结束,开始时间:{},结束时间:{}",
+            m_logBase, 
+            m_alarmPhase.StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(),
+            m_alarmPhase.EndTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
+        
+        /* 清空报警信息 */
+        m_alarmPhase = AlarmInfo_t();
+    }
+}
+
+
+
 /* 结束所有的报警 */
 void CalculateDBThread::endAllAlarm()
 {
@@ -583,6 +714,7 @@ void CalculateDBThread::endAllAlarm()
     m_roadVolumeInfo.isOverload = false;
     m_roadVolumeInfo.isReversed = false;
 
+    /* 发送结束报警的信息 */
     processAlarm();
 }
 

+ 7 - 0
Server/ThreadCalculate/CalculateDBThread.h

@@ -66,6 +66,13 @@ private:
     /* 处理反相报警 */
     void processPhase();
 
+    /* 结束静音报警 */
+    void endSilenceAlarm();
+    /* 结束过载报警 */
+    void endOverloadAlarm();
+    /* 结束反相报警 */
+    void endPhaseAlarm();
+    
     /* 结束所有的报警 */
     void endAllAlarm();
 

+ 5 - 1
Server/ThreadCalculate/CompareItemThread.cpp

@@ -156,6 +156,7 @@ void CompareItemThread::setDetectPeriod(const DetectPeriodConfig_t& detectPeriod
     }
     m_detectPeriod = detectPeriod;
     // m_isDetectPeriodUpdated = true; // 标记检测时段已更新
+    m_isHasDetectPlan.store(true);
 }
 
 
@@ -325,6 +326,8 @@ void CompareItemThread::clearData()
         if(!ThreadMan.removeRecordThread(roadInfo, m_threadInfo.compareItemInfo.nID))
         {
             SPDLOG_LOGGER_ERROR(m_logger, "{} 移除录音通道 {}:{} 失败", m_logBase, roadInfo.strSoundCardName, roadInfo.pcmInfo.strPCMName);
+        }else {
+            SPDLOG_LOGGER_INFO(m_logger, "{} 移除录音通道 {}:{} 成功", m_logBase, roadInfo.strSoundCardName, roadInfo.pcmInfo.strPCMName);
         }
     }
 
@@ -346,6 +349,7 @@ void CompareItemThread::do_timeout()
     if(m_isRunning == false)
     {
         stop_thread();
+        return;
     }
     // std::chrono::steady_clock::time_point startTime = std::chrono::steady_clock::now();
     // SPDLOG_LOGGER_WARN(m_logger, "{} 定时器触发,开始执行定时任务", m_logBase);
@@ -922,7 +926,7 @@ bool CompareItemThread::checkDetectPeriod()
         /* 先判断是否有符合的周几 */
         if(static_cast<int>(period.weekType) == currentWeekday)
         {
-            /* 判断一种特殊情况,开始时间和结束时间都是“00:00:00”,这个是全天都检测 */
+            /* 判断一种特殊情况,开始时间和结束时间都是“ 00:00:00 ”,这个是全天都检测 */
             if(period.timeStart == allDayTime && period.timeEnd == allDayTime)
             {
                 isInDetectPeriod = true;

+ 3 - 1
Server/ThreadCalculate/CompareItemThread.h

@@ -61,7 +61,8 @@ public:
 
     /* 设置检测时段 */
     void setDetectPeriod(const DetectPeriodConfig_t& detectPeriod);
-
+    /* 获取标志位 */
+    bool isHadDetectPlan() { return m_isHasDetectPlan.load(); }
 
 protected:
     /* 线程功能函数,未使用这个函数 */
@@ -169,6 +170,7 @@ private:
     // std::atomic_bool m_isDetectPeriodUpdated = false; /* 检测时段更新标志 */
     DetectPeriodConfig_t m_detectPeriod;    /* 检测时段配置 */
     QDateTime m_lastDetectPeriodUpdateTime; /* 上次检测时段更新时间 */
+    std::atomic_bool m_isHasDetectPlan = false; /* 是否有检测计划,对比项刚启动的时候是false,后续都是true */
 
     /* 噪音检测参数 */
     NoiseDetectBaseConfig_t m_noiseDetectConfig;

+ 17 - 9
Server/ThreadCalculate/ConsistencyCompareThread.cpp

@@ -115,8 +115,20 @@ void ConsistencyCompareThread::task()
     bool isConsistency = true;
 #endif 
 
-    while(m_isRunning)
+    while(true)
     {
+        /* 判断是否需要退出线程 */
+        if(m_isRunning == false)
+        {
+            /* 如果此时还在非一致性报警中,结束报警 */
+            if(m_alarmConsistencyMain.isAlarm || m_alarmConsistencySub.isAlarm)
+            {
+                endAlarm();
+            }
+            /* 退出线程 */
+            break;
+        }
+
         std::this_thread::sleep_for(std::chrono::milliseconds(100));
 
         /* 判断是否开启不一致检测 */
@@ -426,7 +438,7 @@ void ConsistencyCompareThread::endAlarm()
         /* 之前在一致性报警中,这次一致,结束不一致性报警 */
         m_alarmConsistencyMain.isAlarm = false;
         m_alarmConsistencySub.isAlarm = false;
-        /* 结束时间向推1秒 */
+        /* 结束时间向推1秒 */
         m_alarmConsistencyMain.EndTime = m_wavFilePath1.endDateTime.addSecs(1);
         m_alarmConsistencySub.EndTime = m_wavFilePath2.endDateTime.addSecs(1);
         /* 结束录制报警音频 */
@@ -436,16 +448,12 @@ void ConsistencyCompareThread::endAlarm()
         m_alarmConsistencyMain.fileState = eRecordState::eRS_RecordCompleted;
         m_alarmConsistencySub.fileState = eRecordState::eRS_RecordCompleted;
         /* 将报警信息写入数据库 */
-        WriteDB.addAlarmInfo(m_alarmConsistencyMain);
-        WriteDB.addAlarmInfo(m_alarmConsistencySub);
+        WriteDB.addAlarmInfo(m_alarmConsistencyMain, m_alarmConsistencySub);
         
-        SPDLOG_LOGGER_INFO(m_logger, "{}: 一致性报警结束", m_logBase);
+        SPDLOG_LOGGER_INFO(m_logger, "{}: 一致性报警结束,结束时间: {}", m_logBase, 
+            m_wavFilePath1.endDateTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
         /* 清除报警信息 */
         m_alarmConsistencyMain = AlarmInfo_t();
         m_alarmConsistencySub = AlarmInfo_t();
     }
-    
 }
-
-
-

+ 32 - 3
Server/ThreadCalculate/NoiseDetectThread.cpp

@@ -24,6 +24,27 @@ NoiseDetectThread::~NoiseDetectThread()
 
 }
 
+
+/* 停止线程,只设置个停止标志,不阻塞等待 */
+void NoiseDetectThread::thread_stop()
+{
+    m_isRunning = false;
+    m_condVar.notify_all();
+}
+
+/* 停止线程 */
+void NoiseDetectThread::thread_stop_block()
+{
+    m_isRunning = false;
+    m_condVar.notify_all();
+
+    while(!m_isStoped)
+    {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+    }
+}
+
+
 /* 开启对比项通道的噪音报警功能 */
 // void NoiseDetectThread::startCompareItemNoiseAlarm(const int itemID, const QString strName, const CompareItemRoadInfo_t& compareItemRoadInfo)
 // {
@@ -85,9 +106,17 @@ void NoiseDetectThread::task()
     bool isNoise = false;
 #endif /* CREATE_NOISE_WARN */
 
-    while(m_isRunning)
+    while(true)
     {
-        std::this_thread::sleep_for(std::chrono::milliseconds(detectInterval));
+        std::unique_lock<std::mutex> lock(m_mutexCondVar);
+        m_condVar.wait_for(lock, std::chrono::milliseconds(detectInterval));
+        if(m_isRunning == false)
+        {
+            /* 退出线程,结束噪音报警 */
+            m_currentIsNoise = false;
+            saveResultOnlyOneItem();
+            break;
+        }
 
         /* 判断是否还在噪音检测时间段内,如果还在噪音报警中,
             则继续保存数据 */
@@ -142,7 +171,7 @@ void NoiseDetectThread::task()
 
     }
     clearData(); // 清理数据
-    SPDLOG_LOGGER_INFO(m_logger, " ★ {} 噪音检测线程结束  ", m_logBase);
+    SPDLOG_LOGGER_WARN(m_logger, " ★ {} 噪音检测线程停止运行  ", m_logBase);
 }
 
 /* 初始化数据 */

+ 12 - 2
Server/ThreadCalculate/NoiseDetectThread.h

@@ -14,7 +14,7 @@
 
 
 class CreateWAVThread;
-class CreateRecordFileThread ;
+class CreateRecordFileThread;
 
 
 /**
@@ -26,7 +26,7 @@ class CreateRecordFileThread ;
         
         上面说明作废,现在是由对比项线程来开启噪音检测线程,因为报警、录制报警文件,检测时段和对比项信息绑定太深了,
         所以,这个线程所有权归到对比项线程中,因为噪音检测动态库检测速度很快,即使同一个通道多次开启噪音检测线程,
-        也不会有太大影响,噪音检测线程会根据对比项,已有的函数没有删除,依旧保留
+        也不会有太大影响,噪音检测线程会被对比项创建,已有的函数没有删除,依旧保留
     
     噪音判断逻辑
         1、每次检测噪音时,都会检测左右声道的噪音,如果有一个声道有噪音,就认为是噪音
@@ -41,6 +41,12 @@ public:
     NoiseDetectThread(CalculateThreadInfo_t& threadInfo);
     ~NoiseDetectThread() override;
 
+
+    /* 停止线程,只设置个停止标志,不阻塞等待 */
+    void thread_stop() override;
+    /* 停止线程 */
+    void thread_stop_block() override;
+
     /* 获取通道信息 */
     const OneSoundCardPCMInfo_t& getRoadInfo() const { return m_roadInfo; }
     /* 获取当前噪音结果 */
@@ -77,6 +83,10 @@ private:
     void endAlarm();
 
 private:
+    /* 条件变量,控制睡眠时间 */
+    std::condition_variable m_condVar;
+    std::mutex m_mutexCondVar;
+
     OneSoundCardPCMInfo_t m_roadInfo;               /* 录音通道编号 */
     std::string m_roadName;                         /* 录音通道名称 */
     CreateWAVThread* m_pThreadWav = nullptr;        /* WAV小文件生成线程指针 */

+ 66 - 16
Server/ThreadManager/ThreadCompareItemManager.cpp

@@ -125,6 +125,7 @@ void ThreadCompareItemManager::do_task()
         SPDLOG_LOGGER_WARN(m_logger, "MQTT未连接,尝试重新连接");
         m_pFromMQTT->connectToServer();
     }
+    m_currentTime = QDateTime::currentDateTime();
     /* ------------------------------------------------------------------
      * 处理对比项信息
      * ------------------------------------------------------------------ */
@@ -198,14 +199,19 @@ void ThreadCompareItemManager::processCompareItemInfo()
         SPDLOG_LOGGER_DEBUG(m_logger, "ThreadCompareItemManager: 获取对比项失败");
         return;
     }
-
-    checkCompareItemInfo(listNewItems, m_listCreateItems, m_listDeleteItems);
-
+    bool isDeleteAll = false;   /* 删除所有对比项 */
+    // if(listNewItems.size() == 0)
+    // {
+    //     isDeleteAll = true;
+    // }else {
+        checkCompareItemInfo(listNewItems, m_listCreateItems, m_listDeleteItems);
+    // }
+    
     SPDLOG_LOGGER_DEBUG(m_logger, "要退出的对比项个数: {}, 要创建的对比项个数: {}",
         m_listDeleteItems.size(), m_listCreateItems.size());
 
     /* 先删除已消失的对比项信息 */
-    processDeleteCompareItemThreads(m_listDeleteItems);
+    processDeleteCompareItemThreads(m_listDeleteItems, isDeleteAll);
     /* 更新需要更新的线程 */
     // updateRunningThreads(m_listUpdateItems);
     /* 再创建新的对比项线程 */
@@ -320,8 +326,31 @@ void ThreadCompareItemManager::checkCompareItemInfo(QList<CompareItemInfo_t>& ne
  * 
  * @param deleteList 
  */
-void ThreadCompareItemManager::processDeleteCompareItemThreads(const QList<int>& deleteList)
+void ThreadCompareItemManager::processDeleteCompareItemThreads(const QList<int>& deleteList, bool isDeleteAll)
 {
+    if(m_mapThreads.empty())
+    {
+        return;
+    }
+    /* 判断是否是删除全部线程 */
+    if(isDeleteAll)
+    {
+        for(auto it = m_mapThreads.begin(); it != m_mapThreads.end(); ++it)
+        {
+            if(it.value() == nullptr)
+            {
+                continue;
+            }
+            std::string compareItemName = it.value()->getThreadInfo().compareItemInfo.strName.toStdString();
+            /* 设置线程停止标志,阻塞等待线程停止,然后再删除 */
+            it.value()->thread_stop_block();
+            delete it.value();
+            it.value() = nullptr; // 设置为nullptr,防止悬空指针
+            SPDLOG_LOGGER_INFO(m_logger, "对比项线程 {} 已删除", compareItemName);
+        }
+        m_mapThreads.clear();
+        return;
+    }
     /* 先处理已经停止运行的线程,是上次循环停止的线程 */
     for(auto it = m_mapThreads.begin(); it != m_mapThreads.end();)
     {
@@ -429,19 +458,29 @@ bool ThreadCompareItemManager::createNewCompareItemThreads(const QList<CompareIt
 }
 
 
-/* 处理检测时段信息 */
+/*  处理检测时段信息
+    设置检测时段信息有两种方式
+    1、某个对比项的检测计划更新了,会主动将这个对比项计划设置过去
+    2、某个对比项刚刚启动,设置标志位需要设置这个计划,则将当前的计划设置过去
+ */
 void ThreadCompareItemManager::processDetectPeriodInfo()
 {
-    /* 获取计划信息 */
-    QMap<int, DetectPeriodConfig_t> mapNewDetectConfig;
-    if(!m_fromWebAPI.getDetectPeriodConfig(mapNewDetectConfig))
+    QMap<int, DetectPeriodConfig_t> mapUpdateDetectConfig;
+    /* 获取计划信息,10秒获取一次 */
+    if(m_currentTime.toSecsSinceEpoch() - m_latestDetectPeriod.toSecsSinceEpoch() > 10)
     {
-        SPDLOG_LOGGER_ERROR(m_logger, "获取检测时段配置失败");
-        return;
-    }
+        QMap<int, DetectPeriodConfig_t> mapNewDetectConfig;
+        if(!m_fromWebAPI.getDetectPeriodConfig(mapNewDetectConfig))
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "获取检测时段配置失败");
+            return;
+        }
+        checkDetectPeriodInfo(m_mapDetectPeriod, mapNewDetectConfig, mapUpdateDetectConfig);
+        /* 更新当前检测时段信息 */
+        m_mapDetectPeriod = mapNewDetectConfig;
 
-    QMap<int, DetectPeriodConfig_t> mapUpdateDetectConfig;
-    checkDetectPeriodInfo(m_mapDetectPeriod, mapNewDetectConfig, mapUpdateDetectConfig);
+        m_latestDetectPeriod = m_currentTime;
+    }
 
     /* 更新检测时段 */
     for(const auto& it : mapUpdateDetectConfig)
@@ -458,8 +497,19 @@ void ThreadCompareItemManager::processDetectPeriodInfo()
             }
         }
     }
-    /* 更新当前检测时段信息 */
-    m_mapDetectPeriod = mapNewDetectConfig;
+    /* 设置需要计划的对比项 */
+    for(auto& pThread : m_mapThreads)
+    {
+        if(pThread != nullptr && !pThread->isHadDetectPlan())
+        {
+            /* 找到这个对比项的计划 */
+            auto detectPlan = m_mapDetectPeriod.find(pThread->getThreadInfo().compareItemInfo.nID);
+            if(detectPlan != m_mapDetectPeriod.end())
+            {
+                pThread->setDetectPeriod(detectPlan.value());
+            }
+        }
+    }
 }
 
 /* 检查获取出更新的对比项信息 */

+ 3 - 1
Server/ThreadManager/ThreadCompareItemManager.h

@@ -72,7 +72,7 @@ private:
                                 QList<int>& deleteList);
 
     /* 处理需要删除的对比项线程 */
-    void processDeleteCompareItemThreads(const QList<int>& deleteList);
+    void processDeleteCompareItemThreads(const QList<int>& deleteList, bool isDeleteAll);
     /* 更新正在运行的线程信息 */
     void updateRunningThreads(const QList<CompareItemInfo_t>& updateList);
     /* 创建新的线程 */
@@ -105,6 +105,7 @@ private:
     QString m_webAPIID;                     /* WebAPI ID */
     QString m_webAPIAppType;                      /* WebAPI应用类型 */
 
+    QDateTime m_currentTime;                /* 当前时间 */
     /* ---------------------- 对比项信息 ---------------------- */
     std::atomic_bool m_isOneSend = true;        /* 开启服务先发送一次 */
     std::mutex m_mutexCompareItemThreads;       /* 对比项线程的互斥锁 */
@@ -120,6 +121,7 @@ private:
     /* ---------------------- 检测时段信息 ---------------------- */
     /* 检测时段,int是对比项ID */
     QMap<int, DetectPeriodConfig_t> m_mapDetectPeriod;
+    QDateTime m_latestDetectPeriod;             /* 上次获取检测时段的时间 */
 
     /* ---------------------- 向MQTT发送对比项信息 ---------------------- */
     QMap<int, CompareItemInfo_t> m_mapMQTTItemInfo;

+ 318 - 549
Server/ThreadManager/ThreadManager.cpp

@@ -10,6 +10,7 @@
 #include "CreateRecordFileThread.h"
 #include "RecordThread.h"
 #include "AssignSrcDataThread.h"
+#include "SoundCards.h"
 
 #include "ThreadPool.h"
 #include <mutex>
@@ -43,12 +44,47 @@ void ThreadManager::thread_destroyeRecordThread()
 {
     while(true)
     {
-        std::this_thread::sleep_for(std::chrono::milliseconds(100));
-        destroyeRecordThread();
+        // SPDLOG_LOGGER_WARN(m_logger, "销毁录音线程函数开始运行");
+        /* 设置超时2秒 */
+        std::unique_lock<std::mutex> m_lock(m_mutexRecordThreadRefCount);
+        m_condVarDestroyRecord.wait_for(m_lock, std::chrono::seconds(2), [this]() {
+            return m_isDestroyeRecordThread.load();
+        });
+        // SPDLOG_LOGGER_WARN(m_logger, "销毁录音线程函数被唤醒, 销毁标志: {}", m_isDestroyeRecordThread.load());
+        if(m_isDestroyeRecordThread.load() == false)
+        {
+            continue;
+        }
+        /* 销毁标志位置为false */
+        m_isDestroyeRecordThread.store(false);
+
+        
+        /* 获取所有引用计数为0的录音线程 */
+        QList<std::string> removePCMList; // 需要移除的录音通道列表
+        for(auto it = m_mapRecordThreadRefCount.begin(); it != m_mapRecordThreadRefCount.end(); it++)
+        {
+            if(it->second.empty())
+            {
+                removePCMList.push_back(it->first);
+            }
+        }
+        
+        
+        /* 停止线程 */
+        for(const auto& pcmName : removePCMList)
+        {
+            OneSoundCardPCMInfo_t pcmInfo;
+            pcmInfo.pcmInfo.strPCMName = pcmName;
+            stopRecordAllThreads(pcmInfo);
+        }
+        /* 销毁线程 */
+        destroyRecordThread();
     }
 }
 
-/* 创建一个录音通道及其附属的线程 */
+/* 创建一个录音通道及其附属的线程
+    注意:这个函数在对比项线程中运行
+*/
 bool ThreadManager::createRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int compareItemID)
 {
     /* 先查找队列中有没有该录音通道 */
@@ -174,9 +210,11 @@ bool ThreadManager::createRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int
 /**
     销毁一个录音通道及其附属的线程,如果引用计数为0, 这里只停止该录音通道的所有线程,不会删除实例
     线程实例会由其他管理线程定期去删除
+    注意:这个函数其实是在对比项线程中运行的
  */
 bool ThreadManager::removeRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int compareItemID)
 {
+    // SPDLOG_LOGGER_WARN(m_logger, "{}:{} 准备减少录音线程计数...", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
     std::unique_lock<std::mutex> lock(m_mutexRecordThreadRefCount);
     // SPDLOG_LOGGER_WARN(m_logger, "{}:{} 准备销毁录音线程, map Size: {}", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName, m_mapRecordThreadRefCount.size());
     /* 先查找这个引用计数是否存在 */
@@ -209,17 +247,197 @@ bool ThreadManager::removeRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int
         SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程未找到,可能已经释放", logBase);
         return true;
     }
-    SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程引用计数为0,即将停止该录音通道的所有线程", logBase);
+    SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程引用计数为0,需要释放该录音通道的所有线程", logBase);
+    
+    /* 设置销毁录音线程标志 */
+    m_isDestroyeRecordThread.store(true);
+    m_condVarDestroyRecord.notify_one();
+
+    return true;
+}
+
+
+
+
+/* 查找录音线程 */
+BaseRecordThread* ThreadManager::findRecordThread(EThreadType type, std::string pcmName)
+{
+    switch(type)
+    {
+        case EThreadType::Type_RecordSrc:           /* 录音线程 */
+            {
+                std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
+                for (auto& pThread : m_recordThreads)
+                {
+                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
+                    {
+                        return pThread;
+                    }
+                }
+            }
+            break;
+        case EThreadType::Type_CreateWAV:           /* 创建wav小文件和分离左右声道的线程 */
+            {
+                std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
+                for (auto& pThread : m_createWAVThreads)
+                {
+                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
+                    {
+                        return pThread;
+                    }
+                }
+            }
+            break;
+        case EThreadType::Type_CreateDB:      /* 计算音量和反相的线程 */
+            {
+                std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
+                for (auto& pThread : m_createDBThreads)
+                {
+                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
+                    {
+                        return pThread;
+                    }
+                }
+            }
+            break;
+        case EThreadType::Type_CreateLongWAV:           /* 创建长文件的线程 */
+            {
+                std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
+                for (auto& pThread : m_createLongWAVThreads)
+                {
+                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
+                    {
+                        return pThread;
+                    }
+                }
+            }
+            break;
+        case EThreadType::Type_AssignSrcData:           /* 分派数据线程 */
+            {
+                std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
+                for (auto& pThread : m_assignSrcDataThreads)
+                {
+                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
+                    {
+                        return pThread;
+                    }
+                }
+            }
+            break;
+        case EThreadType::Type_RtpSend:               /* RTP发送线程 */
+            {
+                std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
+                for (auto& pThread : m_rtpSendThreads)
+                {
+                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
+                    {
+                        return pThread;
+                    }
+                }
+            }
+            break;
+        default:
+            SPDLOG_LOGGER_ERROR(m_logger, "{} 查找录音线程失败,未知线程类型: {}", m_logBase, static_cast<int>(type));
+            return nullptr; // 未知线程类型
+    }
+    
+    
+    return nullptr;
+}
+
+
+/* 获取创建WAV线程指针 */
+CreateWAVThread* ThreadManager::getCreateWAVThread(std::string pcmName)
+{
+    std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
+    for(auto& pThread : m_createWAVThreads)
+    {
+        if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
+        {
+            return dynamic_cast<CreateWAVThread*>(pThread);
+        }
+    }
+    return nullptr;
+}
+
+/* 获取创建音量值的线程 */
+CreateDBThread* ThreadManager::getCreateDBThread(std::string pcmName)
+{
+    std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
+    for(auto& pThread : m_createDBThreads)
+    {
+        if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
+        {
+            return dynamic_cast<CreateDBThread*>(pThread);
+        }
+    }
+    return nullptr;
+}
+
+/* 获取发送Rtp数据的线程 */
+RTPOneRoadThread* ThreadManager::getRtpSendThread(std::string pcmName)
+{
+    std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
+    for(auto& pThread : m_rtpSendThreads)
+    {
+        const auto& threadInfo = pThread->getThreadInfo();
+        if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmName)
+        {
+            return dynamic_cast<RTPOneRoadThread*>(pThread);
+        }
+    }
+    return nullptr;
+}
+
+/* 获取录制报警文件的线程 */
+CreateRecordFileThread* ThreadManager::getCreateRecordFileThread(std::string pcmName)
+{
+    std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
+    for(auto& pThread : m_createLongWAVThreads)
+    {
+        if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
+        {
+            return dynamic_cast<CreateRecordFileThread*>(pThread);
+        }
+    }
+    return nullptr;
+}
+
+
+
+/* RTP线程函数,套一层壳 */
+void ThreadManager::thread_RTPSend(RecordThreadInfo_t& threadInfo)
+{
+    RTPOneRoadThread* pRtpSendThread = new RTPOneRoadThread(threadInfo);
+    if(pRtpSendThread == nullptr)
+    {
+        SPDLOG_ERROR("{}:{} 创建RTP发送线程失败", threadInfo.cardRoadInfo.strSoundCardName, threadInfo.cardRoadInfo.pcmInfo.strPCMName);
+        return;
+    }
+    /* 先加入队列,再开启线程 */
+    ThreadMan.m_mutexRtpSendThreads.lock();
+    ThreadMan.m_rtpSendThreads.push_back(pRtpSendThread);
+    ThreadMan.m_mutexRtpSendThreads.unlock();
+    
+    pRtpSendThread->thread_task();
+}
+
+/* 停止某个录音通道的所有的线程 */
+void ThreadManager::stopRecordAllThreads(const OneSoundCardPCMInfo_t& pcmInfo)
+{
     
+    std::string logBase = fmt::format("{}:{}", pcmInfo.strSoundCardName, pcmInfo.pcmInfo.strPCMName);
     /* 引用计数为0,停止该录音通道的所有线程 */
     /* 停止录音线程 */
     {
         std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
+        SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程列表Size: {}", logBase, m_recordThreads.size());
         for(auto it : m_recordThreads)
         {
             const auto& threadInfo = it->getThreadInfo();
             if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmInfo.pcmInfo.strPCMName)
             {
+                SPDLOG_LOGGER_TRACE(m_logger, "{} 准备停止录音线程: {}", logBase, threadInfo.cardRoadInfo.pcmInfo.strPCMName);
                 it->thread_stop_block();
                 SPDLOG_LOGGER_TRACE(m_logger, "{} 录音线程已停止", logBase);
                 break;
@@ -305,55 +523,46 @@ bool ThreadManager::removeRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int
     if(it != m_mapRecordThreadRefCount.end())
     {
         m_mapRecordThreadRefCount.erase(it);
-        SPDLOG_LOGGER_INFO(m_logger, "{} 录音线程已停止运行", logBase);
+        SPDLOG_LOGGER_WARN(m_logger, " ➢ 录音通道: {} 线程已全部停止运行", logBase);
     } else
     {
         SPDLOG_LOGGER_WARN(m_logger, "{} 录音线程引用计数未找到", logBase);
     }
 
-    // 设置销毁录音线程标志
-    m_isDestroyeRecordThread.store(true);
-    m_condVarDestroyRecord.notify_one();
-
-    return true;
 }
 
+
+
 /* 销毁录音线程 */
-void ThreadManager::destroyeRecordThread()
+void ThreadManager::destroyRecordThread()
 {
-    std::unique_lock<std::mutex> m_lock(m_mutexRecordThreadRefCount);
-    m_condVarDestroyRecord.wait(m_lock, [this]() {
-        return m_isDestroyeRecordThread.load();
-    });
-    if(!m_isDestroyeRecordThread.load())
-    {
-        /* 没有需要销毁的线程 */
-        return;
-    }
-    SPDLOG_LOGGER_INFO(m_logger, "{} 准备销毁录音线程...", m_logBase);
+
+    SPDLOG_LOGGER_DEBUG(m_logger, "{} 准备销毁录音线程...", m_logBase);
     /* 销毁录音线程 */
     {
         std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
         for(auto it = m_recordThreads.begin(); it != m_recordThreads.end(); )
         {
             BaseRecordThread* pThread = *it;
-            if(pThread != nullptr)
+            if(pThread == nullptr)
             {
-                auto threadState = pThread->getThreadInfo().threadState.load();
-                if(EThreadState::State_Stopped == threadState ||
-                   EThreadState::State_Error == threadState )
-                {
-                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁录音线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
-                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
-                    auto pRecordThread = dynamic_cast<RecordThread*>(pThread);
-                    delete pRecordThread; // 删除线程
-                    pThread = nullptr;
-                    it = m_recordThreads.erase(it); // 从列表中移除
-                }
-            } else
+                /* 删除空指针元素 */
+                it = m_recordThreads.erase(it);
+                continue;
+            }
+            auto threadState = pThread->getThreadInfo().threadState.load();
+            if(EThreadState::State_Stopped == threadState ||
+               EThreadState::State_Error == threadState )
             {
-                it++;
+                SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁录音线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                    pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
+                auto pRecordThread = dynamic_cast<RecordThread*>(pThread);
+                delete pRecordThread; // 删除线程
+                pThread = nullptr;
+                it = m_recordThreads.erase(it);
+                continue;
             }
+            ++it;
         }
     }
 
@@ -363,23 +572,24 @@ void ThreadManager::destroyeRecordThread()
         for(auto it = m_assignSrcDataThreads.begin(); it != m_assignSrcDataThreads.end(); )
         {
             BaseRecordThread* pThread = *it;
-            if(pThread != nullptr)
+            if(pThread == nullptr)
             {
-                auto threadState = pThread->getThreadInfo().threadState.load();
-                if(EThreadState::State_Stopped == threadState ||
-                   EThreadState::State_Error == threadState )
-                {
-                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁分派数据线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
-                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
-                    auto pAssignSrcDataThread = dynamic_cast<AssignSrcDataThread*>(pThread);
-                    delete pAssignSrcDataThread; // 删除线程
-                    pThread = nullptr;
-                    it = m_assignSrcDataThreads.erase(it); // 从列表中移除
-                }
-            } else
+                it = m_assignSrcDataThreads.erase(it);
+                continue;
+            }
+            auto threadState = pThread->getThreadInfo().threadState.load();
+            if(EThreadState::State_Stopped == threadState ||
+               EThreadState::State_Error == threadState )
             {
-                it++;
+                SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁分派数据线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                    pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
+                auto pAssignSrcDataThread = dynamic_cast<AssignSrcDataThread*>(pThread);
+                delete pAssignSrcDataThread; // 删除线程
+                pThread = nullptr;
+                it = m_assignSrcDataThreads.erase(it); // 从列表中移除
+                continue;
             }
+            ++it;
         }
     }
 
@@ -389,23 +599,24 @@ void ThreadManager::destroyeRecordThread()
         for(auto it = m_createWAVThreads.begin(); it != m_createWAVThreads.end(); )
         {
             BaseRecordThread* pThread = *it;
-            if(pThread != nullptr)
+            if(pThread == nullptr)
             {
-                auto threadState = pThread->getThreadInfo().threadState.load();
-                if(EThreadState::State_Stopped == threadState ||
-                   EThreadState::State_Error == threadState )
-                {
-                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateWAV 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
-                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
-                    auto pCreateWAVThread = dynamic_cast<CreateWAVThread*>(pThread);
-                    delete pCreateWAVThread; // 删除线程
-                    pThread = nullptr;
-                    it = m_createWAVThreads.erase(it); // 从列表中移除
-                }
-            } else
+                it = m_createWAVThreads.erase(it);
+                continue;
+            }
+            auto threadState = pThread->getThreadInfo().threadState.load();
+            if(EThreadState::State_Stopped == threadState ||
+               EThreadState::State_Error == threadState )
             {
-                it++;
+                SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateWAV 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                    pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
+                auto pCreateWAVThread = dynamic_cast<CreateWAVThread*>(pThread);
+                delete pCreateWAVThread; // 删除线程
+                pThread = nullptr;
+                it = m_createWAVThreads.erase(it); // 从列表中移除
+                continue;
             }
+            ++it;
         }
     }
 
@@ -415,23 +626,24 @@ void ThreadManager::destroyeRecordThread()
         for(auto it = m_createDBThreads.begin(); it != m_createDBThreads.end(); )
         {
             BaseRecordThread* pThread = *it;
-            if(pThread != nullptr)
+            if(pThread == nullptr)
             {
-                auto threadState = pThread->getThreadInfo().threadState.load();
-                if(EThreadState::State_Stopped == threadState ||
-                   EThreadState::State_Error == threadState )
-                {
-                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateDB 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
-                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
-                    auto pCreateDBThread = dynamic_cast<CreateDBThread*>(pThread);
-                    delete pCreateDBThread; // 删除线程
-                    pThread = nullptr;
-                    it = m_createDBThreads.erase(it); // 从列表中移除
-                }
-            } else
+                it = m_createDBThreads.erase(it);
+                continue;
+            }
+            auto threadState = pThread->getThreadInfo().threadState.load();
+            if(EThreadState::State_Stopped == threadState ||
+               EThreadState::State_Error == threadState )
             {
-                it++;
+                SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateDB 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                    pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
+                auto pCreateDBThread = dynamic_cast<CreateDBThread*>(pThread);
+                delete pCreateDBThread; // 删除线程
+                pThread = nullptr;
+                it = m_createDBThreads.erase(it); // 从列表中移除
+                continue;
             }
+            ++it;
         }
     }
 
@@ -441,23 +653,24 @@ void ThreadManager::destroyeRecordThread()
         for(auto it = m_createLongWAVThreads.begin(); it != m_createLongWAVThreads.end(); )
         {
             BaseRecordThread* pThread = *it;
-            if(pThread != nullptr)
+            if(pThread == nullptr)
             {
-                auto threadState = pThread->getThreadInfo().threadState.load();
-                if(EThreadState::State_Stopped == threadState ||
-                   EThreadState::State_Error == threadState )
-                {
-                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 RecordFile 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
-                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
-                    auto pCreateLongWAVThread = dynamic_cast<CreateRecordFileThread*>(pThread);
-                    delete pCreateLongWAVThread; // 删除线程
-                    pThread = nullptr;
-                    it = m_createLongWAVThreads.erase(it); // 从列表中移除
-                }
-            } else
+                it = m_createLongWAVThreads.erase(it);
+                continue;
+            }
+            auto threadState = pThread->getThreadInfo().threadState.load();
+            if(EThreadState::State_Stopped == threadState ||
+               EThreadState::State_Error == threadState )
             {
-                it++;
+                SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 CreateRecordFileThread 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                    pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
+                auto pCreateLongWAVThread = dynamic_cast<CreateRecordFileThread*>(pThread);
+                delete pCreateLongWAVThread; // 删除线程
+                pThread = nullptr;
+                it = m_createLongWAVThreads.erase(it); // 从列表中移除
+                continue;
             }
+            ++it;
         }
     }
 
@@ -467,471 +680,27 @@ void ThreadManager::destroyeRecordThread()
         for(auto it = m_rtpSendThreads.begin(); it != m_rtpSendThreads.end(); )
         {
             BaseRecordThread* pThread = *it;
-            if(pThread != nullptr)
-            {
-                auto threadState = pThread->getThreadInfo().threadState.load();
-                if(EThreadState::State_Stopped == threadState ||
-                   EThreadState::State_Error == threadState )
-                {
-                    SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 RTP Send 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
-                                        pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
-                    auto pRtpSendThread = dynamic_cast<RTPOneRoadThread*>(pThread);
-                    delete pRtpSendThread; // 删除线程
-                    pThread = nullptr;
-                    it = m_rtpSendThreads.erase(it); // 从列表中移除
-                }
-            } else
-            {
-                it++;
-            }
-        }
-    }
-
-    /* 销毁标志位置为false */
-    m_isDestroyeRecordThread.store(false);
-    SPDLOG_LOGGER_INFO(m_logger, "{} 录音线程销毁完成", m_logBase);
-}
-
-
-
-/* 查找录音线程 */
-BaseRecordThread* ThreadManager::findRecordThread(EThreadType type, std::string pcmName)
-{
-    switch(type)
-    {
-        case EThreadType::Type_RecordSrc:           /* 录音线程 */
-            {
-                std::lock_guard<std::mutex> lock(m_mutexRecordThreads);
-                for (auto& pThread : m_recordThreads)
-                {
-                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
-                    {
-                        return pThread;
-                    }
-                }
-            }
-            break;
-        case EThreadType::Type_CreateWAV:           /* 创建wav小文件和分离左右声道的线程 */
-            {
-                std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
-                for (auto& pThread : m_createWAVThreads)
-                {
-                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
-                    {
-                        return pThread;
-                    }
-                }
-            }
-            break;
-        case EThreadType::Type_CreateDB:      /* 计算音量和反相的线程 */
-            {
-                std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
-                for (auto& pThread : m_createDBThreads)
-                {
-                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
-                    {
-                        return pThread;
-                    }
-                }
-            }
-            break;
-        case EThreadType::Type_CreateLongWAV:           /* 创建长文件的线程 */
+            if(pThread == nullptr)
             {
-                std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
-                for (auto& pThread : m_createLongWAVThreads)
-                {
-                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
-                    {
-                        return pThread;
-                    }
-                }
+                it = m_rtpSendThreads.erase(it);
+                continue;
             }
-            break;
-        case EThreadType::Type_AssignSrcData:           /* 分派数据线程 */
+            auto threadState = pThread->getThreadInfo().threadState.load();
+            if(EThreadState::State_Stopped == threadState ||
+               EThreadState::State_Error == threadState )
             {
-                std::lock_guard<std::mutex> lock(m_mutexAssignSrcDataThreads);
-                for (auto& pThread : m_assignSrcDataThreads)
-                {
-                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
-                    {
-                        return pThread;
-                    }
-                }
+                SPDLOG_LOGGER_DEBUG(m_logger, "{} 销毁 RTP Send 线程: {}:{}", m_logBase, pThread->getThreadInfo().cardRoadInfo.strSoundCardName, 
+                                    pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName);
+                auto pRtpSendThread = dynamic_cast<RTPOneRoadThread*>(pThread);
+                delete pRtpSendThread; // 删除线程
+                pThread = nullptr;
+                it = m_rtpSendThreads.erase(it); // 从列表中移除
             }
-            break;
-        case EThreadType::Type_RtpSend:               /* RTP发送线程 */
-            {
-                std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
-                for (auto& pThread : m_rtpSendThreads)
-                {
-                    if (pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName )
-                    {
-                        return pThread;
-                    }
-                }
-            }
-            break;
-        default:
-            SPDLOG_LOGGER_ERROR(m_logger, "{} 查找录音线程失败,未知线程类型: {}", m_logBase, static_cast<int>(type));
-            return nullptr; // 未知线程类型
-    }
-    
-    
-    return nullptr;
-}
-
-
-/* 获取创建WAV线程指针 */
-CreateWAVThread* ThreadManager::getCreateWAVThread(std::string pcmName)
-{
-    std::lock_guard<std::mutex> lock(m_mutexCreateWAVThreads);
-    for(auto& pThread : m_createWAVThreads)
-    {
-        if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
-        {
-            return dynamic_cast<CreateWAVThread*>(pThread);
+            ++it;
         }
     }
-    return nullptr;
-}
 
-/* 获取创建音量值的线程 */
-CreateDBThread* ThreadManager::getCreateDBThread(std::string pcmName)
-{
-    std::lock_guard<std::mutex> lock(m_mutexCreateDBThreads);
-    for(auto& pThread : m_createDBThreads)
-    {
-        if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
-        {
-            return dynamic_cast<CreateDBThread*>(pThread);
-        }
-    }
-    return nullptr;
+    SPDLOG_LOGGER_DEBUG(m_logger, "{} 录音线程销毁完成", m_logBase);
 }
 
-/* 获取发送Rtp数据的线程 */
-RTPOneRoadThread* ThreadManager::getRtpSendThread(std::string pcmName)
-{
-    std::lock_guard<std::mutex> lock(m_mutexRtpSendThreads);
-    for(auto& pThread : m_rtpSendThreads)
-    {
-        const auto& threadInfo = pThread->getThreadInfo();
-        if(threadInfo.cardRoadInfo.pcmInfo.strPCMName == pcmName)
-        {
-            return dynamic_cast<RTPOneRoadThread*>(pThread);
-        }
-    }
-    return nullptr;
-}
-
-/* 获取录制报警文件的线程 */
-CreateRecordFileThread* ThreadManager::getCreateRecordFileThread(std::string pcmName)
-{
-    std::lock_guard<std::mutex> lock(m_mutexCreateLongWAVThreads);
-    for(auto& pThread : m_createLongWAVThreads)
-    {
-        if(pThread->getThreadInfo().cardRoadInfo.pcmInfo.strPCMName == pcmName)
-        {
-            return dynamic_cast<CreateRecordFileThread*>(pThread);
-        }
-    }
-    return nullptr;
-}
-
-
-/* -------------------------------------------------------------------------------------------
- * 获取计算线程,如果该线程不存在则创建该线程
- * 当不需要此线程后,调用remove()函数去掉该线程
- * -------------------------------------------------------------------------------------------- */
-
-/* 获取一致性比对线程,线程不存在则创建 */
-// ConsistencyCompareThread* ThreadManager::getConsistencyCompareThread(const SoundCardRoadInfo_t& roadInfo1, const SoundCardRoadInfo_t& roadInfo2)
-// {
-//     std::lock_guard<std::mutex> lock(m_mutexConsistencyCompareThreads);
-//     for(const auto pThread : m_listConsistencyCompareThreads)
-//     {
-//         if(pThread->isRoadEqual(roadInfo1, roadInfo2))
-//         {
-//             return pThread; // 找到相同的线程,直接返回
-//         }
-//     }
-//     /* 没找到该线程,创建新的线程 */
-//     CompareItemRoadInfo_t item1;
-//     item1.nCompareRoadNum = 1;
-//     item1.scRoadInfo = roadInfo1;
-//     CompareItemRoadInfo_t item2;
-//     item2.nCompareRoadNum = 2;
-//     item2.scRoadInfo = roadInfo2;
-
-//     CalculateThreadInfo_t threadInfo;
-//     threadInfo.compareItemInfo.mapRoad.insert(item1.nCompareRoadNum, item1);
-//     threadInfo.compareItemInfo.mapRoad.insert(item2.nCompareRoadNum, item2);
-//     ConsistencyCompareThread* newThread = new ConsistencyCompareThread(threadInfo);
-    
-//     if(newThread == nullptr)
-//     {
-//         SPDLOG_LOGGER_ERROR(m_logger, "创建一致性比对线程失败");
-//         return nullptr; // 创建失败
-//     }
-//     CPPTP.add_task(&ConsistencyCompareThread::threadTask, newThread);
-
-//     m_listConsistencyCompareThreads.push_back(newThread);
-//     m_referCountConsistencyCompare++; // 引用计数加一
-
-//     return newThread;
-// }
-
-/* 去掉线程,线程使用的计数减一,计数为0则销毁该线程 */
-// bool ThreadManager::removeConsistencyCompareThread(SoundCardRoadInfo_t& roadInfo1, SoundCardRoadInfo_t& roadInfo2)
-// {
-//     std::lock_guard<std::mutex> lock(m_mutexConsistencyCompareThreads);
-//     ConsistencyCompareThread* pThreadToRemove = nullptr;
-//     for(const auto pThread : m_listConsistencyCompareThreads)
-//     {
-//         if(pThread->isRoadEqual(roadInfo1, roadInfo2))
-//         {
-//             pThreadToRemove = pThread; // 找到相同的线程,直接返回
-//             break;
-//         }
-//     }
-//     if(pThreadToRemove == nullptr)
-//     {
-//         SPDLOG_LOGGER_WARN(m_logger, "{}:{} - {}:{} 一致性比对线程未找到", roadInfo1.strSoundCardName.toStdString(), roadInfo1.roadInfo.nRoadNum,
-//             roadInfo2.strSoundCardName.toStdString(), roadInfo2.roadInfo.nRoadNum);
-//         return false; // 没找到该线程
-//     }
-//     m_referCountConsistencyCompare--; // 引用计数减一
-//     if(m_referCountConsistencyCompare <= 0)
-//     {
-//         /* 停止线程,并一直等待其停止 */
-//         pThreadToRemove->thread_stop_block();
-//         m_listConsistencyCompareThreads.remove(pThreadToRemove); // 从列表中移除
-//         delete pThreadToRemove; // 删除线程
-//         pThreadToRemove = nullptr;
-//         m_referCountConsistencyCompare = 0; // 重置引用计数
-//         SPDLOG_LOGGER_WARN(m_logger, "{}:{} - {}:{} 一致性比对线程已销毁", roadInfo1.strSoundCardName.toStdString(), roadInfo1.roadInfo.nRoadNum,
-//             roadInfo2.strSoundCardName.toStdString(), roadInfo2.roadInfo.nRoadNum);
-//     }
-
-//     return true;
-// }
-
-/* 获取噪音检测线程 */
-// NoiseDetectThread* ThreadManager::getNoiseDetectThread(const OneSoundCardPCMInfo_t& roadInfo, int compareItemID)
-// {
-//     std::lock_guard<std::mutex> lock(m_mutexNoiseDetectThreads);
-//     NoiseDetectThread* pNoiseDetectThread = nullptr;
-//     for(const auto pThread : m_listNoiseDetectThreads)
-//     {
-//         const OneSoundCardPCMInfo_t & threadRoadInfo = pThread->getRoadInfo();
-//         if(threadRoadInfo.pcmInfo.strPCMName == roadInfo.pcmInfo.strPCMName)
-//         {
-//             pNoiseDetectThread = pThread;
-//             break;
-//         }
-//     }
-//     /* 判断引用计数是否需要增加 */
-//     if(pNoiseDetectThread != nullptr)
-//     {
-//         /* 查找这个通道是否在列表中(实际上肯定在列表中) */
-//         bool isExist = false;
-//         for(auto it  = m_mapNoiseDetectThreadRefCount.begin(); it != m_mapNoiseDetectThreadRefCount.end(); ++it)
-//         {
-//             if(it->first.roadInfo. == roadInfo.pcmInfo.strPCMName &&
-//                it->first.roadInfo.nRoadNum == roadInfo.roadInfo.nRoadNum)
-//             {
-//                 bool isFound = false;
-//                 for(auto& id : it->second)
-//                 {
-//                     if(id == compareItemID)
-//                     {
-//                         isFound = true;
-//                         break; // 找到相同的对比项ID,直接返回
-//                     }
-//                 }
-//                 if(!isFound)
-//                 {
-//                     it->second.push_back(compareItemID); // 添加新的对比项ID
-//                     SPDLOG_LOGGER_TRACE(m_logger, "{}:{} 噪音检测线程引用计数增加,当前计数: {}",
-//                     roadInfo.strSoundCardName.toStdString(), roadInfo.roadInfo.nRoadNum, it->second.size());
-//                 }
-//                 isExist = true;
-//                 break;
-//             }
-//         }
-//         if(!isExist)
-//         {
-//             /* 不在引用计数的列表中,添加进入 */
-//             m_mapNoiseDetectThreadRefCount[roadInfo].push_back(compareItemID);
-//         }
-//         return pNoiseDetectThread;
-//     }
-
-//     /* 没找到该线程,创建新的线程 */
-//     CalculateThreadInfo_t threadInfo;
-//     CompareItemRoadInfo_t item;
-//     item.nCompareRoadNum = 1; // 假设噪音检测线程
-//     item.scRoadInfo = roadInfo;
-//     threadInfo.compareItemInfo.mapRoad.insert(item.nCompareRoadNum, item);
-//     NoiseDetectThread* newThread = new NoiseDetectThread(threadInfo);
-//     if(newThread == nullptr)
-//     {
-//         SPDLOG_LOGGER_ERROR(m_logger, "创建噪音检测线程失败");
-//         return nullptr; // 创建失败
-//     }
-//     CPPTP.add_task(&NoiseDetectThread::threadTask, newThread);
-//     m_listNoiseDetectThreads.push_back(newThread);
-    
-//     /* 不在引用计数的列表中,添加进入 */
-//     m_mapNoiseDetectThreadRefCount[roadInfo].push_back(compareItemID);
-
-//     return newThread;
-// }
-
-/* 去掉噪音检测线程,线程使用的计数减一,计数为0则销毁该线程 */
-// bool ThreadManager::removeNoiseDetectThread(const SoundCardRoadInfo_t& roadInfo, int compareItemID)
-// {
-//     std::lock_guard<std::mutex> lock(m_mutexNoiseDetectThreads);
-//     NoiseDetectThread* pThreadToRemove = nullptr;
-//     for(const auto pThread : m_listNoiseDetectThreads)
-//     {
-//         const SoundCardRoadInfo_t& threadRoadInfo = pThread->getRoadInfo();
-//         if(threadRoadInfo.nSoundCardNum == roadInfo.nSoundCardNum &&
-//            threadRoadInfo.roadInfo.nRoadNum == roadInfo.roadInfo.nRoadNum)
-//         {
-//             pThreadToRemove = pThread; // 找到相同的线程,直接返回
-//             break;
-//         }
-//     }
-//     if(pThreadToRemove == nullptr)
-//     {
-//         SPDLOG_LOGGER_WARN(m_logger, "{}:{} 噪音检测线程未找到", roadInfo.strSoundCardName.toStdString(), roadInfo.roadInfo.nRoadNum);
-//         return false; // 没找到该线程
-//     }
-
-//     /* 引用计数减一 */
-//     int useCount = 0;
-//     for(auto it = m_mapNoiseDetectThreadRefCount.begin(); it != m_mapNoiseDetectThreadRefCount.end(); ++it)
-//     {
-//         if(it->first.nSoundCardNum == roadInfo.nSoundCardNum &&
-//            it->first.roadInfo.nRoadNum == roadInfo.roadInfo.nRoadNum)
-//         {
-//             /* 将对比项ID从列表中删除 */
-//             auto& compareItemList = it->second;
-//             auto itemIt = std::find(compareItemList.begin(), compareItemList.end(), compareItemID);
-//             if(itemIt != compareItemList.end())
-//             {
-//                 compareItemList.erase(itemIt); // 移除该对比项ID
-//                 SPDLOG_LOGGER_TRACE(m_logger, "{}:{} 噪音检测线程引用计数减少,当前计数: {}",
-//                     roadInfo.strSoundCardName.toStdString(), roadInfo.roadInfo.nRoadNum, compareItemList.size());
-//             }
-//             useCount = compareItemList.size(); // 获取当前引用计数
-//             if(useCount <= 0)
-//             {
-//                 m_mapNoiseDetectThreadRefCount.erase(it); // 如果引用计数为0,则从列表中移除
-//             }
-//             break; // 找到后退出循环
-//         }
-//     }
-
-
-//     if(useCount <= 0)
-//     {
-//         SPDLOG_LOGGER_INFO(m_logger, "{}:{} 噪音检测线程引用计数为0,准备销毁该线程",
-//                     roadInfo.strSoundCardName.toStdString(), roadInfo.roadInfo.nRoadNum);
-//         pThreadToRemove->thread_stop_block(); // 停止线程
-//         m_listNoiseDetectThreads.remove(pThreadToRemove); // 从列表中移除
-//         delete pThreadToRemove; // 删除线程
-//         pThreadToRemove = nullptr;
-//         SPDLOG_LOGGER_INFO(m_logger, "{}:{} 噪音检测线程已销毁", roadInfo.strSoundCardName.toStdString(), roadInfo.roadInfo.nRoadNum);
-//     }
-
-//     return true;
-// }
-
-
-
-// /* 获取音量报警线程 */
-// CalculateDBPhaseThread* ThreadManager::getCalculateDBPhaseThread(const SoundCardRoadInfo_t& roadInfo)
-// {
-//     std::lock_guard<std::mutex> lock(m_mutexCalculateDBPhaseThreads);
-//     for(const auto pThread : m_listCalculateDBPhaseThreads)
-//     {
-//         const SoundCardRoadInfo_t& threadRoadInfo = pThread->getRoadInfo();
-//         if(threadRoadInfo.nSoundCardNum == roadInfo.nSoundCardNum &&
-//            threadRoadInfo.roadInfo.nRoadNum == roadInfo.roadInfo.nRoadNum)
-//         {
-//             return pThread; // 找到相同的线程,直接返回
-//         }
-//     }
-        
-//     /* 没找到该线程,创建新的线程 */
-//     CompareItemRoadInfo_t item;
-//     item.nCompareRoadNum = 1; // 假设音量报警线程
-//     item.scRoadInfo = roadInfo;
-    
-//     threadInfo.compareItemInfo.mapRoad.insert(item.nCompareRoadNum, item);
-//     CalculateDBPhaseThread* newThread = new CalculateDBPhaseThread(threadInfo);
-    
-//     if(newThread == nullptr)
-//     {
-//         SPDLOG_LOGGER_ERROR(m_logger, "创建音量报警线程失败");
-//         return nullptr; // 创建失败
-//     }
-//     CPPTP.add_task(&CalculateDBPhaseThread::threadTask, newThread);
-
-//     m_listCalculateDBPhaseThreads.push_back(newThread);
-//     m_referCountCalculateDBPhase++; // 引用计数加一
-
-//     return newThread;
-// }
-
-// /* 去掉音量报警线程,线程使用的计数减一,计数为0则销毁该线程 */
-// bool ThreadManager::removeCalculateDBPhaseThread(RoadNumberInfo_t& roadInfo)
-// {
-//     std::lock_guard<std::mutex> lock(m_mutexCalculateDBPhaseThreads);
-//     CalculateDBPhaseThread* pThreadToRemove = nullptr;
-//     for(const auto pThread : m_listCalculateDBPhaseThreads)
-//     {
-//         if(pThread->getRoadInfo().roadID == roadInfo.roadID)
-//         {
-//             pThreadToRemove = pThread; // 找到相同的线程,直接返回
-//             break;
-//         }
-//     }
-//     if(pThreadToRemove == nullptr)
-//     {
-//         SPDLOG_LOGGER_WARN(m_logger, "{} 音量报警线程未找到", roadInfo.strRoadName);
-//         return false; // 没找到该线程
-//     }
-//     m_referCountCalculateDBPhase--; // 引用计数减一
-//     if(m_referCountCalculateDBPhase <= 0)
-//     {
-//         pThreadToRemove->thread_stop(); // 停止线程
-//         m_listCalculateDBPhaseThreads.remove(pThreadToRemove); // 从列表中移除
-//         delete pThreadToRemove; // 删除线程
-//         pThreadToRemove = nullptr;
-//         m_referCountCalculateDBPhase = 0; // 重置引用计数
-//         SPDLOG_LOGGER_INFO(m_logger, "{} 音量报警线程已销毁", roadInfo.strRoadName);
-//     }
-
-//     return true;
-// }
-
-/* RTP线程函数,套一层壳 */
-void ThreadManager::thread_RTPSend(RecordThreadInfo_t& threadInfo)
-{
-    RTPOneRoadThread* pRtpSendThread = new RTPOneRoadThread(threadInfo);
-    if(pRtpSendThread == nullptr)
-    {
-        SPDLOG_ERROR("{}:{} 创建RTP发送线程失败", threadInfo.cardRoadInfo.strSoundCardName, threadInfo.cardRoadInfo.pcmInfo.strPCMName);
-        return;
-    }
-    /* 先加入队列,再开启线程 */
-    ThreadMan.m_mutexRtpSendThreads.lock();
-    ThreadMan.m_rtpSendThreads.push_back(pRtpSendThread);
-    ThreadMan.m_mutexRtpSendThreads.unlock();
-    
-    pRtpSendThread->thread_task();
-}
 

+ 6 - 27
Server/ThreadManager/ThreadManager.h

@@ -60,10 +60,7 @@ public:
     bool createRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int compareItemID);
     /* 移除一个录音通道一个录音通道及其附属的线程 */
     bool removeRecordThread(const OneSoundCardPCMInfo_t& pcmInfo, int compareItemID);
-    /* 获取是否需要销毁录音线程实例 */
-    bool isDestroyeRecordThread() const { return m_isDestroyeRecordThread.load(); }
-    /* 销毁录音线程函数 */
-    void destroyeRecordThread();
+    
     
 
 
@@ -83,33 +80,15 @@ public:
     /* 获取录制报警文件的线程 */
     CreateRecordFileThread* getCreateRecordFileThread(std::string pcmName);
 
-    /* -------------------------------------------------------------------------------------------
-     * 获取计算线程,如果该线程不存在则创建该线程
-     * 当不需要此线程后,调用remove()函数去掉该线程
-     * 补充:
-     *      1、能在这里获取的线程是为了尽可能复用线程,这些都是和对比项无关的计算线程
-     *      2、和对比项有关的计算线程由对比项线程启动和管理
-     * -------------------------------------------------------------------------------------------- */
-    // /* 获取一致性比对线程,线程不存在则创建 */
-    // ConsistencyCompareThread* getConsistencyCompareThread(const SoundCardRoadInfo_t& roadInfo1, const SoundCardRoadInfo_t& roadInfo2);
-    // /* 去掉线程,线程使用的计数减一,计数为0则销毁该线程 */
-    // bool removeConsistencyCompareThread(SoundCardRoadInfo_t& roadInfo1, SoundCardRoadInfo_t& roadInfo2);
-
-    /* 获取噪音检测线程,如果不存在,则创建线程 */
-    // NoiseDetectThread* getNoiseDetectThread(const OneSoundCardPCMInfo_t & roadInfo, int compareItemID);
-    /* 去掉噪音检测线程,线程使用的计数减一,计数为0则销毁该线程 */
-    // bool removeNoiseDetectThread(const SoundCardRoadInfo_t& roadInfo, int compareItemID);
-
-    // /* 获取音量报警线程,如果不存在,则创建线程 */
-    // CalculateDBPhaseThread* getCalculateDBPhaseThread(const SoundCardRoadInfo_t& roadInfo);
-    // /* 去掉音量报警线程,线程使用的计数减一,计数为0则销毁该线程 */
-    // bool removeCalculateDBPhaseThread(SoundCardRoadInfo_t& roadInfo);
 
 private:
     /* RTP线程函数,套一层壳 */
     static void thread_RTPSend(RecordThreadInfo_t& threadInfo);
     
-    
+    /* 停止某个录音通道的所有的线程 */
+    void stopRecordAllThreads(const OneSoundCardPCMInfo_t& pcmInfo);
+    /* 销毁录音线程函数 */
+    void destroyRecordThread();
 
 private:
     /* 销毁录音线程的条件变量 */
@@ -159,7 +138,7 @@ private:
     std::shared_ptr<spdlog::logger> m_logger = nullptr; /* 日志记录器 */
     std::string m_logBase;                              /* 日志基础信息 */
     std::atomic_bool m_isDestroyeRecordThread = false;  /* 是否销毁录音线程标志 */
-    
+    std::mutex m_mutexDestroyRecordThread;              /* 互斥锁,保护销毁录音线程标志 */
 
 };
 

+ 2 - 2
Server/common/LHLog/LHLogInit.cpp

@@ -134,8 +134,8 @@ void changeLogLevel(ELogLevel level)
 {
     if(ELogLevel::Log_Debug == level)
     {
-        spdlog::set_level(spdlog::level::debug);
-        spdlog::flush_on(spdlog::level::debug);
+        spdlog::set_level(spdlog::level::trace);
+        spdlog::flush_on(spdlog::level::trace);
     }
     else if(ELogLevel::Log_Info == level)
     {

+ 1 - 1
Server/main.cpp

@@ -31,7 +31,7 @@ int main(int argc, char* argv[])
         return -1;
     }
     SPDLOG_LOGGER_INFO(logger, "★  ★  ★  ★  ★  ★  ★  ☆  ACAServer  ☆  ★  ★  ★  ★  ★  ★  ★");
-    SPDLOG_LOGGER_INFO(logger, "ACServer Version: {}", "6.0.0.2");
+    SPDLOG_LOGGER_INFO(logger, "ACServer Version: {}", "6.0.0.3");
     /* 设置线程池最大线程个数 */
     CPPTP.setThreadMaxNum(1024);
 

+ 5 - 5
SettingLibrary/CMakeLists.txt

@@ -8,7 +8,7 @@ set(libName ACAServerSetting)
 #包含源文件
 file(GLOB LOCAL_SRC
     ${CMAKE_SOURCE_DIR}/External/common/Shadow/*.cpp
-    ${CMAKE_SOURCE_DIR}/External/common/WebAPI/*.cpp
+    # ${CMAKE_SOURCE_DIR}/External/common/WebAPI/*.cpp
     ${CMAKE_SOURCE_DIR}/External/common/Thread/*.cpp
     ${CMAKE_SOURCE_DIR}/External/common/combox/*.cpp
     ${CMAKE_SOURCE_DIR}/External/common/TipWidget/*.cpp
@@ -50,7 +50,7 @@ file(GLOB LOCAL_SRC
 
     
     ${LHQLog_SOURCE_DIRS}/*.cpp
-    ${LHHTTPAPI_SOURCE_DIRS}/*.cpp
+    ${LHHTTPAPI_SOURCE_DIRS}
     ${SM_SOURCE_DIR}/*.cpp
 )
 
@@ -79,7 +79,7 @@ target_include_directories(${libName} PRIVATE
 
     ${CMAKE_SOURCE_DIR}/External/common
     ${CMAKE_SOURCE_DIR}/External/common/Shadow
-    ${CMAKE_SOURCE_DIR}/External/common/WebAPI
+    # ${CMAKE_SOURCE_DIR}/External/common/WebAPI
     ${CMAKE_SOURCE_DIR}/External/common/Thread
     ${CMAKE_SOURCE_DIR}/External/common/combox
     ${CMAKE_SOURCE_DIR}/External/common/TipWidget
@@ -116,7 +116,6 @@ target_include_directories(${libName} PRIVATE
     ${CMAKE_CURRENT_SOURCE_DIR}/DialogBase
     
 
-    ${spdlog_INCLUDE_DIR}
     ${LHQLog_INCLUDE_DIRS}
     ${LHHTTPAPI_INCLUDE_DIRS}
     ${qmqtt_INCLUDE_DIR}
@@ -132,8 +131,9 @@ target_link_libraries(${libName} PRIVATE
 )
 
 target_link_libraries(${libName} PRIVATE
-    ${spdlog_STATIC_LIBRARY}
+    # ${spdlog_STATIC_LIBRARY}
     ${qmqtt_LIBRARY}
     ${SM_LIB_LIBRARY}
+    External::spdlog
 )
 

+ 25 - 9
SettingLibrary/Modules/Basic/compareitemdialog.cpp

@@ -182,25 +182,41 @@ CompareItemInfo_t& CompareItemDialog::getCompareItemInfo()
 /* 新增通道 */
 void CompareItemDialog::do_pBtn_add_clicked()
 {
+    /* 判断数目是否已经达到最大值,最大就5个通道 */
+    if(m_listOtherRoadWgt.size() >= 5)
+    {
+        TipWidget::display(TipWidget::OPERATOR_WARN, "对比通道数目已达上限", this);
+        return;
+    }
     /* 从3开始编号,1是主通道,2是第二通道 */
-    int index = m_listOtherRoadWgt.size() + 3;
+    int index = m_listOtherRoadWgt.size() + 1;
     addOneRoadWidget(index, true);
 }
 
 /* 删除通道 */
 void CompareItemDialog::do_CompareRoadWgtDeleted(int nIndex)
 {
-    int nRealIndex = nIndex - 3;
-    if(nRealIndex < m_listOtherRoadWgt.size())
+    for(auto& it : m_listOtherRoadWgt)
     {
-        SingleCompareRoadWidget *pWgt = m_listOtherRoadWgt.at(nRealIndex);
-        m_listOtherRoadWgt.removeOne(pWgt);
-        delete pWgt;
-        pWgt = nullptr;
+        if(it->getIndex() == nIndex)
+        {
+            it->setParent(nullptr);
+            m_listOtherRoadWgt.removeOne(it);
+            break;
+        }
     }
-    for(int i = nRealIndex; i < m_listOtherRoadWgt.size(); i++)
+    /* 剩下的重新排序,不排主通道和2通道 */
+    for(auto& it : m_listOtherRoadWgt)
     {
-        m_listOtherRoadWgt.at(i)->setIndex(i + 3);
+        if(it == ui->widget_mainRoad || it == ui->widget_secondRoad)
+        {
+            continue;
+        }
+        int currentIndex = it->getIndex();
+        if(currentIndex > nIndex)
+        {
+            it->setIndex(currentIndex - 1);
+        }
     }
 }
 

+ 19 - 2
SettingLibrary/Modules/CheckPeriod/checkperiodwidget.cpp

@@ -419,9 +419,9 @@ void CheckPeriodWidget::do_detectPlanModifiedTime(QPoint pBtnSize, bool isStartT
     tw->setIconShow(true);
     tw->setIconSize(16, 16);
     /* 重新设置大小 */
-    tw->setEditLine(112, 32);
+    tw->setEditLine(120, 32);
     /* 设置选择框大小 */
-    tw->setTimeAreaWidth(140);
+    tw->setTimeAreaWidth(120);
     /* 移动位置,覆盖显示时间的按钮,获取的坐标是相对于Dialog的位置 */
     auto pos = this->mapFromGlobal(pBtnSize);
     // pos.setX(pos.x() - 1);     /* 去掉阴影的宽度 */
@@ -456,6 +456,23 @@ void CheckPeriodWidget::do_detectPlanModifiedTime(QPoint pBtnSize, bool isStartT
         }
     }
     SPDLOG_LOGGER_DEBUG(m_logger, "修改时间: {}, {}", time.toString("hh:mm:ss").toStdString(), isStartTime ? "开始时间" : "结束时间");
+    /* 先判断结束时间有没有晚于结束时间 */
+    if(isStartTime)
+    {
+        if(time >= plan.timeEnd)
+        {
+            TipWidget::display(TipWidget::OPERATOR_WARN, "结束时间不能早于等于开始时间", GInfo.getTopWindow());
+            SPDLOG_LOGGER_WARN(m_logger, "结束时间不能早于等于开始时间");
+            return;
+        }
+    }else {
+        if((time <= plan.timeStart) && (time != QTime(0,0,0)))
+        {
+            TipWidget::display(TipWidget::OPERATOR_WARN, "结束时间不能早于等于开始时间", GInfo.getTopWindow());
+            SPDLOG_LOGGER_WARN(m_logger, "结束时间不能早于等于开始时间");
+            return;
+        }
+    }
     OnePlan_t newPlan = plan;
     if(isStartTime)
     {

+ 0 - 1
SettingLibrary/acaserversetinfo.cpp

@@ -37,7 +37,6 @@ int DoGetChangedData(QString& strData)
 int DoSave(int nServiceID)
 {
     return g_managerObj.Save();
-    return 0;
 }
 
 int DoRelease()

+ 1 - 0
SettingLibrary/setinfomanager.cpp

@@ -136,6 +136,7 @@ int SetInfoManager::Save()
     {
         if(!m_pWgtSet->saveData())
         {
+            SPDLOG_INFO("设置保存失败");
             return -1;
         }
     }

+ 1 - 1
common/Network/FromWebAPI.cpp

@@ -802,7 +802,7 @@ bool FromWebAPI::insertConsistencyAlarmInfo(const AlarmInfo_t& mainAlarm, const
         json1["fileState2"] = static_cast<int>(subAlarm.fileState);
 
         json0["paramList"] = json1;
-        // SPDLOG_LOGGER_DEBUG(m_logger, "写入一致性报警信息: {}", json0.dump(4));
+        SPDLOG_LOGGER_DEBUG(m_logger, "写入一致性报警信息: {}", json0.dump(4));
         QString strSend = QString::fromStdString(json0.dump());
         QString strRet;
         int ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Insert, strSend, strRet, true);

+ 3 - 3
show1/CMakeLists.txt

@@ -38,7 +38,7 @@ target_include_directories(${this_exe} PRIVATE
     ${CMAKE_SOURCE_DIR}/External/common
     ${CMAKE_SOURCE_DIR}/External/module
     
-    ${spdlog_INCLUDE_DIR}
+    # ${spdlog_INCLUDE_DIR}
 )
 
 
@@ -51,8 +51,8 @@ target_link_libraries(${this_exe} PRIVATE
 )
 
 target_link_libraries(${this_exe} PRIVATE
-    ${spdlog_LIBRARY}
-
+    # ${spdlog_LIBRARY}
+    External::spdlog
 )
 
 

+ 2 - 2
show1/widget.cpp

@@ -32,8 +32,8 @@ Widget::Widget(QWidget *parent) :
     stInitData initData;
     initData.strWebAddr = "http://192.1.3.133:31000/v6/";
 
-    initData.strDBID = "cf6b57fa3d9841e22c3c897e6b8e66b8";       /* 达梦数据库 */
-    // initData.strDBID = "3b8889a0d58b8d71affc04bc27d14e42";          /* GBase */
+    // initData.strDBID = "cf6b57fa3d9841e22c3c897e6b8e66b8";       /* 达梦数据库 */
+    initData.strDBID = "3b8889a0d58b8d71affc04bc27d14e42";          /* GBase */
 
     DoInit(&initData);
     // 创建窗口

+ 1 - 1
show3/CMakeLists.txt

@@ -61,7 +61,7 @@ target_link_libraries(${this_exe} PRIVATE
 )
 # message(STATUS "可执行文件输出位置: ${EXECUTABLE_OUTPUT_PATH}")
 target_link_libraries(${this_exe} PRIVATE
-    ${spdlog_LIBRARY}
+    External::spdlog
     libsignalstats.so
     asound
 )