123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807 |
- #include "FuncOnAndOffJob.h"
- #include "GlobalVariable.h"
- #include "GlobalConfig.h"
- #include "UniversalFunc.h"
- #include "FromRedis.h"
- #include "FromWebAPI.h"
- DecCondition::DecCondition()
- {
- ChannelID = -1;
- leaveTimeMaxNum = 0;
- leaveNumOnTime = 0;
- leaveOneTime = 0;
- }
- DecCondition::DecCondition(const DecCondition& other)
- {
- ChannelID = other.ChannelID;
- leaveTimeMaxNum = other.leaveTimeMaxNum;
- leaveNumOnTime = other.leaveNumOnTime;
- leaveOneTime = other.leaveOneTime;
- }
- DecCondition& DecCondition::operator=(const DecCondition& other)
- {
- if (this != &other)
- {
- ChannelID = other.ChannelID;
- leaveTimeMaxNum = other.leaveTimeMaxNum;
- leaveNumOnTime = other.leaveNumOnTime;
- leaveOneTime = other.leaveOneTime;
- }
- return *this;
- }
- RoomOnWorkInfo::RoomOnWorkInfo()
- {
- bOnWork = false;
- PKID = 0;
- ChannelID = 0;
- RoomID = 0;
- CameraID = 0;
- RoomType = Enum_RoomType::ROOM_NONE;
- strRoomName = "";
- StartTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
- EndTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
- strImagePath = "";
- listLeaveTime.clear();
- listPersonInfo.clear();
- }
- RoomOnWorkInfo& RoomOnWorkInfo::operator=(const RoomOnWorkInfo& other)
- {
- if (this != &other)
- {
- bOnWork = other.bOnWork;
- PKID = other.PKID;
- ChannelID = other.ChannelID;
- RoomID = other.RoomID;
- CameraID = other.CameraID;
- RoomType = other.RoomType;
- strRoomName = other.strRoomName;
- StartTime = other.StartTime;
- EndTime = other.EndTime;
- strImagePath = other.strImagePath;
- listPersonInfo = other.listPersonInfo;
- listLeaveTime = other.listLeaveTime;
- }
- return *this;
- }
- RoomOnWorkInfo::RoomOnWorkInfo(const RoomOnWorkInfo& other)
- {
- bOnWork = other.bOnWork;
- PKID = other.PKID;
- ChannelID = other.ChannelID;
- RoomID = other.RoomID;
- CameraID = other.CameraID;
- RoomType = other.RoomType;
- strRoomName = other.strRoomName;
- StartTime = other.StartTime;
- EndTime = other.EndTime;
- strImagePath = other.strImagePath;
- listPersonInfo = other.listPersonInfo;
- listLeaveTime = other.listLeaveTime;
-
- }
- void RoomOnWorkInfo::clear()
- {
- bOnWork = false;
- PKID = 0;
- ChannelID = 0;
- RoomID = 0;
- CameraID = 0;
- RoomType = Enum_RoomType::ROOM_NONE;
- strRoomName = "";
- StartTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
- EndTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
- strImagePath = "";
- listLeaveTime.clear();
- listPersonInfo.clear();
- }
- /* 添加人员信息,进行查重 */
- void RoomOnWorkInfo::addPersonInfo(const std::list<PersonInfo>& vecInfo)
- {
- for(auto& it : vecInfo)
- {
- /* 查重 */
- bool bFind = false;
- for(auto& it0 : listPersonInfo)
- {
- if(it0.PersonID == it.PersonID && it0.PersonName == it.PersonName)
- {
- bFind = true;
- break;
- }
- }
- if(!bFind)
- {
- listPersonInfo.push_back(it);
- }
- }
- }
- /* 更新在岗时间 */
- void RoomOnWorkInfo::updateOnWorkTime(const QDateTime& time)
- {
- for(auto& it : listPersonInfo)
- {
- it.lastOnWork = time;
- }
- }
- /* 获取人脸ID字符串 */
- std::string RoomOnWorkInfo::getFaceIDListString()
- {
- std::string strFaceList;
- for(const auto& it : listPersonInfo)
- {
- strFaceList += it.PersonID + ";" ;
- }
- /* 去掉最后的“;” */
- strFaceList = strFaceList.substr(0, strFaceList.size() - 1);
- return strFaceList;
- }
- /* 获取人脸字符串 */
- std::string RoomOnWorkInfo::getFaceNameListString()
- {
- std::string strFaceName;
- for(const auto& it : listPersonInfo)
- {
- strFaceName += it.PersonName + ";";
- }
- /* 去掉最后的“;” */
- strFaceName = strFaceName.substr(0, strFaceName.size() - 1);
- return strFaceName;
- }
- /* 获取离岗时间字符串 */
- std::string RoomOnWorkInfo::getLeaveTimeString()
- {
- std::string strLeaveTime;
- for(const auto& it : listLeaveTime)
- {
- strLeaveTime += it.toString("yyyy-MM-dd hh:mm:ss").toStdString() + ";";
- }
- /* 去掉最后的“;” */
- strLeaveTime = strLeaveTime.substr(0, strLeaveTime.size() - 1);
- return strLeaveTime;
- }
- /* 获取人员最后在岗时间字符串 */
- std::string RoomOnWorkInfo::getLastOnWorkTimeString()
- {
- std::string strLastOnWorkTime;
- for(const auto& it : listPersonInfo)
- {
- strLastOnWorkTime += it.lastOnWork.toString("yyyy-MM-dd hh:mm:ss").toStdString() + ";";
- }
- /* 去掉最后的“;” */
- strLastOnWorkTime = strLastOnWorkTime.substr(0, strLastOnWorkTime.size() - 1);
- return strLastOnWorkTime;
- }
- /* 添加一次离岗时间 */
- void RoomOnWorkInfo::addOneLeaveTime(const QDateTime& time, int maxLeaveTime)
- {
- if(isLeaveTimeExist(time))
- {
- return;
- }
- /* 对时间个数进行限制,不能太多 */
- if(listLeaveTime.size() > maxLeaveTime)
- {
- listLeaveTime.pop_front();
- }
- listLeaveTime.push_back(time);
- }
- /* 对离岗时间进行查重 */
- bool RoomOnWorkInfo::isLeaveTimeExist(const QDateTime& time)
- {
- for(auto& it : listLeaveTime)
- {
- if(it == time)
- {
- return true;
- }
- }
- return false;
- }
- FuncOnAndOffJob::FuncOnAndOffJob()
- {
- m_pListAlarm = new ListAlarmInfo();
- m_logger = spdlog::get("SPAServer");
- if(m_logger == nullptr)
- {
- SPDLOG_ERROR("FuncOnAndOffJob logger is nullptr");
- return;
- }
- }
- FuncOnAndOffJob::~FuncOnAndOffJob()
- {
- if(m_pListAlarm != nullptr)
- {
- delete m_pListAlarm;
- m_pListAlarm = nullptr;
- }
- }
- void FuncOnAndOffJob::task()
- {
- while(GThreadInfo.getRunning())
- {
- /* 判断是否需要退出 */
- if(m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP)
- {
- break;
- }
- /* 判断是否在检测时间段内 */
- if(!isInDetectTime(m_funcThreadInfo.StartTime, m_funcThreadInfo.EndTime))
- {
- /* 休眠一段时间 */
- std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS));
- continue;
- }
- /* 先获取所有的直播间,这里不需要读取所有的房间数据
- * 理论上一个频率只有一个直播间 */
- std::map<int, RoomCamActInfo> mapRoomCamActInfo;
- for(auto& it : m_funcThreadInfo.listRoomCamActInfo)
- {
- /* 判断是不是直播间 */
- if(it.RoomType == Enum_RoomType::ROOM_LIVE)
- {
- mapRoomCamActInfo.insert(std::make_pair(it.RoomID, it));
- }
- }
- /* 获取当前频率的在岗离岗信息,在表格“tChannel”中 */
- if(!getCurrentFrequencyInfo(m_funcThreadInfo.ChannelID, m_nowChnDetecRule))
- {
- SPDLOG_LOGGER_ERROR(m_logger, "获取当前频率信息失败, ChannelID:{}", m_funcThreadInfo.ChannelID);
- std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS));
- continue;
- }
- /* 读取Redis数据 */
- for(const auto& RoomInfo : mapRoomCamActInfo)
- {
- /* it是摄像机信息,it.first是摄像机ID */
- for(const auto& it : RoomInfo.second.mapCameraAction)
- {
- for(const auto& act : it.second)
- {
- std::string strKey = std::to_string(it.first) + ":" + act;
- std::string strRetValue;
- if(!m_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;
- }
- m_pListAlarm->addAlarmInfo(alarmInfo);
- }
- }
- }
- /* 获取当前时间 */
- m_curTime = QDateTime::currentDateTime();
- /* 创建本轮的临时变量 */
- m_nowRoomOnWorkInfo.clear();
- /* 对所有房间挨个判断 */
- for(auto& roomInfo : mapRoomCamActInfo)
- {
- bool bHasPeople = false;
- bool bOnWork = false;
- m_strBaseInfo = fmt::format("频道[{}][{}], 房间[{}][{}]:", m_funcThreadInfo.ChannelID, m_funcThreadInfo.strChannelName, roomInfo.second.RoomID, roomInfo.second.strRoomName);
- /* 先使用人员计数判断直播间有没有人,如果直播间有人,再使用人脸识别算法判断是否是认识的人(是认识的人才会被识别到) */
- for(auto& alarm : m_pListAlarm->listAlarmInfo)
- {
- if(alarm->RoomID == roomInfo.first)
- {
- if(alarm->ActionID == GVariable.ActPersonCount)
- {
- if(alarm->listBbox.size() > 0)
- {
- bHasPeople = true;
- break;
- }
- }
- }
- }
-
- /* 如果有人,记录可以识别到的人员信息,记录在岗时间 */
- if(bHasPeople)
- {
- for(auto& alarm : m_pListAlarm->listAlarmInfo)
- {
- if(alarm->RoomID == roomInfo.first)
- {
- if(alarm->ActionID == GVariable.ActFaceIdentify)
- {
- if(alarm->listPersonInfo.size() > 0)
- {
- bOnWork = true;
- /* 记录人员信息 */
- m_nowRoomOnWorkInfo.addPersonInfo(alarm->listPersonInfo);
- /* 更新在岗时间 */
- m_nowRoomOnWorkInfo.updateOnWorkTime(m_curTime);
- }
- }
- }
- }
- }
- /* 查找这个房间对应的房间信息 */
- RoomOnWorkInfo* pRoomOnWorkInfo = nullptr;
- auto it0 = m_mapRoomOnWorkInfo.find(roomInfo.first);
- if(it0 != m_mapRoomOnWorkInfo.end())
- {
- pRoomOnWorkInfo = it0->second;
- }
- else
- {
- /* 没找到,就创建一个 */
- pRoomOnWorkInfo = new RoomOnWorkInfo();
- pRoomOnWorkInfo->bOnWork = bOnWork;
- pRoomOnWorkInfo->ChannelID = m_funcThreadInfo.ChannelID;
- pRoomOnWorkInfo->RoomID = roomInfo.first;
- pRoomOnWorkInfo->RoomID = roomInfo.second.RoomID;
- pRoomOnWorkInfo->RoomType = roomInfo.second.RoomType;
- pRoomOnWorkInfo->StartTime = m_curTime;
- pRoomOnWorkInfo->strImagePath = m_nowRoomOnWorkInfo.strImagePath;
- pRoomOnWorkInfo->listPersonInfo = m_nowRoomOnWorkInfo.listPersonInfo;
- m_mapRoomOnWorkInfo.insert(std::make_pair(roomInfo.first, pRoomOnWorkInfo));
- }
- if(pRoomOnWorkInfo == nullptr)
- {
- SPDLOG_LOGGER_ERROR(m_logger, "创建房间在岗信息失败,频率ID:{},房间ID:{}", m_funcThreadInfo.ChannelID, roomInfo.first);
- continue;
- }
- /* 处理此次在岗和离岗 */
- if(bOnWork)
- {
- /* 在岗 */
- onWorkProcess(pRoomOnWorkInfo, roomInfo);
- } else
- {
- /* 离岗 */
- offWorkProcess(pRoomOnWorkInfo, roomInfo);
- }
- }
- }
- }
- /* 获取当前频率信息 */
- bool FuncOnAndOffJob::getCurrentFrequencyInfo(const int ChannelID, DecCondition& info)
- {
- auto str = m_fromWebAPI->getChannelInfo(ChannelID);
- if(str == "")
- {
- SPDLOG_LOGGER_ERROR(m_logger, "获取通道信息失败, ChannelID:{}", ChannelID);
- return false;
- }
- /* 解析数据 */
- try
- {
- nJson json1 = nJson::parse(str);
- info.ChannelID = ChannelID;
- info.strChannelName = json1["chnName"].is_null() ? "" : json1["chnName"].get<std::string>();
- info.leaveTimeMaxNum = json1["leaveNum"].is_null() ? 0 : json1["leaveNum"].get<int>();
- info.leaveNumOnTime = json1["leaveNumTime"].is_null() ? 0 : json1["leaveNumTime"].get<int>();
- info.leaveOneTime = json1["leaveLongTime"].is_null() ? 0 : json1["leaveLongTime"].get<int>();
- }
- catch (const nJson::parse_error& e) {
- SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id);
- return false;
- }
- catch (const nJson::type_error& e) {
- SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id);
- return false;
- }
- catch(...) {
- SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败");
- return false;
- }
- return true;
- }
- /**
- * @brief 人员在岗情况处理
- 1、判断上次是在岗还是离岗
- (1) 上次是离岗,结束离岗报警,需要判断是否已经写入数据库
- 1) 已经写入数据库,更新数据库报警记录,更新结束时间,清空内存中的报警记录,主要是清空PKID,置为0
- 2) 还未写入数据库,打印个日志,不需要做什么操作
- (2) 上次是在岗,更新数据,主要是更新图片
- 1) 如果上次在岗记录已经写入数据库,判断人脸列表是否相等
- 1) 不相等,更新数据库
- 2) 相等,更新在岗时间
- 2) 如果上次在岗记录还未写入数据库,直接写入数据库
-
- * @param pRoomOnWorkInfo 这个是内存中的记录,是历史记录
- * @param roomInfo
- */
- void FuncOnAndOffJob::onWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<const int, RoomCamActInfo>& roomInfo)
- {
- /* 判断上次是否在岗,上次是离岗,结束离岗报警 */
- if(pRoomOnWorkInfo->bOnWork == false)
- {
- SPDLOG_LOGGER_DEBUG(m_logger, "{} 上次是离岗", m_strBaseInfo);
- /* 判断是否已经写入数据库,已经写入就结束报警 */
- if(pRoomOnWorkInfo->PKID > 0)
- {
- SPDLOG_LOGGER_INFO(m_logger, "·人员报警结束,{}", m_strBaseInfo);
- /* 结束报警,写入数据库 */
- m_fromWebAPI->endAlarmInfoByPKID(pRoomOnWorkInfo->PKID, m_curTime);
- /* 删除离岗记录,重新开始 */
- pRoomOnWorkInfo->PKID = 0;
- pRoomOnWorkInfo->listLeaveTime.clear();
- pRoomOnWorkInfo->StartTime = m_curTime;
- }else
- {
- /* 没有写入数据库 */
- SPDLOG_LOGGER_INFO(m_logger, "·{}人员离岗报警结束,结束时间:{}", m_strBaseInfo, m_curTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
- }
- }
- pRoomOnWorkInfo->bOnWork = true;
- /* 记录在岗最后一次的状态,主要是更新图片 */
- if(m_nowRoomOnWorkInfo.strImagePath != "")
- {
- pRoomOnWorkInfo->strImagePath = m_nowRoomOnWorkInfo.strImagePath;
- }
- /* 在岗记录还未写入数据库,就写入数据库 */
- if(0 == pRoomOnWorkInfo->PKID)
- {
- SPDLOG_LOGGER_DEBUG(m_logger, "{}在岗人脸:{},{}", m_strBaseInfo, m_nowRoomOnWorkInfo.getFaceNameListString(), m_nowRoomOnWorkInfo.getLeaveTimeString());
- /* 删除离岗人员和非法人员,未知人员不判断为离岗 */
- deleteNoWorkPerson(m_nowRoomOnWorkInfo.listPersonInfo);
- SPDLOG_LOGGER_DEBUG(m_logger, "{}删除离岗后的人员信息:{}", m_strBaseInfo, m_nowRoomOnWorkInfo.getFaceNameListString());
- /* 写入数据库 */
- if(m_nowRoomOnWorkInfo.listPersonInfo.size() > 0)
- {
- pRoomOnWorkInfo->listPersonInfo.assign(m_nowRoomOnWorkInfo.listPersonInfo.begin(), m_nowRoomOnWorkInfo.listPersonInfo.end());
- AlarmInfo alarmInfo;
- alarmInfo.appFunction = m_funcThreadInfo.appFunction;
- alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
- alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
- alarmInfo.DeviceID = 0;
- if(roomInfo.second.mapCameraAction.size() == 1)
- {
- alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
- }
- alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
- alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
- alarmInfo.EventTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
- alarmInfo.ActionID = "";
- alarmInfo.Is_OnWork = true;
- alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
- alarmInfo.ActionDes = fmt::format("人员在岗[{}][{}]", alarmInfo.getFaceIDListString(), alarmInfo.getFaceNameListString());
- int PKID = 0;
- m_fromWebAPI->insertAlarmInfo(alarmInfo, PKID);
- if(PKID > 0)
- {
- pRoomOnWorkInfo->PKID = PKID;
- }
- }
- } else
- {
- /* 在岗记录已经写入数据库,对比人脸列表是否相等 */
- if(m_nowRoomOnWorkInfo.getFaceIDListString() != pRoomOnWorkInfo->getFaceIDListString())
- {
- if(m_nowRoomOnWorkInfo.listPersonInfo.size() > 0)
- {
- /* 合并在岗人员 */
- m_nowRoomOnWorkInfo.addPersonInfo(pRoomOnWorkInfo->listPersonInfo);
- SPDLOG_LOGGER_DEBUG(m_logger, "合并在岗人脸信息前: {}; {}", m_nowRoomOnWorkInfo.getFaceNameListString(), m_nowRoomOnWorkInfo.getLastOnWorkTimeString());
- /* 删除离岗人员和非法人员 */
- deleteNoWorkPerson(m_nowRoomOnWorkInfo.listPersonInfo);
- SPDLOG_LOGGER_DEBUG(m_logger, "删除离岗人员信息后: {}", m_nowRoomOnWorkInfo.getFaceNameListString());
- /* 更新在岗信息 */
- if(m_nowRoomOnWorkInfo.listPersonInfo.size() > 0)
- {
- pRoomOnWorkInfo->listPersonInfo.assign(m_nowRoomOnWorkInfo.listPersonInfo.begin(), m_nowRoomOnWorkInfo.listPersonInfo.end());
- /* 更新到数据库 */
- if(m_fromWebAPI->updatePersonInfo(*pRoomOnWorkInfo))
- {
- SPDLOG_LOGGER_INFO(m_logger, "·更新在岗人员信息成功,{}{}{}", m_strBaseInfo, pRoomOnWorkInfo->getFaceIDListString(), pRoomOnWorkInfo->getFaceNameListString());
- }else {
- SPDLOG_LOGGER_ERROR(m_logger, "·更新在岗人员信息失败,{}", m_strBaseInfo);
- }
- }
- }
- if(m_nowRoomOnWorkInfo.listPersonInfo.size() <= 0)
- {
- SPDLOG_LOGGER_DEBUG(m_logger, "没有在岗人员信息,不更新在岗人员");
- }
- }else
- {
- /* 人员信息没有变化,更新在岗时间 */
- pRoomOnWorkInfo->updateOnWorkTime(m_curTime);
- SPDLOG_LOGGER_DEBUG(m_logger, "人员信息没有变化,更新在岗时间: {}", m_nowRoomOnWorkInfo.getLastOnWorkTimeString());
- }
- }
- }
- /**
- * @brief 人员离岗情况处理
- 1、判断上次是在岗还是离岗
- (1) 上次是在岗,开启离岗报警,然后判断是否已经写入数据库,更新离岗时间
- 1) 已经写入数据库,更新在岗结束,离岗开始
- 2) 还未写入数据库,打印个日志,不需要做什么操作
- (2) 上次是离岗,不需要做啥
- 2、更新在岗离岗状态,主要是更新图片
- 3、判断有没有写入数据库
-
- * @param pRoomOnWorkInfo
- * @param roomInfo
- */
- void FuncOnAndOffJob::offWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<const int, RoomCamActInfo>& roomInfo)
- {
- if(true == pRoomOnWorkInfo->bOnWork)
- {
- /* 上次是在岗 */
- SPDLOG_LOGGER_DEBUG(m_logger, "{} 上次是在岗", m_strBaseInfo);
- pRoomOnWorkInfo->bOnWork = false;
- /* 判断有没有写入数据库 */
- if(pRoomOnWorkInfo->PKID > 0)
- {
- SPDLOG_LOGGER_INFO(m_logger, "人员在岗结束(PKID:{}),离岗开始,{}", pRoomOnWorkInfo->PKID, m_strBaseInfo);
- /* 更新数据库,结束在岗 */
- m_fromWebAPI->endAlarmInfoByPKID(pRoomOnWorkInfo->PKID, m_curTime);
- pRoomOnWorkInfo->PKID = 0;
- pRoomOnWorkInfo->StartTime = m_curTime;
- }else
- {
- /* 没有写入数据库 */
- SPDLOG_LOGGER_INFO(m_logger, "人员在岗结束,离岗开始,{}", m_strBaseInfo);
- }
- pRoomOnWorkInfo->addOneLeaveTime(m_curTime, m_nowChnDetecRule.leaveTimeMaxNum);
- auto strLeaveTime = pRoomOnWorkInfo->getLeaveTimeString();
- if(strLeaveTime != "")
- {
- SPDLOG_LOGGER_DEBUG(m_logger, "★ 人员最近离岗时间, {}, {}", m_strBaseInfo, strLeaveTime);
- }
- } else
- {
- /* 上次是离岗 */
- SPDLOG_LOGGER_DEBUG(m_logger, "{} 没有人员,可能离岗了", m_strBaseInfo);
- }
- if(!m_nowRoomOnWorkInfo.strImagePath.empty())
- {
- pRoomOnWorkInfo->strImagePath = m_nowRoomOnWorkInfo.strImagePath;
- }
- /* 判断有没有写入数据库 */
- if(pRoomOnWorkInfo->PKID == 0)
- {
- /* 没有写入数据库,现在写入 */
-
- /* 判断单次离岗超时,计算时间差,leaveOneTime设置为0表示不启用检测 */
- int nLeaveTime = pRoomOnWorkInfo->StartTime.secsTo(m_curTime);
- if(nLeaveTime > m_nowChnDetecRule.leaveOneTime && m_nowChnDetecRule.leaveOneTime > 0)
- {
- AlarmInfo alarmInfo;
- alarmInfo.appFunction = m_funcThreadInfo.appFunction;
- alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
- alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
- alarmInfo.DeviceID = 0;
- if(roomInfo.second.mapCameraAction.size() == 1)
- {
- alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
- }
- alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
- alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
- alarmInfo.EventTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
- alarmInfo.ActionID = "";
- alarmInfo.Is_OnWork = false;
- alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
- if(alarmInfo.listPersonInfo.size() > 0)
- {
- alarmInfo.ActionDes = fmt::format("离岗人员[{}][{}],人员单次离岗时间超过{}秒", alarmInfo.getFaceIDListString(), alarmInfo.getFaceNameListString(), m_nowChnDetecRule.leaveOneTime);
- }else {
- alarmInfo.ActionDes = fmt::format("人员单次离岗时间超过{}秒", m_nowChnDetecRule.leaveOneTime);
- }
- /* 写入数据库 */
- m_fromWebAPI->insertAlarmInfo(alarmInfo, pRoomOnWorkInfo->PKID);
- if(pRoomOnWorkInfo->PKID > 0)
- {
- SPDLOG_LOGGER_INFO(m_logger, "写入离岗报警成功,{}{}", m_strBaseInfo, pRoomOnWorkInfo->getFaceNameListString());
- }else {
- SPDLOG_LOGGER_ERROR(m_logger, "写入离岗报警失败,{}", m_strBaseInfo);
- }
- pRoomOnWorkInfo->listLeaveTime.clear();
- /* 获取当前频率,应用的报警信息的最大PKID */
- int maxPKID = 0;
- m_fromWebAPI->getMaxAlarmPKID(m_funcThreadInfo.ChannelID, m_funcThreadInfo.appFunction, maxPKID);
- if(maxPKID > 0)
- {
- std::string actionDes = "人员离岗了清空在岗人员信息,方便客户端显示";
- /* 不知道这里为啥要单独获取PKID,按理说用上面返回的即可 */
- if(m_fromWebAPI->clearOnWorkAlarmInfo(maxPKID, true, actionDes))
- {
- SPDLOG_LOGGER_INFO(m_logger, "☆ {} 人员离岗了清空在岗人员信息,方便客户端显示", m_strBaseInfo);
- } else {
- SPDLOG_LOGGER_ERROR(m_logger, "× {} 人员离岗了清空在岗人员信息失败", m_strBaseInfo);
- }
- }
- }
- /* 判断多次频繁离岗 */
- if((pRoomOnWorkInfo->listLeaveTime.size() >= m_nowChnDetecRule.leaveNumOnTime) &&
- (m_nowChnDetecRule.leaveNumOnTime > 0) && (m_nowChnDetecRule.leaveTimeMaxNum > 0))
- {
- /* 计算距离第一次离岗时间长度 */
- int nLeaveTime = pRoomOnWorkInfo->listLeaveTime.front().secsTo(m_curTime);
- if(nLeaveTime <= m_nowChnDetecRule.leaveOneTime)
- {
- AlarmInfo alarmInfo;
- alarmInfo.appFunction = m_funcThreadInfo.appFunction;
- alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
- alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
- alarmInfo.DeviceID = 0;
- if(roomInfo.second.mapCameraAction.size() == 1)
- {
- alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
- }
- alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
- alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
- alarmInfo.EventTime = pRoomOnWorkInfo->listLeaveTime.front().toString("yyyy-MM-dd hh:mm:ss").toStdString();
- alarmInfo.ActionID = "";
- alarmInfo.Is_OnWork = false;
- alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
- if(alarmInfo.listPersonInfo.size() > 0)
- {
- alarmInfo.ActionDes = fmt::format("离岗人员[{}],人员离岗([]秒内发生{}次离岗)",
- alarmInfo.getFaceNameListString(), m_nowChnDetecRule.leaveOneTime, m_nowChnDetecRule.leaveNumOnTime);
- }else {
- alarmInfo.ActionDes = fmt::format("人员离岗({}秒内发生{}次离岗)", m_nowChnDetecRule.leaveOneTime, m_nowChnDetecRule.leaveNumOnTime);
- }
- /* 写入数据库报警表 */
- m_fromWebAPI->insertAlarmInfo(alarmInfo, pRoomOnWorkInfo->PKID);
- if(pRoomOnWorkInfo->PKID > 0)
- {
- SPDLOG_LOGGER_INFO(m_logger, "写入离岗报警成功,{}{}", m_strBaseInfo, pRoomOnWorkInfo->getFaceNameListString());
- }else {
- SPDLOG_LOGGER_ERROR(m_logger, "写入离岗报警失败,{}", m_strBaseInfo);
- }
- pRoomOnWorkInfo->listLeaveTime.clear();
- /* 获取当前频率,应用的报警信息的最大PKID */
- int maxPKID = 0;
- m_fromWebAPI->getMaxAlarmPKID(m_funcThreadInfo.ChannelID, m_funcThreadInfo.appFunction, maxPKID);
- if(maxPKID > 0)
- {
- std::string actionDes = "人员离岗了清空在岗人员信息,方便客户端显示";
- /* 不知道这里为啥要单独获取PKID,按理说用上面返回的即可 */
- if(m_fromWebAPI->clearOnWorkAlarmInfo(maxPKID, true, actionDes))
- {
- SPDLOG_LOGGER_INFO(m_logger, "☆ {} 人员离岗了清空在岗人员信息,方便客户端显示", m_strBaseInfo);
- } else {
- SPDLOG_LOGGER_ERROR(m_logger, "× {} 人员离岗了清空在岗人员信息失败", m_strBaseInfo);
- }
- }
- }
- }
- }
- }
- /* 删除离岗人员和未知人员信息 */
- void FuncOnAndOffJob::deleteNoWorkPerson(std::list<PersonInfo>& listPersonInfo)
- {
- /* 删除离岗人员 */
- for(auto it = listPersonInfo.begin(); it != listPersonInfo.end();)
- {
- if((it->lastOnWork < m_curTime) || it->PersonID == "-1" || it->PersonID == "-2")
- {
- it = listPersonInfo.erase(it);
- } else
- {
- ++it;
- }
- }
- }
- /* 获取当前直播间的摄像机名称列表 */
- std::list<std::string> FuncOnAndOffJob::getCameraNameList(const std::map<int, std::list<std::string>>& mapCameraAction)
- {
- std::list<std::string> listCameraName;
- for(const auto& it : mapCameraAction)
- {
- listCameraName.push_back(m_funcThreadInfo.getCameraName(it.first));
- }
- return listCameraName;
- }
- /* 创建报警记录 */
- // void FuncOnAndOffJob::createAlarmInfo(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<const int, RoomCamActInfo>& roomInfo, std::string actionDes, AlarmInfo& alarmInfo)
- // {
- // if(pRoomOnWorkInfo == nullptr)
- // {
- // return;
- // }
- // alarmInfo.appFunction = m_funcThreadInfo.appFunction;
- // alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
- // alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
- // alarmInfo.DeviceID = 0;
- // if(roomInfo.second.mapCameraAction.size() == 1)
- // {
- // alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
- // }
- // alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
- // alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
- // alarmInfo.EventTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
- // alarmInfo.ActionID = "";
- // alarmInfo.Is_OnWork = false;
- // alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
- // alarmInfo.ActionDes = actionDes;
- // }
|