FuncOnAndOffJob.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. #include "FuncOnAndOffJob.h"
  2. #include "GlobalVariable.h"
  3. #include "GlobalConfig.h"
  4. #include "UniversalFunc.h"
  5. #include "FromRedis.h"
  6. #include "FromWebAPI.h"
  7. DecCondition::DecCondition()
  8. {
  9. ChannelID = -1;
  10. leaveNum = 0;
  11. leaveNumOnTime = 0;
  12. leaveOneTime = 0;
  13. }
  14. DecCondition::DecCondition(const DecCondition& other)
  15. {
  16. ChannelID = other.ChannelID;
  17. leaveNum = other.leaveNum;
  18. leaveNumOnTime = other.leaveNumOnTime;
  19. leaveOneTime = other.leaveOneTime;
  20. }
  21. DecCondition& DecCondition::operator=(const DecCondition& other)
  22. {
  23. if (this != &other)
  24. {
  25. ChannelID = other.ChannelID;
  26. leaveNum = other.leaveNum;
  27. leaveNumOnTime = other.leaveNumOnTime;
  28. leaveOneTime = other.leaveOneTime;
  29. }
  30. return *this;
  31. }
  32. RoomOnWorkInfo::RoomOnWorkInfo()
  33. {
  34. bOnWork = false;
  35. PKID = 0;
  36. ChannelID = 0;
  37. RoomID = 0;
  38. CameraID = 0;
  39. RoomType = 0;
  40. strRoomName = "";
  41. StartTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
  42. EndTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
  43. strImagePath = "";
  44. listLeaveTime.clear();
  45. listPersonInfo.clear();
  46. }
  47. RoomOnWorkInfo& RoomOnWorkInfo::operator=(const RoomOnWorkInfo& other)
  48. {
  49. if (this != &other)
  50. {
  51. bOnWork = other.bOnWork;
  52. PKID = other.PKID;
  53. ChannelID = other.ChannelID;
  54. RoomID = other.RoomID;
  55. CameraID = other.CameraID;
  56. RoomType = other.RoomType;
  57. strRoomName = other.strRoomName;
  58. StartTime = other.StartTime;
  59. EndTime = other.EndTime;
  60. strImagePath = other.strImagePath;
  61. listPersonInfo = other.listPersonInfo;
  62. listLeaveTime = other.listLeaveTime;
  63. }
  64. return *this;
  65. }
  66. RoomOnWorkInfo::RoomOnWorkInfo(const RoomOnWorkInfo& other)
  67. {
  68. bOnWork = other.bOnWork;
  69. PKID = other.PKID;
  70. ChannelID = other.ChannelID;
  71. RoomID = other.RoomID;
  72. CameraID = other.CameraID;
  73. RoomType = other.RoomType;
  74. strRoomName = other.strRoomName;
  75. StartTime = other.StartTime;
  76. EndTime = other.EndTime;
  77. strImagePath = other.strImagePath;
  78. listPersonInfo = other.listPersonInfo;
  79. listLeaveTime = other.listLeaveTime;
  80. }
  81. void RoomOnWorkInfo::clear()
  82. {
  83. bOnWork = false;
  84. PKID = 0;
  85. ChannelID = 0;
  86. RoomID = 0;
  87. CameraID = 0;
  88. RoomType = 0;
  89. strRoomName = "";
  90. StartTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
  91. EndTime = QDateTime::fromString("1970-01-01 00:00:00", "yyyy-MM-dd hh:mm:ss");
  92. strImagePath = "";
  93. listLeaveTime.clear();
  94. listPersonInfo.clear();
  95. }
  96. /* 添加人员信息,进行查重 */
  97. void RoomOnWorkInfo::addPersonInfo(const std::list<PersonInfo>& vecInfo)
  98. {
  99. for(auto& it : vecInfo)
  100. {
  101. /* 查重 */
  102. bool bFind = false;
  103. for(auto& it0 : listPersonInfo)
  104. {
  105. if(it0.PersonID == it.PersonID && it0.PersonName == it.PersonName)
  106. {
  107. bFind = true;
  108. break;
  109. }
  110. }
  111. if(!bFind)
  112. {
  113. listPersonInfo.push_back(it);
  114. }
  115. }
  116. }
  117. /* 更新在岗时间 */
  118. void RoomOnWorkInfo::updateOnWorkTime(const QDateTime& time)
  119. {
  120. for(auto& it : listPersonInfo)
  121. {
  122. it.lastOnWork = time;
  123. }
  124. }
  125. /* 获取人脸ID字符串 */
  126. std::string RoomOnWorkInfo::getFaceIDListString()
  127. {
  128. std::string strFaceList;
  129. for(const auto& it : listPersonInfo)
  130. {
  131. strFaceList += it.PersonID + ";" ;
  132. }
  133. /* 去掉最后的“;” */
  134. strFaceList = strFaceList.substr(0, strFaceList.size() - 1);
  135. return strFaceList;
  136. }
  137. /* 获取人脸字符串 */
  138. std::string RoomOnWorkInfo::getFaceNameListString()
  139. {
  140. std::string strFaceName;
  141. for(const auto& it : listPersonInfo)
  142. {
  143. strFaceName += it.PersonName + ";";
  144. }
  145. /* 去掉最后的“;” */
  146. strFaceName = strFaceName.substr(0, strFaceName.size() - 1);
  147. return strFaceName;
  148. }
  149. /* 获取离岗时间字符串 */
  150. std::string RoomOnWorkInfo::getLeaveTimeString()
  151. {
  152. std::string strLeaveTime;
  153. for(const auto& it : listLeaveTime)
  154. {
  155. strLeaveTime += it.toString("yyyy-MM-dd hh:mm:ss").toStdString() + ";";
  156. }
  157. /* 去掉最后的“;” */
  158. strLeaveTime = strLeaveTime.substr(0, strLeaveTime.size() - 1);
  159. return strLeaveTime;
  160. }
  161. /* 获取人员最后在岗时间字符串 */
  162. std::string RoomOnWorkInfo::getLastOnWorkTimeString()
  163. {
  164. std::string strLastOnWorkTime;
  165. for(const auto& it : listPersonInfo)
  166. {
  167. strLastOnWorkTime += it.lastOnWork.toString("yyyy-MM-dd hh:mm:ss").toStdString() + ";";
  168. }
  169. /* 去掉最后的“;” */
  170. strLastOnWorkTime = strLastOnWorkTime.substr(0, strLastOnWorkTime.size() - 1);
  171. return strLastOnWorkTime;
  172. }
  173. /* 添加一次离岗时间 */
  174. void RoomOnWorkInfo::addOneLeaveTime(const QDateTime& time, int maxLeaveTime)
  175. {
  176. if(isLeaveTimeExist(time))
  177. {
  178. return;
  179. }
  180. /* 对时间个数进行限制,不能太多 */
  181. if(listLeaveTime.size() > maxLeaveTime)
  182. {
  183. listLeaveTime.pop_front();
  184. }
  185. listLeaveTime.push_back(time);
  186. }
  187. /* 对离岗时间进行查重 */
  188. bool RoomOnWorkInfo::isLeaveTimeExist(const QDateTime& time)
  189. {
  190. for(auto& it : listLeaveTime)
  191. {
  192. if(it == time)
  193. {
  194. return true;
  195. }
  196. }
  197. return false;
  198. }
  199. FuncOnAndOffJob::FuncOnAndOffJob()
  200. {
  201. m_pListAlarm = new ListAlarmInfo();
  202. m_logger = spdlog::get("SPAServer");
  203. if(m_logger == nullptr)
  204. {
  205. SPDLOG_ERROR("FuncOnAndOffJob logger is nullptr");
  206. return;
  207. }
  208. }
  209. FuncOnAndOffJob::~FuncOnAndOffJob()
  210. {
  211. }
  212. void FuncOnAndOffJob::task()
  213. {
  214. while(GThreadInfo.getRunning())
  215. {
  216. /* 判断是否需要退出 */
  217. if(m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP)
  218. {
  219. break;
  220. }
  221. /* 判断是否在检测时间段内 */
  222. if(!isInDetectTime(m_funcThreadInfo.StartTime, m_funcThreadInfo.EndTime))
  223. {
  224. /* 休眠一段时间 */
  225. std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
  226. continue;
  227. }
  228. /* 先获取所有的直播间,这里不需要读取所有的房间数据
  229. * 理论上一个频率只有一个直播间 */
  230. std::map<int, RoomCamActInfo> mapRoomCamActInfo;
  231. for(auto& it : m_funcThreadInfo.listRoomCamActInfo)
  232. {
  233. /* 判断是不是直播间 */
  234. if(it.RoomType == GConfig.liveRoomType)
  235. {
  236. mapRoomCamActInfo.insert(std::make_pair(it.RoomID, it));
  237. }
  238. }
  239. /* 获取当前频率的在岗离岗信息,在表格“tChannel”中 */
  240. if(!getCurrentFrequencyInfo(m_funcThreadInfo.ChannelID, m_nowChnDecCondition))
  241. {
  242. SPDLOG_LOGGER_ERROR(m_logger, "获取当前频率信息失败, ChannelID:{}", m_funcThreadInfo.ChannelID);
  243. std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
  244. continue;
  245. }
  246. /* 读取Redis数据 */
  247. for(const auto& RoomInfo : mapRoomCamActInfo)
  248. {
  249. /* it是摄像机信息,it.first是摄像机ID */
  250. for(const auto& it : RoomInfo.second.mapCameraAction)
  251. {
  252. for(const auto& act : it.second)
  253. {
  254. std::string strKey = std::to_string(it.first) + ":" + act;
  255. std::string strRetValue;
  256. if(!m_fromRedis->getRedisString(strKey, strRetValue))
  257. {
  258. SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
  259. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  260. continue;
  261. }
  262. /* 解析数据 */
  263. AlarmInfo alarmInfo;
  264. parseRedisBaseData(strRetValue, alarmInfo);
  265. parseRedisBBoxesData(strRetValue, alarmInfo);
  266. /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
  267. if(isEventTimeVaild(alarmInfo.EventTime))
  268. {
  269. SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, alarmInfo.EventTime);
  270. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  271. continue;
  272. }
  273. m_pListAlarm->addAlarmInfo(alarmInfo);
  274. }
  275. }
  276. }
  277. /* 获取当前时间 */
  278. m_curTime = QDateTime::currentDateTime();
  279. /* 创建本轮的临时变量 */
  280. m_nowRoomOnWorkInfo.clear();
  281. /* 对所有房间挨个判断 */
  282. for(auto& roomInfo : mapRoomCamActInfo)
  283. {
  284. bool bHasPeople = false;
  285. bool bOnWork = false;
  286. m_strBaseInfo = fmt::format("频道[{}][{}], 房间[{}][{}]:", m_funcThreadInfo.ChannelID, m_funcThreadInfo.strChannelName, roomInfo.second.RoomID, roomInfo.second.strRoomName);
  287. /* 先使用人员计数判断直播间有没有人,如果直播间有人,再使用人脸识别算法判断是否是认识的人(是认识的人才会被识别到) */
  288. for(auto& alarm : m_pListAlarm->listAlarmInfo)
  289. {
  290. if(alarm->RoomID == roomInfo.first)
  291. {
  292. if(alarm->ActionID == g_actionList.ActPersonNumber)
  293. {
  294. if(alarm->listBbox.size() > 0)
  295. {
  296. bHasPeople = true;
  297. break;
  298. }
  299. }
  300. }
  301. }
  302. /* 如果有人,记录可以识别到的人员信息,记录在岗时间 */
  303. if(bHasPeople)
  304. {
  305. for(auto& alarm : m_pListAlarm->listAlarmInfo)
  306. {
  307. if(alarm->RoomID == roomInfo.first)
  308. {
  309. if(alarm->ActionID == g_actionList.ActFace)
  310. {
  311. if(alarm->listPersonInfo.size() > 0)
  312. {
  313. bOnWork = true;
  314. /* 记录人员信息 */
  315. m_nowRoomOnWorkInfo.addPersonInfo(alarm->listPersonInfo);
  316. /* 更新在岗时间 */
  317. m_nowRoomOnWorkInfo.updateOnWorkTime(m_curTime);
  318. }
  319. }
  320. }
  321. }
  322. }
  323. /* 查找这个房间对应的房间信息 */
  324. RoomOnWorkInfo* pRoomOnWorkInfo = nullptr;
  325. auto it0 = m_mapRoomOnWorkInfo.find(roomInfo.first);
  326. if(it0 != m_mapRoomOnWorkInfo.end())
  327. {
  328. pRoomOnWorkInfo = it0->second;
  329. }
  330. else
  331. {
  332. /* 没找到,就创建一个 */
  333. pRoomOnWorkInfo = new RoomOnWorkInfo();
  334. pRoomOnWorkInfo->bOnWork = bOnWork;
  335. pRoomOnWorkInfo->ChannelID = m_funcThreadInfo.ChannelID;
  336. pRoomOnWorkInfo->RoomID = roomInfo.first;
  337. pRoomOnWorkInfo->RoomID = roomInfo.second.RoomID;
  338. pRoomOnWorkInfo->RoomType = roomInfo.second.RoomType;
  339. pRoomOnWorkInfo->StartTime = m_curTime;
  340. pRoomOnWorkInfo->strImagePath = m_nowRoomOnWorkInfo.strImagePath;
  341. pRoomOnWorkInfo->listPersonInfo = m_nowRoomOnWorkInfo.listPersonInfo;
  342. m_mapRoomOnWorkInfo.insert(std::make_pair(roomInfo.first, pRoomOnWorkInfo));
  343. }
  344. if(pRoomOnWorkInfo == nullptr)
  345. {
  346. SPDLOG_LOGGER_ERROR(m_logger, "创建房间在岗信息失败,频率ID:{},房间ID:{}", m_funcThreadInfo.ChannelID, roomInfo.first);
  347. continue;
  348. }
  349. /* 处理此次在岗和离岗 */
  350. if(bOnWork)
  351. {
  352. /* 在岗 */
  353. onWorkProcess(pRoomOnWorkInfo, roomInfo);
  354. } else
  355. {
  356. /* 离岗 */
  357. }
  358. }
  359. }
  360. }
  361. /* 获取当前频率信息 */
  362. bool FuncOnAndOffJob::getCurrentFrequencyInfo(const int ChannelID, DecCondition& info)
  363. {
  364. auto str = m_fromWebAPI->getChannelInfo(ChannelID);
  365. if(str == "")
  366. {
  367. SPDLOG_LOGGER_ERROR(m_logger, "获取通道信息失败, ChannelID:{}", ChannelID);
  368. return false;
  369. }
  370. /* 解析数据 */
  371. try
  372. {
  373. nJson json1 = nJson::parse(str);
  374. info.ChannelID = ChannelID;
  375. info.strChannelName = json1["chnName"].is_null() ? "" : json1["chnName"].get<std::string>();
  376. info.leaveTimeMaxNum = json1["leaveNum"].is_null() ? 0 : json1["leaveNum"].get<int>();
  377. info.leaveNumOnTime = json1["leaveNumTime"].is_null() ? 0 : json1["leaveNumTime"].get<int>();
  378. info.leaveOneTime = json1["leaveLongTime"].is_null() ? 0 : json1["leaveLongTime"].get<int>();
  379. }
  380. catch (const nJson::parse_error& e) {
  381. SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id);
  382. return false;
  383. }
  384. catch (const nJson::type_error& e) {
  385. SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id);
  386. return false;
  387. }
  388. catch(...) {
  389. SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败");
  390. return false;
  391. }
  392. return true;
  393. }
  394. /**
  395. * @brief 人员在岗情况处理
  396. *
  397. * @param pRoomOnWorkInfo 这个是内存中的记录,是历史记录
  398. * @param roomInfo
  399. */
  400. void FuncOnAndOffJob::onWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<const int, RoomCamActInfo>& roomInfo)
  401. {
  402. /* 判断上次是否在岗,上次是离岗,结束离岗报警 */
  403. if(pRoomOnWorkInfo->bOnWork == false)
  404. {
  405. SPDLOG_LOGGER_DEBUG(m_logger, "{} 上次是离岗", m_strBaseInfo);
  406. /* 判断是否已经写入数据库,已经写入就结束报警 */
  407. if(pRoomOnWorkInfo->PKID > 0)
  408. {
  409. SPDLOG_LOGGER_INFO(m_logger, "·人员报警结束,{}", m_strBaseInfo);
  410. /* 结束报警,写入数据库 */
  411. m_fromWebAPI->endAlarmInfoByPKID(pRoomOnWorkInfo->PKID, m_curTime);
  412. /* 删除离岗记录,重新开始 */
  413. pRoomOnWorkInfo->PKID = 0;
  414. pRoomOnWorkInfo->listLeaveTime.clear();
  415. pRoomOnWorkInfo->StartTime = m_curTime;
  416. }else
  417. {
  418. /* 没有写入数据库 */
  419. SPDLOG_LOGGER_INFO(m_logger, "·{}人员离岗报警结束,结束时间:{}", m_strBaseInfo, m_curTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
  420. }
  421. }
  422. pRoomOnWorkInfo->bOnWork = true;
  423. /* 记录在岗最后一次的状态,主要是更新图片 */
  424. if(m_nowRoomOnWorkInfo.strImagePath != "")
  425. {
  426. pRoomOnWorkInfo->strImagePath = m_nowRoomOnWorkInfo.strImagePath;
  427. }
  428. /* 在岗记录还未写入数据库,就写入数据库 */
  429. if(0 == pRoomOnWorkInfo->PKID)
  430. {
  431. SPDLOG_LOGGER_DEBUG(m_logger, "{}在岗人脸:{},{}", m_strBaseInfo, m_nowRoomOnWorkInfo.getFaceNameListString(), m_nowRoomOnWorkInfo.getLeaveTimeString());
  432. /* 删除离岗人员和非法人员,未知人员不判断为离岗 */
  433. deleteNoWorkPerson(m_nowRoomOnWorkInfo.listPersonInfo);
  434. SPDLOG_LOGGER_DEBUG(m_logger, "{}删除离岗后的人员信息:{}", m_strBaseInfo, m_nowRoomOnWorkInfo.getFaceNameListString());
  435. /* 写入数据库 */
  436. if(m_nowRoomOnWorkInfo.listPersonInfo.size() > 0)
  437. {
  438. pRoomOnWorkInfo->listPersonInfo.assign(m_nowRoomOnWorkInfo.listPersonInfo.begin(), m_nowRoomOnWorkInfo.listPersonInfo.end());
  439. AlarmInfo alarmInfo;
  440. alarmInfo.appFunction = m_funcThreadInfo.appFunction;
  441. alarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
  442. alarmInfo.RoomID = pRoomOnWorkInfo->RoomID;
  443. alarmInfo.DeviceID = 0;
  444. if(roomInfo.second.mapCameraAction.size() == 1)
  445. {
  446. alarmInfo.DeviceID = roomInfo.second.mapCameraAction.begin()->first;
  447. }
  448. alarmInfo.listBbox = getCameraNameList(roomInfo.second.mapCameraAction); /* 直播间摄像机列表 */
  449. alarmInfo.ImageInfo = pRoomOnWorkInfo->strImagePath;
  450. alarmInfo.StartTime = pRoomOnWorkInfo->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString();
  451. alarmInfo.ActionID = "";
  452. alarmInfo.Is_OnWork = true;
  453. alarmInfo.listPersonInfo = pRoomOnWorkInfo->listPersonInfo;
  454. alarmInfo.ActionDes = fmt::format("人员在岗[{}][{}]", alarmInfo.getFaceIDListString(), alarmInfo.getFaceNameListString());
  455. int PKID = 0;
  456. m_fromWebAPI->insertAlarmInfo(alarmInfo, PKID);
  457. if(PKID > 0)
  458. {
  459. pRoomOnWorkInfo->PKID = PKID;
  460. }
  461. }
  462. } else
  463. {
  464. /* 在岗记录已经写入数据库,对比人脸列表是否相等 */
  465. if(m_nowRoomOnWorkInfo.getFaceIDListString() != pRoomOnWorkInfo->getFaceIDListString())
  466. {
  467. if(m_nowRoomOnWorkInfo.listPersonInfo.size() > 0)
  468. {
  469. /* 合并在岗人员 */
  470. m_nowRoomOnWorkInfo.addPersonInfo(pRoomOnWorkInfo->listPersonInfo);
  471. SPDLOG_LOGGER_DEBUG(m_logger, "合并在岗人脸信息前: {}; {}", m_nowRoomOnWorkInfo.getFaceNameListString(), m_nowRoomOnWorkInfo.getLastOnWorkTimeString());
  472. /* 删除离岗人员和非法人员 */
  473. deleteNoWorkPerson(m_nowRoomOnWorkInfo.listPersonInfo);
  474. SPDLOG_LOGGER_DEBUG(m_logger, "删除离岗人员信息后: {}", m_nowRoomOnWorkInfo.getFaceNameListString());
  475. /* 更新在岗信息 */
  476. if(m_nowRoomOnWorkInfo.listPersonInfo.size() > 0)
  477. {
  478. pRoomOnWorkInfo->listPersonInfo.assign(m_nowRoomOnWorkInfo.listPersonInfo.begin(), m_nowRoomOnWorkInfo.listPersonInfo.end());
  479. /* 更新到数据库 */
  480. if(m_fromWebAPI->updatePersonInfo(*pRoomOnWorkInfo))
  481. {
  482. SPDLOG_LOGGER_INFO(m_logger, "·更新在岗人员信息成功,{}{}{}", m_strBaseInfo, pRoomOnWorkInfo->getFaceIDListString(), pRoomOnWorkInfo->getFaceNameListString());
  483. }else {
  484. SPDLOG_LOGGER_ERROR(m_logger, "·更新在岗人员信息失败,{}", m_strBaseInfo);
  485. }
  486. }
  487. }
  488. if(m_nowRoomOnWorkInfo.listPersonInfo.size() <= 0)
  489. {
  490. SPDLOG_LOGGER_DEBUG(m_logger, "没有在岗人员信息,不更新在岗人员");
  491. }
  492. }else
  493. {
  494. /* 人员信息没有变化,更新在岗时间 */
  495. pRoomOnWorkInfo->updateOnWorkTime(m_curTime);
  496. SPDLOG_LOGGER_DEBUG(m_logger, "人员信息没有变化,更新在岗时间: {}", m_nowRoomOnWorkInfo.getLastOnWorkTimeString());
  497. }
  498. }
  499. }
  500. /* 人员离岗情况 */
  501. void FuncOnAndOffJob::offWorkProcess(RoomOnWorkInfo* pRoomOnWorkInfo, std::pair<const int, RoomCamActInfo>& roomInfo)
  502. {
  503. if(true == pRoomOnWorkInfo->bOnWork)
  504. {
  505. /* 上次是在岗 */
  506. SPDLOG_LOGGER_DEBUG(m_logger, "{} 上次是在岗", m_strBaseInfo);
  507. pRoomOnWorkInfo->bOnWork = false;
  508. /* 判断有没有写入数据库 */
  509. if(pRoomOnWorkInfo->PKID > 0)
  510. {
  511. SPDLOG_LOGGER_INFO(m_logger, "人员在岗结束(PKID:{}),离岗开始,{}", pRoomOnWorkInfo->PKID, m_strBaseInfo);
  512. /* 更新数据库,结束在岗 */
  513. m_fromWebAPI->endAlarmInfoByPKID(pRoomOnWorkInfo->PKID, m_curTime);
  514. pRoomOnWorkInfo->PKID = 0;
  515. pRoomOnWorkInfo->StartTime = m_curTime;
  516. }else
  517. {
  518. /* 没有写入数据库 */
  519. SPDLOG_LOGGER_INFO(m_logger, "人员在岗结束,离岗开始,{}", m_strBaseInfo);
  520. }
  521. pRoomOnWorkInfo->addOneLeaveTime(m_curTime, m_nowChnDecCondition.leaveTimeMaxNum);
  522. auto strLeaveTime = pRoomOnWorkInfo->getLeaveTimeString();
  523. if(strLeaveTime != "")
  524. {
  525. SPDLOG_LOGGER_DEBUG(m_logger, "★ 人员最近离岗时间, {}, {}", m_strBaseInfo, strLeaveTime);
  526. }
  527. } else
  528. {
  529. /* 上次是离岗 */
  530. SPDLOG_LOGGER_DEBUG(m_logger, "{} 没有人员,可能离岗了", m_strBaseInfo);
  531. }
  532. }
  533. /* 删除离岗人员和未知人员信息 */
  534. void FuncOnAndOffJob::deleteNoWorkPerson(std::list<PersonInfo>& listPersonInfo)
  535. {
  536. /* 删除离岗人员 */
  537. for(auto it = listPersonInfo.begin(); it != listPersonInfo.end();)
  538. {
  539. if((it->lastOnWork < m_curTime) || it->PersonID == "-1" || it->PersonID == "-2")
  540. {
  541. it = listPersonInfo.erase(it);
  542. } else
  543. {
  544. ++it;
  545. }
  546. }
  547. }
  548. /* 获取当前直播间的摄像机名称列表 */
  549. std::list<std::string> FuncOnAndOffJob::getCameraNameList(const std::map<int, std::list<std::string>>& mapCameraAction)
  550. {
  551. std::list<std::string> listCameraName;
  552. for(const auto& it : mapCameraAction)
  553. {
  554. listCameraName.push_back(m_funcThreadInfo.getCameraName(it.first));
  555. }
  556. return listCameraName;
  557. }