Browse Source

区域时间段超员设置及功能

chensongchao 5 years ago
parent
commit
87d6908e08

+ 171 - 0
area.cpp

@@ -225,6 +225,117 @@ bool area::in_area(const std::shared_ptr<site>&s,const std::shared_ptr<card_loca
     }
 }
 
+void area::add_persons_thre(const SArea_Persons_Thre & thre)
+{
+	m_area_persons_thre[thre.db_id] = thre;
+}
+void area::del_persons_thre(int thre_db_id)
+{
+	m_area_persons_thre.erase(thre_db_id);
+}
+void area::clear_persons_thre()
+{
+	m_area_persons_thre.clear();
+}
+//
+int area::get_limit_person_count()
+{
+	return get_limit_person_count(tool_time::now_to_seconds());
+}
+int area::get_limit_person_count(uint64_t cur_time)
+{
+	std::string sz_cur_time = tool_time::to_str_time(cur_time);
+	for (auto it : m_area_persons_thre)
+	{
+		SArea_Persons_Thre &d = it.second;
+		if (sz_cur_time >= d.start_time && sz_cur_time <= d.end_time)
+		{
+			return d.thre_value;
+		}
+	}
+	return m_limit_person_count;
+}
+
+// 判断区域中是否有时间段超员设定
+bool area::is_time_person_thre()
+{
+    return m_area_persons_thre.size() > 0;
+}
+
+int area::update_persons_thre()
+{
+	uint32_t cur_time = tool_time::now_to_seconds();
+	std::string sz_cur_time = tool_time::to_str_time(cur_time);
+	for (auto &it : m_area_persons_thre)
+	{
+		SArea_Persons_Thre &d = it.second;
+		int t_state = d.in_time_state;
+		if (sz_cur_time < d.start_time)
+		{
+			d.in_time_state = EIN_TIME_STATE::NotYet;
+            log_info("area::update_persons_thre : Init areaid=%d db_id=%d time=%s -> %s val=%d "
+                    ,m_id,d.db_id,d.start_time.c_str(),sz_cur_time.c_str(),d.thre_value);
+        }
+		else if (sz_cur_time >= d.start_time && sz_cur_time <= d.end_time)
+		{
+            d.in_time_state = EIN_TIME_STATE::Middle;
+			if (t_state == EIN_TIME_STATE::NotYet)
+			{
+				d.check_state_time =cur_time;
+				log_info("area::update_persons_thre : areaid=%d db_id=%d time=%s -> %s val=%d state=%d -> %d"
+						,m_id,d.db_id,d.start_time.c_str(),d.end_time.c_str(),d.thre_value,t_state,d.in_time_state);
+				return d.in_time_state;
+			}
+		}
+		else
+		{
+            d.in_time_state = EIN_TIME_STATE::Overtime;
+			if (t_state == EIN_TIME_STATE::Middle)
+			{
+                d.check_state_time =cur_time;
+				log_info("area::update_persons_thre : areaid=%d db_id=%d time=%s -> %s val=%d state=%d -> %d"
+						,m_id,d.db_id,d.start_time.c_str(),d.end_time.c_str(),d.thre_value,t_state,d.in_time_state);
+
+				return d.in_time_state;
+			}
+		}
+	}
+	return EIN_TIME_STATE::NotYet;
+}
+
+void area::init_persons_thre()
+{
+	std::string sz_cur_time = tool_time::to_str_time(tool_time::now_to_seconds());
+	for (auto &it : m_area_persons_thre)
+	{
+		SArea_Persons_Thre &d = it.second;
+		if (sz_cur_time < d.start_time)
+		{
+			d.in_time_state = EIN_TIME_STATE::NotYet;
+		}
+		else if (sz_cur_time >= d.start_time && sz_cur_time <= d.end_time)
+		{
+			if (d.old_in_time_state == EIN_TIME_STATE::Middle)
+			{
+				d.in_time_state = EIN_TIME_STATE::Middle;
+			}
+		}
+		else
+		{
+			d.in_time_state = EIN_TIME_STATE::Overtime;
+			if (d.old_in_time_state == EIN_TIME_STATE::Middle)
+			{
+				d.in_time_state = EIN_TIME_STATE::Middle;
+			}
+		}
+
+		log_info("area::init_persons_thre : areaid=%d time=%s -> %s val=%d state=%d -> %d"
+				,m_id,d.start_time.c_str(),d.end_time.c_str(),d.thre_value,d.old_in_time_state,d.in_time_state);
+	}
+	log_info("area::init_persons_thre : areaid=%d count=%d",m_id,m_area_persons_thre.size());
+}
+
+/////////////////// area_list //////////////////////////////////////////////////
 area_list::area_list()
 {
 }
@@ -567,6 +678,66 @@ std::vector<std::shared_ptr<area>> area_list::get_area(const std::shared_ptr<sit
 	//区域覆盖不完全地图,很多车辆人行驶在地图外,如何确认.
 	return std::move(ret);
 }
+// 区域时间段超员设置
+void area_list::init_area_persons_dynamic_thre_from_db(int area_id/* = -1*/)
+{
+	std::string sql = "SELECT area_id,adpt_id,start_time,end_time,thre_value from dat_area_persons_dynamic_thre ";
+	if (area_id > -1 )
+	{
+		sql.append(" where area_id=");
+		sql.append(std::to_string(area_id));
+	}
+	sql.append(" order by area_id asc,start_time asc ;");
+	log_info("加载区域:%d 时间段人员超员设置sql: %s",area_id, sql.c_str());
+
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql.c_str(),DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount < 1)
+	{
+		return;
+	}
+	MAP_AREA_PERSONS_THRE map_thre;
+	std::shared_ptr<area> tmp_area = nullptr;
+	while ( DBRes.GetNextRecod(Error) )
+	{
+		SArea_Persons_Thre td;
+		DBRes.GetField("area_id", td.area_id, Error);
+		DBRes.GetField("adpt_id", td.db_id, Error);
+		DBRes.GetField("start_time", td.start_time, Error);
+		DBRes.GetField("end_time", td.end_time, Error);
+		DBRes.GetField("thre_value", td.thre_value, Error);
+
+		if (nullptr == tmp_area || tmp_area->m_id != td.area_id)
+		{
+			if (nullptr != tmp_area )
+			{
+				tmp_area->init_persons_thre();
+			}
+			tmp_area = area_list::instance()->get(td.area_id);
+			if (nullptr == tmp_area)
+			{
+				continue;
+			}
+			map_thre = tmp_area->m_area_persons_thre;
+			tmp_area->clear_persons_thre();
+		}
+		auto iter = map_thre.find(td.db_id);
+		if (iter != map_thre.end())
+		{
+			td.old_in_time_state = iter->second.in_time_state;
+			td.check_state_time = iter->second.check_state_time;
+		}
+		tmp_area->add_persons_thre(td);
+	}
+	if (nullptr != tmp_area )
+	{
+		tmp_area->init_persons_thre();
+	}
+
+}
+/////////////////////////////////////////////////////////////////////
 area_hover::area_hover(const std::shared_ptr<area>&area,const point&pt)
 	:m_area(area)
 {

+ 53 - 0
area.h

@@ -19,6 +19,40 @@ struct business_data;
 struct card_location_base;
 struct site;
 
+
+//区域时间段超员设置
+enum EIN_TIME_STATE
+{
+    NotYet   = 0,       //时间未到
+    Middle   = 1,       //时间过程中
+    Overtime = 2        //时间已过
+};
+
+struct SArea_Persons_Thre
+{
+    int db_id;
+    int area_id;
+    int thre_value;
+    int old_in_time_state;
+    int in_time_state;        //EIN_TIME_STATE
+    uint32_t check_state_time;//修改in_time_state时间
+    std::string start_time;
+    std::string end_time;
+
+    SArea_Persons_Thre()
+    {
+        db_id = 0;
+        area_id = 0;
+        thre_value = 0;
+        start_time = "";
+        end_time = "";
+        old_in_time_state = EIN_TIME_STATE::NotYet;
+        in_time_state = EIN_TIME_STATE::NotYet;
+    }
+};
+
+typedef std::map<int,SArea_Persons_Thre> MAP_AREA_PERSONS_THRE;
+
 /*
 	每个区域对应一个area对象。
 */
@@ -136,6 +170,23 @@ public:
     std::map<int,double> m_speed;
     std::vector<point> m_bound;
 	std::vector<area_business*> m_area_business_list;
+
+	//区域时间段超员限制
+    MAP_AREA_PERSONS_THRE m_area_persons_thre;
+    void add_persons_thre(const SArea_Persons_Thre & thre);
+    void del_persons_thre(int thre_db_id);
+    void clear_persons_thre();
+
+    // 获取区域cur_time超员的阈值,区域可能有时间段限制
+    int get_limit_person_count(uint64_t cur_time);
+    // 获取区域当前超员的阈值,区域可能有时间段限制
+    int get_limit_person_count();
+
+    // 判断区域中是否有时间段超员设定
+    bool is_time_person_thre();
+    // 更新区域时间段超员设置 return false:没有更新的记录
+    int update_persons_thre();
+    void init_persons_thre();
 };
 
 struct area_list:single_base<area_list,int,std::shared_ptr<area>>
@@ -148,6 +199,8 @@ struct area_list:single_base<area_list,int,std::shared_ptr<area>>
     ///id=-1为初始化所有
     void init_from_db(int id=-1);
     void init_monkeycar_area(int id=-1);
+    // 区域时间段超员设置
+    void init_area_persons_dynamic_thre_from_db(int area_id = -1);
 private:
 	std::shared_ptr<area>  create(int type,int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t b_type);
 };

+ 2 - 0
main.cpp

@@ -77,6 +77,8 @@ struct Init_Setting
         sit_list::instance()->load_from_db();
         card_list::instance()->init_card_from_db();
         area_list::instance()->init_from_db();
+        area_list::instance()->init_area_persons_dynamic_thre_from_db();
+
         forbid_staff_down_mine::instance()->init_forbid_staff();
         //point pt(3348,100);
         //int id = area_list::instance()->get_area(pt)->id();

+ 55 - 2
module_service/area_business_count_checker.cpp

@@ -50,7 +50,7 @@ void area_business_count_checker::on_enter(const std::shared_ptr<area_hover>&a,
 		return ;
 	if (c->is_person())
 	{
-        int limit_val=a->m_area->m_limit_person_count;
+        int limit_val=a->m_area->get_limit_person_count();
         int aid=a->m_area->id();
         if(limit_val<=0)
         {
@@ -120,6 +120,59 @@ void area_business_count_checker::on_hover(const std::shared_ptr<area_hover>&a,
           on_leave(a,c,ptr);
         c->update_display();
         ptr=nullptr;
+        return;
+    }
+
+    if (c->is_person() && a->m_area->is_time_person_thre())
+    {
+
+        int aid = a->m_area->id();
+        int in_time_state = a->m_area->update_persons_thre();
+        if (in_time_state == EIN_TIME_STATE::NotYet)
+        {
+            return;
+        }
+        int limit_val = a->m_area->get_limit_person_count();
+        if (limit_val <= 0) {
+            log_warn("on_enter_area_id:%d,limit_person_count is 0.so should not run area_business_count_checker...",
+                     aid);
+            return;
+        }
+        int pc = a->m_area->m_person_count.load();
+        int pc_ = a->m_area->m_person_show_count.load();
+        EVENT_TYPE ev = a->m_area->is_mine() ? EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON;
+        if (in_time_state == EIN_TIME_STATE::Middle)
+        {
+            //时间已到
+            if(pc>limit_val && !a->m_area->m_event_person_count){
+                lock();
+                event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc,a->m_area->m_event_person_count=true,DT_NORMAL);
+                unlock();
+                log_info("person_count_hover_enter:%d,v_count:%d limit:%d",aid,pc,limit_val);
+            }
+            if(pc_>limit_val && !a->m_area->m_event_person_show_count){
+                lock();
+                event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc_,a->m_area->m_event_person_show_count=true,DT_SPECIAL);
+                unlock();
+                log_info("person_count_hover_enter:%d,v_count:%d limit:%d",aid,pc_,limit_val);
+            }
+        }
+        else if(in_time_state == EIN_TIME_STATE::Overtime)
+        {
+            //时间已过
+            if(pc <= limit_val && a->m_area->m_event_person_count){
+                lock();
+                event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc,a->m_area->m_event_person_count=false,DT_NORMAL);
+                unlock();
+                log_info("person_count_hover_leave:%d,v_count:%d limit:%d",aid,pc,limit_val);
+            }
+            if(pc_ <= limit_val && a->m_area->m_event_person_show_count){
+                lock();
+                event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc_,a->m_area->m_event_person_show_count=false,DT_SPECIAL);
+                unlock();
+                log_info("person_count_hover_leave:%d,v_count:%d limit:%d",aid,pc_,limit_val);
+            }
+        }
     }
 }
 
@@ -150,7 +203,7 @@ void area_business_count_checker::on_leave(const std::shared_ptr<area_hover>&a,
         }
         int pc=a->m_area->m_person_count.load();
         int pc_=a->m_area->m_person_show_count.load();
-        int limit_val=a->m_area->m_limit_person_count;
+        int limit_val=a->m_area->get_limit_person_count();
         int aid=a->m_area->id();
 	    EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
 		if(a->m_area->m_event_person_count&& pc <= limit_val){

+ 13 - 1
module_service/module_meta_date_changed.cpp

@@ -16,6 +16,7 @@
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string.hpp>
 #include <card_path.h>
+#include "ya_setting.h"
 ///基础数据
 void module_meta_date_changed::accept(sio::message::ptr const& data)
 {
@@ -95,6 +96,11 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
         {
             deal_call_edit_forbid_person_down_mine(szParam,edit_type_id);
         }
+        else if (JSON_KEY_NAME_PERSONS_DYNAMIC_THRE == name)
+        {
+            int id = std::stoi(szParam);
+            deal_call_edit_persons_dynamic_thre(id,edit_type_id);
+        }
         else
         {
             log_error("web发来的数据: 基础数据name字段错误:name=%s", name.c_str());
@@ -305,9 +311,15 @@ void module_meta_date_changed::deal_call_edit_forbid_person_down_mine(const std:
     }
 }
 
+// 设置区域中时间段人员超员阈值等数据
+void module_meta_date_changed::deal_call_edit_persons_dynamic_thre(int area_id,EDIT_TYPE_ID edit_type_id)
+{
+    area_list::instance()->init_area_persons_dynamic_thre_from_db(area_id);
+}
+
 void module_meta_date_changed::init_setting()
 {
-    //pRes = getMysqlRes("select setting_id, name, type, value from dat_setting;");
+    CYaSetting::Init_sys_setting();
 }
 
 void module_meta_date_changed::remove_card(uint32_t id, int32_t type) {

+ 3 - 0
module_service/module_meta_date_changed.h

@@ -72,6 +72,9 @@ private:
     // 禁止指定人员下井
     void deal_call_edit_forbid_person_down_mine(const std::string & lszId,EDIT_TYPE_ID edit_type_id);
 
+    // 设置区域中时间段人员超员阈值等数据
+    void deal_call_edit_persons_dynamic_thre(int area_id,EDIT_TYPE_ID edit_type_id);
+
     ///待实现
     void init_setting();
 

+ 10 - 0
tool_time.h

@@ -129,6 +129,16 @@ public:
 
         return std::string(_time);
     }
+    //"%H:%M:%S"
+    static std::string to_str_time(const std::time_t &time)
+    {
+        char _time[25] = {0};
+        struct tm local_time;
+        localtime_r(&time, &local_time);
+        strftime(_time, 22, "%H:%M:%S", &local_time);
+
+        return std::string(_time);
+    }
     static int get_hour()
     {
         time_t tt = time(0);

+ 2 - 1
websocket/constdef.h

@@ -74,7 +74,8 @@
 #define JSON_KEY_NAME_HAND_UP "dat_handup_vehicle"
 //禁止指定人员下井
 #define JSON_KEY_NAME_FORBID_PERSON_DOWN_MINE "rt_person_forbid_down_mine"
-
+//设置区域中时间段人员超员阈值等数据
+#define JSON_KEY_NAME_PERSONS_DYNAMIC_THRE "area_persons_dynamic_thre"
 
 #define JSON_KEY_CALL_CARD_CALL_TYPE "call_type_id"
 #define JSON_KEY_CALL_CARD_CALL_TIME_OUT "call_time_out"