/* * @file * module_call.h * * @brief * 呼叫业务 * @version * V1.0 * @author * * @date * 2021/05/10 * @note * * @warning * @bug * @copyright * */ #ifndef MODULE_CALL_H #define MODULE_CALL_H #include #include #include #include #include #include #include #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" #include "module_singleton_base.h" #include "card.h" #include "websocket/sio/sio_client.h" #include "module_i_thread.h" #include "config_file.h" /** * @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 }; /** * @brief 呼叫卡的信息 */ struct call_card { /// 呼叫卡号 0为全员 uint32_t cardid; int32_t cardtype; /// 分站号 0为全员 int stationid; ///呼叫类型 全员0, 定员1 CALL_CARD_TYPE int call_type_id; /// 呼叫类型:一般1,紧急2 CALL_CARD_LEVEL int call_level_id; /// 呼叫时长,单位分钟 uint32_t call_time_out; int call_time_interval; /// 呼叫开始时间 std::chrono::system_clock::time_point call_time; /// 呼叫状态,正在呼叫、呼叫成功 int call_state; ///呼叫人 std::string user_name; bool is_display = true; call_card() {} call_card(uint32_t id, int32_t type, int level_id, CALL_CARD_TYPE call_type, int sid): cardid(id), cardtype(type), stationid(sid), call_type_id(call_type), call_level_id(level_id) { user_name = "system"; } bool is_call_all() { return CCT_CALL_ALL == call_type_id; } uint64_t to_id64(); std::string to_id64_str(); bool is_timeout(); }; using call_card_ptr = std::shared_ptr; /** * @brief 呼叫模块 */ class module_call : public i_thread, public singleton_base { private: friend class singleton_base; module_call() { } private: typedef std::map call_card_map; /** * @brief 呼叫用户信息 */ struct call_user { ///呼叫人 std::string user_name; ///呼叫类型 全员0, 定员1 CALL_CARD_TYPE int call_type_id; /// 呼叫等级:一般1,紧急2 CALL_CARD_LEVEL int call_level_id; /// 呼叫时长,单位分钟 uint32_t call_time_out; int call_time_interval; /// 呼叫开始时间 std::chrono::system_clock::time_point call_time; ///呼叫卡列表 call_card_map cards; bool is_timeout(); bool is_call_all() { return CCT_CALL_ALL == call_type_id; } }; typedef std::shared_ptr call_user_ptr; typedef std::map call_user_map; struct call_site { int32_t site_id; ///呼叫类型 全员0, 定员1 CALL_CARD_TYPE int call_type_id; /// 呼叫等级:一般1,紧急2 CALL_CARD_LEVEL int call_level_id; call_card_map cards; bool is_call_all() { return CCT_CALL_ALL == call_type_id; } }; typedef std::shared_ptr call_site_ptr; typedef std::map call_site_map; public: /** * @brief web发给采集:发起呼叫 * @param node_data */ void accept_call(sio::message::ptr const& data); /** * @brief web发给采集:取消呼叫 * @param node_data */ void accept_cancel(sio::message::ptr const& data); /** * @brief 登陆时,采集发送web:请求井下所有呼叫 */ std::string accept_login(); void rev_from_card_resp(std::shared_ptr card_ptr); /** * @brief 系统自动发送呼叫给指定的卡 */ void system_call_apoint(int card_id,int card_type); /** * @brief 系统自动发送呼叫给指定的卡 */ void system_cancel_call_apoint(int card_id,int card_type); void send_anti_collision(const std::map& cards); std::string get_json_anti_collision(); /**int card_id,int card_type * @brief */ void init(config_file& config) { sleep_ms = std::stoi(config.get("service.send_call_interval_ms","5000")); } private: /** * @brief 采集回复web发起呼叫 * @param arr */ void response_accept_call(const std::vector arr); /** * @brief 采集回复web:取消呼叫 * @param node_data */ void response_accept_cancel(const call_user_ptr user_ptr); void add_cards_to_user(const std::vector& card_vec, call_user_ptr user_ptr); /** * @brief 线程函数 */ void run(); void copy(const call_user_ptr src, call_user_ptr des) { des->call_level_id = src->call_level_id; des->call_time = src->call_time; des->call_time_out = src->call_time_out; des->call_type_id = src->call_type_id; des->user_name = src->user_name; } void copy(const call_card_ptr src, call_card_ptr des) { des->call_level_id = src->call_level_id; des->call_state = src->call_state; des->call_time = src->call_time; des->call_time_out = src->call_time_out; des->cardid = src->cardid; des->cardtype = src->cardtype; des->user_name = src->user_name; des->stationid = src->stationid; des->call_type_id = src->call_type_id; } void copy(const call_user_ptr src, call_card_ptr des) { des->call_level_id = src->call_level_id; //des->call_state = src->call_state; des->call_time = src->call_time; des->call_time_out = src->call_time_out; des->call_time_interval = src->call_time_interval; //des->cardid = src->cardid; des->user_name = src->user_name; des->call_type_id = src->call_type_id; } /** * @brief 获取用户下的所有呼叫卡 * @param user_ptr * @param cardlist * @param out_data */ void get_user_all_call_cards(call_user_ptr& user_ptr, const std::unordered_map>& cardlist, std::vector& out_data); /** * @brief 获取所有的呼叫卡 * @param user_map * @param cardlist * @param out_data */ void get_all_call_cards(call_user_map& user_map, const std::unordered_map>& cardlist, std::vector& out_data) { auto iter_m_map=user_map.begin(); for(;iter_m_map!=user_map.end();++iter_m_map) { get_user_all_call_cards(iter_m_map->second, cardlist, out_data); if(iter_m_map->second->cards.empty())//没有卡了 删除呼叫用户 { user_map.erase(iter_m_map--); } } } /** * @brief 获取所有的呼叫卡 * @param out_data */ void get_all_call_cards(std::vector& out_data) { auto cardlist = card_list::instance()->m_map; { std::lock_guard lock(_mutex); get_all_call_cards(_map, cardlist, out_data); } } /* * @brief * ["fjb", // 发起呼叫人 * "0010000000001", // 呼叫的卡号 * 103, // 分站号 * 23431, // 发起呼叫时间 * 0, // * 0 // 正在呼叫:2/结束呼叫/ * ] */ static void to_node_element(rapidjson::Value& out_elemet, const std::shared_ptr card_ptr, rapidjson::Document::AllocatorType& allocator,bool f); static void to_node_array(rapidjson::Value& out_array, const std::vector> cards, rapidjson::Document::AllocatorType& allocator,bool f=true) { std::vector>::size_type i; for(i=0; iis_display) { continue; } rapidjson::Value node_card(rapidjson::kArrayType); to_node_element(node_card, cards[i], allocator,f); out_array.PushBack(node_card, allocator); } } /** * @brief 生成所有呼叫卡的json * @param cards * @return */ std::string to_call_card_list_json(std::vector cards); void get_site_map(const std::vector& arr, call_site_map& out_site_map) { auto card_ptr = arr.begin(); for(;card_ptr!=arr.end();++card_ptr) { if((*card_ptr)->stationid<1) { continue; } auto iter = out_site_map.find((*card_ptr)->stationid); if(out_site_map.end()==iter) { call_site_ptr site_ptr(new call_site()); site_ptr->site_id = (*card_ptr)->stationid; site_ptr->call_type_id = (*card_ptr)->call_type_id; site_ptr->call_level_id = (*card_ptr)->call_level_id; out_site_map.insert(std::make_pair(site_ptr->site_id, site_ptr)); iter = out_site_map.find((*card_ptr)->stationid); } if(iter->second->is_call_all()) { continue; } if((*card_ptr)->is_call_all()) { iter->second->call_type_id = (*card_ptr)->call_type_id; iter->second->cards.clear(); continue; } iter->second->cards[(*card_ptr)->cardid]=(*card_ptr); } } ///发呼叫的报文数据给分站 void send_to_sites(call_site_map& site_map); static void print_test(std::vector&& arr, int siteid); void static memcpy_uint32(std::vector& arr, uint32_t dwSrc) { char bt = HIBYTE(HIWORD(dwSrc)); arr.push_back(bt); bt = LOBYTE(HIWORD(dwSrc)); arr.push_back(bt); bt = HIBYTE(LOWORD(dwSrc)); arr.push_back(bt); bt = LOBYTE(LOWORD(dwSrc)); arr.push_back(bt); } static char HIBYTE(uint16_t dwSrc) { return static_cast(dwSrc>>8); } static char LOBYTE(uint16_t dwSrc) { return static_cast(dwSrc); } static uint16_t HIWORD(uint32_t dwSrc) { return static_cast(dwSrc>>16); } static uint16_t LOWORD(uint32_t dwSrc) { return static_cast(dwSrc); } private: /// 呼叫用户列表 call_user_map _map; }; #endif // MODULE_CALL_H