Browse Source

V0.5.3
1、完成了区域人员检测功能

Apple 1 month ago
parent
commit
76efd2e9f2

+ 6 - 1
SQL/SecurePlay.sqlbook

@@ -96,13 +96,18 @@ VALUES (:roomID, :camerID);
 SELECT *
 FROM "tAlarmInfo";
 
+#倒叙显示报警信息
+SELECT *
+FROM "tAlarmInfo"
+ORDER BY "PKID" DESC;
+
 #插入报警信息
 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")
 OUTPUT INSERTED."PKID"
-VALUES(@AlarmID, @StartTime, @CreateTime, @EndTime, @bBox, @PicUrl, @AppID, @ActionID, @ActionDes, @CamerID, @RoomID, @chnID, @Stat, @FaceIDList, @FaceNameList, @OnWork);
+VALUES(@alarmID, @startTime, @createTime, @endTime, @bbox, @picUrl, @appID, @actionID, @actionDes, @camerID, @roomID, @chnid, @state, @faceIDList, @faceNameList, @onWork);
 
 
 

+ 5 - 3
SecurePlayAuxServer/Application/FuncBase.cpp

@@ -49,7 +49,7 @@ void FuncBase::thread_task()
         SPDLOG_LOGGER_ERROR(m_logger, "未设置线程功能信息");
         return;
     }
-    SPDLOG_LOGGER_INFO(m_logger, "开启频道: [{}:{}] “{}”功能线程", m_funcThreadInfo.strChannelName, m_funcThreadInfo.ChannelID, m_funcThreadInfo.strFunctionName);
+    SPDLOG_LOGGER_INFO(m_logger, "---------------------- 开启频道: [{}:{}] “{}”功能 ----------------------", m_funcThreadInfo.strChannelName, m_funcThreadInfo.ChannelID, m_funcThreadInfo.strFunctionName);
     for(auto& room : m_funcThreadInfo.listRoomCamActInfo)
     {
         for(auto& cam : room.mapCameraAction)
@@ -60,15 +60,17 @@ void FuncBase::thread_task()
             }
         }
     }
+    /* 设置线程的全局运行状态 */
+    GThreadInfo.setThreadState(m_funcThreadInfo, RunTimeState::RUN_STATE_RUN);
     /* 设置线程运行状态 */
     m_bRunning = true;
     /* 设置初始化字符串 */
-    m_baseLog = fmt::format("★ 频道[{}] 功能线程[{}] ", m_funcThreadInfo.strChannelName, m_funcThreadInfo.strFunctionName);
+    m_baseLog = fmt::format("★  频道[{}] 功能线程[{}] ", m_funcThreadInfo.strChannelName, m_funcThreadInfo.strFunctionName);
     /* 执行线程功能,会一直阻塞,直到退出 */
     task();
     /* 设置线程退出的状态,设置成 RUN_STATE_EXITCOMPLET ,就会被管理线程回收 */
     GThreadInfo.setThreadState(m_funcThreadInfo, RunTimeState::RUN_STATE_EXITCOMPLET);
-    SPDLOG_LOGGER_INFO(m_logger, "{}}退出", m_baseLog);
+    SPDLOG_LOGGER_INFO(m_logger, "{} 退出", m_baseLog);
     m_bRunning = false;
 }
 

+ 5 - 6
SecurePlayAuxServer/Application/FuncOrdinary.cpp

@@ -42,7 +42,7 @@ void FuncOrdinary::task()
         if(m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP)
         {
             /* 退出线程 */
-            break;
+            return;
         }
 
         /* 判断是否在检测时间段内 */
@@ -69,14 +69,13 @@ void FuncOrdinary::task()
                         std::this_thread::sleep_for(std::chrono::milliseconds(10));
                         continue;
                     }
-                    SPDLOG_LOGGER_DEBUG(m_logger, "数据:{}", strRetValue);
 
                     /* 解析数据,先设置基础数据 */
-                    // AlarmInfo newAlarmInfo;
-                    // newAlarmInfo.ActionID = act;
-                    // newAlarmInfo.appFunction = m_funcThreadInfo.appFunction;
+                    AlarmInfo newAlarmInfo;
+                    newAlarmInfo.ActionID = act;
+                    newAlarmInfo.appFunction = m_funcThreadInfo.appFunction;
 
-                    // parseRedisBaseData(strRetValue, newAlarmInfo);
+                    parseRedisBaseData(strRetValue, newAlarmInfo);
                     // parseRedisBBoxesData(strRetValue, newAlarmInfo);
                     /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
                     // if(isEventTimeVaild(newAlarmInfo.EventTime))

+ 315 - 157
SecurePlayAuxServer/Application/FuncRegionalPerson.cpp

@@ -12,6 +12,8 @@
 
 PersonCountRuleInfo::PersonCountRuleInfo()
 {
+    isUpdate = false;
+    noRule = false;
     ChannelID = -1;
     // week = 0;
     // RuleType = Enum_PeriodType::PERIOD_ALL;
@@ -59,55 +61,20 @@ PersonCountRuleInfo& PersonCountRuleInfo::operator=(PersonCountRuleInfo& other)
     return *this;
 }
 
-
-EndAlarmParam::EndAlarmParam()
-{
-    ChannelID = -1;
-    AppID = AppFunction::APP_NONE;
-    CameraID = -1;
-    insertAlarmNum = 0;
-}
-
-EndAlarmParam::EndAlarmParam(const EndAlarmParam& other)
-{
-    ChannelID = other.ChannelID;
-    AppID = other.AppID;
-    CameraID = other.CameraID;
-    insertAlarmNum = other.insertAlarmNum;
-}
-
-EndAlarmParam& EndAlarmParam::operator=(const EndAlarmParam& other)
-{
-    if(this != &other)
-    {
-        ChannelID = other.ChannelID;
-        AppID = other.AppID;
-        CameraID = other.CameraID;
-        insertAlarmNum = other.insertAlarmNum;
-    }
-    return *this;
-}
-
-bool EndAlarmParam::operator==(const EndAlarmParam& other)
+/* 对比规则需不需要更新 */
+bool PersonCountRuleInfo::equals(const PersonCountRuleInfo& other) const 
 {
-    if(this == &other)
-    {
-        return true;
-    }
-    if(ChannelID != other.ChannelID)
-    {
+    if (ChannelID != other.ChannelID) {
         return false;
     }
-    if(AppID != other.AppID)
-    {
+    if (LiveMinEnable != other.LiveMinEnable || LiveMaxEnable != other.LiveMaxEnable ||
+        DicMinEnable != other.DicMinEnable || DicMaxEnable != other.DicMaxEnable ||
+        LiveDicMinEnable != other.LiveDicMinEnable || LiveDicMaxEnable != other.LiveDicMaxEnable) {
         return false;
     }
-    if(CameraID != other.CameraID)
-    {
-        return false;
-    }
-    if(insertAlarmNum != other.insertAlarmNum)
-    {
+    if (LiveMin != other.LiveMin || LiveMax != other.LiveMax ||
+        DicMin != other.DicMin || DicMax != other.DicMax ||
+        LiveDicMin != other.LiveDicMin || LiveDicMax != other.LiveDicMax) {
         return false;
     }
     return true;
@@ -146,7 +113,7 @@ RoomPeopleInfo& RoomPeopleInfo::operator=(const RoomPeopleInfo& other)
 
 AlarmBuffer::AlarmBuffer()
 {
-    isMax = false;
+    // isMax = false;
     // isInsertDB = false;
     ChannelID = -1;
     RoomID = -1;
@@ -160,7 +127,7 @@ AlarmBuffer::AlarmBuffer()
 
 AlarmBuffer::AlarmBuffer(const AlarmBuffer& other)
 {
-    isMax = other.isMax;
+    // isMax = other.isMax;
     // isInsertDB = other.isInsertDB;
     ChannelID = other.ChannelID;
     RoomID = other.RoomID;
@@ -175,7 +142,7 @@ AlarmBuffer::AlarmBuffer(const AlarmBuffer& other)
 AlarmBuffer& AlarmBuffer::operator=(const AlarmBuffer& other)
 {
     if (this != &other) {
-        isMax = other.isMax;
+        // isMax = other.isMax;
         // isInsertDB = other.isInsertDB;
         ChannelID = other.ChannelID;
         RoomID = other.RoomID;
@@ -245,12 +212,24 @@ void FuncRegionalPersonCount::task()
         }
 
         /* 更新报警规则 */
-        if(!getPersonCountRuleInfo(m_personCountRule))
+        if(!getPersonCountRuleInfo())
         {
-            /* 判断报警是否已经结束,没有结束就结束报警 */
-            autoEndAlarm();
+            /* 判断是不是无报警规则了 */
+            if(m_personCountRule.noRule)
+            {
+                SPDLOG_LOGGER_ERROR(m_logger, "{} 没有报警规则,退出功能检测线程", m_baseLog);
+                /* 判断报警是否已经结束,没有结束就结束报警 */
+                autoEndAlarm();
+                return;
+            }
+            
             continue;
         }
+        if(m_personCountRule.isUpdate)
+        {
+            /* 报警规则更新了,结束报警 */
+            autoEndAlarm();
+        }
 
         /* 更新房间列表 */
         updateRoomList();
@@ -286,6 +265,11 @@ void FuncRegionalPersonCount::task()
 
                     /* 解析数据 */
                     AlarmInfo alarmInfo;
+                    alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
+                    alarmInfo.RoomID = RoomInfo.RoomID;
+                    alarmInfo.appFunction = m_funcThreadInfo.appFunction;
+                    alarmInfo.ActionID = act;
+
                     parseRedisBaseData(strRetValue, alarmInfo);
                     parseOtherDataPersonCount(strRetValue, alarmInfo);
                     /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
@@ -300,6 +284,10 @@ void FuncRegionalPersonCount::task()
             }
         }
 
+
+        // SPDLOG_LOGGER_DEBUG(m_logger, "房间数目: {}, 报警条目数目: {}", m_listRoomCamAct.size(), m_pListAlarm->listAlarmInfo.size());
+        // SPDLOG_LOGGER_DEBUG(m_logger, "报警人数: {}", m_pListAlarm->listAlarmInfo.front()->listPersonInfo.size());
+
         /************ 挨个房间检测人数,取出每个房间内人数的最大值 ************/
         for(const auto& RoomInfo : m_listRoomCamAct)
         {
@@ -317,18 +305,39 @@ void FuncRegionalPersonCount::task()
         /************ 单独判断每个房间内人数的最大值和最小值 ************/
         for(const auto& it : m_mapRoomPeople)
         {
+            // SPDLOG_LOGGER_DEBUG(m_logger, "房间:{} 人数: {}", it.second.RoomName, it.second.MaxNum);
             /* 处理房间内的人数最大值 */
             handleRoomMaxNum(it.second);
+            /* 处理房间内人数最小值 */
+            handleRoomMinNum(it.second);
         }
 
         /************ 检测频率直播间 + 导播间房间的人数 ************/
-
+        int liveDicMaxNum = 0;
+        std::string strImagePath = "";
+        for(const auto& it : m_mapRoomPeople)
+        {
+            /* 直播间 + 导播间 */
+            if(it.second.RoomType == Enum_RoomType::ROOM_LIVE || it.second.RoomType == Enum_RoomType::ROOM_DIC)
+            {
+                liveDicMaxNum += it.second.MaxNum;
+                strImagePath = it.second.imagePath;
+            }
+        }
+        RoomPeopleInfo liveDicMaxNumInfo;
+        liveDicMaxNumInfo.RoomID = 0;
+        liveDicMaxNumInfo.RoomType = Enum_RoomType::ROOM_LIVEDIC;
+        liveDicMaxNumInfo.MaxNum = liveDicMaxNum;
+        liveDicMaxNumInfo.imagePath = strImagePath;
+        liveDicMaxNumInfo.RoomName = "直播间+导播间";
+        handleRoomMaxNum(liveDicMaxNumInfo);
+        handleRoomMinNum(liveDicMaxNumInfo);
     }
 
 }
 
 /* 获取该频率的人员计数规则 */
-bool FuncRegionalPersonCount::getPersonCountRuleInfo(PersonCountRuleInfo& personCountRuleInfo)
+bool FuncRegionalPersonCount::getPersonCountRuleInfo()
 {
     std::list<PersonCountRuleInfo> listRule;
     if(!m_fromWebAPI->getPersonCountRuleInfo(listRule))
@@ -344,65 +353,35 @@ bool FuncRegionalPersonCount::getPersonCountRuleInfo(PersonCountRuleInfo& person
         return false;
     }
     /* 获取这个频率的报警信息 */
-    m_personCountRule.ChannelID = -1;
+    bool isFind = false;
+    m_personCountRule.noRule = false;
+    m_personCountRule.isUpdate = false;
     for(auto& it : listRule)
     {
         if(it.ChannelID == m_funcThreadInfo.ChannelID)
         {
-            m_personCountRule = it;
+            isFind = true;
+            /* 判断规则是否有更新 */
+            if(!it.equals(m_personCountRule))
+            {
+                /* 规则有更新 */
+                m_personCountRule = it;
+                m_personCountRule.isUpdate = true;
+                SPDLOG_LOGGER_INFO(m_logger, "{} 报警规则有更新", m_baseLog);
+            }
             break;
         }
     }
-    if(m_personCountRule.ChannelID == -1)
+    if(!isFind)
     {
         SPDLOG_LOGGER_ERROR(m_logger, "频率:{}《人员计数》无报警规则", m_funcThreadInfo.ChannelID);
+        m_personCountRule.noRule = true;
         return false;
     }
 
     return true;
 }
 
-/* 判断是否在检测时间段内 */
-// bool FuncRegionalPersonCount::isInPeriodTime()
-// {
-//     /* 所有时段 */
-//     if(m_personCountRule.RuleType == Enum_PeriodType::PERIOD_ALL)
-//     {
-//         return true;
-//     }
-//     /* 按天检测 */
-//     else if(m_personCountRule.RuleType == Enum_PeriodType::PERIOD_DAY)
-//     {
-//         if(m_personCountRule.StartTime <= m_nowTime && m_personCountRule.EndTime >= m_nowTime)
-//         {
-//             /* 在检测时间内 */
-//             return true;
-//         } else {
-//             /* 不在检测时间内 */
-//             return false;
-//         }
-//     }
-//     /* 按周检测 */
-//     else if (m_personCountRule.RuleType == Enum_PeriodType::PERIOD_WEEK)
-//     {
-//         if(m_personCountRule.week != m_nowTime.date().dayOfWeek())
-//         {
-//             /* 一周日期不相等 */
-//             return false;
-//         }
-//         /* 判断周日期是否相等 */
-//         if(m_personCountRule.StartTime.time() <= m_nowTime.time() && m_personCountRule.EndTime.time() >= m_nowTime.time())
-//         {
-//             return true;
-//         } else {
-//             /* 不在检测时间内 */
-//             return false;
-//         }
-//     }
-
-//     return true;
-// }
-
 
 /* 更新房间列表 */
 void FuncRegionalPersonCount::updateRoomList()
@@ -424,45 +403,23 @@ void FuncRegionalPersonCount::updateRoomList()
 /* 自动结束报警 */
 void FuncRegionalPersonCount::autoEndAlarm()
 {
-    EndAlarmParam alarmParam;
-    alarmParam.ChannelID = m_funcThreadInfo.ChannelID;
-    alarmParam.AppID = m_funcThreadInfo.appFunction;
     /* 判断报警是否已经结束,没有结束就结束报警 */
-    if(findAlarmEnd(alarmParam))
+    if(m_mapAlarmBuffer.empty())
     {
-        SPDLOG_LOGGER_DEBUG(m_logger, "频率:{}《人员计数》报警已经结束", m_funcThreadInfo.strChannelName);
+        SPDLOG_LOGGER_DEBUG(m_logger, "{} 报警已经结束", m_baseLog);
         return;
     }
-    if(!m_fromWebAPI->endPersonCountAlarm(alarmParam))
+    /* 结束该频率人员计数的所有报警 */
+    if(!m_fromWebAPI->endPersonCountAlarm(m_funcThreadInfo.ChannelID, m_funcThreadInfo.appFunction))
     {
-        SPDLOG_LOGGER_ERROR(m_logger, "频率:{}《人员计数》结束报警失败", m_funcThreadInfo.strChannelName);
+        SPDLOG_LOGGER_ERROR(m_logger, "{} 结束报警失败", m_baseLog);
         return;
     }
-    /* 记录已经结束报警的信息,限制一下记录列表的大小 */
-    if(m_listEndAlarmPara.size() > 1024)
-    {
-        m_listEndAlarmPara.clear();
-    }
-    m_listEndAlarmPara.push_back(alarmParam);
-    
+    /* 清空报警列表 */
+    clearAlarmBufferMap();
+    SPDLOG_LOGGER_INFO(m_logger, "{} 结束报警,已清空报警缓存", m_baseLog);
 }
 
-/* 查找是否已经结束了报警 */
-bool FuncRegionalPersonCount::findAlarmEnd(EndAlarmParam& alarmParam)
-{
-    if(m_listEndAlarmPara.empty())
-    {
-        return false;
-    }
-    for(auto& it : m_listEndAlarmPara)
-    {
-        if(it == alarmParam)
-        {
-            return true;
-        }
-    }
-    return false;
-}
 
 /* 取出一个房间内的最大人数 */
 bool FuncRegionalPersonCount::getRoomMaxNum(int roomID, int& maxNum, std::string& strImagePath)
@@ -499,7 +456,7 @@ void FuncRegionalPersonCount::handleRoomMaxNum(const RoomPeopleInfo& peopleInfo)
     {
         if(!m_personCountRule.LiveMaxEnable)
         {
-            SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间最大人数检测功能未开启", m_baseLog);
+            // SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间最大人数检测功能未开启", m_baseLog);
             return;
         }
         /* 判断有没有名称 */
@@ -515,7 +472,7 @@ void FuncRegionalPersonCount::handleRoomMaxNum(const RoomPeopleInfo& peopleInfo)
     {
         if(!m_personCountRule.DicMaxEnable)
         {
-            SPDLOG_LOGGER_DEBUG(m_logger, "{} 导播间最大人数检测功能未开启", m_baseLog);
+            // SPDLOG_LOGGER_DEBUG(m_logger, "{} 导播间最大人数检测功能未开启", m_baseLog);
             return;
         }
         /* 判断有没有名称 */
@@ -527,11 +484,11 @@ void FuncRegionalPersonCount::handleRoomMaxNum(const RoomPeopleInfo& peopleInfo)
         }
         maxNum = m_personCountRule.DicMax;
     } 
-    else if(peopleInfo.RoomType == Enum_RoomType::ROOM_ALL)
+    else if(peopleInfo.RoomType == Enum_RoomType::ROOM_LIVEDIC)
     {
         if(!m_personCountRule.LiveDicMaxEnable)
         {
-            SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间+导播间最大人数检测功能未开启", m_baseLog);
+            // SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间+导播间最大人数检测功能未开启", m_baseLog);
             return;
         }
         /* 判断有没有名称 */
@@ -551,21 +508,29 @@ void FuncRegionalPersonCount::handleRoomMaxNum(const RoomPeopleInfo& peopleInfo)
 
     /* 查找房间信息 */
     RoomCamActInfo roomInfo;
-    if(!findRoomInfo(peopleInfo.RoomID, roomInfo))
-    {
-        SPDLOG_LOGGER_ERROR(m_logger, "房间ID:{},房间信息不存在", peopleInfo.RoomID);
-        return;
+    if(peopleInfo.RoomType == Enum_RoomType::ROOM_LIVEDIC)
+    {
+        /* 创造一个摄像机和算法信息 */
+        std::list<std::string> listAct;
+        listAct.push_back("0");
+        roomInfo.mapCameraAction.insert(std::make_pair(0, listAct));
+    } else {
+        if(!findRoomInfo(peopleInfo.RoomID, roomInfo))
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "房间ID:{},房间信息不存在", peopleInfo.RoomID);
+            return;
+        }
     }
 
     /* 开启了最大人数的检测,判断是否超过最大人数 */
     if(peopleInfo.MaxNum > maxNum)
     {
         /* 超过了最大人数,判断是否已经加入了内存缓冲区 */
-        AlarmBuffer alarmBuffer;
-        if(findAlarmBuffer(peopleInfo.RoomID, alarmBuffer))
+        AlarmBuffer* alarmBuffer = findAlarmBuffer(peopleInfo.RoomID);
+        if(alarmBuffer != nullptr)
         {
             /* 更新时间,这里只更新时间吗?最大人数和图片不更新吗? */
-            alarmBuffer.AlarmTime = m_nowTime;
+            alarmBuffer->AlarmTime = m_nowTime;
         }else 
         {
             /* 没有加入缓冲区,先写入数据库,再加入缓冲区 */
@@ -574,8 +539,9 @@ void FuncRegionalPersonCount::handleRoomMaxNum(const RoomPeopleInfo& peopleInfo)
             alarmInfo.appFunction = m_funcThreadInfo.appFunction;
             alarmInfo.RoomID = peopleInfo.RoomID;
             alarmInfo.DeviceID = roomInfo.mapCameraAction.begin()->first;
-            alarmInfo.ImageInfo = peopleInfo.imagePath;
+            alarmInfo.PicUrl = peopleInfo.imagePath;
             alarmInfo.ActionID = roomInfo.mapCameraAction.begin()->second.front();
+            alarmInfo.StartTime = m_nowTime.toString("yyyy-MM-dd hh:mm:ss.zzz").toStdString();
             alarmInfo.EventTime = m_nowTime.toString("yyyy-MM-dd hh:mm:ss.zzz").toStdString();
             alarmInfo.Is_Alarm = true;
             alarmInfo.ActionDes = fmt::format("{}人数为{},已超过最大人数{}限制", 
@@ -590,59 +556,236 @@ void FuncRegionalPersonCount::handleRoomMaxNum(const RoomPeopleInfo& peopleInfo)
                 SPDLOG_LOGGER_ERROR(m_logger, "{} 写入报警信息失败", m_baseLog);
                 return;
             }
+            SPDLOG_LOGGER_INFO(m_logger, "{} 房间: {},超过最大人数{},报警开始,已写入数据库", 
+                                m_baseLog, roomName, maxNum);
             /* 将报警信息写入缓存中 */
-            alarmBuffer.isMax = true;
+            // alarmBuffer.isMax = true;
             // alarmBuffer.isInsertDB = true;
-            alarmBuffer.ChannelID = m_funcThreadInfo.ChannelID;
-            alarmBuffer.RoomID = peopleInfo.RoomID;
-            alarmBuffer.PKID = pkid;
-            alarmBuffer.RoomType = peopleInfo.RoomType;
-            alarmBuffer.PeopleNum = peopleInfo.MaxNum;
-            alarmBuffer.AlarmTime = m_nowTime;
-            alarmBuffer.imagePath = peopleInfo.imagePath;
-            alarmBuffer.actionDecs = alarmInfo.ActionDes;
+            AlarmBuffer* alarmBuffer = new AlarmBuffer();
+            if(alarmBuffer == nullptr)
+            {
+                SPDLOG_LOGGER_ERROR(m_logger, "{} 创建报警缓冲区失败", m_baseLog);
+                return;
+            }
+            alarmBuffer->ChannelID = m_funcThreadInfo.ChannelID;
+            alarmBuffer->RoomID = peopleInfo.RoomID;
+            alarmBuffer->PKID = pkid;
+            alarmBuffer->RoomType = peopleInfo.RoomType;
+            alarmBuffer->PeopleNum = peopleInfo.MaxNum;
+            alarmBuffer->AlarmTime = m_nowTime;
+            alarmBuffer->imagePath = peopleInfo.imagePath;
+            alarmBuffer->actionDecs = alarmInfo.ActionDes;
             m_mapAlarmBuffer.insert(std::make_pair(peopleInfo.RoomID, alarmBuffer));
         }
     }else 
     {
         /* 未超过最大人数,判断是否已经写入的数据库,如果已经写入了数据库,就结束报警 */
-        AlarmBuffer alarmBuffer;
-        if(findAlarmBuffer(peopleInfo.RoomID, alarmBuffer))
+        AlarmBuffer* alarmBuffer = findAlarmBuffer(peopleInfo.RoomID);
+        if(alarmBuffer != nullptr)
         {
             /* 已写入数据库,结束报警,但是需要注意,人数少于一定时间后才结束报警,不会立马结束 */
-            if(alarmBuffer.AlarmTime.secsTo(m_nowTime) > GVariable.AppPeopleCount_LessTime)
+            if(alarmBuffer->AlarmTime.secsTo(m_nowTime) > GVariable.AppPeopleCount_LessTime)
             {
                 SPDLOG_LOGGER_INFO(m_logger, "{} 房间: {},超过最大人数{},报警结束", 
                                     m_baseLog, roomName, maxNum);
                 /* 结束报警 */
-                if(!m_fromWebAPI->endAlarmInfoByPKID(alarmBuffer.PKID, m_nowTime))
+                if(!m_fromWebAPI->endAlarmInfoByPKID(alarmBuffer->PKID, m_nowTime))
                 {
-                    SPDLOG_LOGGER_ERROR(m_logger, "{} 结束超过最大人数报警失败,PKID: {}", m_baseLog, alarmBuffer.PKID);
+                    SPDLOG_LOGGER_ERROR(m_logger, "{} 结束超过最大人数报警失败,PKID: {}", m_baseLog, alarmBuffer->PKID);
                     return;
                 }
                 /* 删除报警缓冲区 */
                 m_mapAlarmBuffer.erase(peopleInfo.RoomID);
+                delete alarmBuffer;
+                alarmBuffer = nullptr;
             }
         }
     }
 }
 
+
+/* 处理房间内人数最小值 */
+void FuncRegionalPersonCount::handleRoomMinNum(const RoomPeopleInfo& peopleInfo)
+{
+    std::string roomName = "";
+    int minNum = 0;
+    /* 判断当前房间是否开启了最少人员检测功能 */
+    if(peopleInfo.RoomType == Enum_RoomType::ROOM_LIVE)
+    {
+        if(!m_personCountRule.LiveMinEnable)
+        {
+            // SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间最少人数检测功能未开启", m_baseLog);
+            return;
+        }
+        /* 判断有没有名称 */
+        if(peopleInfo.RoomName.empty())
+        {
+            roomName = "直播间";
+        } else {
+            roomName = peopleInfo.RoomName;
+        }
+        minNum = m_personCountRule.LiveMin;
+    }
+    else if(peopleInfo.RoomType == Enum_RoomType::ROOM_DIC)
+    {
+        if(!m_personCountRule.DicMinEnable)
+        {
+            // SPDLOG_LOGGER_DEBUG(m_logger, "{} 导播间最少人数检测功能未开启", m_baseLog);
+            return;
+        }
+        /* 判断有没有名称 */
+        if(peopleInfo.RoomName.empty())
+        {
+            roomName = "导播间";
+        } else {
+            roomName = peopleInfo.RoomName;
+        }
+        minNum = m_personCountRule.DicMin;
+    } 
+    else if(peopleInfo.RoomType == Enum_RoomType::ROOM_LIVEDIC)
+    {
+        if(!m_personCountRule.LiveDicMinEnable)
+        {
+            // SPDLOG_LOGGER_DEBUG(m_logger, "{} 直播间+导播间最少人数检测功能未开启", m_baseLog);
+            return;
+        }
+        /* 判断有没有名称 */
+        if(peopleInfo.RoomName.empty())
+        {
+            roomName = "直播间+导播间";
+        } else {
+            roomName = peopleInfo.RoomName;
+        }
+        minNum = m_personCountRule.LiveDicMin;
+    }
+    else
+    {
+        SPDLOG_LOGGER_WARN(m_logger, "{} 房间类型错误", m_baseLog);
+        return;
+    }
+
+    /* 查找房间信息 */
+    RoomCamActInfo roomInfo;
+    if(peopleInfo.RoomType == Enum_RoomType::ROOM_LIVEDIC)
+    {
+        /* 创造一个摄像机和算法信息 */
+        std::list<std::string> listAct;
+        listAct.push_back("0");
+        roomInfo.mapCameraAction.insert(std::make_pair(0, listAct));
+    } else {
+        if(!findRoomInfo(peopleInfo.RoomID, roomInfo))
+        {
+            SPDLOG_LOGGER_ERROR(m_logger, "房间ID:{},房间信息不存在", peopleInfo.RoomID);
+            return;
+        }
+    }
+
+    /* 开启了最小人数的检测,判断是否小于最少人数
+       如果小于,不会立刻写入数据库,先存储到缓存中,经过一定时间后再写入数据库 */
+    if(peopleInfo.MaxNum < minNum)
+    {
+        /* 小于最少人数,判断是否已经加入了内存缓冲区 */
+        AlarmBuffer* alarmBuffer = findAlarmBuffer(peopleInfo.RoomID);
+        if(alarmBuffer != nullptr)
+        {
+            /* 已经存在缓存中了,判断是否已经写入数据库 */
+            if(alarmBuffer->PKID == 0)
+            {
+                /* 还未写入数据库,判断是否超过时间 */
+                // if(alarmBuffer->AlarmTime.secsTo(m_nowTime) > 2)
+                if(alarmBuffer->AlarmTime.secsTo(m_nowTime) > GVariable.AppPeopleCount_LessTime)
+                {
+                    /* 超过时间,写入数据库 */
+                    AlarmInfo alarmInfo;
+                    alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
+                    alarmInfo.appFunction = m_funcThreadInfo.appFunction;
+                    alarmInfo.RoomID = peopleInfo.RoomID;
+                    alarmInfo.DeviceID = roomInfo.mapCameraAction.begin()->first;
+                    alarmInfo.PicUrl = peopleInfo.imagePath;
+                    alarmInfo.ActionID = roomInfo.mapCameraAction.begin()->second.front();
+                    alarmInfo.EventTime = m_nowTime.toString("yyyy-MM-dd hh:mm:ss.zzz").toStdString();
+                    alarmInfo.Is_Alarm = true;
+                    alarmInfo.ActionDes = fmt::format("{}人数为{},已低于最小人数{}限制", 
+                                                        roomName, peopleInfo.MaxNum, minNum);
+                    for(auto& it : roomInfo.mapCameraAction)
+                    {
+                        alarmInfo.listBbox.push_back(GConfig.getCameraName(it.first));
+                    }
+                    int pkid = 0;
+                    if(!m_fromWebAPI->insertAlarmInfo(alarmInfo, pkid))
+                    {
+                        SPDLOG_LOGGER_ERROR(m_logger, "{} 写入报警信息失败", m_baseLog);
+                        return;
+                    }
+                    SPDLOG_LOGGER_INFO(m_logger, "{} 房间: {},人数为{},已低于最小人数{}限制,已写入数据库", 
+                                        m_baseLog, roomName, peopleInfo.MaxNum, minNum);
+                    /* 更新报警缓冲区 */
+                    alarmBuffer->PKID = pkid;
+                }
+            }
+        }else 
+        {
+            AlarmBuffer* alarmBuffer = new AlarmBuffer();
+            if(alarmBuffer == nullptr)
+            {
+                SPDLOG_LOGGER_ERROR(m_logger, "{} 创建报警缓冲区失败", m_baseLog);
+                return;
+            }
+            /* 将报警信息写入缓存中 */
+            alarmBuffer->ChannelID = m_funcThreadInfo.ChannelID;
+            alarmBuffer->RoomID = peopleInfo.RoomID;
+            alarmBuffer->PKID = 0;
+            alarmBuffer->RoomType = peopleInfo.RoomType;
+            alarmBuffer->PeopleNum = peopleInfo.MaxNum;
+            alarmBuffer->AlarmTime = m_nowTime;
+            alarmBuffer->imagePath = peopleInfo.imagePath;
+            m_mapAlarmBuffer.insert(std::make_pair(peopleInfo.RoomID, alarmBuffer));
+            SPDLOG_LOGGER_INFO(m_logger, "{} 房间: {},人数为{},已低于最小人数{}限制,已写入缓存", 
+                                    m_baseLog, roomName, peopleInfo.MaxNum, minNum);
+        }
+    }else 
+    {
+        /* 不小于最少人数 */
+        auto alarmBuffer = findAlarmBuffer(peopleInfo.RoomID);
+        if(alarmBuffer != nullptr)
+        {
+            /* 判断是否已经写入数据库 */
+            if(alarmBuffer->PKID != 0)
+            {
+                /* 已经写入数据库,结束报警 */
+                if(!m_fromWebAPI->endAlarmInfoByPKID(alarmBuffer->PKID, m_nowTime))
+                {
+                    SPDLOG_LOGGER_ERROR(m_logger, "{} 结束低于最小人数报警失败,PKID: {}", m_baseLog, alarmBuffer->PKID);
+                    return;
+                }
+                SPDLOG_LOGGER_INFO(m_logger, "{} 房间: {},人数为{},结束低于最小人数{}报警", 
+                                    m_baseLog, roomName, peopleInfo.MaxNum, minNum);
+                /* 删除报警缓冲区 */
+                m_mapAlarmBuffer.erase(peopleInfo.RoomID);
+                delete alarmBuffer;
+                alarmBuffer = nullptr;
+            }
+        }
+    }
+}
+
+
+
 /* 根据房间ID查找报警缓冲区 */
-bool FuncRegionalPersonCount::findAlarmBuffer(int roomID, AlarmBuffer& alarmBuffer)
+AlarmBuffer* FuncRegionalPersonCount::findAlarmBuffer(int roomID)
 {
     if(m_mapAlarmBuffer.empty())
     {
-        return false;
+        return nullptr;
     }
     for(auto& it : m_mapAlarmBuffer)
     {
         if(it.first == roomID)
         {
-            alarmBuffer = it.second;
-            return true;
+            return it.second;
         }
     }
-    return false;
+    return nullptr;
 }
 
 /* 根据房间ID查找房间信息 */
@@ -664,3 +807,18 @@ bool FuncRegionalPersonCount::findRoomInfo(int roomID, RoomCamActInfo& roomInfo)
 }
 
 
+/* 清空报警列表 */
+void FuncRegionalPersonCount::clearAlarmBufferMap()
+{
+    for(auto& it : m_mapAlarmBuffer)
+    {
+        if(it.second != nullptr)
+        {
+            delete it.second;
+            it.second = nullptr;
+        }
+    }
+    m_mapAlarmBuffer.clear();
+}
+
+

+ 13 - 26
SecurePlayAuxServer/Application/FuncRegionalPerson.h

@@ -14,6 +14,8 @@
  */
 struct PersonCountRuleInfo
 {
+    bool isUpdate;              /* 是否更新 */
+    bool noRule;                /* 没有规则 */
     int ChannelID;              /* 通道ID */
     // std::string PeriodName;     /* 时间段名称 */
     // QDateTime StartTime;        /* 开始时间 */
@@ -37,24 +39,10 @@ struct PersonCountRuleInfo
 
     PersonCountRuleInfo();
     PersonCountRuleInfo& operator=(PersonCountRuleInfo& other);
+    /* 对比规则需不需要更新 */
+    bool equals(const PersonCountRuleInfo& other) const;
 };
 
-/**
- * @brief 报警参数
- * 
- */
-struct EndAlarmParam
-{
-    int ChannelID;              /* 通道ID */
-    AppFunction AppID;          /* 应用功能 */
-    int CameraID;               /* 摄像机ID */
-    uint64_t insertAlarmNum;    /* 报警编号?PKID? */ 
-
-    EndAlarmParam();
-    EndAlarmParam(const EndAlarmParam& other);
-    EndAlarmParam& operator=(const EndAlarmParam& other);
-    bool operator==(const EndAlarmParam& other);
-};
 
 
 /**
@@ -78,7 +66,7 @@ struct RoomPeopleInfo
 
 struct AlarmBuffer
 {
-    bool isMax;                 /* 是否最大人数,false是最小人数 */
+    // bool isMax;                 /* 是否最大人数,false是最小人数 */
     // bool isInsertDB;            /* 是否已经插入数据库 */
     int ChannelID;              /* 通道ID */
     int RoomID;                 /* 房间ID */
@@ -115,38 +103,37 @@ protected:
 
 private:
     /* 获取该频率的人员计数规则 */
-    bool getPersonCountRuleInfo(PersonCountRuleInfo& personCountRuleInfo);
-    /* 判断是否在检测时间段内 */
-    // bool isInPeriodTime();
+    bool getPersonCountRuleInfo();
     /* 更新房间列表 */
     void updateRoomList();
 
     /* 自动结束报警 */
     void autoEndAlarm();
-    /* 查找是否已经结束了报警 */
-    bool findAlarmEnd(EndAlarmParam& alarmParam);
     /* 取出一个房间内的最大人数 */
     bool getRoomMaxNum(int roomID, int& maxNum, std::string& strImagePath);
 
     /* 处理房间内的人数最大值 */
     void handleRoomMaxNum(const RoomPeopleInfo& peopleInfo);
+    /* 处理房间内人数最小值 */
+    void handleRoomMinNum(const RoomPeopleInfo& peopleInfo);
 
     /* 根据房间ID查找报警缓冲区 */
-    bool findAlarmBuffer(int roomID, AlarmBuffer& alarmBuffer);
+    AlarmBuffer* findAlarmBuffer(int roomID);
     /* 根据房间ID查找房间信息 */
     bool findRoomInfo(int roomID, RoomCamActInfo& roomInfo);
 
+    /* 清空报警缓存列表 */
+    void clearAlarmBufferMap();
+
 private:
     ListAlarmInfo* m_pListAlarm = nullptr;                      /* 报警信息 */
     std::list<RoomCamActInfo> m_listRoomCamAct;                 /* 房间和算法ID关联列表,这里存储的是直播间和导播间的房间信息 */
     PersonCountRuleInfo m_personCountRule;                      /* 人员计数规则 */
 
-    std::list<EndAlarmParam> m_listEndAlarmPara;                /* 报警列表 */
-
     int m_liveDicNum = 0;                                       /* 直播间和导播间的最大人数之和 */
     std::string m_strLiveDicImagePath;                          /* 直播间和导播间的报警图片路径 */
     std::map<int, RoomPeopleInfo> m_mapRoomPeople;              /* 房间内的人数信息,int是房间ID */
-    std::map<int, AlarmBuffer> m_mapAlarmBuffer;                /* 报警信息,int是房间ID */
+    std::map<int, AlarmBuffer*> m_mapAlarmBuffer;               /* 报警信息,int是房间ID */
 };
 
 

+ 1 - 1
SecurePlayAuxServer/GlobalInfo/GlobalConfig.cpp

@@ -9,7 +9,7 @@
 
 GlobalVariable::GlobalVariable()
 {
-    ThreadSleepMS = 300;
+    ThreadSleepMS = 1000;
 
     ActFaceIdentify.clear();
     ActPersonCount.clear();

+ 10 - 29
SecurePlayAuxServer/GlobalInfo/GlobalFuncThread.cpp

@@ -504,7 +504,7 @@ void GlobalThreadInfo::unlockRunFAI()
 
 /**
  * @brief 添加应用信息,一个应用功能在一个频道内只有一个实例
- *        这里是添加应用功能和时间段信息
+ *        这里是添加应用功能,检测时间段在每个功能线程内部自己获取
  * 
  * @param func 
  * @return true 
@@ -523,7 +523,7 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
         fa->ChannelID = func.ChannelID;
         fa->StartTime = func.StartTime;
         fa->EndTime = func.EndTime;
-        fa->RunState = RunTimeState::RUN_STATE_NONE;
+        fa->RunState = RunTimeState::RUN_STATE_INIT;
         
         AppFunction appFunc = getAppFunctionID(func.AppType);
         if(AppFunction::APP_OnWork == appFunc)
@@ -533,8 +533,8 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             if(pFuncThreadInfo != nullptr)
             {
                 /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
+                // pFuncThreadInfo->StartTime = func.StartTime;
+                // pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -546,9 +546,6 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_Contraband);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -560,9 +557,6 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_Illegal);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -574,9 +568,6 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_Fatigue);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -588,9 +579,6 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_Regional);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -602,9 +590,6 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_Mouse);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -616,9 +601,6 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_PlayPhone);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -630,9 +612,6 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_NoMask);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
@@ -644,15 +623,17 @@ bool GlobalThreadInfo::addFuncThreadInfo(const AppAndTimeInfo& func)
             auto pFuncThreadInfo = findAppFunction(func.ChannelID, AppFunction::APP_AllDown);
             if(pFuncThreadInfo != nullptr)
             {
-                /* 更新时间信息 */
-                pFuncThreadInfo->StartTime = func.StartTime;
-                pFuncThreadInfo->EndTime = func.EndTime;
                 continue;
             }
             fa->appFunction = appFunc;
             fa->strFunctionName = "摔倒识别";
             m_listFuncThreadInfo.push_back(fa);
         }
+        else {
+            SPDLOG_WARN("未知的算法ID: {}", func.AppType);
+            delete fa;
+            return false;
+        }
     }
 
 
@@ -839,7 +820,6 @@ void GlobalThreadInfo::setAppFunction(const ActionInfo& info, const AppFunction
     if(pFuncThreadInfo != nullptr)
     {
         pFuncThreadInfo->addActionInfo(info);
-        pFuncThreadInfo->RunState = RunTimeState::RUN_STATE_INIT;
     }
 }
 
@@ -860,6 +840,7 @@ void GlobalThreadInfo::setThreadState(FuncThreadInfo& pInfo, RunTimeState state)
     auto p = findAppFunction(pInfo);
     if(p != nullptr)
     {
+        pInfo.RunState = state;
         p->RunState = state;
     }
 }

+ 1 - 1
SecurePlayAuxServer/GlobalInfo/GlobalVariable.h

@@ -65,7 +65,7 @@ enum class Enum_RoomType
     ROOM_NONE = 0,              /* 无房间 */
     ROOM_LIVE = 1,              /* 直播间 */
     ROOM_DIC = 2,               /* 导播间 */
-    ROOM_ALL = 3,               /* 所有房间 */
+    ROOM_LIVEDIC = 3,           /* 直播间和导播间 */
 };
 
 

+ 10 - 13
SecurePlayAuxServer/GlobalInfo/UniversalFunc.cpp

@@ -16,7 +16,7 @@ void parseRedisBaseData(const std::string& strData, AlarmInfo& alarmInfo)
     {
         nJson json0;
         json0 = nJson::parse(strData);
-        // SPDLOG_DEBUG("解析Redis数据: \n{}", json0.dump(4));
+        SPDLOG_DEBUG("解析Redis数据: \n{}", json0.dump(4));
 
         alarmInfo.AlarmID = json0["alarmId"].get<int>();
         alarmInfo.ActionID = json0["actionId"].get<std::string>();
@@ -223,24 +223,21 @@ bool parseOtherDataPersonCount(const std::string& strData, AlarmInfo& alarmInfo)
             /* 其他报警信息,直接获取(已经在基础解析中获取了) */
             // alarmInfo.ActionDes = json0["actionDes"].get<std::string>();
             
-            /* 判断有没有报警数据 */
+            /* 判断有没有报警图片 */
             if(alarmInfo.ImageInfo.empty())
             {
                 SPDLOG_WARN("有报警区域,但是没有图片信息");
                 return false;
             }
             /* 如果是人员报警,就存储人员报警信息 */
-            // if(alarmInfo.ActionID == GVariable.ActFaceIdentify)
-            // {
-            //     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.listPersonInfo.push_back(personInfo);
-            //     }
-            // }
+            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.listPersonInfo.push_back(personInfo);
+            }
         }
     }
     catch (const nJson::parse_error& e)

+ 11 - 6
SecurePlayAuxServer/SPAServer.cpp

@@ -52,6 +52,8 @@ void SPAServer::startServer()
     std::this_thread::sleep_for(std::chrono::seconds(2));
     /* 添加分配任务的线程 */
     CPPTP.add_task(&SPAServer::threadDistribution, this);
+    // threadDistribution();
+
 
     /* 测试Redis读取并解析数据线程 */
     
@@ -519,6 +521,7 @@ void SPAServer::threadDistribution()
         /* 开启线程 */
         for(const auto& func : GThreadInfo.getList())
         {
+            /* 只有状态是 RUN_STATE_INIT 的才创建线程实例 */
             if(func->RunState == RunTimeState::RUN_STATE_INIT)
             {
                 /* 创建实例 */
@@ -537,6 +540,7 @@ void SPAServer::threadDistribution()
 
         /* 休眠n秒,默认应该是300秒 */
         std::this_thread::sleep_for(std::chrono::seconds(GVariable.CheckSet));
+        // std::this_thread::sleep_for(std::chrono::seconds(3));
     }
 
     SPDLOG_LOGGER_INFO(m_logger, "分派任务线程退出");
@@ -560,9 +564,10 @@ FuncBase* SPAServer::createFuncInstance(FuncThreadInfo& info)
         info.appFunction == AppFunction::APP_PlayPhone || info.appFunction == AppFunction::APP_Mouse ||
         info.appFunction == AppFunction::APP_Fatigue || info.appFunction == AppFunction::APP_Contraband )
     {
-        // auto tmpFunc = new FuncOrdinary();
-        // tmpFunc->setFuncThreadInfo(info);
-        // pFunc = tmpFunc;
+        /* 普通检测功能 */
+        auto tmpFunc = new FuncOrdinary();
+        tmpFunc->setFuncThreadInfo(info);
+        pFunc = tmpFunc;
     }
     else if(info.appFunction == AppFunction::APP_OnWork)
     {
@@ -581,9 +586,9 @@ FuncBase* SPAServer::createFuncInstance(FuncThreadInfo& info)
     else if(info.appFunction == AppFunction::APP_Regional)
     {
         /* 区域人员检测 */
-        auto tmpFunc = new FuncRegionalPersonCount();
-        tmpFunc->setFuncThreadInfo(info);
-        pFunc = tmpFunc;
+        // auto tmpFunc = new FuncRegionalPersonCount();
+        // tmpFunc->setFuncThreadInfo(info);
+        // pFunc = tmpFunc;
     }
 
     return pFunc;

+ 56 - 36
SecurePlayAuxServer/communication/FromWebAPI.cpp

@@ -1276,7 +1276,7 @@ bool FromWebAPI::insertAlarmInfo(const AlarmInfo& alarmInfo, int& PKID)
         return false;
     }
     /* 判断是否有图片,没有图片就取消报警 */
-    if(alarmInfo.ImageInfo.empty())
+    if(alarmInfo.PicUrl.empty())
     {
         SPDLOG_LOGGER_WARN(m_logger, "× 取消新增报警信息,因为没有图片,频道[{}],房间[{}],摄像头[{}],{},{},有{}个区域,有{}个人脸",
                             alarmInfo.ChannelID, alarmInfo.RoomID, alarmInfo.DeviceID, alarmInfo.ActionDes, alarmInfo.ImageInfo, alarmInfo.listBbox.size(), alarmInfo.listPersonInfo.size());
@@ -1292,29 +1292,31 @@ bool FromWebAPI::insertAlarmInfo(const AlarmInfo& alarmInfo, int& PKID)
     /* 去掉最后一个“|” */
     strBbox.pop_back();
 
+    // printAlarmInfo(alarmInfo, strBbox);
     try
     {
         nJson json0;
         json0["opName"] = "SPSS_InsertToAlarm";
         nJson json1;
-        json1["AlarmID"] = alarmInfo.AlarmID;
-        json1["StartTime"] = alarmInfo.StartTime;
-        json1["CreateTime"] = alarmInfo.EventTime;
-        json1["EndTime"] = alarmInfo.EndTime;
-        json1["bBox"] = strBbox;
-        json1["PicUrl"] = alarmInfo.PicUrl;
-        json1["AppID"] = static_cast<int>(alarmInfo.appFunction);
-        json1["ActionID"] = alarmInfo.ActionID;
-        json1["ActionDes"] = alarmInfo.ActionDes;
-        json1["CamerID"] = alarmInfo.DeviceID;
-        json1["RoomID"] = alarmInfo.RoomID;
-        json1["chnID"] = alarmInfo.ChannelID;
-        json1["Stat"] = alarmInfo.State;
-        json0["FaceIDList"] = alarmInfo.FaceIDList;
-        json0["FaceNameList"] = alarmInfo.FaceNameList;
-        json0["OnWork"] = alarmInfo.OnWork;
+        json1["alarmID"] = alarmInfo.AlarmID;
+        json1["startTime"] = alarmInfo.StartTime.empty() ? "" : alarmInfo.StartTime;
+        json1["createTime"] = alarmInfo.EventTime.empty() ? "" : alarmInfo.EventTime;
+        json1["endTime"] = alarmInfo.EndTime;
+        json1["bbox"] = strBbox;
+        json1["picUrl"] = alarmInfo.PicUrl;
+        json1["appID"] = getAppFunctionID(alarmInfo.appFunction);
+        json1["actionID"] = alarmInfo.ActionID;
+        json1["actionDes"] = alarmInfo.ActionDes;
+        json1["camerID"] = alarmInfo.DeviceID;
+        json1["roomID"] = alarmInfo.RoomID;
+        json1["chnid"] = alarmInfo.ChannelID;
+        json1["state"] = alarmInfo.State;
+        json1["faceIDList"] = alarmInfo.FaceIDList;
+        json1["faceNameList"] = alarmInfo.FaceNameList;
+        json1["onWork"] = alarmInfo.OnWork;
 
         json0["paramList"] = json1;
+        // SPDLOG_LOGGER_DEBUG(m_logger, "写入报警信息的字符串:{}\n", json0.dump(4));
         QString strCmd = QString::fromStdString(json0.dump());
         QString strRet;
         auto ret = m_httpApi->DBDoInterface(enDBOperatorType::EDBOT_Insert, strCmd, strRet);
@@ -1324,13 +1326,13 @@ bool FromWebAPI::insertAlarmInfo(const AlarmInfo& alarmInfo, int& PKID)
             return false;
         }
         // SPDLOG_LOGGER_DEBUG(m_logger,"插入报警信息成功!");
-        SPDLOG_LOGGER_DEBUG(m_logger, "返回的数据:{}", strRet.toStdString());
+        // SPDLOG_LOGGER_DEBUG(m_logger, "返回的数据:{}", strRet.toStdString());
 
         nJson retJson = nJson::parse(strRet.toStdString());
         int retCode = retJson["code"].get<int>();
         if(retCode != 0)
         {
-            SPDLOG_LOGGER_ERROR(m_logger,"插入报警信息失败, 错误信息:{}", retJson["msg"].get<std::string>());
+            SPDLOG_LOGGER_ERROR(m_logger,"获取写入报警信息的PKID失败, 错误信息:{}", retJson["msg"].get<std::string>());
             return false;
         }
         /* 解析返回的报警ID */
@@ -1362,6 +1364,30 @@ bool FromWebAPI::insertAlarmInfo(const AlarmInfo& alarmInfo, int& PKID)
     return true;
 }
 
+/* 打印报警数据信息 */
+void FromWebAPI::printAlarmInfo(const AlarmInfo& alarmInfo, std::string strBBox)
+{
+    std::string strLog;
+    strLog += "写入报警信息:\n";
+    strLog += fmt::format("alarmID: {}\n", alarmInfo.AlarmID);
+    strLog += fmt::format("startTime: {}\n", alarmInfo.StartTime);
+    strLog += fmt::format("createTime: {}\n", alarmInfo.EventTime);
+    strLog += fmt::format("endTime: {}\n", alarmInfo.EndTime);
+    strLog += fmt::format("bbox: {}\n", strBBox);
+    strLog += fmt::format("picUrl: {}\n", alarmInfo.PicUrl);
+    strLog += fmt::format("appID: {}\n", getAppFunctionID(alarmInfo.appFunction));
+    strLog += fmt::format("actionID: {}\n", alarmInfo.ActionID);
+    strLog += fmt::format("actionDes: {}\n", alarmInfo.ActionDes);
+    strLog += fmt::format("camerID: {}\n", alarmInfo.DeviceID);
+    strLog += fmt::format("roomID: {}\n", alarmInfo.RoomID);
+    strLog += fmt::format("chnid: {}\n", alarmInfo.ChannelID);
+    strLog += fmt::format("state: {}\n", alarmInfo.State);
+    strLog += fmt::format("faceIDList: {}\n", alarmInfo.FaceIDList);
+    strLog += fmt::format("faceNameList: {}\n", alarmInfo.FaceNameList);
+    strLog += fmt::format("onWork: {}", alarmInfo.OnWork);
+    SPDLOG_LOGGER_DEBUG(m_logger, strLog);
+}
+
 /* 更新报警结束时间 */
 bool FromWebAPI::updateAlarmEndTime(const AlarmInfo& alarmInfo)
 {
@@ -1632,14 +1658,8 @@ bool FromWebAPI::getPersonCountRuleInfo(std::list<PersonCountRuleInfo>& list)
         for(const auto& it : result)
         {
             PersonCountRuleInfo info;
-            info.ChannelID = it["chnId"].get<int>();
-            info.RuleName = it["periodName"].get<std::string>();
-            // QString strStart = QString::fromStdString(it["startTime"].get<std::string>());
-            // info.StartTime = QDateTime::fromString(strStart, "yyyy-MM-ss hh:mm:ss");
-            // QString strEnd = QString::fromStdString(it["endTime"].get<std::string>());
-            // info.EndTime = QDateTime::fromString(strEnd, "yyyy-MM-ss hh:mm:ss");
-            // info.week = it["week"].get<int>();
-            // info.RuleType = static_cast<Enum_PeriodType>(it["type"].get<int>());
+            info.ChannelID = it["chnId"].is_null() ? -1 : it["chnId"].get<int>();
+            info.RuleName = it["periodName"].is_null() ? "" : it["periodName"].get<std::string>();
 
             info.RuleName = it["ruleName"].get<std::string>();
             info.LiveMinEnable = it["liveMinEnable"].get<int>() == 1 ? true : false;
@@ -1648,12 +1668,12 @@ bool FromWebAPI::getPersonCountRuleInfo(std::list<PersonCountRuleInfo>& list)
             info.DicMaxEnable = it["dicMaxEnable"].get<int>() == 1 ? true : false;
             info.LiveDicMinEnable = it["liveDicMinEnable"].get<int>() == 1 ? true : false;
             info.LiveDicMaxEnable = it["liveDicMaxEnable"].get<int>() == 1 ? true : false;
-            info.LiveMin = it["liveMin"].get<int>();
-            info.LiveMax = it["liveMax"].get<int>();
-            info.DicMin = it["dicMin"].get<int>();
-            info.DicMax = it["dicMax"].get<int>();
-            info.LiveDicMin = it["liveDicMin"].get<int>();
-            info.LiveDicMax = it["liveDicMax"].get<int>();
+            info.LiveMin = it["liveMin"].is_null() ? 0 : it["liveMin"].get<int>();
+            info.LiveMax = it["liveMax"].is_null() ? 0 : it["liveMax"].get<int>();
+            info.DicMin = it["dicMin"].is_null() ? 0 : it["dicMin"].get<int>();
+            info.DicMax = it["dicMax"].is_null() ? 0 : it["dicMax"].get<int>();
+            info.LiveDicMin = it["liveDicMin"].is_null() ? 0 : it["liveDicMin"].get<int>();
+            info.LiveDicMax = it["liveDicMax"].is_null() ? 0 : it["liveDicMax"].get<int>();
             list.push_back(info);
         }
     } 
@@ -1736,7 +1756,7 @@ bool FromWebAPI::getAlarmAppInfo(std::list<AppAndTimeInfo>& listInfo)
 
 
 /* 结束人员计数报警,通过频率ID和应用ID */
-bool FromWebAPI::endPersonCountAlarm(EndAlarmParam& alarmParam)
+bool FromWebAPI::endPersonCountAlarm(int chnID, AppFunction appID)
 {
     if(m_httpApi == nullptr)
     {
@@ -1748,8 +1768,8 @@ bool FromWebAPI::endPersonCountAlarm(EndAlarmParam& alarmParam)
         nJson json0;
         json0["opName"] = "SPSS_EndPersonCountAlarm";
         nJson json1;
-        json1["channelID"] = alarmParam.ChannelID;
-        json1["appID"] = static_cast<int>(alarmParam.AppID);
+        json1["channelID"] = chnID;
+        json1["appID"] = getAppFunctionID(appID);
         json0["paramList"] = json1;
 
         QString strCmd = QString::fromStdString(json0.dump());

+ 3 - 1
SecurePlayAuxServer/communication/FromWebAPI.h

@@ -66,6 +66,8 @@ public:
     /* 写入报警信息 */
     bool insertAlarmInfo(const AlarmInfo& alarmInfo);
     bool insertAlarmInfo(const AlarmInfo& alarmInfo, int& PKID);
+    /* 打印报警数据信息 */
+    void printAlarmInfo(const AlarmInfo& alarmInfo, std::string strBBox);
     /* 更新报警结束时间 */
     bool updateAlarmEndTime(const AlarmInfo& alarmInfo);
     /* 根据PKID更新报警记录,用来结束报警 */
@@ -83,7 +85,7 @@ public:
     /* 获取报警时段,也同时获取报警的应用信息 */
     bool getAlarmAppInfo(std::list<AppAndTimeInfo>& listInfo);
     /* 结束人员计数报警,通过频率ID和应用ID */
-    bool endPersonCountAlarm(EndAlarmParam& alarmParam);
+    bool endPersonCountAlarm(int chnID, AppFunction appID);
 
     /* 写入在岗信息 */
     bool insertOnWorkInfo(const RoomFaceInfo& onWorkInfo);

+ 0 - 0
jsons/人员计数json.json → jsons/人员计数.json


+ 42 - 0
jsons/玩手机识别.json

@@ -0,0 +1,42 @@
+{
+    "actionDes": "",
+    "actionId": "OD447_022_000070_001",
+    "actionName": "k2玩手机",
+    "actionResult": true,
+    "alarmId": 3415,
+    "bBoxes": [
+        {
+            "bbox": [
+                1149,
+                144,
+                1317,
+                355
+            ],
+            "colorFlag": 1,
+            "conf": [
+                "0.89"
+            ],
+            "label": [
+                "玩手机的人"
+            ],
+            "match_id": "",
+            "status": false
+        }
+    ],
+    "beginTime": "2025-05-08T19:37:02.433",
+    "classifyId": 64,
+    "deviceSerial": "rtsp://admin:LH123456@172.16.9.31:554",
+    "endTime": "2025-05-08T19:38:02.433",
+    "eventTime": "2025-05-08T19:37:32.433",
+    "imageInfo": "http://nginx-webdav-out.mid:80/webdav////GUI/1/WATER/2025/05/08//1920442943592726528.jpg",
+    "isKeyPoint": 0,
+    "personList": [
+        {
+            "personName": "未知",
+            "personId": "-1"
+        }
+    ],
+    "picUrl": "681c977ce4b076d9b370448d.jpg",
+    "taskId": 6,
+    "taskName": "玩手机识别"
+}