1
0

module_call.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. #include "module_call.h"
  2. #include <boost/bind.hpp>
  3. #include <vector>
  4. #include <set>
  5. #include <string>
  6. #include <chrono>
  7. #include<algorithm>
  8. /**
  9. * @brief 呼叫类型 全员 定员
  10. */
  11. enum CALL_CARD_TYPE
  12. {
  13. /// 全员呼叫
  14. CCT_CALL_ALL = 0,
  15. /// 定员
  16. CCT_CALL_APOINT=1,
  17. };
  18. /**
  19. * @brief 呼叫等级 一般呼叫 紧急呼叫
  20. */
  21. enum CALL_CARD_LEVEL
  22. {
  23. /// 呼叫等级: 1 一般呼叫
  24. CALL_LEVEL_NORMAL=1,
  25. /// 呼叫等级: 2 紧急呼叫
  26. CALL_LEVEL_CRITICAL=2
  27. };
  28. /**
  29. * @brief 呼叫状态
  30. */
  31. enum CALL_STATE{
  32. ///无呼叫信息
  33. CALL_NONE = 0,
  34. ///呼叫成功
  35. CALL_SUCCESSED = 1,
  36. ///呼叫中
  37. CALL_ING = 2,
  38. ///呼叫失败
  39. CALL_FAILED = 3,
  40. ///呼叫结束
  41. CALL_END=100
  42. };
  43. void module_call::run()
  44. {
  45. std::vector<call_card_ptr> arr;
  46. get_all_call_cards(arr);
  47. if(arr.empty())
  48. {
  49. return ;
  50. }
  51. //转发给web
  52. swsClientMgr.send(JSON_CMD_VALUE_PUSH, to_call_card_list_json(arr));
  53. //将呼叫命令发送给标识卡终端
  54. }
  55. /*
  56. web发给采集:发起呼叫
  57. {
  58. cmd: 'call_card_req',
  59. data: {
  60. call_type_id: this.cal_type, // 全员呼叫:0 定员呼叫:1
  61. call_time_out: this.choosedTime, // 呼叫时长
  62. call_level_id: this.call_type_id, // 呼叫类型 一般呼叫:1 紧急呼叫:2
  63. user_name: xdata.userName, // 呼叫人
  64. call_time: time, // 呼叫时间戳
  65. stations: [{ stationid: 0 }], // 分站 0为全员
  66. cards: cards // 人员 0为全员 //旧代码为map格式 [{ stationid: 0 }]
  67. }
  68. }
  69. */
  70. void module_call::accept_call(const rapidjson::Document& node_data)
  71. {
  72. int call_type = -1, call_level = -1, call_time_out;
  73. std::string user_name;
  74. if(!tool_json::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, node_data)
  75. || !tool_json::try_get_value(call_level, JSON_KEY_CALL_CARD_CALL_LEVEL, node_data)
  76. || !tool_json::try_get_value(call_time_out, JSON_KEY_CALL_CARD_CALL_TIME_OUT, node_data)
  77. || !tool_json::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, node_data)
  78. )
  79. {
  80. log_error("收到的json不对,解析不出int call_type = -1, call_level = -1, call_time_out,user_name");
  81. return;
  82. }
  83. if(user_name.empty())
  84. {
  85. log_error("user_name用户名为空");
  86. return;
  87. }
  88. std::vector<call_card_ptr> arr;//结果集
  89. call_user_ptr user_ptr;
  90. if(CCT_CALL_ALL==call_type)// 全员
  91. {
  92. user_ptr=call_user_ptr(new call_user());
  93. user_ptr->call_time=std::chrono::system_clock::now();
  94. user_ptr->call_time_out=call_time_out;
  95. user_ptr->call_type_id=call_type;
  96. user_ptr->call_level_id=call_level;
  97. user_ptr->user_name=user_name;
  98. call_card_ptr temp(new call_card());
  99. copy(user_ptr, temp);
  100. temp->cardid = CCT_CALL_ALL; //全员卡
  101. arr.push_back(temp);//增加到结果集中
  102. //添加全员卡
  103. user_ptr->cards.insert(std::make_pair(CCT_CALL_ALL, temp));
  104. //更新用户信息
  105. std::lock_guard<std::mutex> lock(_mutex);
  106. _map[user_name]=user_ptr;
  107. }
  108. else// 定员: 如果有全员,定员不生效
  109. {
  110. std::lock_guard<std::mutex> lock(_mutex);
  111. auto user_map_ptr = _map.find(user_name);
  112. if(user_map_ptr==_map.end())//没有这个用户就新建并加入
  113. {
  114. user_ptr=call_user_ptr(new call_user());
  115. _map[user_name]=user_ptr;
  116. }
  117. else//有这个用户
  118. {
  119. user_ptr=user_map_ptr->second;
  120. // 如果有全员,定员不生效
  121. if(user_ptr->cards.size()==1 && CCT_CALL_ALL == user_ptr->cards[CCT_CALL_ALL]->cardid)
  122. {
  123. return;
  124. }
  125. }
  126. //更新用户信息
  127. user_ptr->call_time=std::chrono::system_clock::now();
  128. user_ptr->call_time_out=call_time_out;
  129. user_ptr->call_type_id=call_type;
  130. user_ptr->call_level_id=call_level;
  131. user_ptr->user_name=user_name;
  132. auto node_cards_ptr = node_data.FindMember(JSON_KEY_CALL_CARD_CARDS);
  133. if(node_data.MemberEnd()==node_cards_ptr)
  134. {
  135. return;
  136. }
  137. const rapidjson::Value& node_cards = node_cards_ptr->value;
  138. if(!node_cards.IsArray())
  139. {
  140. return;
  141. }
  142. add_cards_to_user(call_level, node_cards, user_ptr);
  143. for(auto& it:user_ptr->cards)//添加到结果集中
  144. {
  145. arr.push_back(it.second);
  146. }
  147. }
  148. //组装json发送给web
  149. if(!arr.empty())
  150. {
  151. response_accept_call(arr);
  152. }
  153. }
  154. //采集回复web发起呼叫
  155. //{
  156. // 'cmd': 'call_card_resp',
  157. // 'data': [
  158. // ["fjb", // 发起呼叫人
  159. // "0010000000001", // 呼叫的卡号
  160. // 103, // 分站号
  161. // 23431, // 发起呼叫时间
  162. // 0, //
  163. // 0 // 正在呼叫:2/结束呼叫/
  164. // ]
  165. // ]
  166. //}
  167. void module_call::response_accept_call(std::vector<call_card_ptr> cards)
  168. {
  169. rapidjson::Document doc(rapidjson::kObjectType);
  170. auto& allocator = doc.GetAllocator();
  171. rapidjson::Value node_cards(rapidjson::kArrayType);
  172. //组装json发送给web
  173. to_node_array(node_cards, cards, allocator);
  174. doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_CALL_CARD_RESPONSE, allocator);
  175. doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator);
  176. doc.AddMember(JSON_ROOT_KEY_DATA, node_cards, allocator);
  177. swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
  178. }
  179. //web发给采集:取消呼叫
  180. //{
  181. // cmd: 'call_card_cancel_req',
  182. // data: {
  183. // call_type_id: type, // 全员/定员
  184. // user_name: xdata.userName, // 取消人
  185. // call_time: callTime, // 时间戳
  186. // stations: this.stationid, // 分站
  187. // cards: this.cards // 取消呼叫卡 //旧代码为map格式 [{ stationid: 0 }]
  188. // }
  189. //}
  190. void module_call::accept_cancel(const rapidjson::Document& node_data)
  191. {
  192. int call_type = -1, call_level = -1;
  193. std::string user_name;
  194. if(!tool_json::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, node_data)
  195. || !tool_json::try_get_value(call_level, JSON_KEY_CALL_CARD_CALL_LEVEL, node_data)
  196. || !tool_json::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, node_data)
  197. )
  198. {
  199. log_error("收到的json不对,解析不出int call_type = -1, call_level = -1,user_name");
  200. return;
  201. }
  202. if(user_name.empty())
  203. {
  204. log_error("user_name用户名为空");
  205. return;
  206. }
  207. call_user_ptr result_user_ptr(new call_user());
  208. result_user_ptr->call_type_id=call_type;
  209. result_user_ptr->call_level_id=call_level;
  210. result_user_ptr->user_name=user_name;
  211. //取消呼叫有两种:
  212. //取消全员呼叫
  213. //对指定卡取消呼叫
  214. if(CCT_CALL_ALL==call_type)// 取消全员呼叫
  215. {
  216. //删除用户
  217. std::lock_guard<std::mutex> lock(_mutex);
  218. _map.erase(user_name);
  219. }
  220. else// 取消定员呼叫
  221. {
  222. auto node_cards_ptr = node_data.FindMember(JSON_KEY_CALL_CARD_CARDS);
  223. if(node_data.MemberEnd()==node_cards_ptr)
  224. {
  225. return;
  226. }
  227. const rapidjson::Value& node_cards = node_cards_ptr->value;
  228. if(!node_cards.IsArray())
  229. {
  230. return;
  231. }
  232. std::lock_guard<std::mutex> lock(_mutex);
  233. call_user_ptr user_ptr(new call_user());
  234. auto it_map = _map.find(user_name);
  235. if(_map.end()!=it_map)//呼叫用户
  236. {
  237. user_ptr=it_map->second;
  238. }
  239. uint64_t id_card;
  240. for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i)
  241. {
  242. if(!tool_json::try_get_value( id_card, JSON_KEY_CALL_CARD_CARD_ID, node_cards[i])
  243. || 0==id_card
  244. )
  245. {
  246. continue;
  247. }
  248. call_card_ptr card_ptr(new call_card());
  249. card_ptr->cardid = id_card;
  250. result_user_ptr->cards[id_card]=card_ptr;//增加到结果集中
  251. user_ptr->cards.erase(id_card);//删除这个卡
  252. }
  253. // 没有呼叫信息,删除该用户记录
  254. if(user_ptr->cards.empty())
  255. {
  256. _map.erase(user_name);
  257. }
  258. }
  259. //如果要取消呼叫的用户下没有卡,建一张CCT_CALL_ALL卡返回
  260. if(result_user_ptr->cards.empty())
  261. {
  262. result_user_ptr->call_level_id=call_level;
  263. result_user_ptr->call_time=std::chrono::system_clock::now();
  264. result_user_ptr->call_time_out=0;
  265. result_user_ptr->call_type_id=call_type;
  266. result_user_ptr->user_name=user_name;
  267. call_card_ptr card_ptr(new call_card());
  268. card_ptr->cardid=CCT_CALL_ALL;
  269. result_user_ptr->cards[card_ptr->cardid]=card_ptr;
  270. }
  271. //转发给web
  272. response_accept_cancel(result_user_ptr);
  273. }
  274. /*
  275. 采集回复web:取消呼叫
  276. {
  277. "user_name":"fjb", // 取消人
  278. "call_time": 23432, // 发起呼叫时间
  279. "stations":[{"stationid":102}], // 分站号
  280. "cards":[{"cardid":"0","cardtype":"1"}] // 取消的卡
  281. }
  282. */
  283. void module_call::response_accept_cancel(const call_user_ptr user_ptr)
  284. {
  285. rapidjson::Document doc(rapidjson::kObjectType);
  286. auto& allocator = doc.GetAllocator();
  287. rapidjson::Value node_data(rapidjson::kObjectType);
  288. node_data.AddMember(JSON_KEY_CALL_CARD_USER_NAME, rapidjson::StringRef(user_ptr->user_name.c_str()), allocator);
  289. node_data.AddMember(JSON_KEY_CALL_CARD_CALL_TIME, tool_time::to_ms(user_ptr->call_time), allocator);
  290. rapidjson::Value node_cards(rapidjson::kArrayType);
  291. //加入取消呼叫的卡
  292. auto iter = user_ptr->cards.begin();
  293. for(;iter != user_ptr->cards.end();++iter)
  294. {
  295. rapidjson::Value node_card(rapidjson::kObjectType);
  296. node_card.AddMember(JSON_KEY_CALL_CARD_CARD_ID,iter->second->cardid, allocator);
  297. node_cards.PushBack(node_card,allocator);
  298. }
  299. node_data.AddMember(JSON_KEY_CALL_CARD_CARDS, node_cards, allocator);
  300. doc.AddMember(JSON_ROOT_KEY_CMD, JSON_CMD_VALUE_CALL_CARD_CANCEL_RESPONSE, allocator);
  301. doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator);
  302. doc.AddMember(JSON_ROOT_KEY_DATA, node_data, allocator);
  303. //转发给web
  304. swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
  305. }
  306. //void module_call::get_cancel_user_info(const call_user_ptr user_ptr,
  307. // const rapidjson::Value& node_cards, call_user_ptr& result_user_ptr)
  308. //{
  309. // copy(user_ptr, result_user_ptr);
  310. // uint16_t cardid;
  311. // for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i)
  312. // {
  313. // call_card_ptr card_ptr;
  314. // const rapidjson::Value& node = node_cards[i];
  315. // if(!node.IsUint64() || !find_card(user_ptr, cardid=node.GetUint64(), card_ptr))
  316. // {
  317. // continue;
  318. // }
  319. // user_ptr->cards.erase(cardid);//从呼叫用户卡中删除
  320. // result_user_ptr->cards[cardid]=card_ptr;
  321. // }
  322. //}
  323. /*
  324. 登陆时,采集发送web:井下所有呼叫
  325. {"cmd":"callcardlist","data":[
  326. ["fjb", // 发起呼叫人
  327. "0010000000001", // 呼叫的卡号
  328. 103, // 分站号
  329. 23431, // 发起呼叫时间
  330. 0, //
  331. 0 // 正在呼叫:2/结束呼叫/
  332. ]
  333. ]}
  334. */
  335. std::string module_call::accept_login()
  336. {
  337. std::vector<call_card_ptr> arr;
  338. get_all_call_cards(arr);
  339. if(arr.empty())
  340. {
  341. return "";
  342. }
  343. return to_call_card_list_json(arr);
  344. }
  345. std::string module_call::to_call_card_list_json(std::vector<call_card_ptr> arr)
  346. {
  347. rapidjson::Document doc(rapidjson::kObjectType);
  348. auto& allocator = doc.GetAllocator();
  349. rapidjson::Value node_cards(rapidjson::kArrayType);
  350. to_node_array(node_cards, arr, allocator);
  351. doc.AddMember(JSON_ROOT_KEY_CMD, JSON_CMD_VALUE_CALL_CARD_LIST, allocator);
  352. doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator);
  353. doc.AddMember(JSON_ROOT_KEY_DATA, node_cards, allocator);
  354. return tool_json::doc_to_json(doc);
  355. }
  356. void module_call::add_cards_to_user(int call_level, const rapidjson::Value& node_cards, call_user_ptr user_ptr)
  357. {
  358. uint64_t id_card;
  359. for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i)
  360. {
  361. if(!tool_json::try_get_value( id_card, JSON_KEY_CALL_CARD_CARD_ID, node_cards[i])
  362. || 0==id_card
  363. )
  364. {
  365. continue;
  366. }
  367. call_card_ptr card_ptr(new call_card());
  368. card_ptr->cardid = id_card;
  369. copy(user_ptr, card_ptr);
  370. card_ptr->call_state = CALL_ING;
  371. user_ptr->cards[card_ptr->cardid]=card_ptr;
  372. }
  373. }
  374. void module_call::get_user_all_call_cards(call_user_ptr& user_ptr,
  375. const std::unordered_map<uint64_t,std::shared_ptr<card_location_base>>& cardlist,
  376. std::vector<call_card_ptr>& out_data)
  377. {
  378. auto& cards=user_ptr->cards;
  379. int status = CALL_ING;
  380. //如果是全员呼叫,增加所有卡
  381. if(cards.size()==1 && CCT_CALL_ALL == cards[0]->cardid)
  382. {
  383. uint32_t seconds = tool_time::elapse_seconds(user_ptr->call_time);
  384. if(seconds > user_ptr->call_time_out*60)//呼叫超时, 清空全员卡, 并设置呼叫状态为结束
  385. {
  386. cards.clear();
  387. status=CALL_END;
  388. }
  389. auto g_it=cardlist.begin();
  390. for(;g_it!=cardlist.end();++g_it)//如果是全员呼叫,增加所有卡
  391. {
  392. call_card_ptr card_ptr(new call_card());
  393. copy(user_ptr, card_ptr);
  394. card_ptr->cardid = g_it->second->m_id;
  395. card_ptr->stationid=g_it->second->m_site_id;
  396. card_ptr->call_state=status;
  397. out_data.push_back(card_ptr);
  398. }
  399. return;
  400. }
  401. auto iter_card = cards.begin();
  402. for(;iter_card!=cards.end();++iter_card)
  403. {
  404. //增加到结果集中
  405. out_data.push_back(iter_card->second);
  406. auto g_card = cardlist.find(iter_card->second->cardid);
  407. if(cardlist.end()==g_card)//在全局卡列表中没有这张卡,
  408. {
  409. iter_card->second->call_state = CALL_FAILED;
  410. cards.erase(iter_card--); //在用户下删除这张卡
  411. continue;
  412. }
  413. //更新卡的分站id
  414. iter_card->second->stationid = g_card->second->m_site_id;
  415. uint32_t seconds = tool_time::elapse_seconds(iter_card->second->call_time);
  416. if(seconds > iter_card->second->call_time_out*60)//呼叫超时
  417. {
  418. iter_card->second->call_state = CALL_END;
  419. cards.erase(iter_card--);//在用户下删除这张卡
  420. }
  421. }
  422. }