Procházet zdrojové kódy

V0.4.3
1、完善了部分“获取算法并写入EQM数据库的功能

Apple před 1 měsícem
rodič
revize
d07bcd196b

+ 68 - 0
SQL/SecurePlay.sql

@@ -0,0 +1,68 @@
+-- Active: 1725354130110@@192.1.3.105@1433@EQM_BJ
+
+#算子信息表
+SELECT *
+FROM "tAction";
+
+#算子摄像头信息表
+SELECT *
+FROM "tActionCamer";
+
+#摄像头信息表
+SELECT *
+FROM "tCamerinfo";
+
+#报警信息表
+SELECT *
+FROM "tAlarmInfo";
+
+#系统运行状态表
+SELECT *
+FROM "tCheckSystemInfo";
+
+#识别人员信息表
+SELECT *
+FROM "tFaceUser";
+
+
+#人员预警信息表
+SELECT *
+FROM "tFaultUser";
+
+#模板名称表
+SELECT *
+FROM "tModelinfo";
+
+#模板时段关联表
+SELECT *
+FROM "tModleDetial";
+
+#时段详细信息表
+SELECT *
+FROM "tPeriod";
+
+#直播间摄像头关联表
+SELECT *
+FROM "tRoomCamer";
+
+#监测频道表
+SELECT *
+FROM "tChannel";
+
+#直播间信息表
+SELECT *
+FROM "tRoomInfo";
+
+#报警规则表
+SELECT *
+FROM "tRuleInfo";
+
+#系统设置表
+SELECT *
+FROM "tSetupAI";
+
+#人员在岗信息表
+SELECT *
+FROM "tWorkOnInfo";
+
+

+ 141 - 0
SQL/SecurePlay.sqlbook

@@ -0,0 +1,141 @@
+-- SQLBook: Code
+-- Active: 1725354130110@@192.1.3.105@1433@EQM_BJ
+
+#算子信息表
+SELECT *
+FROM "tAction";
+
+#插入信息
+INSERT INTO "tAction" ("ActionId","ActionTaskid","ActionName")
+VALUES ('1',1,'test');
+
+#插入信息,带有参数
+INSERT INTO "tAction" ("ActionId","ActionTaskid","ActionName")
+VALUES (:actionID, :actionTaskID, :actionName);
+
+#删除信息
+DELETE FROM "tAction"
+WHERE "ActionId" = '123';
+
+#带参数的删除
+DELETE FROM "tAction"
+WHERE "PKID" = :actionID;
+
+#重置自增键
+DBCC CHECKIDENT ('tAction', RESEED, 0);
+-- SQLBook: Code
+-- Active: 1725354130110@@192.1.3.105@1433@EQM_BJ
+#算子摄像头信息表,将摄像机和算法关联起来
+SELECT *
+FROM "tActionCamer";
+
+#根据摄像头ID,从tAction表中查询算法信息
+SELECT "tActionCamer"."CamerId", "tActionCamer"."ActionId", "tAction"."ActionName", "tAction"."ActionTaskid"
+FROM "tActionCamer"
+LEFT JOIN "tAction"
+ON "tActionCamer"."ActionId" = "tAction"."ActionId";
+
+
+SELECT *
+FROM "tActionCamer"
+LEFT JOIN "tAction"
+ON "tActionCamer"."ActionId" = "tAction"."ActionId";
+
+#插入信息
+INSERT INTO "tActionCamer" ("ActionId","CamerId")
+VALUES (:actionID, :cameraID);
+
+#删除信息
+DELETE FROM "tActionCamer"
+WHERE "CamerId" = :CameraID;
+-- SQLBook: Code
+#摄像头信息表
+SELECT *
+FROM "tCamerinfo";
+
+SELECT cam.CamerName AS camerinfo
+FROM "tCamerinfo" AS cam;
+
+#插入设备信息
+INSERT INTO "tCamerinfo" ("CamerId","CamerName","CamerIp","CamerPort","CamerUsr","CamerPwd","CamerChannel","CamerSerial","CamerType","CamerUrl")
+VALUES (:camerID, :camerName, :camerIP, :camerPort, :camerUser, :camerPwd, :camerChannel, :camerSerial, :camerType, :camerUrl);
+
+
+#更新数据值,根据CmaerID更新
+UPDATE "tCamerinfo"
+SET "CamerName" = :camerName, "CamerIp" = :camerIP, "CamerPort" = :camerPort, "CamerUsr" = :camerUser, "CamerPwd" = :camerPwd, "CamerChannel" = :camerChannel, "CamerSerial" = :camerSerial, "CamerType" = :camerType, "CamerUrl" = :camerUrl
+WHERE "CamerId" = :camerID;
+
+#根据CamerId删除数据
+DELETE FROM "tCamerinfo"
+WHERE "CamerId" = :camerID;
+-- SQLBook: Code
+#直播间摄像头关联表
+SELECT *
+FROM "tRoomCamer";
+
+SELECT *
+FROM "tRoomInfo";
+
+
+#关联算法信息,"tRoomInfo"."PKID" = "tRoomCamer"."RoomId"
+SELECT "tRoomCamer".PKID, "tRoomCamer".RoomId, "tRoomCamer".CamerId, "tActionCamer".ActionId, "tRoomInfo"."Chnid", "tRoomInfo"."Rtype", "tRoomInfo"."Rname"
+FROM "tRoomCamer"
+LEFT JOIN "tActionCamer"
+ON "tRoomCamer"."CamerId" = "tActionCamer"."CamerId"
+LEFT JOIN "tRoomInfo"
+ON "tRoomCamer"."RoomId" = "tRoomInfo"."PKID";
+
+
+#插入信息
+INSERT INTO "tRoomCamer" ("RoomId","CamerId")
+VALUES (:roomID, :camerID);
+-- SQLBook: Code
+#报警信息表
+SELECT *
+FROM "tAlarmInfo";
+
+#插入报警信息
+INSERT INTO "tAlarmInfo" ("AlarmId","StartTime","CreateTime","EndTime","bBox","PicUrl","Appid","ActionId","ActionDes","CamerId","RoomId","chnID","State","FaceIdList","FaceNameList","OnWork")
+VALUES(:AlarmID, :StartTime, :CreateTime, :EndTime, :bBox, :PicUrl, :AppID, :ActionID, :ActionDes, :CamerID, :RoomID, :chnID, :Stat, :FaceIDList, :FaceNameList, :OnWork);
+
+INSERT INTO "tAlarmInfo" ("AlarmId","StartTime","CreateTime","EndTime","bBox","PicUrl","Appid","ActionId","ActionDes","CamerId","RoomId","chnID","State","FaceIdList","FaceNameList","OnWork")
+VALUES(@AlarmID, @StartTime, @CreateTime, @EndTime, @bBox, @PicUrl, @AppID, @ActionID, @ActionDes, @CamerID, @RoomID, @chnID, @Stat, @FaceIDList, @FaceNameList, @OnWork);
+
+
+#插入报警信息示例
+INSERT INTO "tAlarmInfo" ("AlarmId","StartTime","CreateTime","EndTime","bBox","PicUrl","Appid","ActionId","ActionDes","CamerId","RoomId","chnID","State","FaceIdList","FaceNameList","OnWork")
+VALUES('0', '2024-10-08 14:00:00', '2024-10-08 14:00:00','','112,112,112,112','PicURL', '1', '2', '报警测试', '3', '4', '5', '6', 'FaceIDList','FaceNameList', '1');
+
+#删除一行
+DELETE FROM "tAlarmInfo"
+WHERE "PKID" = :pkid;
+
+#更新结束时间
+UPDATE "tAlarmInfo"
+SET "EndTime" = :EndTime
+WHERE ("chnID" = :ChannelID AND "RoomId" = :RoomID AND "CamerId" = :CamerID AND "ActionId" = :ActionID);
+
+UPDATE "tAlarmInfo"
+SET "EndTime" = @EndTime
+WHERE ("chnID" = @ChannelID AND "RoomId" = @RoomID AND "CamerId" = @CamerID AND "ActionId" = @ActionID);
+-- SQLBook: Code
+#报警规则表
+SELECT *
+FROM "tRuleInfo";
+
+-- SQLBook: Code
+#时段详细信息表,从这里获取到开启了哪些检测功能
+SELECT *
+FROM "tPeriod";
+-- SQLBook: Code
+#人员在岗信息表
+SELECT *
+FROM "tWorkOnInfo";
+
+#插入信息
+INSERT INTO "tWorkOnInfo" ("nChID", "FaceIdList", "FaceNameList", "StartTime", "EndTime", "MaxNumber", "MinNumber", "CamerId")
+VALUES (:nChID, :FaceIdList, :FaceNameList, :StartTime, :EndTime, :MaxNumber, :MinNumber, :CamerId);
+
+INSERT INTO "tWorkOnInfo" ("nChID", "FaceIdList", "FaceNameList", "StartTime", "EndTime", "MaxNumber", "MinNumber", "CamerId")
+VALUES (1, '-1;-1', '未知;未知', '2024-10-21 18:03:00', '2024-10-21 18:13:00', 5, 1, 117);

+ 10 - 10
SecurePlayAuxServer/Application/FuncOrdinary.cpp

@@ -34,20 +34,20 @@ void FuncOrdinary::thread_task()
         SPDLOG_LOGGER_ERROR(m_logger, "未设置线程功能信息");
         return;
     }
-    SPDLOG_LOGGER_INFO(m_logger, "开启 {} 线程, ChannelID:{}",m_pFuncAct->strFunctionName, m_pFuncAct->ChannelID);
+    SPDLOG_LOGGER_INFO(m_logger, "开启 {} 功能线程, ChannelID:{}",m_pFuncAct->strFunctionName, m_pFuncAct->ChannelID);
 
     while (GThreadInfo.getRunning())
     {
-        /* 更新算法关联的摄像机ID */
-        // updateFuncInfo(pFuncAct);
-        /* 如果线程的运行状态为 */
+        /* 从全局的信息块中更新功能信息,如是否需要退出线程,主要是更新摄像机关联的算法信息 */
+        GThreadInfo.updateFuncInfo(m_pFuncAct);
+        /* 如果线程的运行状态为停止 */
         if(m_pFuncAct->RunState == RunTimeState::RUN_STATE_STOP)
         {
             /* 设置为NONE,就会被管理线程回收释放内存 */
             m_pFuncAct->appFunction = AppFunction::APP_NONE;
             break;
         }
-        /* 读取Redis信息,处理数据 */
+        /* 读取Redis信息,处理数据,第一层循环是根据房间读取,第二个循环是根据房间内的摄像机读取 */
         for(const auto& roomInfo : m_pFuncAct->listRoomCamActInfo)
         {
             for(const auto& it : roomInfo.mapCameraAction)
@@ -101,7 +101,7 @@ void FuncOrdinary::thread_task()
                         }
                     } else {
                         /* 报警结束,判断时长,更新数据库结束时间,结束时间是此时电脑时间 */
-                        if(timeDiffWithNow(pAlarmInfo->EventTime) > g_config.Contraband)
+                        if(timeDiffWithNow(pAlarmInfo->EventTime) > GConfig.Contraband)
                         {
                             pAlarmInfo->EndTime = chronoToStrTime(std::chrono::system_clock::now());
                             m_toEQMDataBase->updateAlarmEndTime(*pAlarmInfo);
@@ -132,7 +132,7 @@ void FuncOrdinary::thread_task()
                                 SPDLOG_LOGGER_ERROR(m_logger, "写入tAlarmInfo报警数据失败, Key: {}", strKey);
                             }
                         }else {
-                            SPDLOG_LOGGER_ERROR(m_logger, "频道:{}, 房间:{}, 摄像机:{}, 算法:{}, 有报警区域, 但是没有图片信息", pFuncAct->ChannelID, roomInfo.RoomID, it.first, it.second);
+                            SPDLOG_LOGGER_ERROR(m_logger, "频道:{}, 房间:{}, 摄像机:{}, 算法:{}, 有报警区域, 但是没有图片信息", m_pFuncAct->ChannelID, roomInfo.RoomID, it.first, it.second);
                         }
                     }
                 }
@@ -141,9 +141,9 @@ void FuncOrdinary::thread_task()
         }
         
         /* 休眠设置的时间 */
-        std::this_thread::sleep_for(std::chrono::seconds(g_config.ThreadSleepMS));
+        std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
     }
     /* 设置线程退出的状态 */
-    setThreadState(m_pFuncAct, RunTimeState::RUN_STATE_STOP);
-    SPDLOG_LOGGER_INFO(m_logger, "{} 线程退出,Channel:{}", m_pFuncAct->strFunctionName, m_pFuncAct->ChannelID);
+    // GThreadInfo.setThreadState(m_pFuncAct, RunTimeState::RUN_STATE_EXITCOMPLET);
+    SPDLOG_LOGGER_INFO(m_logger, "{} 功能线程退出,Channel:{}", m_pFuncAct->strFunctionName, m_pFuncAct->ChannelID);
 }

+ 12 - 0
SecurePlayAuxServer/Application/FuncOrdinary.h

@@ -6,6 +6,18 @@
 
 struct ListAlarmInfo;
 
+/**
+ * @brief 普通任务识别,一个算法只需要一个摄像机,包括 违禁品识别、玩手机检测、老鼠等
+            1、报警判断条件:机房内出现摄像头的违禁物品识别算法输出结果包含指定违规内容时,记为报警行为,直接
+                展示报警结果
+            2、这里应该是不区分违禁物品是什么,只要有违禁物品就报警。如果一个违禁物品消失之前又出现了第二个违禁物品,
+                两个违禁物品都消失后,这次报警才会结束,也就是说,不会同时出现两个报警信息。
+            3、一有报警信息就写入到EQM数据库的tAlarmInfo表中,报警开始时间是EventTime
+            4、如果报警结束时间小于设置的最小间隔,就删除这条数据,超过这个时间,就更新结束时间
+            5、报警信息要有图片,如果当前没有图片,就使用上一张图片
+ * 
+ * @param info 线程信息
+ */
 class FuncOrdinary : public FuncBase
 {
 public:

+ 0 - 5
SecurePlayAuxServer/Application/PersonCount.cpp

@@ -1,5 +0,0 @@
-#include "PersionCount.h"
-
-
-
-

+ 0 - 22
SecurePlayAuxServer/Application/PersonCount.h

@@ -1,22 +0,0 @@
-#ifndef PERSONCOUNT_H
-#define PERSONCOUNT_H
-
-
-
-
-/* 区域人员检测(人员计数),检测这个区域内的人数,不能少于多少人,不能多余多少人 */
-class PersonCount
-{
-public:
-    PersonCount();
-    ~PersonCount();
-    void task();        /* 任务线程 */
-
-private:
-    
-
-
-};
-
-
-#endif /* PERSONCOUNT_H */

+ 1 - 0
SecurePlayAuxServer/CMakeLists.txt

@@ -9,6 +9,7 @@ file(GLOB LOCAL_SRC
     ${CMAKE_CURRENT_SOURCE_DIR}/common/LHLog/*.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/communication/*.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/GlobalInfo/*.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/Application/*.cpp
 
     ${CMAKE_SOURCE_DIR}/External/common/Thread/*.cpp
     ${CMAKE_SOURCE_DIR}/External/module/CurlHttp/*.cpp

+ 428 - 2
SecurePlayAuxServer/GlobalInfo/GlobalConfig.cpp

@@ -8,8 +8,7 @@
  * **************************    GlobalConfig成员函数    ******************************
  * ====================================================================================*/
 
-/* 创建实例 */
-GlobalConfig g_config;
+
 
 GlobalConfig::GlobalConfig()
 {
@@ -90,3 +89,430 @@ void GlobalThreadInfo::setRunning(bool bRunning)
 {
     m_bRunning = bRunning;
 }
+
+/* 手动给功能块列表加锁 */
+void GlobalThreadInfo::lockRunFAI()
+{
+    m_mutexRunFAI.lock();
+}
+
+/* 手动解锁 */
+void GlobalThreadInfo::unlockRunFAI()
+{
+    m_mutexRunFAI.unlock();
+}
+
+
+/**
+ * @brief 添加应用信息,一个应用功能在一个频道内只有一个实例
+ *        这里是添加应用功能和时间段信息
+ * 
+ * @param func 
+ * @return true 
+ * @return false 
+ */
+bool GlobalThreadInfo::addFuncActionInfo(const AppAndTimeInfo& func)
+{
+    if(func.AppType == 0)
+    {
+        return false;
+    }
+    /* 解出这条信息里包含几个App,AppType按位计算,总共8个应用信息 */
+    for(int i = 0; i < 8; ++i)
+    {
+        if(func.AppType & 0x01)
+        {
+            /* 查找有没有这个应用 */
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_OnWork);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_OnWork;
+            fa->strFunctionName = "人员在岗识别";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if(func.AppType & 0x02)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Contraband);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_Contraband;
+            fa->strFunctionName = "违禁品识别";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if (func.AppType & 0x04)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Illegal);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_Illegal;
+            fa->strFunctionName = "非法入侵检测";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if (func.AppType & 0x08)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Fatigue);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_Fatigue;
+            fa->strFunctionName = "疲劳检测";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if (func.AppType & 0x10)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Regional);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_Regional;
+            fa->strFunctionName = "区域人员检测";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if (func.AppType & 0x20)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Mouse);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_Mouse;
+            fa->strFunctionName = "老鼠识别";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if (func.AppType & 0x40)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_PlayPhone);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_PlayPhone;
+            fa->strFunctionName = "玩手机识别";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if (func.AppType & 0x80)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_NoMask);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_NoMask;
+            fa->strFunctionName = "未戴口罩识别";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+        else if (func.AppType & 0x0100)
+        {
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_AllDown);
+            if(pFuncActionInfo != nullptr)
+            {
+                /* 更新时间信息 */
+                pFuncActionInfo->StartTime = func.StartTime;
+                pFuncActionInfo->EndTime = func.EndTime;
+                continue;
+            }
+            FuncActionInfo* fa = new FuncActionInfo;
+            fa->ChannelID = func.ChannelID;
+            fa->appFunction = AppFunction::APP_AllDown;
+            fa->strFunctionName = "摔倒识别";
+            fa->StartTime = func.StartTime;
+            fa->EndTime = func.EndTime;
+            m_listFuncActionInfo.push_back(fa);
+        }
+    }
+
+
+    return true;
+}
+
+
+
+/**
+ * @brief 添加算法信息,根据传进来的算法ID,将其加入到对应的功能中
+ * 
+ * @param info 
+ * @return true 
+ * @return false 
+ */
+bool GlobalThreadInfo::addActionInfo(const ActionInfo& info)
+{
+    if(info.ActionID.empty())
+    {
+        return false;
+    }
+    /* 人脸识别算法(人员在岗识别、非法入侵检测需要) */
+    if(info.ActionID == g_actionList.ActFace)
+    {
+        /* 人员在岗识别 */
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_OnWork);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+        /* 非法入侵检测 */
+        pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Illegal);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 人员计数 */
+    else if (info.ActionID == g_actionList.ActPersonNumber)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Regional);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 违禁物品 */
+    else if (info.ActionID == g_actionList.ActContraband)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Contraband);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 玩手机 */
+    else if (info.ActionID == g_actionList.ActPlayPhone)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_PlayPhone);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 睡岗识别 */
+    else if (info.ActionID == g_actionList.ActSleep)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Fatigue);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 疲劳检测 */
+    else if(info.ActionID == g_actionList.ActFatigueDetection)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Fatigue);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 动物识别 */
+    else if (info.ActionID == g_actionList.ActAnimalDetect)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Mouse);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 老鼠识别 */
+    else if (info.ActionID == g_actionList.ActMouseDetect)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Mouse);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    /* 口罩识别 */
+    else if (info.ActionID == g_actionList.ActMask)
+    {
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_NoMask);
+        if(pFuncActionInfo != nullptr)
+        {
+            pFuncActionInfo->addActionInfo(info);
+        }
+    }
+    else {
+        SPDLOG_WARN("未知的算法ID: {}", info.ActionID);
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * @brief 清空无用的功能信息
+ *          摄像机和算法信息为空的,或者运行状态为STOP,都会被清理掉
+ * 
+ */
+void GlobalThreadInfo::clearNoneFuncActionInfo()
+{
+    for(auto it0 = m_listFuncActionInfo.begin(); it0 != m_listFuncActionInfo.end();)
+    {
+        if((*it0)->listRoomCamActInfo.empty() || ((*it0)->RunState == RunTimeState::RUN_STATE_STOP))
+        {
+            delete *it0;
+            it0 = m_listFuncActionInfo.erase(it0);
+        }else {
+            ++it0;
+        }
+    }
+}
+
+/* 清空算法列表 */
+void GlobalThreadInfo::clearActionList()
+{
+    for(auto& it0 : m_listFuncActionInfo)
+    {
+        it0->listRoomCamActInfo.clear();
+    }
+}
+
+/* 设置没有配置摄像机的功能退出 */
+void GlobalThreadInfo::setNoneCameraFuncStop()
+{
+    for(auto& it : m_listFuncActionInfo)
+    {
+        if(it->listRoomCamActInfo.empty())
+        {
+            it->RunState = RunTimeState::RUN_STATE_STOP;
+        }
+    }
+}
+
+/* 查找应用信息 */
+bool GlobalThreadInfo::findAppFunction(const AppFunction func)
+{
+    for(const auto& it0 : m_listFuncActionInfo)
+    {
+        if(it0->appFunction == func)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+/* 根据频率和功能查找实例 */
+FuncActionInfo* GlobalThreadInfo::findAppFunction(const int ChannelID, const AppFunction func)
+{
+    for(const auto& it0 : m_listFuncActionInfo)
+    {
+        if( (it0->appFunction == func) && (it0->ChannelID == ChannelID) )
+        {
+            return it0;
+        }
+    }
+    return nullptr;
+}
+
+/**
+ * @brief 查找这个应用信息
+ * 
+ * @param func 
+ * @return FuncActionInfo* 
+ */
+FuncActionInfo* GlobalThreadInfo::findAppFunction(const FuncActionInfo& func)
+{
+    for(const auto& it0 : m_listFuncActionInfo)
+    {
+        if(it0->ChannelID == func.ChannelID && it0->appFunction == func.appFunction)
+        {
+            return it0;
+        }
+    }
+    return nullptr;
+}
+
+/* 设置线程状态 */
+void GlobalThreadInfo::setThreadState(FuncActionInfo* pInfo, RunTimeState state)
+{
+    std::lock_guard<std::mutex> look(m_mutexRunFAI);
+    auto p = findAppFunction(*pInfo);
+    if(p != nullptr)
+    {
+        p->RunState = state;
+    }
+}
+
+/**
+ * @brief 功能线程更新功能信息,这里是从内存中的数组里获取
+ * 
+ * @param pInfo 
+ * @return true 
+ * @return false 
+ */
+ bool GlobalThreadInfo::updateFuncInfo(FuncActionInfo* pInfo)
+{
+    pInfo->clearActionList();
+    std::lock_guard<std::mutex> look(m_mutexRunFAI);
+    auto fa = findAppFunction(*pInfo);
+    if(fa == nullptr)
+    {
+        return false;
+    }
+    *pInfo = *fa;
+
+    return true;
+}
+

+ 57 - 9
SecurePlayAuxServer/GlobalInfo/GlobalConfig.h

@@ -2,21 +2,32 @@
 #define GLOBALCONFIG_H
 
 #include <QString>
-
+#include "GlobalVariable.h"
 
 /* ====================================================================================
- * **************************    GlobalConfig成员函数    ******************************
+ * *****************************    GlobalConfig   ***********************************
  * ====================================================================================*/
 
+
+#define GConfig GlobalConfig::getInstance()
 /**
- * @brief 读取配置文件
+ * @brief 配置文件信息
  * 
  */
  class GlobalConfig
  {
-public:
+
     GlobalConfig();
     ~GlobalConfig() = default;
+    GlobalConfig(const GlobalConfig& other) = delete;
+    GlobalConfig& operator=(const GlobalConfig& other) = delete;
+
+public:
+    static GlobalConfig& getInstance()
+    {
+        static GlobalConfig gc;
+        return gc;
+    }
 
     /* 读取配置文件 */
     bool readConfig(const QString& strConfigFile);
@@ -42,17 +53,21 @@ public:
     std::string Secret;         /* Secret */
  };
 
-extern GlobalConfig g_config;
 
 
 /* ====================================================================================
- * ************************    GlobalThreadInfo成员函数    *****************************
+ * ************************    GlobalThreadInfo成员函数    ****************************
  * ====================================================================================*/
 
 #define GThreadInfo GlobalThreadInfo::getInstance()
+
+/**
+ * @brief 线程信息,也是应用功能块列表,每个频率下的每个功能就是一个线程
+ * 
+ */
 class GlobalThreadInfo
 {
-    GlobalThreadInfo();
+    GlobalThreadInfo() {}
     ~GlobalThreadInfo() {}
     GlobalThreadInfo(const GlobalThreadInfo& other) = delete;
     GlobalThreadInfo& operator=(const GlobalThreadInfo& other) = delete;
@@ -63,12 +78,45 @@ public:
         return instance;
     }
     /* 获取线程运行标志位 */
-    inline bool getRunning() const;
+    bool getRunning() const;
     /* 设置线程运行标志位 */
-    inline void setRunning(bool bRunning);
+    void setRunning(bool bRunning);
+    
+    /* 手动给功能块列表加锁 */
+    void lockRunFAI();
+    /* 手动解锁 */
+    void unlockRunFAI();
+    /* 添加功能信息 */
+    bool addFuncActionInfo(const AppAndTimeInfo& func);
+    /* 添加算法信息 */
+    bool addActionInfo(const ActionInfo& info);
+    /* 清空无用的功能信息 */
+    void clearNoneFuncActionInfo();
+    /* 清空房间和算法列表 */
+    void clearActionList();
+    /* 设置没有配置摄像机的功能退出 */
+    void setNoneCameraFuncStop();
+
+    /* 获取容器 */
+    std::list<FuncActionInfo*>& getList() {
+        return m_listFuncActionInfo;
+    }
+    /* 查找应用信息 */
+    bool findAppFunction(const AppFunction func);
+    FuncActionInfo* findAppFunction(const int ChannelID, const AppFunction func);
+    FuncActionInfo* findAppFunction(const FuncActionInfo& func);
+
+    /* 设置线程状态 */
+    void setThreadState(FuncActionInfo* pInfo, RunTimeState state);
+    /* 更新算法的摄像机ID */
+    bool updateFuncInfo(FuncActionInfo* pInfo);
 
 private:
     std::atomic_bool m_bRunning;    /* 线程运行状态 */
+
+    /* 运行时应用线程功能相关信息 */
+    std::mutex m_mutexRunFAI;
+    std::list<FuncActionInfo*> m_listFuncActionInfo;    /* 功能信息列表 */
 };
 
 #endif /* GLOBALCONFIG_H */

+ 28 - 28
SecurePlayAuxServer/GlobalInfo/GlobalVariable.cpp

@@ -881,7 +881,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         if(func.AppType & 0x01)
         {
             /* 查找有没有这个应用 */
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_ONWORK);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_OnWork);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -891,7 +891,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_ONWORK;
+            fa->appFunction = AppFunction::APP_OnWork;
             fa->strFunctionName = "人员在岗识别";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -899,7 +899,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if(func.AppType & 0x02)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_CONTRABAND);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Contraband);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -909,7 +909,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_CONTRABAND;
+            fa->appFunction = AppFunction::APP_Contraband;
             fa->strFunctionName = "违禁品识别";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -917,7 +917,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if (func.AppType & 0x04)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_ILLEGAL);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Illegal);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -927,7 +927,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_ILLEGAL;
+            fa->appFunction = AppFunction::APP_Illegal;
             fa->strFunctionName = "非法入侵检测";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -935,7 +935,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if (func.AppType & 0x08)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_FATIGUE);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Fatigue);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -945,7 +945,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_FATIGUE;
+            fa->appFunction = AppFunction::APP_Fatigue;
             fa->strFunctionName = "疲劳检测";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -953,7 +953,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if (func.AppType & 0x10)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_REGIONAL);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Regional);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -963,7 +963,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_REGIONAL;
+            fa->appFunction = AppFunction::APP_Regional;
             fa->strFunctionName = "区域人员检测";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -971,7 +971,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if (func.AppType & 0x20)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_MOUSE);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_Mouse);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -981,7 +981,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_MOUSE;
+            fa->appFunction = AppFunction::APP_Mouse;
             fa->strFunctionName = "老鼠识别";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -989,7 +989,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if (func.AppType & 0x40)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_PLAYPHONE);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_PlayPhone);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -999,7 +999,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_PLAYPHONE;
+            fa->appFunction = AppFunction::APP_PlayPhone;
             fa->strFunctionName = "玩手机识别";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -1007,7 +1007,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if (func.AppType & 0x80)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_NOMASK);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_NoMask);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -1017,7 +1017,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_NOMASK;
+            fa->appFunction = AppFunction::APP_NoMask;
             fa->strFunctionName = "未戴口罩识别";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -1025,7 +1025,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
         }
         else if (func.AppType & 0x0100)
         {
-            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_ALLDOWN);
+            auto pFuncActionInfo = findAppFunction(func.ChannelID, AppFunction::APP_AllDown);
             if(pFuncActionInfo != nullptr)
             {
                 /* 更新时间信息 */
@@ -1035,7 +1035,7 @@ bool ListFuncActInfo::addFuncActionInfo(const AppAndTimeInfo& func)
             }
             FuncActionInfo* fa = new FuncActionInfo;
             fa->ChannelID = func.ChannelID;
-            fa->appFunction = AppFunction::APP_ALLDOWN;
+            fa->appFunction = AppFunction::APP_AllDown;
             fa->strFunctionName = "摔倒识别";
             fa->StartTime = func.StartTime;
             fa->EndTime = func.EndTime;
@@ -1066,13 +1066,13 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     if(info.ActionID == g_actionList.ActFace)
     {
         /* 人员在岗识别 */
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_ONWORK);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_OnWork);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
         }
         /* 非法入侵检测 */
-        pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_ILLEGAL);
+        pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Illegal);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1081,7 +1081,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 人员计数 */
     else if (info.ActionID == g_actionList.ActPersonNumber)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_REGIONAL);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Regional);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1090,7 +1090,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 违禁物品 */
     else if (info.ActionID == g_actionList.ActContraband)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_CONTRABAND);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Contraband);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1099,7 +1099,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 玩手机 */
     else if (info.ActionID == g_actionList.ActPlayPhone)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_PLAYPHONE);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_PlayPhone);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1108,7 +1108,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 睡岗识别 */
     else if (info.ActionID == g_actionList.ActSleep)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_FATIGUE);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Fatigue);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1117,7 +1117,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 疲劳检测 */
     else if(info.ActionID == g_actionList.ActFatigueDetection)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_FATIGUE);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Fatigue);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1126,7 +1126,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 动物识别 */
     else if (info.ActionID == g_actionList.ActAnimalDetect)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_MOUSE);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Mouse);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1135,7 +1135,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 老鼠识别 */
     else if (info.ActionID == g_actionList.ActMouseDetect)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_MOUSE);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_Mouse);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);
@@ -1144,7 +1144,7 @@ bool ListFuncActInfo::addActionInfo(const ActionInfo& info)
     /* 口罩识别 */
     else if (info.ActionID == g_actionList.ActMask)
     {
-        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_NOMASK);
+        auto pFuncActionInfo = findAppFunction(info.ChannelID, AppFunction::APP_NoMask);
         if(pFuncActionInfo != nullptr)
         {
             pFuncActionInfo->addActionInfo(info);

+ 14 - 13
SecurePlayAuxServer/GlobalInfo/GlobalVariable.h

@@ -32,26 +32,27 @@ extern int g_eventTimeVaild;
 /* 线程运行时的状态 */
 enum class RunTimeState
 {
-    RUN_STATE_INIT = 0,         /* 初始化 */
+    RUN_STATE_NONE = 0,         /* 无状态 */
+    RUN_STATE_INIT,             /* 初始化 */
     RUN_STATE_RUN,              /* 运行 */
-    RUN_STATE_STOP,             /* 停止 */
+    RUN_STATE_STOP,             /* 停止,是外部给子线程的信号,让其退出 */
     RUN_STATE_ERROR,            /* 错误 */
-    RUN_STATE_NONE              /* 无状态 */
+    RUN_STATE_EXITCOMPLET,      /* 退出完成 */
 };
 
 /* 应用功能 */
 enum class AppFunction
 {
     APP_NONE = 0,               /* 无功能 */
-    APP_ONWORK = 1,             /* 人员在岗识别(需要多个摄像机配合) */
-    APP_CONTRABAND,             /* 违禁品识别 */
-    APP_ILLEGAL,                /* 非法入侵检测 */
-    APP_FATIGUE,                /* 疲劳检测 */
-    APP_REGIONAL,               /* 区域人员检测,人员计数(需要多个摄像机配合) */
-    APP_MOUSE,                  /* 老鼠识别 */
-    APP_PLAYPHONE,              /* 玩手机识别 */
-    APP_NOMASK,                 /* 未戴口罩识别 */
-    APP_ALLDOWN,                /* 摔倒识别 */
+    APP_OnWork = 1,             /* 人员在岗识别(需要多个摄像机配合) */
+    APP_Contraband,             /* 违禁品识别 */
+    APP_Illegal,                /* 非法入侵检测 */
+    APP_Fatigue,                /* 疲劳检测 */
+    APP_Regional,               /* 区域人员检测,人员计数(需要多个摄像机配合) */
+    APP_Mouse,                  /* 老鼠识别 */
+    APP_PlayPhone,              /* 玩手机识别 */
+    APP_NoMask,                 /* 未戴口罩识别 */
+    APP_AllDown,                /* 摔倒识别 */
 };
 
 
@@ -658,7 +659,7 @@ public:
  };
 
 /**
- * @brief 
+ * @brief 线程功能块
  * 
  */
  struct ListFuncActInfo

+ 40 - 31
SecurePlayAuxServer/GlobalInfo/UniversalFunc.cpp

@@ -8,36 +8,41 @@
  * @param strData Redis返回的源数据,JSON格式
  * @param alarmInfo 解析出来的数据
  */
- void parseRedisBaseData(const std::string& strData, AlarmInfo& alarmInfo)
- {
-     try
-     {
-         nJson json0;
-         json0 = nJson::parse(strData);
-         alarmInfo.AlarmID = json0["alarmId"].get<int>();
-         alarmInfo.ChannelID = json0["channel"].get<int>();
-         alarmInfo.PicUrl = json0["picUrl"].get<std::string>();
-         alarmInfo.ImageInfo = json0["imageInfo"].get<std::string>();
-         
-         /* 解析时间,需要将时间中的“T”换成空格 */
-         alarmInfo.StartTime = json0["beginTime"].get<std::string>();
-         std::replace(alarmInfo.StartTime.begin(), alarmInfo.StartTime.end(), 'T', ' ');
-         alarmInfo.EndTime = json0["endTime"].get<std::string>();
-         std::replace(alarmInfo.EndTime.begin(), alarmInfo.EndTime.end(), 'T', ' ');
-         alarmInfo.EventTime = json0["eventTime"].get<std::string>();
-         std::replace(alarmInfo.EventTime.begin(), alarmInfo.EventTime.end(), 'T', ' ');
-         
-     }
-     catch (const nJson::parse_error& e)
-     {
-         SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-         return;
-     }
-     catch (const nJson::type_error& e)
-     {
-         SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-         return;
-     }
+void parseRedisBaseData(const std::string& strData, AlarmInfo& alarmInfo)
+{
+    try
+    {
+        nJson json0;
+        json0 = nJson::parse(strData);
+        alarmInfo.AlarmID = json0["alarmId"].get<int>();
+        alarmInfo.ChannelID = json0["channel"].get<int>();
+        alarmInfo.PicUrl = json0["picUrl"].get<std::string>();
+        alarmInfo.ImageInfo = json0["imageInfo"].get<std::string>();
+        
+        /* 解析时间,需要将时间中的“T”换成空格 */
+        alarmInfo.StartTime = json0["beginTime"].get<std::string>();
+        std::replace(alarmInfo.StartTime.begin(), alarmInfo.StartTime.end(), 'T', ' ');
+        alarmInfo.EndTime = json0["endTime"].get<std::string>();
+        std::replace(alarmInfo.EndTime.begin(), alarmInfo.EndTime.end(), 'T', ' ');
+        alarmInfo.EventTime = json0["eventTime"].get<std::string>();
+        std::replace(alarmInfo.EventTime.begin(), alarmInfo.EventTime.end(), 'T', ' ');
+        
+    }
+    catch (const nJson::parse_error& e)
+    {
+        SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
+        return;
+    }
+    catch (const nJson::type_error& e)
+    {
+        SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
+        return;
+    }
+    catch (...)
+    {
+       SPDLOG_ERROR("解析Redis数据失败,其他错误!");
+       return;
+    }
  }
 
  /**
@@ -154,7 +159,11 @@ void parseRedisBBoxesData(const std::string& strData, AlarmInfo& alarmInfo)
         SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
         return;
     }
-
+    catch (...)
+    {
+       SPDLOG_ERROR("解析Redis数据失败,其他错误!");
+       return;
+    }
 }
 
 

+ 33 - 516
SecurePlayAuxServer/SPAServer.cpp

@@ -5,6 +5,7 @@
 #include "ThreadPool/ThreadPool.h"
 #include "GlobalInfo/GlobalVariable.h"
 #include "GlobalInfo/GlobalConfig.h"
+#include "UniversalFunc.h"
 
 #include <QApplication>
 #include <QVector>
@@ -21,12 +22,12 @@ SPAServer::SPAServer()
 
     /* 读取全局的配置文件 */
     QString strConfigFile = QApplication::applicationDirPath() + "/config.ini";
-    if(!g_config.readConfig(strConfigFile))
+    if(!GConfig.readConfig(strConfigFile))
     {
         /* 读取配置文件失败,直接退出程序 */
         return;
     }
-    g_config.printValue();
+    GConfig.printValue();
     
 
     m_threadRunning = true;
@@ -63,11 +64,12 @@ void SPAServer::startServer()
 
 /**
  * @brief 从基础平台获取算法信息和设备信息的线程函数
+ *        从基础平台获取算法信息和设备信息,然后更新到EQM数据库所对应的表中
  * 
  */
 void SPAServer::threadFromSuperBrain()
 {
-    SPDLOG_LOGGER_INFO(m_logger, "开启 fromSuperBrainThread 线程");
+    SPDLOG_LOGGER_INFO(m_logger, "开启 fromSuperBrainThread 线程, 获取算法和设备信息");
     /* 创建变量 */
     std::vector<AlgorithmInfo> vecAlgNewInfo;
     std::vector<DeviceInfo> vecDevNewInfo;
@@ -81,6 +83,7 @@ void SPAServer::threadFromSuperBrain()
         m_toEQMDataBase.getAlgorithmInfo(m_vecEqmAlgInfo);
         m_toEQMDataBase.getDeviceInfo(m_vecEqmDevInfo);
         m_toEQMDataBase.getDeviceAlgorithmInfo(m_vecEqmDevInfo, m_listDevIDDelete);
+
         /* 从超脑获取基础信息 */
         m_fromSuperBrain.getTaskTypeList(vecAlgNewInfo);
         m_fromSuperBrain.getDeviceList(vecDevNewInfo);
@@ -92,12 +95,16 @@ void SPAServer::threadFromSuperBrain()
 
         vecAlgNewInfo.clear();
         vecDevNewInfo.clear();
+
         /* 更新算法详细信息 */
         m_mutexActionInfo.lock();
         m_toEQMDataBase.getActionInfo(m_listActionInfo);
         m_mutexActionInfo.unlock();
+
+        /* 10秒更新一次 */
         std::this_thread::sleep_for(std::chrono::seconds(10));
     }
+    SPDLOG_LOGGER_INFO(m_logger, "退出 fromSuperBrainThread 线程");
 }
 
 /* 处理算法信息,返回值为true,说明有改变,需要重新读取 */
@@ -431,287 +438,6 @@ void SPAServer::threadFromRedis(const CameraThreadInfo& info)
     return;
 }
 
-// /* 解析Redis基础数据 */
-// void SPAServer::parseRedisData(const std::string& strData, AlarmInfo& alarmInfo)
-// {
-//     try
-//     {
-//         nJson json0;
-//         json0 = nJson::parse(strData);
-//         alarmInfo.AlarmID = json0["alarmId"].get<int>();
-//         alarmInfo.ChannelID = json0["channel"].get<int>();
-//         alarmInfo.PicUrl = json0["picUrl"].get<std::string>();
-//         alarmInfo.ImageInfo = json0["imageInfo"].get<std::string>();
-        
-//         /* 解析时间,需要将时间中的“T”换成空格 */
-//         alarmInfo.StartTime = json0["beginTime"].get<std::string>();
-//         std::replace(alarmInfo.StartTime.begin(), alarmInfo.StartTime.end(), 'T', ' ');
-//         alarmInfo.EndTime = json0["endTime"].get<std::string>();
-//         std::replace(alarmInfo.EndTime.begin(), alarmInfo.EndTime.end(), 'T', ' ');
-//         alarmInfo.EventTime = json0["eventTime"].get<std::string>();
-//         std::replace(alarmInfo.EventTime.begin(), alarmInfo.EventTime.end(), 'T', ' ');
-//         /* 判断bBoxes有无数据,有数据就解析,没数据就直接返回了 */
-//         nJson json1 = json0["bBoxes"];
-        
-//         std::string labelList;              /* 记录违禁品 */
-//         std::string bboxList;               /* 记录bbox */
-//         if(!json1.empty())
-//         {
-//             for(auto& it0 : json1)
-//             {
-//                 /* 如果status是true,就不是报警,直接跳过 */
-//                 bool status = it0["status"].get<bool>();
-//                 if(status)
-//                 {
-//                     continue;
-//                 }
-//                 /* 这一条Box数据报警了将其内容存储起来 */
-//                 alarmInfo.Is_Alarm = true;
-//                 /* 解析label,违禁品关键字,先判断这个是不是违禁品检测的算法ID */
-//                 if(alarmInfo.ActionID == g_actionList.ActContraband)
-//                 {
-//                     /* 解析报警,取出报警类型 */
-//                     nJson label = it0["label"];
-//                     for(auto& it1 : label)
-//                     {
-//                         std::string strLabel = it1.get<std::string>();
-//                         /* 检测是否已经加入到字符串中了 */
-//                         strLabel += "|";
-//                         if(labelList.find(strLabel) != std::string::npos)
-//                         {
-//                             continue;
-//                         }
-//                         labelList += strLabel;
-//                     }
-//                 }
-//                 /* 解析bbox,貌似是在图像中的位置 */
-//                 nJson bbox = it0["bbox"];
-//                 std::string strBbox;
-//                 for(auto& it1 : bbox)
-//                 {
-//                     strBbox += std::to_string(it1.get<int>()) + ",";
-//                 }
-//                 /* 去掉最后一个“,” */
-//                 if(!strBbox.empty())
-//                 {
-//                     strBbox.pop_back();
-//                 }
-//                 bboxList += strBbox + "|";
-//             }
-//             /* 去掉最后一个“|” */
-//             if(!labelList.empty())
-//             {
-//                 labelList.pop_back();
-//             }
-//             if(!bboxList.empty())
-//             {
-//                 bboxList.pop_back();
-//             }
-//             SPDLOG_LOGGER_DEBUG(m_logger, "违禁品列表:{}", labelList);
-//             SPDLOG_LOGGER_DEBUG(m_logger, "bbox列表:{}", bboxList);
-//         }
-        
-//         /* 如果有报警的Box */
-//         if(alarmInfo.Is_Alarm)
-//         {
-//             /* 添加报警信息的提示信息 */
-//             alarmInfo.BboxList = bboxList;
-//             if( (alarmInfo.ActionID == g_actionList.ActContraband) && !labelList.empty() )
-//             {
-//                 alarmInfo.ActionDes = fmt::format("出现违禁品[{}]告警", labelList);
-//                 SPDLOG_LOGGER_INFO(m_logger, "{}", alarmInfo.ActionDes);
-//             }else {
-//                 alarmInfo.ActionDes = json0["actionDes"].get<std::string>();
-//             }
-//             /* 判断有没有报警数据 */
-//             if(alarmInfo.ImageInfo.empty())
-//             {
-//                 SPDLOG_LOGGER_ERROR(m_logger, "有报警区域,但是没有图片信息");
-//                 return;
-//             }
-//             /* 如果是人员报警,就存储人员报警信息 */
-//             if(alarmInfo.ActionID == g_actionList.ActFace)
-//             {
-//                 nJson jsonArray = json0["personList"];
-//                 for(auto& it : jsonArray)
-//                 {
-//                     PersonInfo personInfo;
-//                     personInfo.PersonID = it["personId"].get<std::string>();
-//                     personInfo.PersonName = it["personName"].get<std::string>();
-//                     alarmInfo.vecPersonInfo.push_back(personInfo);
-//                 }
-//             }
-//         }
-
-        
-//     }
-//     catch (const nJson::parse_error& e)
-//     {
-//         SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-//         return;
-//     }
-//     catch (const nJson::type_error& e)
-//     {
-//         SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-//         return;
-//     }
-
-// }
-
-/**
- * @brief 解析Redis的基础通用数据,不包含bBoxes数组数据
- * 
- * @param strData Redis返回的源数据,JSON格式
- * @param alarmInfo 解析出来的数据
- */
-void SPAServer::parseRedisBaseData(const std::string& strData, AlarmInfo& alarmInfo)
-{
-    try
-    {
-        nJson json0;
-        json0 = nJson::parse(strData);
-        alarmInfo.AlarmID = json0["alarmId"].get<int>();
-        alarmInfo.ChannelID = json0["channel"].get<int>();
-        alarmInfo.PicUrl = json0["picUrl"].get<std::string>();
-        alarmInfo.ImageInfo = json0["imageInfo"].get<std::string>();
-        
-        /* 解析时间,需要将时间中的“T”换成空格 */
-        alarmInfo.StartTime = json0["beginTime"].get<std::string>();
-        std::replace(alarmInfo.StartTime.begin(), alarmInfo.StartTime.end(), 'T', ' ');
-        alarmInfo.EndTime = json0["endTime"].get<std::string>();
-        std::replace(alarmInfo.EndTime.begin(), alarmInfo.EndTime.end(), 'T', ' ');
-        alarmInfo.EventTime = json0["eventTime"].get<std::string>();
-        std::replace(alarmInfo.EventTime.begin(), alarmInfo.EventTime.end(), 'T', ' ');
-        
-    }
-    catch (const nJson::parse_error& e)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-        return;
-    }
-    catch (const nJson::type_error& e)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-        return;
-    }
-}
-
-/**
- * @brief 解析Redis的bBoxes数据,这个内容可能根据算法ID不同,内容不同
- * 
- * @param strData 
- * @param alarmInfo 
- */
-void SPAServer::parseRedisBBoxesData(const std::string& strData, AlarmInfo& alarmInfo)
-{
-    try
-    {
-        nJson json0;
-        json0 = nJson::parse(strData);
-        /* 判断bBoxes有无数据,有数据就解析,没数据就直接返回了 */
-        nJson json1 = json0["bBoxes"];
-        
-        std::string labelList;              /* 记录违禁品 */
-        std::list<std::string> listBbox;    /* 记录bbox */
-        if(!json1.empty())
-        {
-            for(auto& it0 : json1)
-            {
-                /* 如果status是true,就不是报警,直接跳过 */
-                bool status = it0["status"].get<bool>();
-                if(status)
-                {
-                    continue;
-                }
-                /* 这一条Box数据报警了将其内容存储起来 */
-                alarmInfo.Is_Alarm = true;
-                /* 解析label,违禁品关键字,先判断这个是不是违禁品检测的算法ID */
-                if(alarmInfo.ActionID == g_actionList.ActContraband)
-                {
-                    /* 解析报警,取出报警类型 */
-                    nJson label = it0["label"];
-                    for(auto& it1 : label)
-                    {
-                        std::string strLabel = it1.get<std::string>();
-                        /* 检测是否已经加入到字符串中了 */
-                        strLabel += "|";
-                        if(labelList.find(strLabel) != std::string::npos)
-                        {
-                            continue;
-                        }
-                        labelList += strLabel;
-                    }
-                }
-                /* 解析bbox,貌似是在图像中的位置 */
-                nJson bbox = it0["bbox"];
-                std::string strBbox;
-                for(auto& it1 : bbox)
-                {
-                    strBbox += std::to_string(it1.get<int>()) + ",";
-                }
-                /* 去掉最后一个“,” */
-                if(!strBbox.empty())
-                {
-                    strBbox.pop_back();
-                }
-                listBbox.push_back(strBbox);
-            }
-            /* 去掉最后一个“|” */
-            if(!labelList.empty())
-            {
-                labelList.pop_back();
-            }
-            SPDLOG_LOGGER_DEBUG(m_logger, "违禁品列表:{}", labelList);
-            
-        }
-        /* 如果有报警的Box,解析出报警的说明 */
-        if(alarmInfo.Is_Alarm)
-        {
-            /* 添加报警信息的提示信息 */
-            alarmInfo.listBbox = listBbox;
-            /* 违禁品报警信息,违禁品列表不是空的,就添加补充的文字 */
-            if( (alarmInfo.ActionID == g_actionList.ActContraband) && !labelList.empty() )
-            {
-                alarmInfo.ActionDes = fmt::format("出现违禁品[{}]告警", labelList);
-                SPDLOG_LOGGER_INFO(m_logger, "{}", alarmInfo.ActionDes);
-            }else {
-                /* 其他报警信息,直接获取 */
-                alarmInfo.ActionDes = json0["actionDes"].get<std::string>();
-            }
-            /* 判断有没有报警数据 */
-            if(alarmInfo.ImageInfo.empty())
-            {
-                SPDLOG_LOGGER_WARN(m_logger, "有报警区域,但是没有图片信息");
-                return;
-            }
-            /* 如果是人员报警,就存储人员报警信息 */
-            if(alarmInfo.ActionID == g_actionList.ActFace)
-            {
-                nJson jsonArray = json0["personList"];
-                for(auto& it : jsonArray)
-                {
-                    PersonInfo personInfo;
-                    personInfo.PersonID = it["personId"].get<std::string>();
-                    personInfo.PersonName = it["personName"].get<std::string>();
-                    alarmInfo.vecPersonInfo.push_back(personInfo);
-                }
-            }
-        }
-
-        
-    }
-    catch (const nJson::parse_error& e)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-        return;
-    }
-    catch (const nJson::type_error& e)
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
-        return;
-    }
-
-}
 
 
 /**
@@ -765,39 +491,34 @@ void SPAServer::threadRoomCamera()
 
     while (m_threadRunning)
     {
-        m_mutexRunFAI.lock();
+        GThreadInfo.lockRunFAI();
         /* 先清理已经退出的线程所用到的Action或者RoomAction */
-        m_runListFuncActInfo.clearNoneFuncActionInfo();
+        GThreadInfo.clearNoneFuncActionInfo();
 
         /* 创建应用信息,根据从EQM数据库读取到的配置的应用信息创建 */
         toEQMDataBase->getAlarmAppInfo(listAppAndTime);
         for(const auto& it : listAppAndTime)
         {
             /* 创建应用信息,如果已有该应用,就更新时间 */
-            m_runListFuncActInfo.addFuncActionInfo(it);
+            GThreadInfo.addFuncActionInfo(it);
         }
 
         /* 先获取EQM数据库信息,取出房间和摄像机关联信息 */
         m_mutexActionInfo.lock();
         toEQMDataBase->getActionInfo(m_listActionInfo);
         /* 将算法信息加入到不同的列表中 */
-        m_runListFuncActInfo.clearActionList();
+        GThreadInfo.clearActionList();
         for(const auto& it : m_listActionInfo.getData())
         {
-            m_runListFuncActInfo.addActionInfo(*it);
+            GThreadInfo.addActionInfo(*it);
         }
 
         /* 检查算法信息的状态,频率里的应用没有配置摄像机就设置为线程运行状态为停止,退出该线程 */
-        for(const auto& it : m_runListFuncActInfo.getData())
-        {
-            if(it->listRoomCamActInfo.size() == 0)
-            {
-                it->RunState = RunTimeState::RUN_STATE_STOP;
-            }
-        }
+        GThreadInfo.setNoneCameraFuncStop();
         m_mutexActionInfo.unlock();
+
         /* 开启线程 */
-        for(const auto& it0 : m_runListFuncActInfo.getData())
+        for(const auto& it0 : GThreadInfo.getList())
         {
             /* 人员在岗识别 */
 
@@ -808,20 +529,20 @@ void SPAServer::threadRoomCamera()
             /* 违禁品识别 */
             
             /* 普通任务线程,一个任务对应一个摄像机和一个算法ID,无需联动 */
-            if(it0->appFunction == AppFunction::APP_ALLDOWN)
+            if(it0->appFunction == AppFunction::APP_AllDown)
             {
                 if(it0->RunState == RunTimeState::RUN_STATE_INIT)
                 {
-                    CPPTP.add_task(&SPAServer::threadActNormal, this, it0);
+                    // CPPTP.add_task(&SPAServer::threadActNormal, this, it0);
                 }
             }
         }
         
 
-        m_mutexRunFAI.unlock();
+        GThreadInfo.unlockRunFAI();
 
         /* 休眠n秒,默认应该是300秒 */
-        std::this_thread::sleep_for(std::chrono::seconds(g_config.CheckSet));
+        std::this_thread::sleep_for(std::chrono::seconds(GConfig.CheckSet));
     }
 }
 
@@ -855,7 +576,7 @@ void SPAServer::threadActPersonWork(FuncActionInfo* RFAInfo)
     while (m_threadRunning)
     {
         /* 更新线程信息 */
-        updateFuncInfo(pRFAInfo);
+        GThreadInfo.updateFuncInfo(pRFAInfo.get());
         if(pRFAInfo->appFunction == AppFunction::APP_NONE)
         {
             break;
@@ -909,7 +630,7 @@ void SPAServer::threadActPersonWork(FuncActionInfo* RFAInfo)
                 it->MinNum = it->listPersonInfo.size();
             }
             /* 判断是否需要写入数据库,超过设置的时间就写入,默认是600秒 */
-            if(now.toSecsSinceEpoch() - it->StartTime.toSecsSinceEpoch() > g_config.AppUpdateOnWorkTimeInterval)
+            if(now.toSecsSinceEpoch() - it->StartTime.toSecsSinceEpoch() > GConfig.AppUpdateOnWorkTimeInterval)
             {
                 /* 写入数据库 */
                 if(toEQMDataBase->insertOnWorkInfo(*it))
@@ -922,9 +643,9 @@ void SPAServer::threadActPersonWork(FuncActionInfo* RFAInfo)
             }
             ++it;
         }
-        std::this_thread::sleep_for(std::chrono::milliseconds(g_config.ThreadSleepMS));
+        std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
     }
-    setThreadState(pRFAInfo, RunTimeState::RUN_STATE_STOP);
+    GThreadInfo.setThreadState(pRFAInfo.get(), RunTimeState::RUN_STATE_STOP);
     SPDLOG_LOGGER_INFO(m_logger, "关闭 {} 线程,ChannelID:{}", pRFAInfo->strFunctionName, pRFAInfo->ChannelID);
 }
 
@@ -976,7 +697,7 @@ void SPAServer::threadActIllegalInvasion(FuncActionInfo* RFAInfo)
     while (m_threadRunning)
     {
         /* 更新线程信息 */
-        updateFuncInfo(pRFAInfo);
+        GThreadInfo.updateFuncInfo(pRFAInfo.get());
         if(pRFAInfo->appFunction == AppFunction::APP_NONE)
         {
             break;
@@ -1113,7 +834,7 @@ void SPAServer::threadActIllegalInvasion(FuncActionInfo* RFAInfo)
                 /* 没有报警,检查是否是报警结束了,是否符合写入数据库的条件 */
                 QDateTime currTime = QDateTime::currentDateTime();
                 int secs = currTime.toSecsSinceEpoch() - pIll->FirstTime.toSecsSinceEpoch();
-                if(secs >= g_config.AppBadMan)
+                if(secs >= GConfig.AppBadMan)
                 {
                     if(!pIll->strImageInfo.empty())
                     {
@@ -1142,9 +863,9 @@ void SPAServer::threadActIllegalInvasion(FuncActionInfo* RFAInfo)
                 }
             }
         }
-        std::this_thread::sleep_for(std::chrono::milliseconds(g_config.ThreadSleepMS));
+        std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
     }
-    setThreadState(pRFAInfo, RunTimeState::RUN_STATE_STOP);
+    GThreadInfo.setThreadState(pRFAInfo.get(), RunTimeState::RUN_STATE_STOP);
     SPDLOG_LOGGER_INFO(m_logger, "关闭 {} 线程,ChannelID:{}", pRFAInfo->strFunctionName, pRFAInfo->ChannelID);
 }
 
@@ -1181,9 +902,9 @@ void SPAServer::threadActRegionalPersonnelDetection(FuncActionInfo* RFAInfo)
     
     while (m_threadRunning)
     {
-        std::this_thread::sleep_for(std::chrono::milliseconds(g_config.ThreadSleepMS));
+        std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
         /************ 更新线程信息 ************/
-        updateFuncInfo(pRFAInfo);
+        GThreadInfo.updateFuncInfo(pRFAInfo.get());
         if(pRFAInfo->appFunction == AppFunction::APP_NONE)
         {
             break;
@@ -1286,146 +1007,10 @@ void SPAServer::threadActRegionalPersonnelDetection(FuncActionInfo* RFAInfo)
         /************ 检测频率直播间 + 导播间房间的人数 ************/
 
     }
-    setThreadState(pRFAInfo, RunTimeState::RUN_STATE_STOP);
+    GThreadInfo.setThreadState(pRFAInfo.get(), RunTimeState::RUN_STATE_STOP);
     SPDLOG_LOGGER_INFO(m_logger, "关闭 {} 线程,ChannelID:{}", pRFAInfo->strFunctionName, pRFAInfo->ChannelID);
 }
 
-/**
- * @brief 普通任务识别,一个算法只需要一个摄像机,包括 违禁品识别、玩手机检测、老鼠等
-            1、报警判断条件:机房内出现摄像头的违禁物品识别算法输出结果包含指定违规内容时,记为报警行为,直接
-                展示报警结果
-            2、这里应该是不区分违禁物品是什么,只要有违禁物品就报警。如果一个违禁物品消失之前又出现了第二个违禁物品,
-                两个违禁物品都消失后,这次报警才会结束。
-            3、一有报警信息就写入到EQM数据库的tAlarmInfo表中,报警开始时间是EventTime
-            4、如果报警结束时间小于设置的最小间隔,就删除这条数据,超过这个时间,就更新结束时间
-            5、报警信息要有图片,如果当前没有图片,就使用上一张图片
- * 
- * @param info 线程信息
- */
-void SPAServer::threadActNormal(FuncActionInfo* info)
-{
-    SPDLOG_LOGGER_INFO(m_logger, "开启 {} 线程, ChannelID:{} ,App:{}",info->strFunctionName, info->ChannelID, info->strFunctionName);
-    /* 创建读取Redis的实例 */
-    std::shared_ptr<FromRedis> fromRedis = std::make_shared<FromRedis>();
-    /* 创建写入EQM数据库实例 */
-    std::shared_ptr<ToEQMDataBase> toEQMDataBase = std::make_shared<ToEQMDataBase>();
-    /* 局部变量,保存这个线程的信息 */
-    std::shared_ptr<FuncActionInfo> pFuncAct = std::make_shared<FuncActionInfo>();
-    *pFuncAct = *info;
-    /* 保存报警数据 */
-    std::shared_ptr<ListAlarmInfo> listAlarmInfo = std::make_shared<ListAlarmInfo>();
-
-    while (m_threadRunning)
-    {
-        /* 更新算法关联的摄像机ID */
-        updateFuncInfo(pFuncAct);
-        /* 如果线程的运行状态为 */
-        if(pFuncAct->RunState == RunTimeState::RUN_STATE_STOP)
-        {
-            pFuncAct->appFunction = AppFunction::APP_NONE;
-            break;
-        }
-        /* 读取Redis信息,处理数据 */
-        for(const auto& roomInfo : pFuncAct->listRoomCamActInfo)
-        {
-            for(const auto& it : roomInfo.mapCameraAction)
-            {
-                /* 读取Redis数据 */
-                std::string strKey = std::to_string(it.first) + ":" + it.second;
-                std::string strRetValue;
-                if(!fromRedis->getRedisString(strKey, strRetValue))
-                {
-                    SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
-                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
-                    continue;
-                }
-                /* 解析数据 */
-                AlarmInfo alarmInfo;
-                parseRedisBaseData(strRetValue, alarmInfo);
-                parseRedisBBoxesData(strRetValue, alarmInfo);
-                /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
-                if(isEventTimeVaild(alarmInfo.EventTime))
-                {
-                    SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, alarmInfo.EventTime);
-                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
-                    continue;
-                }
-                /* 找出数组中与当前报警ID相同的的报警信息 */
-                auto pAlarmInfo = listAlarmInfo->findAlarmInfo(alarmInfo);
-                if(pAlarmInfo == nullptr)
-                {
-                    /* 没有找到报警记录,就新建一个 */
-                    AlarmInfo newAlarmInfo = alarmInfo;
-                    listAlarmInfo->addAlarmInfo(newAlarmInfo);
-                    /* 重新查找该报警信息 */
-                    pAlarmInfo = listAlarmInfo->findAlarmInfo(alarmInfo);
-                    if(pAlarmInfo == nullptr)
-                    {
-                        SPDLOG_LOGGER_ERROR(m_logger, "查找报警信息失败, Key:{}", strKey);
-                        continue;
-                    }
-                }
-                /* 判断有无报警记录,新的报警就写入到EQM的tAlarmInfo表中,正在报警的记录就判断和更新,
-                * 结束报警就更新tAlarmInfo的报警数据的结束时间,并清空pAlarmInfo */
-                if(pAlarmInfo->Is_Alarm)
-                {
-                    /* 正在报警中,检查是否报警结束 */
-                    if(alarmInfo.Is_Alarm)
-                    {
-                        /* 更新图片信息 */
-                        if(!alarmInfo.ImageInfo.empty())
-                        {
-                            pAlarmInfo->ImageInfo = alarmInfo.ImageInfo;
-                        }
-                    } else {
-                        /* 报警结束,判断时长,更新数据库结束时间,结束时间是此时电脑时间 */
-                        if(timeDiffWithNow(pAlarmInfo->EventTime) > g_config.Contraband)
-                        {
-                            pAlarmInfo->EndTime = chronoToStrTime(std::chrono::system_clock::now());
-                            toEQMDataBase->updateAlarmEndTime(*pAlarmInfo);
-                        }else {
-                            /* 不够报警时间,目前不做任何处理,不删除EQM报警记录 */
-                        }
-
-                        /* 清空报警信息 */
-                        pAlarmInfo->reInit();
-                    }
-                }
-                else
-                {
-                    /* 是新的报警 */
-                    if(alarmInfo.Is_Alarm)
-                    {
-                        /* 图片不能是空,如果是空的,就不写入数据库 */
-                        if(!alarmInfo.ImageInfo.empty())
-                        {
-                            /* 违禁品检测,开始时间是事件时间 */
-                            alarmInfo.StartTime = alarmInfo.EventTime;
-                            alarmInfo.EndTime = "";
-                            if(toEQMDataBase->insertAlarmInfo(alarmInfo))
-                            {
-                                /* 保存新的报警记录 */
-                                *pAlarmInfo = alarmInfo;
-                            }else {
-                                SPDLOG_LOGGER_ERROR(m_logger, "写入tAlarmInfo报警数据失败, Key: {}", strKey);
-                            }
-                        }else {
-                            SPDLOG_LOGGER_ERROR(m_logger, "频道:{}, 房间:{}, 摄像机:{}, 算法:{}, 有报警区域, 但是没有图片信息", pFuncAct->ChannelID, roomInfo.RoomID, it.first, it.second);
-                        }
-                    }
-                }
-
-            }
-        }
-        
-        /* 休眠设置的时间 */
-        std::this_thread::sleep_for(std::chrono::seconds(g_config.ThreadSleepMS));
-    }
-    /* 设置线程退出的状态 */
-    setThreadState(pFuncAct, RunTimeState::RUN_STATE_STOP);
-    SPDLOG_LOGGER_INFO(m_logger, "{} 线程退出,Channel:{}",pFuncAct->strFunctionName, pFuncAct->ChannelID);
-}
-
 
 
 /* 将该算法对应的摄像机放入摄像机列表 */
@@ -1454,71 +1039,3 @@ bool SPAServer::insertCameraToAction(RoomActionInfo* pRAInfo, std::list<RoomCame
     }
     return true;
 }
-
-
-/**
- * @brief 功能线程更新功能信息,这里是从内存中的数组里获取
- * 
- * @param pInfo 
- * @return true 
- * @return false 
- */
- bool SPAServer::updateFuncInfo(std::shared_ptr<FuncActionInfo> pInfo)
-{
-    pInfo->clearActionList();
-    std::lock_guard<std::mutex> look(m_mutexRunFAI);
-    auto fa = m_runListFuncActInfo.findAppFunction(*pInfo);
-    if(fa == nullptr)
-    {
-        return false;
-    }
-    *pInfo = *fa;
-
-    return true;
-}
-
-/* 设置线程状态 */
-void SPAServer::setThreadState(std::shared_ptr<FuncActionInfo> pInfo, RunTimeState state)
-{
-    std::lock_guard<std::mutex> look(m_mutexRunFAI);
-    auto p = m_runListFuncActInfo.findAppFunction(*pInfo);
-    if(p != nullptr)
-    {
-        p->RunState = state;
-    }
-}
-
-
-
-/* 计算与当前时间的时间差,返回秒 */
-int SPAServer::timeDiffWithNow(const std::string& strTime)
-{
-    auto now = std::chrono::system_clock::now();
-
-    auto eventTime = strTimeToChrono(strTime);
-    std::chrono::duration<double> diff = now - eventTime;
-
-    return diff.count();
-}
-
-/* 字符串时间转换成std::chrono时间点 */
-std::chrono::system_clock::time_point SPAServer::strTimeToChrono(const std::string& strTime)
-{
-    std::istringstream iss(strTime);
-    std::tm tmEvent = {};
-    iss >> std::get_time(&tmEvent, "%Y-%m-%d %H:%M:%S");
-
-    return std::chrono::system_clock::from_time_t(std::mktime(&tmEvent));
-}
-
-/* 时间点转换成字符串 */
-std::string SPAServer::chronoToStrTime(const std::chrono::system_clock::time_point& timePoint)
-{
-    std::time_t time = std::chrono::system_clock::to_time_t(timePoint);
-    std::tm tmEvent = *std::localtime(&time);
-    char buf[64] = {0};
-    std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tmEvent);
-
-    return std::string(buf);
-}
-

+ 0 - 40
SecurePlayAuxServer/SPAServer.h

@@ -34,12 +34,6 @@ private:
     /* 从Redis获取数据线程函数,这个是摄像机线程(注意,这个函数未被使用,不从这里获取Redis数据) */
     void threadFromRedis(const CameraThreadInfo& info);
 
-    /* 解析Redis基础数据 */
-    // void parseRedisData(const std::string& strData, AlarmInfo& alarmInfo);
-    /* 解析Redis的基础通用数据,不包含bBoxes数组数据 */
-    void parseRedisBaseData(const std::string& strData, AlarmInfo& alarmInfo);
-    /* 解析Redis的bBoxes数据, */
-    void parseRedisBBoxesData(const std::string& strData, AlarmInfo& alarmInfo);
     /* 判断时间是否长时间没有更新 */
     bool isEventTimeVaild(const std::string& strTime);
 
@@ -52,26 +46,10 @@ private:
     void threadActIllegalInvasion(FuncActionInfo* RFAInfo);
     /* 区域人员检测(人员计数),检测这个区域内的人数,不能少于多少人,不能多余多少人 */
     void threadActRegionalPersonnelDetection(FuncActionInfo* RFAInfo);
-    /* 普通任务线程,一个算法值对应一个摄像机 */
-    void threadActNormal(FuncActionInfo* info);
-    
 
     /* 将该算法对应的摄像机放入摄像机列表 */
     bool insertCameraToAction(RoomActionInfo* pRAInfo, std::list<RoomCameraInfo>& listRC, std::multimap<int, std::string>& mapCameraActionID);
 
-    /* 更新算法的摄像机ID */
-    bool updateFuncInfo(std::shared_ptr<FuncActionInfo> pInfo);
-    /* 设置线程状态 */
-    void setThreadState(std::shared_ptr<FuncActionInfo> pInfo, RunTimeState state);
-
-
-    /* 计算与当前时间的时间差,返回秒 */
-    int timeDiffWithNow(const std::string& strTime);
-    /* 字符串时间转换成std::chrono时间点 */
-    std::chrono::system_clock::time_point strTimeToChrono(const std::string& strTime);
-    /* 时间点转换成字符串 */
-    std::string chronoToStrTime(const std::chrono::system_clock::time_point& timePoint);
-
 
 private:
     std::shared_ptr<spdlog::logger> m_logger = nullptr;
@@ -81,13 +59,6 @@ private:
     FromSuperBrain m_fromSuperBrain;
     ToEQMDataBase m_toEQMDataBase;
 
-    // std::mutex m_mutexActionID;                         /* 算法ID的互斥锁 */
-    // std::string ActPersonWork;                          /* 人员在岗识别 */
-    // std::string ActPersonNumber;                        /* 区域人员检测(区域人员计数) */
-    // std::string ActIllegalInvasion;                     /* 非法入侵检测 */
-    // std::string ActContraband;                          /* 违禁品检测 */
-    // std::string ActFatigueDetection;                    /* 疲劳检测 */
-
     /* 算法信息,这个就是tAction在内存中的数据,方便后续对比,程序启动的时候会先获取一份 */
     std::vector<AlgorithmInfo> m_vecEqmAlgInfo;
     /* 设备信息,这个是tActionCamer的信息 */
@@ -98,17 +69,6 @@ private:
     /* 设备和算法关联信息,这里存储着已经删除的设备对应的算法信息,将在这一轮循环中删除 */
     std::list<int> m_listDevIDDelete;
 
-
-    // /* 房间和算法关联的信息,包含所需要的摄像机ID */
-    // std::mutex m_mutexRunRAI;
-    // ListRoomActionInfo m_runListRoomActionInfo;
-    // /* 运行时的算法信息列表,这个容器存储的是不需要摄像机融合的算法 */
-    // std::mutex m_mutexRunAI;
-    // ListActionInfo m_runListActionInfo;
-    /* 运行时应用线程功能相关信息 */
-    std::mutex m_mutexRunFAI;
-    ListFuncActInfo m_runListFuncActInfo;
-
 };
 
 #endif /* SPASERVER_H */

+ 97 - 48
SecurePlayAuxServer/communication/FromSuperBrain.cpp

@@ -3,7 +3,7 @@
 
 #include "CurlHttp.h"
 #include "fmt.h"
-#include "GlobalInfo.h"
+#include "GlobalVariable.h"
 
 
 FromSuperBrain::FromSuperBrain()
@@ -43,15 +43,35 @@ bool FromSuperBrain::getToken()
     }
     // SPDLOG_LOGGER_DEBUG(m_logger, "response:{}", response);
     /* 解析json信息 */
-    nJson json0 = nJson::parse(response);
-    auto code = json0["code"].get<std::string>();
-    if(code != "0")
+    try
     {
-        SPDLOG_LOGGER_ERROR(m_logger, "Get Token failed");
+        nJson json0 = nJson::parse(response);
+        auto code = json0["code"].get<std::string>();
+        if(code != "0")
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "Get Token failed");
+            return false;
+        }
+        json0["data"]["accessToken"].get_to(m_token);
+        // SPDLOG_LOGGER_DEBUG(m_logger, "Token:{}", m_token);
+    }catch (const nJson::parse_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 Token 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch (const nJson::type_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 Token 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(const std::exception& e)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 Token 数据失败:{}",e.what());
+        return false;
+    }
+    catch(...)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 Token 数据失败");
         return false;
     }
-    json0["data"]["accessToken"].get_to(m_token);
-    // SPDLOG_LOGGER_DEBUG(m_logger, "Token:{}", m_token);
 
     return true;
 }
@@ -75,22 +95,37 @@ bool FromSuperBrain::getTaskTypeList(std::vector<AlgorithmInfo>& vecInfo)
     }
     // SPDLOG_LOGGER_DEBUG(m_logger, "TaskTypeList: \n{}", response);
     /* 解析json信息 */
-    nJson json0 = nJson::parse(response);
-    auto retCode = json0.at("code").get<std::string>();
-    if(retCode != "0")
+    try
     {
-        SPDLOG_LOGGER_ERROR(m_logger, "Get TaskTypeList failed");
+        nJson json0 = nJson::parse(response);
+        auto retCode = json0.at("code").get<std::string>();
+        if(retCode != "0")
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "Get TaskTypeList failed");
+            return false;
+        }
+        auto data = json0.at("data");
+        for(auto& it : data)
+        {
+            // SPDLOG_LOGGER_DEBUG(m_logger, "muAiName:{}", it["muAiName"].get<std::string>());
+            AlgorithmInfo info;
+            info.ActionID = it.at("ability").get<std::string>();
+            info.ActionName = it.at("muAiName").get<std::string>();
+            info.ActionTaskID = it["taskTypeId"].get<int>();
+            vecInfo.push_back(info);
+        }
+    }
+    catch (const nJson::parse_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 算法列表 数据失败:{}, 错误ID:{}",e.what(), e.id);
         return false;
     }
-    auto data = json0.at("data");
-    for(auto& it : data)
-    {
-        // SPDLOG_LOGGER_DEBUG(m_logger, "muAiName:{}", it["muAiName"].get<std::string>());
-        AlgorithmInfo info;
-        info.ActionID = it.at("ability").get<std::string>();
-        info.ActionName = it.at("muAiName").get<std::string>();
-        info.ActionTaskID = it["taskTypeId"].get<int>();
-        vecInfo.push_back(info);
+    catch (const nJson::type_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 算法列表 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 算法列表 数据失败");
+        return false;
     }
 
     return true;
@@ -115,38 +150,52 @@ bool FromSuperBrain::getDeviceList(std::vector<DeviceInfo>& vecInfo)
     }
     // SPDLOG_LOGGER_DEBUG(m_logger, "DeivceList: \n{}", response);
     /* 解析JSON信息 */
-    nJson json0 = nJson::parse(response);
-    auto retCode = json0.at("code").get<std::string>();
-    if(retCode != "0")
+    try
     {
-        SPDLOG_LOGGER_ERROR(m_logger, "Get DeviceList failed");
-        return false;
-    }
-    DeviceInfo info;
-    nJson json1 = json0["data"];
-    for(const auto& it : json1)
-    {
-        info.DeviceID = it["deviceId"].get<int>();
-        info.DeviceName = it["deviceName"].is_null() ? "" : it["deviceName"].get<std::string>();
-        info.DeviceSerial = it["deviceSerial"].is_null() ? "" : it["deviceSerial"].get<std::string>();
-        info.DeviceType = it["deviceType"].is_null() ? "" : it["deviceType"].get<std::string>();
-        /* 这三个可能是null */
-        info.DevicePort = it["port"].is_null() ? 0 : it["port"].get<int>();
-        info.UserAccount = it["userAccount"].is_null() ? "" : it["userAccount"].get<std::string>();
-        info.UserPassword = it["userPWD"].is_null() ? "" : it["userPWD"].get<std::string>();
-        /* 解析任务类型列表 */
-        nJson json2 = it["taskTypeList"];
-        for(const auto& it1 : json2)
+        nJson json0 = nJson::parse(response);
+        auto retCode = json0.at("code").get<std::string>();
+        if(retCode != "0")
         {
-            AlgorithmInfo info1;
-            info1.ActionID = it1["ability"].get<std::string>();
-            info1.ActionName = it1["taskTypeName"].get<std::string>();
-            info1.ActionTaskID = it1["taskTypeId"].get<int>();
-            info.vecAlgorithmInfo.push_back(info1);
+            SPDLOG_LOGGER_ERROR(m_logger, "Get DeviceList failed");
+            return false;
         }
-        vecInfo.push_back(info);
+        DeviceInfo info;
+        nJson json1 = json0["data"];
+        for(const auto& it : json1)
+        {
+            info.DeviceID = it["deviceId"].get<int>();
+            info.DeviceName = it["deviceName"].is_null() ? "" : it["deviceName"].get<std::string>();
+            info.DeviceSerial = it["deviceSerial"].is_null() ? "" : it["deviceSerial"].get<std::string>();
+            info.DeviceType = it["deviceType"].is_null() ? "" : it["deviceType"].get<std::string>();
+            /* 这三个可能是null */
+            info.DevicePort = it["port"].is_null() ? 0 : it["port"].get<int>();
+            info.UserAccount = it["userAccount"].is_null() ? "" : it["userAccount"].get<std::string>();
+            info.UserPassword = it["userPWD"].is_null() ? "" : it["userPWD"].get<std::string>();
+            /* 解析任务类型列表 */
+            nJson json2 = it["taskTypeList"];
+            for(const auto& it1 : json2)
+            {
+                AlgorithmInfo info1;
+                info1.ActionID = it1["ability"].get<std::string>();
+                info1.ActionName = it1["taskTypeName"].get<std::string>();
+                info1.ActionTaskID = it1["taskTypeId"].get<int>();
+                info.vecAlgorithmInfo.push_back(info1);
+            }
+            vecInfo.push_back(info);
+        }
+    }
+    catch (const nJson::parse_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 设备列表 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch (const nJson::type_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 设备列表 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 设备列表 数据失败");
+        return false;
     }
-    
 
     return true;
 }

+ 153 - 84
SecurePlayAuxServer/communication/ToEQMDataBase.cpp

@@ -101,24 +101,39 @@ bool ToEQMDataBase::writeAlgorithmInfo(std::vector<AlgorithmInfo>& vecInfo)
     //     }
     // }
     /* 循环写入数据 */
-    for(const auto& it : vecInfo)
+    try
     {
-        QString retStr;
-        /* 操作名称,现在一次性将设备位置和线条信息都下载下来 */
-        nJson json0;
-        json0["opName"] = "SPSS_InsertToAction";
-        nJson json1;
-        json1["actionID"] = it.ActionID;                    /* 算法ID */
-        json1["actionName"] = it.ActionName;                /* 算法名称 */
-        json1["actionTaskID"] = it.ActionTaskID;            /* 算法类型 */
-        json0["paramList"] = json1;
-        QString strCmd = QString::fromStdString(json0.dump());
-        int ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Insert, strCmd, retStr);
-        if(ret < 0)
+        for(const auto& it : vecInfo)
         {
-            SPDLOG_LOGGER_DEBUG(m_logger,"写入tAction失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
+            QString retStr;
+            /* 操作名称,现在一次性将设备位置和线条信息都下载下来 */
+            nJson json0;
+            json0["opName"] = "SPSS_InsertToAction";
+            nJson json1;
+            json1["actionID"] = it.ActionID;                    /* 算法ID */
+            json1["actionName"] = it.ActionName;                /* 算法名称 */
+            json1["actionTaskID"] = it.ActionTaskID;            /* 算法类型 */
+            json0["paramList"] = json1;
+            QString strCmd = QString::fromStdString(json0.dump());
+            int ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Insert, strCmd, retStr);
+            if(ret < 0)
+            {
+                SPDLOG_LOGGER_DEBUG(m_logger,"写入tAction失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
+            }
+            SPDLOG_LOGGER_DEBUG(m_logger,"写入一条算法 {} 到 tAction成功!", it.ActionID);
         }
-        SPDLOG_LOGGER_DEBUG(m_logger,"写入一条算法 {} 到 tAction成功!", it.ActionID);
+    }
+    catch (const nJson::parse_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 算法JSON 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch (const nJson::type_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 算法JSON 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 算法JSON 数据失败");
+        return false;
     }
 
     return true;
@@ -195,8 +210,17 @@ bool ToEQMDataBase::getAlgorithmInfo(std::vector<AlgorithmInfo>& vecInfo)
             // SPDLOG_LOGGER_DEBUG(m_logger,"ActionID:{}, ActionName:{}, ActionTaskID:{}",info.ActionID,info.ActionName,info.ActionTaskID);
             vecInfo.push_back(info);
         }
-    } catch (const nJson::parse_error& e) {
-        SPDLOG_LOGGER_ERROR(m_logger,"解析tAction数据失败:{}",e.what());
+    }
+    catch (const nJson::parse_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 tAction 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch (const nJson::type_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 tAction 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 tAction 数据失败");
         return false;
     }
 
@@ -217,55 +241,70 @@ bool ToEQMDataBase::insertDeviceInfo(std::vector<DeviceInfo>& vecInfo)
         return false;
     }
     bool isSuccess = true;
-    for(const auto& it : vecInfo)
-    {
-        nJson json0;
-        json0["opName"] = "SPSS_InsertToCamerInfo";
-        nJson json1;
-        /* 这里不知道是不是“?”运算符的等级是不是不够,不加括号会报错 */
-        json1["camerID"] = it.DeviceID;
-        json1["camerName"] =  it.DeviceName;
-        json1["camerIP"] = it.DeviceIP;
-        json1["camerPort"] = it.DevicePort;
-        json1["camerUser"] = it.UserAccount;
-        json1["camerPwd"] = it.UserPassword;
-        json1["camerType"] = it.DeviceType;
-        json1["camerSerial"] = it.DeviceSerial;
-        json1["camerChannel"] = nullptr;
-        json1["camerUrl"] = nullptr;
-
-        json0["paramList"] = json1;
-        QString strCmd = QString::fromStdString(json0.dump());
-        QString strRet;
-        auto ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Insert, strCmd, strRet);
-        if(ret < 0)
-        {
-            SPDLOG_LOGGER_DEBUG(m_logger,"插入设备信息失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
-            isSuccess = false;
-        }
-        SPDLOG_LOGGER_DEBUG(m_logger,"插入ID {} 信息到 CamerInfo 成功!", it.DeviceID);
-    }
-    /* 插入信息到tActionCamer表 */
-    for(const auto& it0 : vecInfo)
+    try
     {
-        for(const auto& it1 : it0.vecAlgorithmInfo)
+        for(const auto& it : vecInfo)
         {
             nJson json0;
-            json0["opName"] = "SPSS_InsertToActionCamer";
+            json0["opName"] = "SPSS_InsertToCamerInfo";
             nJson json1;
-            json1["actionID"] = it1.ActionID;
-            json1["camerID"] = it0.DeviceID;
+            /* 这里不知道是不是“?”运算符的等级是不是不够,不加括号会报错 */
+            json1["camerID"] = it.DeviceID;
+            json1["camerName"] =  it.DeviceName;
+            json1["camerIP"] = it.DeviceIP;
+            json1["camerPort"] = it.DevicePort;
+            json1["camerUser"] = it.UserAccount;
+            json1["camerPwd"] = it.UserPassword;
+            json1["camerType"] = it.DeviceType;
+            json1["camerSerial"] = it.DeviceSerial;
+            json1["camerChannel"] = nullptr;
+            json1["camerUrl"] = nullptr;
+
             json0["paramList"] = json1;
             QString strCmd = QString::fromStdString(json0.dump());
             QString strRet;
             auto ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Insert, strCmd, strRet);
             if(ret < 0)
             {
-                SPDLOG_LOGGER_DEBUG(m_logger,"插入设备信息到tActionCamer失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
+                SPDLOG_LOGGER_DEBUG(m_logger,"插入设备信息失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
                 isSuccess = false;
             }
-            SPDLOG_LOGGER_DEBUG(m_logger,"插入DeviceID {} 和 ActionID {} 到 ActionCamer 成功!", it0.DeviceID, it1.ActionID);
+            SPDLOG_LOGGER_DEBUG(m_logger,"插入ID {} 信息到 CamerInfo 成功!", it.DeviceID);
         }
+        /* 插入信息到tActionCamer表 */
+        for(const auto& it0 : vecInfo)
+        {
+            for(const auto& it1 : it0.vecAlgorithmInfo)
+            {
+                nJson json0;
+                json0["opName"] = "SPSS_InsertToActionCamer";
+                nJson json1;
+                json1["actionID"] = it1.ActionID;
+                json1["camerID"] = it0.DeviceID;
+                json0["paramList"] = json1;
+                QString strCmd = QString::fromStdString(json0.dump());
+                QString strRet;
+                auto ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Insert, strCmd, strRet);
+                if(ret < 0)
+                {
+                    SPDLOG_LOGGER_DEBUG(m_logger,"插入设备信息到tActionCamer失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
+                    isSuccess = false;
+                }
+                SPDLOG_LOGGER_DEBUG(m_logger,"插入DeviceID {} 和 ActionID {} 到 ActionCamer 成功!", it0.DeviceID, it1.ActionID);
+            }
+        }
+    }
+    catch (const nJson::parse_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 设备信息JSON 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch (const nJson::type_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 设备信息JSON 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 设备信息JSON 数据失败");
+        return false;
     }
 
     return isSuccess;
@@ -285,35 +324,47 @@ bool ToEQMDataBase::updateDeviceInfo(std::vector<DeviceInfo>& vecUpdateInfo)
         return false;
     }
     bool isSuccess = true;
-
-    for(const auto& it : vecUpdateInfo)
-    {
-        nJson json0;
-        json0["opName"] = "SPSS_UpdateToCamerInfo";
-        nJson json1;
-        json1["camerID"] = it.DeviceID;
-        json1["camerName"] =  it.DeviceName;
-        json1["camerIP"] = it.DeviceIP;
-        json1["camerPort"] = it.DevicePort;
-        json1["camerUser"] = it.UserAccount;
-        json1["camerPwd"] = it.UserPassword;
-        json1["camerType"] = it.DeviceType;
-        json1["camerSerial"] = it.DeviceSerial;
-        json1["camerChannel"] = nullptr;
-        json1["camerUrl"] = nullptr;
-
-        json0["paramList"] = json1;
-        QString strCmd = QString::fromStdString(json0.dump());
-        QString strRet;
-        auto ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Update, strCmd, strRet);
-        if(ret < 0)
+    try{
+        for(const auto& it : vecUpdateInfo)
         {
-            SPDLOG_LOGGER_DEBUG(m_logger,"更新设备信息失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
-            isSuccess = false;
+            nJson json0;
+            json0["opName"] = "SPSS_UpdateToCamerInfo";
+            nJson json1;
+            json1["camerID"] = it.DeviceID;
+            json1["camerName"] =  it.DeviceName;
+            json1["camerIP"] = it.DeviceIP;
+            json1["camerPort"] = it.DevicePort;
+            json1["camerUser"] = it.UserAccount;
+            json1["camerPwd"] = it.UserPassword;
+            json1["camerType"] = it.DeviceType;
+            json1["camerSerial"] = it.DeviceSerial;
+            json1["camerChannel"] = nullptr;
+            json1["camerUrl"] = nullptr;
+
+            json0["paramList"] = json1;
+            QString strCmd = QString::fromStdString(json0.dump());
+            QString strRet;
+            auto ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Update, strCmd, strRet);
+            if(ret < 0)
+            {
+                SPDLOG_LOGGER_DEBUG(m_logger,"更新设备信息失败:{}, 错误信息:{}",ret,m_httpApi->DoGetLastError(&ret).toStdString());
+                isSuccess = false;
+            }
+            SPDLOG_LOGGER_DEBUG(m_logger,"更新ID {} 信息到 CamerInfo 成功!", it.DeviceID);
         }
-        SPDLOG_LOGGER_DEBUG(m_logger,"更新ID {} 信息到 CamerInfo 成功!", it.DeviceID);
     }
-
+    catch (const nJson::parse_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 更新设备信息JSON 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch (const nJson::type_error& e) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 更新设备信息JSON 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...) {
+        SPDLOG_LOGGER_ERROR(m_logger,"创建 更新设备信息JSON 数据失败");
+        return false;
+    }
 
 
     return isSuccess;
@@ -402,17 +453,20 @@ bool ToEQMDataBase::getDeviceInfo(std::vector<DeviceInfo>& vecInfo)
             info.UserPassword = it["camerPwd"].is_null() ? "" : it["camerPwd"].get<std::string>();
             info.DeviceType = it["camerType"].is_null() ? "" : it["camerType"].get<std::string>();
             info.DeviceSerial = it["camerSerial"].is_null() ? "" : it["camerSerial"].get<std::string>();
-            
 
             vecInfo.push_back(info);
         }
     }
     catch (const nJson::parse_error& e) {
-        SPDLOG_LOGGER_ERROR(m_logger,"解析CamerInfo数据失败:{}, 错误ID:{}",e.what(), e.id);
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 CamerInfo数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id);
         return false;
     }
     catch (const nJson::type_error& e) {
-        SPDLOG_LOGGER_ERROR(m_logger,"解析CamerInfo数据失败:{}, 错误ID:{}",e.what(), e.id);
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 CamerInfo数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...) {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 CamerInfo数据失败 数据失败");
         return false;
     }
 
@@ -726,11 +780,16 @@ bool ToEQMDataBase::getActionInfo(ListActionInfo& listInfo)
         }
     }
     catch (const nJson::parse_error& e) {
-        SPDLOG_LOGGER_ERROR(m_logger,"解析ActionCamer数据失败:{}, 错误ID:{}",e.what(), e.id);
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 ActionCamer 数据失败:{}, 错误ID:{}",e.what(), e.id);
         return false;
     }
     catch (const nJson::type_error& e) {
-        SPDLOG_LOGGER_ERROR(m_logger,"解析ActionCamer数据失败:{}, 错误ID:{}",e.what(), e.id);
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 ActionCamer 数据失败:{}, 错误ID:{}",e.what(), e.id);
+        return false;
+    }
+    catch(...)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析 ActionCamer 数据失败");
         return false;
     }
 
@@ -803,6 +862,16 @@ bool ToEQMDataBase::getRoomCameraInfo(std::list<RoomCameraInfo>& vecInfo)
         SPDLOG_LOGGER_ERROR(m_logger,"解析ActionCamer数据失败:{}, 错误ID:{}",e.what(), e.id);
         return false;
     }
+    catch(const std::exception& e)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析ActionCamer数据失败:{}",e.what());
+        return false;
+    }
+    catch(...)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger,"解析ActionCamer数据失败");
+        return false;
+    }
 
     return true;
 }

+ 1 - 0
SecurePlayAuxServer/communication/ToEQMDataBase.h

@@ -13,6 +13,7 @@ public:
 
     /* 初始化WebAPI */
     bool initWebApi(const QString& url,const QString& serverIP,const QString& serID);
+    
     /* 写入算法信息,写入tAction表 */
     bool writeAlgorithmInfo(std::vector<AlgorithmInfo>& vecInfo);
     /* 删除算法信息 */