#include "module_call.h" #include #include #include #include #include #include /** * @brief 呼叫类型 全员 定员 */ enum CALL_CARD_TYPE { /// 全员呼叫 CCT_CALL_ALL = 0, /// 定员 CCT_CALL_APOINT=1, }; /** * @brief 呼叫等级 一般呼叫 紧急呼叫 */ enum CALL_CARD_LEVEL { /// 呼叫等级: 1 一般呼叫 CALL_LEVEL_NORMAL=1, /// 呼叫等级: 2 紧急呼叫 CALL_LEVEL_CRITICAL=2 }; /** * @brief 呼叫状态 */ enum CALL_STATE{ ///无呼叫信息 CALL_NONE = 0, ///呼叫成功 CALL_SUCCESSED = 1, ///呼叫中 CALL_ING = 2, ///呼叫失败 CALL_FAILED = 3, ///呼叫结束 CALL_END=100 }; void module_call::run() { std::vector arr; get_all_call_cards(arr); if(arr.empty()) { return ; } //转发给web swsClientMgr.send(JSON_CMD_VALUE_PUSH, to_call_card_list_json(arr)); //将呼叫命令发送给标识卡终端 } /* web发给采集:发起呼叫 { cmd: 'call_card_req', data: { call_type_id: this.cal_type, // 全员呼叫:0 定员呼叫:1 call_time_out: this.choosedTime, // 呼叫时长 call_level_id: this.call_type_id, // 呼叫类型 一般呼叫:1 紧急呼叫:2 user_name: xdata.userName, // 呼叫人 call_time: time, // 呼叫时间戳 stations: [{ stationid: 0 }], // 分站 0为全员 cards: cards // 人员 0为全员 //旧代码为map格式 [{ stationid: 0 }] } } */ void module_call::accept_call(const rapidjson::Document& node_data) { int call_type = -1, call_level = -1, call_time_out; std::string user_name; if(!tool_json::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, node_data) || !tool_json::try_get_value(call_level, JSON_KEY_CALL_CARD_CALL_LEVEL, node_data) || !tool_json::try_get_value(call_time_out, JSON_KEY_CALL_CARD_CALL_TIME_OUT, node_data) || !tool_json::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, node_data) ) { log_error("收到的json不对,解析不出int call_type = -1, call_level = -1, call_time_out,user_name"); return; } if(user_name.empty()) { log_error("user_name用户名为空"); return; } std::vector arr;//结果集 call_user_ptr user_ptr; if(CCT_CALL_ALL==call_type)// 全员 { user_ptr=call_user_ptr(new call_user()); user_ptr->call_time=std::chrono::system_clock::now(); user_ptr->call_time_out=call_time_out; user_ptr->call_type_id=call_type; user_ptr->call_level_id=call_level; user_ptr->user_name=user_name; call_card_ptr temp(new call_card()); copy(user_ptr, temp); temp->cardid = CCT_CALL_ALL; //全员卡 arr.push_back(temp);//增加到结果集中 //添加全员卡 user_ptr->cards.insert(std::make_pair(CCT_CALL_ALL, temp)); //更新用户信息 std::lock_guard lock(_mutex); _map[user_name]=user_ptr; } else// 定员: 如果有全员,定员不生效 { std::lock_guard lock(_mutex); auto user_map_ptr = _map.find(user_name); if(user_map_ptr==_map.end())//没有这个用户就新建并加入 { user_ptr=call_user_ptr(new call_user()); _map[user_name]=user_ptr; } else//有这个用户 { user_ptr=user_map_ptr->second; // 如果有全员,定员不生效 if(user_ptr->cards.size()==1 && CCT_CALL_ALL == user_ptr->cards[CCT_CALL_ALL]->cardid) { return; } } //更新用户信息 user_ptr->call_time=std::chrono::system_clock::now(); user_ptr->call_time_out=call_time_out; user_ptr->call_type_id=call_type; user_ptr->call_level_id=call_level; user_ptr->user_name=user_name; auto node_cards_ptr = node_data.FindMember(JSON_KEY_CALL_CARD_CARDS); if(node_data.MemberEnd()==node_cards_ptr) { return; } const rapidjson::Value& node_cards = node_cards_ptr->value; if(!node_cards.IsArray()) { return; } add_cards_to_user(call_level, node_cards, user_ptr); for(auto& it:user_ptr->cards)//添加到结果集中 { arr.push_back(it.second); } } //组装json发送给web if(!arr.empty()) { response_accept_call(arr); } } //采集回复web发起呼叫 //{ // 'cmd': 'call_card_resp', // 'data': [ // ["fjb", // 发起呼叫人 // "0010000000001", // 呼叫的卡号 // 103, // 分站号 // 23431, // 发起呼叫时间 // 0, // // 0 // 正在呼叫:2/结束呼叫/ // ] // ] //} void module_call::response_accept_call(std::vector cards) { rapidjson::Document doc(rapidjson::kObjectType); auto& allocator = doc.GetAllocator(); rapidjson::Value node_cards(rapidjson::kArrayType); //组装json发送给web to_node_array(node_cards, cards, allocator); doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_CALL_CARD_RESPONSE, allocator); doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator); doc.AddMember(JSON_ROOT_KEY_DATA, node_cards, allocator); swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc)); } //web发给采集:取消呼叫 //{ // cmd: 'call_card_cancel_req', // data: { // call_type_id: type, // 全员/定员 // user_name: xdata.userName, // 取消人 // call_time: callTime, // 时间戳 // stations: this.stationid, // 分站 // cards: this.cards // 取消呼叫卡 //旧代码为map格式 [{ stationid: 0 }] // } //} void module_call::accept_cancel(const rapidjson::Document& node_data) { int call_type = -1, call_level = -1; std::string user_name; if(!tool_json::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, node_data) || !tool_json::try_get_value(call_level, JSON_KEY_CALL_CARD_CALL_LEVEL, node_data) || !tool_json::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, node_data) ) { log_error("收到的json不对,解析不出int call_type = -1, call_level = -1,user_name"); return; } if(user_name.empty()) { log_error("user_name用户名为空"); return; } call_user_ptr result_user_ptr(new call_user()); result_user_ptr->call_type_id=call_type; result_user_ptr->call_level_id=call_level; result_user_ptr->user_name=user_name; //取消呼叫有两种: //取消全员呼叫 //对指定卡取消呼叫 if(CCT_CALL_ALL==call_type)// 取消全员呼叫 { //删除用户 std::lock_guard lock(_mutex); _map.erase(user_name); } else// 取消定员呼叫 { auto node_cards_ptr = node_data.FindMember(JSON_KEY_CALL_CARD_CARDS); if(node_data.MemberEnd()==node_cards_ptr) { return; } const rapidjson::Value& node_cards = node_cards_ptr->value; if(!node_cards.IsArray()) { return; } std::lock_guard lock(_mutex); call_user_ptr user_ptr(new call_user()); auto it_map = _map.find(user_name); if(_map.end()!=it_map)//呼叫用户 { user_ptr=it_map->second; } uint64_t id_card; for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i) { if(!tool_json::try_get_value( id_card, JSON_KEY_CALL_CARD_CARD_ID, node_cards[i]) || 0==id_card ) { continue; } call_card_ptr card_ptr(new call_card()); card_ptr->cardid = id_card; result_user_ptr->cards[id_card]=card_ptr;//增加到结果集中 user_ptr->cards.erase(id_card);//删除这个卡 } // 没有呼叫信息,删除该用户记录 if(user_ptr->cards.empty()) { _map.erase(user_name); } } //如果要取消呼叫的用户下没有卡,建一张CCT_CALL_ALL卡返回 if(result_user_ptr->cards.empty()) { result_user_ptr->call_level_id=call_level; result_user_ptr->call_time=std::chrono::system_clock::now(); result_user_ptr->call_time_out=0; result_user_ptr->call_type_id=call_type; result_user_ptr->user_name=user_name; call_card_ptr card_ptr(new call_card()); card_ptr->cardid=CCT_CALL_ALL; result_user_ptr->cards[card_ptr->cardid]=card_ptr; } //转发给web response_accept_cancel(result_user_ptr); } /* 采集回复web:取消呼叫 { "user_name":"fjb", // 取消人 "call_time": 23432, // 发起呼叫时间 "stations":[{"stationid":102}], // 分站号 "cards":[{"cardid":"0","cardtype":"1"}] // 取消的卡 } */ void module_call::response_accept_cancel(const call_user_ptr user_ptr) { rapidjson::Document doc(rapidjson::kObjectType); auto& allocator = doc.GetAllocator(); rapidjson::Value node_data(rapidjson::kObjectType); node_data.AddMember(JSON_KEY_CALL_CARD_USER_NAME, rapidjson::StringRef(user_ptr->user_name.c_str()), allocator); node_data.AddMember(JSON_KEY_CALL_CARD_CALL_TIME, tool_time::to_ms(user_ptr->call_time), allocator); rapidjson::Value node_cards(rapidjson::kArrayType); //加入取消呼叫的卡 auto iter = user_ptr->cards.begin(); for(;iter != user_ptr->cards.end();++iter) { rapidjson::Value node_card(rapidjson::kObjectType); node_card.AddMember(JSON_KEY_CALL_CARD_CARD_ID,iter->second->cardid, allocator); node_cards.PushBack(node_card,allocator); } node_data.AddMember(JSON_KEY_CALL_CARD_CARDS, node_cards, allocator); doc.AddMember(JSON_ROOT_KEY_CMD, JSON_CMD_VALUE_CALL_CARD_CANCEL_RESPONSE, allocator); doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator); doc.AddMember(JSON_ROOT_KEY_DATA, node_data, allocator); //转发给web swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc)); } //void module_call::get_cancel_user_info(const call_user_ptr user_ptr, // const rapidjson::Value& node_cards, call_user_ptr& result_user_ptr) //{ // copy(user_ptr, result_user_ptr); // uint16_t cardid; // for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i) // { // call_card_ptr card_ptr; // const rapidjson::Value& node = node_cards[i]; // if(!node.IsUint64() || !find_card(user_ptr, cardid=node.GetUint64(), card_ptr)) // { // continue; // } // user_ptr->cards.erase(cardid);//从呼叫用户卡中删除 // result_user_ptr->cards[cardid]=card_ptr; // } //} /* 登陆时,采集发送web:井下所有呼叫 {"cmd":"callcardlist","data":[ ["fjb", // 发起呼叫人 "0010000000001", // 呼叫的卡号 103, // 分站号 23431, // 发起呼叫时间 0, // 0 // 正在呼叫:2/结束呼叫/ ] ]} */ std::string module_call::accept_login() { std::vector arr; get_all_call_cards(arr); if(arr.empty()) { return ""; } return to_call_card_list_json(arr); } std::string module_call::to_call_card_list_json(std::vector arr) { rapidjson::Document doc(rapidjson::kObjectType); auto& allocator = doc.GetAllocator(); rapidjson::Value node_cards(rapidjson::kArrayType); to_node_array(node_cards, arr, allocator); doc.AddMember(JSON_ROOT_KEY_CMD, JSON_CMD_VALUE_CALL_CARD_LIST, allocator); doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator); doc.AddMember(JSON_ROOT_KEY_DATA, node_cards, allocator); return tool_json::doc_to_json(doc); } void module_call::add_cards_to_user(int call_level, const rapidjson::Value& node_cards, call_user_ptr user_ptr) { uint64_t id_card; for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i) { if(!tool_json::try_get_value( id_card, JSON_KEY_CALL_CARD_CARD_ID, node_cards[i]) || 0==id_card ) { continue; } call_card_ptr card_ptr(new call_card()); card_ptr->cardid = id_card; copy(user_ptr, card_ptr); card_ptr->call_state = CALL_ING; user_ptr->cards[card_ptr->cardid]=card_ptr; } } void module_call::get_user_all_call_cards(call_user_ptr& user_ptr, const std::unordered_map>& cardlist, std::vector& out_data) { auto& cards=user_ptr->cards; int status = CALL_ING; //如果是全员呼叫,增加所有卡 if(cards.size()==1 && CCT_CALL_ALL == cards[0]->cardid) { uint32_t seconds = tool_time::elapse_seconds(user_ptr->call_time); if(seconds > user_ptr->call_time_out*60)//呼叫超时, 清空全员卡, 并设置呼叫状态为结束 { cards.clear(); status=CALL_END; } auto g_it=cardlist.begin(); for(;g_it!=cardlist.end();++g_it)//如果是全员呼叫,增加所有卡 { call_card_ptr card_ptr(new call_card()); copy(user_ptr, card_ptr); card_ptr->cardid = g_it->second->m_id; //card_ptr->stationid=g_it->second->m_site_id; card_ptr->call_state=status; out_data.push_back(card_ptr); } return; } auto iter_card = cards.begin(); for(;iter_card!=cards.end();++iter_card) { //增加到结果集中 out_data.push_back(iter_card->second); auto g_card = cardlist.find(iter_card->second->cardid); if(cardlist.end()==g_card)//在全局卡列表中没有这张卡, { iter_card->second->call_state = CALL_FAILED; cards.erase(iter_card--); //在用户下删除这张卡 continue; } //更新卡的分站id //iter_card->second->stationid = g_card->second->m_site_id; uint32_t seconds = tool_time::elapse_seconds(iter_card->second->call_time); if(seconds > iter_card->second->call_time_out*60)//呼叫超时 { iter_card->second->call_state = CALL_END; cards.erase(iter_card--);//在用户下删除这张卡 } } }