Browse Source

Merge branch 'master' of http://local.beijingyongan.com:3000/linux-dev/ya-serv

liulei 6 years ago
parent
commit
5d5a72f4a2
76 changed files with 2255 additions and 1444 deletions
  1. 8 0
      .gitignore
  2. 3 2
      Makefile.am
  3. 309 116
      ant.cpp
  4. 43 79
      ant.h
  5. 286 134
      area.cpp
  6. 63 15
      area.h
  7. 13 14
      area_business.cpp
  8. 5 1
      area_business.h
  9. 33 15
      card.cpp
  10. 6 4
      card.h
  11. 29 15
      card_base.cpp
  12. 8 2
      card_base.h
  13. 6 17
      card_car.cpp
  14. 3 8
      card_message_handle.cpp
  15. 7 0
      card_message_handle.h
  16. 16 26
      card_path.cpp
  17. 34 27
      card_person.cpp
  18. 10 56
      client.cpp
  19. 11 6
      common.h
  20. 1 1
      db/Makefile.am
  21. 1 0
      db/db_api/CDBConnPool.cpp
  22. 6 9
      db/db_card.cpp
  23. 3 3
      db/db_card.h
  24. 3 7
      db/db_tool.cpp
  25. 30 27
      event.cpp
  26. 15 19
      event.h
  27. 124 0
      forbid_staff_down_mine.cpp
  28. 51 0
      forbid_staff_down_mine.h
  29. 24 6
      line.h
  30. 38 41
      main.cpp
  31. 25 3
      message.cpp
  32. 5 3
      message.h
  33. 91 19
      message_file.cpp
  34. 5 2
      message_file.h
  35. 13 8
      mine.h
  36. 3 3
      mine_business.cpp
  37. 0 5
      module_service/area_business_car_attendance.h
  38. 0 5
      module_service/area_business_card_enter_or_leave.h
  39. 103 59
      module_service/area_business_count_checker.cpp
  40. 20 6
      module_service/area_business_count_checker.h
  41. 0 4
      module_service/area_business_forbid.h
  42. 5 8
      module_service/area_business_geofault.cpp
  43. 0 5
      module_service/area_business_geofault.h
  44. 19 9
      module_service/area_business_motionless_persion.cpp
  45. 1 4
      module_service/area_business_motionless_persion.h
  46. 13 99
      module_service/area_business_person_attendance.cpp
  47. 0 6
      module_service/area_business_person_attendance.h
  48. 13 6
      module_service/area_business_person_dwell_checker.cpp
  49. 0 4
      module_service/area_business_person_dwell_checker.h
  50. 1 1
      module_service/area_business_post_area.cpp
  51. 0 4
      module_service/area_business_post_area.h
  52. 1 1
      module_service/area_business_speed_checker.cpp
  53. 0 5
      module_service/area_business_speed_checker.h
  54. 0 5
      module_service/area_business_work_rate.h
  55. 3 2
      module_service/module_call_help.cpp
  56. 119 123
      module_service/module_meta_date_changed.cpp
  57. 12 13
      module_service/module_meta_date_changed.h
  58. 1 1
      module_service/module_web.cpp
  59. 30 8
      net-service.cpp
  60. 8 5
      select_tool.cpp
  61. 4 2
      select_tool.h
  62. 159 276
      test.cpp
  63. 2 2
      tool_time.h
  64. 1 1
      websocket/Makefile.am
  65. 6 2
      websocket/constdef.h
  66. 4 4
      websocket/jsonBuilder.cpp
  67. 104 0
      websocket/web_connect.cpp
  68. 34 0
      websocket/web_connect.h
  69. 6 3
      websocket/wsClient.cpp
  70. 13 14
      websocket/wsTimerThread.cpp
  71. 1 1
      websocket/wsTimerThread.h
  72. 58 7
      worker.cpp
  73. 33 12
      worker.h
  74. 146 44
      znet.cpp
  75. 2 0
      znet.h
  76. 2 0
      zstream.h

+ 8 - 0
.gitignore

@@ -26,5 +26,13 @@ CMakeFiles/
 .git/
 .vscode/
 Makefile
+Debug/*
+CMakeFile*
+*.txt*
+/etc
+config_file.h
+log.h
+struct_def.h
+three_rates.h
 
 

+ 3 - 2
Makefile.am

@@ -21,7 +21,8 @@ SRC_MAIN= ant.cpp area.cpp base64.cpp bindmorecard.cpp mine_business.cpp card_ar
     	  card.cpp card_message_handle.cpp cardMgr.cpp card_path.cpp card_person.cpp crc.cpp geo_hash.cpp \
 		  landmark.cpp line_fit.cpp loc_point.cpp loc_tool.cpp message.cpp message_file.cpp mine.cpp \
 		  net-service.cpp point.cpp select_tool.cpp  special_area.cpp tdoa_sync.cpp visit.cpp \
-		  web-client.cpp worker.cpp event.cpp znet.cpp ya_setting.cpp area_business.cpp
+		  web-client.cpp worker.cpp event.cpp znet.cpp ya_setting.cpp area_business.cpp\
+		  forbid_staff_down_mine.cpp
 
 AM_SOURCES=$(SRC_MONKEYCAR) $(SRC_MODULE_SERVICE) $(SRC_MAIN) $(SRC_MAIN_EVENT)
 
@@ -43,7 +44,7 @@ client_SOURCES=client.cpp message_file.cpp
 client_CPPFLAGS=${AM_CPPFLAGS}
 client_LDFLAGS=${AM_LDFLAGS}  -L. -lzlog
 
-test_SOURCES=test.cpp base64.cpp
+test_SOURCES=test.cpp base64.cpp point.cpp
 test_CPPFLAGS=${AM_CPPFLAGS}
 test_LDFLAGS=${AM_LDFLAGS}  -L. -lzlog -lrt
 

+ 309 - 116
ant.cpp

@@ -6,6 +6,7 @@
 #include "event.h"
 #include "tool_time.h"
 #include "area.h"
+#include "card_path.h"
 //template<> std::shared_ptr<sit_list> single_base<sit_list, int, std::shared_ptr<site>>::m_instance=std::make_shared<sit_list>();
 
 int site::index()const
@@ -16,8 +17,8 @@ int site::index()const
 site::site(int id)
 	:m_algo(0)
 	,m_num_dims(0)
-    ,m_id(id)
-    ,m_path_empty(true)
+	,m_id(id)
+	,m_path_empty(true)
 {
 	m_time=time(0);
 }
@@ -27,143 +28,331 @@ const algo_config&site::config()const
 	return g_config[index()];
 }
 
-bool visit_site_status::visit(std::shared_ptr<site> s)
+void ant::set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator itm)
 {
-	time_t now=time(0);
-	int diff = now-s->m_time;
-	event_tool::instance()->handle_event(OT_DEVICE_READER,ET_READER_ERROR,s->m_id,READER_TIMEOUT,diff,[diff](){return diff>READER_TIMEOUT;});
-	return true;
+	auto it=itm;
+	for(int i=0;i<2 && it!=v_line.end();++it,++i)
+		m_path[0][i]=*it;
+
+	it=itm-1;
+	for(int i=0;i<2 && it>=v_line.begin();--it,++i)
+	{
+		m_path[1][i]=*it;
+		m_path[1][i].swap_point();
+	}
+
+	for(const auto&p:m_path)
+	{
+		log_info("site-path: %s",p.to_str().c_str());
+	}
 }
 
-void sit_list::read_ant_path(int id)
+void ant::set_path(const std::vector<line_v>&v_line_)
 {
-     std::string sql = "SELECT reader_id,tof_flag,b_x,b_y,b_z,e_x,e_y,e_z,spacing_ratio FROM dat_reader_path_tof_n";
+	std::vector<line_v> vl(v_line_);
+	vl.reserve(vl.size()+2);
+	//找到距离天线最近的端点
+	auto min_it=vl.begin();
+	double dist=10;
+	for(auto it=vl.begin();it!=vl.end();it++)
+	{
+		double d=it->as_line().dist(*this);
+		if(d<dist)
+		{
+			dist=d;
+			min_it=it;
+		}
+	}
+
+	if(min_it==vl.end())
+	{
+		log_error("分站路径距离分站太远site_id=%d",m_id);
+		return;
+	}
 
-     if(-1 == id)
-     {
-         sql.append(";");
-     }
-     else
-     {
-         sql.append(" AND reader_id=");
-         sql.append(std::to_string(id));
-         sql.append(";");
+	if(abs(min_it->v[0].dist(*this)-dist)<1)
+	{
+		set_path(vl,min_it);
+	}
+	else if(abs(min_it->v[1].dist(*this)-dist)<1)
+	{
+		set_path(vl,min_it+1);
+	}
+	else
+	{
+		point proj=min_it->projection(*this);
+		vl.insert(min_it+1,line_v(proj,min_it->v[1]));
+		min_it->set_point(1,proj);
+
+		if(min_it->v[0].z)//slope ..555
+		{
+			double slope=min_it->v[0].z;
+			double len_a=min_it->v[0].dist((min_it+1)->v[1]);
+			double len_0=slope*min_it->length()/len_a;
+			double len_1=slope-len_0;
+			
+			min_it->v[0].z=min_it->v[1].z=len_0;
+			(min_it+1)->v[0].z=(min_it+1)->v[1].z=len_1;
+		}
+
+		set_path(vl,min_it+1);
+	}
+}
 
-         std_debug("修改path sql=%s", sql.c_str());
-         log_info("修改path sql=%s", sql.c_str());
-     }
+void site::set_path(const std::vector<line_v>&v_line)
+{
+	if(v_line.empty())
+		return;
+
+	const auto&find_line=[](const point&pt,int first,std::vector<line_v>&vl){
+		for(auto it=vl.begin();it!=vl.end();it++)
+		{
+			if(it->v[first].dist(pt)<1)
+				return it;
+			if(it->v[first?0:1].dist(pt)<1)
+			{
+				point p=it->v[0];
+				it->v[0]=it->v[1];
+				it->v[1]=p;
+				return it;
+			}
+		}
+
+		return vl.end();
+	};
+	
+	//构造一个首尾相连的结构
+
+	std::vector<line_v> vl(v_line.begin()+1,v_line.end());
+	std::vector<line_v> target(v_line.begin(),v_line.begin()+1);
+#if 0
+	target[0][0].z=target[0][1].z=slope[0];
+	for(int i=0,c=vl.size();i<c;i++)
+		vl[i][0].z=vl[i][1].z=slope[i+1];
+#endif
 
-     std::string Error;
-     YADB::CDBResultSet DBRes;
-     sDBConnPool.Query(sql.c_str(),DBRes,Error);
-     int nCount = DBRes.GetRecordCount( Error );
-     if (nCount < 1)
-     {
-         log_error("修改path失败,数据库中找不到(dat_reader_path_tof_n): 分站id=%d", id);
-         return ;
-     }
+	for(;;)
+	{
+		auto it=find_line(target.back().v[1],0,vl);
+		if(it==vl.end())
+			break;
 
-    log_info( "read_ant_path. The record count=%ld\n", nCount );
-     while ( DBRes.GetNextRecod(Error) )
-     {
-         int reader_id  = 0;
-         DBRes.GetField( "reader_id",reader_id, Error );
+		target.insert(target.end(),it,it+1);
+		vl.erase(it);
+	}
 
-         auto site_ptr=sit_list::instance()->get(reader_id);
-         if(nullptr==site_ptr)
-             continue;
+	for(;;)
+	{
+		auto it=find_line(target.front().v[0],1,vl);
+		if(it==vl.end())
+			break;
 
-         int pid=0;
-         DBRes.GetField( "tof_flag",pid, Error );
+		target.insert(target.begin(),it,it+1);
+		vl.erase(it);
+	}
 
-         double b_x= 0;
-         DBRes.GetField( "b_x",b_x, Error );
+	log_info("初始化分站路径:site_id=%d",m_id);
 
-         double b_y= 0;
-         DBRes.GetField( "b_y",b_y, Error );
+	for(auto&a:m_ant)
+	{
+		a.set_path(target);
+	}
+	m_path_empty= !m_ant[0][0].valid() && !m_ant[0][1].valid() ;
+}
 
-         double b_z= 0;
-         DBRes.GetField( "b_z",b_z, Error );
+std::vector<point> ant::getsol(const double &dist) const
+{
+	std::vector<point> v;
+	for(const auto & p : m_path)
+	{
+		if(!p.valid())
+			continue;
+
+		point pt;
+		double d  = dist;
+
+		if(dist <= p.m_line[0].length())
+		{
+			d += d*p.m_line[0][0].z;
+			pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
+		}
+		else if(p.m_line[1].length()>0)
+		{
+			d -= p.m_line[0].length()*(1-d*p.m_line[0][1].z);
+			d += d*p.m_line[1][0].z;
+
+			pt = point(p.m_line[1][0].x+d*p.m_line[1].cos(),p.m_line[1][0].y+d*p.m_line[1].sin());
+		}
+		else
+		{
+			continue;
+		}
+		v.push_back(pt);
+	}
+	return std::move(v);
+}
 
-         double e_x= 0;
-         DBRes.GetField( "e_x",e_x, Error );
+bool visit_site_status::visit(std::shared_ptr<site> s)
+{
+	time_t now=time(0);
+	int diff = now-s->m_time;
+	event_tool::instance()->handle_event(OT_DEVICE_READER,ET_READER_ERROR,s->m_id,READER_TIMEOUT,diff,diff>READER_TIMEOUT);
+	return true;
+}
 
-         double e_y= 0;
-         DBRes.GetField( "e_y",e_y, Error );
+void sit_list::read_ant_path(int id)
+{
+	std::string sql = "SELECT reader_id,tof_flag,b_x,b_y,b_z,e_x,e_y,e_z,spacing_ratio FROM dat_reader_path_tof_n";
 
-         double e_z= 0;
-         DBRes.GetField( "e_z",e_z, Error );
+	std::map<int,std::vector<line_v>> map_path;
 
-         double spacing_ratio = 0;
-         DBRes.GetField( "spacing_ratio",spacing_ratio, Error );
-         log_info("ant_path:%d,%.2f,%.2f,%.2f,%.2f",reader_id,b_x,b_y,e_x,e_y);
-         point p1(b_x,-b_y);
-         point p2(e_x,-e_y);
-         auto &sit_ = *site_ptr;
-         if(-1!=id)//清空path
-         {
-            sit_.clear_path();
-            log_info( "修改path 清空path,分站id=%d\n", id );
-         }
+	if(-1 == id)
+	{
+		sql.append(";");
+	}
+	else
+	{
+		sql.append(" where reader_id=");
+		sql.append(std::to_string(id));
+		sql.append(";");
+
+		std_debug("修改path sql=%s", sql.c_str());
+		log_info("修改path sql=%s", sql.c_str());
+	}
+
+	std::string Error;
+	YADB::CDBResultSet DBRes;
+	sDBConnPool.Query(sql.c_str(),DBRes,Error);
+	int nCount = DBRes.GetRecordCount( Error );
+	if (nCount < 1)
+	{
+		log_error("修改path失败,数据库中找不到(dat_reader_path_tof_n): 分站id=%d", id);
+		return ;
+	}
 
-         if(pid == 0)
-         {
-             line_v l(p1,p2);
-             {
-                 point px = l.line::projection(sit_);
-                 sit_.set(px);
-                 for(int i=0;i<2;i++)
-                 {
-                     path p;
-                     p.m_slope[0] = spacing_ratio;
-                     p.m_line[0] = line_v(px,l[i]);
-                     sit_.m_ant[i].m_path.push_back(p);
-                 }
-             }
-         }
-         else
-         {
-             ant &a = pid<0?sit_.m_ant[0]:sit_.m_ant[1];
-             if(a.m_path.size()!=0)
-             {
-                 path &p = a.m_path[0];
-                 p.m_line[abs(pid)-1] = line_v(p1,p2);
-                 p.m_slope[abs(pid)-1] = spacing_ratio;
-             }
-             else
-             {
-                 path p;
-                 p.m_line[abs(pid)-1] = line_v(p1,p2);
-                 p.m_slope[abs(pid)-1] = spacing_ratio;
-                 a.m_path.push_back(p);
-             }
-             if(abs(pid)==1)
-                 sit_.set(p1);
-         }
-     }
+	log_info( "read_ant_path. The record count=%ld\n", nCount );
+	while ( DBRes.GetNextRecod(Error) )
+	{
+		int reader_id  = 0;
+		DBRes.GetField( "reader_id",reader_id, Error );
+
+		auto site_ptr=sit_list::instance()->get(reader_id);
+		if(nullptr==site_ptr)
+			continue;
+
+		int pid=0;
+		DBRes.GetField( "tof_flag",pid, Error );
+
+		double b_x= 0;
+		DBRes.GetField( "b_x",b_x, Error );
+
+		double b_y= 0;
+		DBRes.GetField( "b_y",b_y, Error );
+
+		double b_z= 0;
+		DBRes.GetField( "b_z",b_z, Error );
+
+		double e_x= 0;
+		DBRes.GetField( "e_x",e_x, Error );
+
+		double e_y= 0;
+		DBRes.GetField( "e_y",e_y, Error );
+
+		double e_z= 0;
+		DBRes.GetField( "e_z",e_z, Error );
+
+		double spacing_ratio = 0;
+		DBRes.GetField( "spacing_ratio",spacing_ratio, Error );
+		log_info("ant_path:%d,%.2f,%.2f,%.2f,%.2f",reader_id,b_x,b_y,e_x,e_y);
+		point p1(b_x,-b_y, spacing_ratio);
+		point p2(e_x,-e_y, spacing_ratio);
+
+		map_path.insert(std::make_pair(reader_id,std::vector<line_v>()));
+		map_path.find(reader_id)->second.push_back(line_v(p1,p2));
+#if 0
+
+		auto &sit_ = *site_ptr;
+		if(-1!=id)//清空path
+		{
+			sit_.clear_path();
+			log_info( "修改path 清空path,分站id=%d\n", id );
+		}
+
+		if(pid == 0)
+		{
+			line_v l(p1,p2);
+			{
+				point px = l.line::projection(sit_);
+				sit_.set(px);
+				for(int i=0;i<2;i++)
+				{
+					path p;
+					p.m_slope[0] = spacing_ratio;
+					p.m_line[0] = line_v(px,l[i]);
+					sit_.m_ant[i].m_path.push_back(p);
+				}
+			}
+		}
+		else
+		{
+			ant &a = pid<0?sit_.m_ant[0]:sit_.m_ant[1];
+			if(a.m_path.size()!=0)
+			{
+				path &p = a.m_path[0];
+				p.m_line[abs(pid)-1] = line_v(p1,p2);
+				p.m_slope[abs(pid)-1] = spacing_ratio;
+			}
+			else
+			{
+				path p;
+				p.m_line[abs(pid)-1] = line_v(p1,p2);
+				p.m_slope[abs(pid)-1] = spacing_ratio;
+				a.m_path.push_back(p);
+			}
+			if(abs(pid)==1)
+				sit_.set(p1);
+		}
+#endif
+	}
 
-     if(-1==id)
-     {
-         for(auto&_s:sit_list::instance()->m_map)
-         {
-             _s.second->deal_path();
-         }
-     }
-     else
-     {
-         auto sit_ptr=sit_list::instance()->get(id);
-         if(sit_ptr)
-         {
-             sit_ptr->deal_path();
-             log_info( "修改path成功,分站id=%d\n", id );
-         }
-     }
+#if 0
+	if(-1==id)
+	{
+		for(auto&_s:sit_list::instance()->m_map)
+		{
+			_s.second->deal_path();
+		}
+	}
+	else
+	{
+		auto sit_ptr=sit_list::instance()->get(id);
+		if(sit_ptr)
+		{
+			sit_ptr->deal_path();
+			log_info( "修改path成功,分站id=%d\n", id );
+		}
+	}
+#endif
+
+	for(auto&vl:map_path)
+	{
+		auto sit_ptr=sit_list::instance()->get(vl.first);
+		if(!sit_ptr)
+		{
+			log_error("定义了分站路径,但是没有定义分站:%d",vl.first);
+			continue;
+		}
+
+		sit_ptr->set_path(vl.second);
+	}
+
+	card_path::init();
 }
 
 void sit_list::init_site(int id)
 {
      std::string sql = "SELECT reader_id, reader_type_id, dat_reader.map_id, \
-             area_id, device_type_id, dimension, dat_map.scale\
+             area_id, device_type_id, dimension, dat_map.scale,need_power_alarm\
              FROM dat_reader, dat_map where \
              dat_reader.map_id=dat_map.map_id and state=0";
 
@@ -223,9 +412,13 @@ void sit_list::init_site(int id)
          double scale= 0;
          DBRes.GetField( "scale",scale, Error );
 
+         int power_alarm  = 0;
+         DBRes.GetField( "need_power_alarm",power_alarm, Error );
+
          site_ptr->m_reader_type_id = reader_type_id;
          site_ptr->m_map_id = map_id;
          site_ptr->m_area_id = area_id;
+         site_ptr->m_power_check_enable=power_alarm;
 
          site_ptr->m_device_type_id = device_type_id;
 
@@ -314,7 +507,7 @@ void sit_list::read_sit_list(int id)
 }
 void site::create_area()
 {
-    m_area=std::make_shared<area>(-m_id,0,0,m_scale,m_map_id,1<<9);
+    m_area=std::make_shared<area>(-m_id,0,0,m_scale,m_map_id,1<<7);
 }
 /*
    处理分站供电状态,交流供电时,ac_down=false,直流供电时,ac_down=true

+ 43 - 79
ant.h

@@ -9,6 +9,7 @@
 #include <deque>
 #include <tuple>
 #include <memory>
+#include <memory.h>
 #include <algorithm>
 #include <sstream>
 #include "log.h"
@@ -22,22 +23,20 @@ class area;
 struct path
 {
     std::array<line_v,2>	m_line;
-    std::array<double,2>    m_slope;
     path()
     {
-        for(auto &d:m_slope)
-            d=0;
     }
+
     std::string to_str() const
     {
         std::stringstream ss;
         for(int i=0;i<2;i++)
         {
-            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_slope[i]<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
+            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_line[i][0].z<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
         }
         return ss.str();
     }
-    bool vaild() const
+    bool valid() const
     {
         return !m_line[0].empty();
     }
@@ -49,7 +48,6 @@ struct path
     {
         return m_line[i];
     }
-
 };
 //?
 struct algo_config
@@ -63,49 +61,27 @@ struct algo_config
 //
 struct ant :point
 {
+    std::array<path,2> m_path;
     int m_id;
-    std::vector<path> m_path;
+
     path & operator[](int i)
     {
         return m_path[i];
     }
+
     const path & operator[](int i) const
     {
         return m_path[i];
     }
+
     size_t size() const
     {
         return m_path.size();
     }
-    std::vector<point> getsol(const double &dist) const
-    {
-        std::vector<point> v;
-        for(const auto & p : m_path)
-        {
-            double d  = dist;
-            if(p.vaild())
-            {
-                point pt;
-                if(dist <= p.m_line[0].length() || (dist > p.m_line[0].length() && p.m_line[1].empty()))
-                {
-                    d += d*p.m_slope[0];
-                    pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
-                }
-                else
-                {
-                    d -= p.m_line[0].length();
-                    d += d*p.m_slope[1];
-                    pt = point(p.m_line[1][0].x+d*p.m_line[1].cos(),p.m_line[1][0].y+d*p.m_line[1].sin());
-                }
-                v.push_back(pt);
-                //std_info("get_sol:x:%.2f,y:%.2f",pt.x,pt.y);
-            }
-            else
-                std_error(".%s","ant::getsol empty path..");
-        }
-        return std::move(v);
-    }
 
+	void set_path(const std::vector<line_v>&v_line);
+	void set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator it);
+    std::vector<point> getsol(const double &dist) const;
 };
 
 struct site:point,std::enable_shared_from_this<site>
@@ -148,6 +124,28 @@ struct site:point,std::enable_shared_from_this<site>
     site(int id=-1);
 
 
+	char m_timestamp[8]={0};
+	bool check_timestamp(const char*time)
+	{
+		//秒、分、时、天、周、月、年, 脑残的设计
+		
+		char buf[6];
+		buf[0]=time[6];
+		buf[1]=time[5];
+		buf[2]=time[3];
+		buf[3]=time[2];
+		buf[4]=time[1];
+		buf[5]=time[0];
+
+		if(memcmp(m_timestamp,buf,6)<=0)
+		{
+			memcpy(m_timestamp,buf,6);
+			return true;
+		}
+		return false;
+	}
+
+
     int index()const;
     const algo_config&config()const;
     int id()const
@@ -171,7 +169,7 @@ struct site:point,std::enable_shared_from_this<site>
         return READER_TYPE_ID_UP == m_reader_type_id;
     }
     void create_area();
-    const std::shared_ptr<area>& get_area()const{return m_area;}
+    const std::shared_ptr<area> &get_area()const{return m_area;}
     point get_dstp(const point pt) const
     {
         point tmp;
@@ -211,13 +209,7 @@ struct site:point,std::enable_shared_from_this<site>
             m_ant_dist_cnt_new = 0;
         }
     }
-    void swap()
-    {
-        auto v0 =  m_ant[0].m_path;
-        auto v1 =  m_ant[1].m_path;
-        std::copy (std::begin(v0),std::end(v0),std::back_inserter(m_ant[1].m_path));
-        std::copy (std::begin(v1),std::end(v1),std::back_inserter(m_ant[0].m_path));
-    }
+
     double ant_dist()const
     {
         return m_ant[0].dist(m_ant[1]);
@@ -237,10 +229,10 @@ struct site:point,std::enable_shared_from_this<site>
     {
         std::stringstream ss;
         ss<<"site_id:"<<m_id<<"x:"<<x<<" y: "<<y<<" scale:"<<m_scale;
-        for(const auto a:m_ant)
+        for(const auto&a:m_ant)
         {
             ss<<"<";
-            for(const auto p:a.m_path)
+            for(const auto&p:a.m_path)
             {
                 ss<<"{"<<p.to_str()<<"}";
             }
@@ -257,6 +249,7 @@ struct site:point,std::enable_shared_from_this<site>
         return m_ant[0].m_path[i].m_line[0][1];
     }
 
+	void set_path(const std::vector<line_v>&v_line);
     std::vector<point> solving(int ant_id, double dist)const
     {
         const ant &a = m_ant[ant_id];
@@ -274,11 +267,13 @@ struct site:point,std::enable_shared_from_this<site>
         }
         return std::move(a.getsol(dist));
     }
-    ant operator[](int i)
+
+    ant&operator[](int i)
     {
         return m_ant[i];
     }
-    const ant operator[](int i) const
+
+    const ant&operator[](int i) const
     {
         return m_ant[i];
     }
@@ -298,42 +293,11 @@ struct site:point,std::enable_shared_from_this<site>
         set( (m_ant[0].x+m_ant[1].x)/2,(m_ant[0].y+m_ant[1].y)/2);
     }
 
-    void deal_path()
-    {
-        if(m_id==-1)
-            return;
-        swap();
-        if((path(0).empty() && path(1).empty()))
-            return;
-        m_path_empty=false;
-
-        for(auto &a:m_ant)
-        for(auto &p:a.m_path)
-        {
-            if(!p.m_line[0].empty())
-            {
-                point px = p.m_line[0].line::projection(a);
-                p.m_line[0]=line_v(px,p.m_line[0][1]);
-            }
-        }
-        //std_info("%s",sit_ptr->to_string().c_str());
-        log_info("%s",to_string().c_str());
-        //std_info("%f----%f",sit_ptr->x,sit_ptr->y);
-    }
-
     void delete_antenna(int antidx)
     {
-        m_ant[antidx].m_path.clear();
-        m_ant[antidx].m_id=0;
-        point pt;
-        m_ant[antidx].set(pt);
+        m_ant[antidx].set(point(0,0));
     }
 
-    void clear_path()
-    {
-        m_ant[0].m_path.clear();
-        m_ant[1].m_path.clear();
-    }
 /*
 
 	处理分站供电状态,交流供电时,ac_down=false,直流供电时,ac_down=true

+ 286 - 134
area.cpp

@@ -4,6 +4,7 @@
 #include "log.h"
 
 #include <area.h>
+#include "worker.h"
 #include "point.h"
 #include "tool_time.h"
 #include "common_tool.h"
@@ -22,13 +23,14 @@
 #include "websocket/ws_common.h"
 #include "websocket/wsClientMgr.h"
 #include "ant.h"
+#include "event.h"
 
 //template<> std::shared_ptr<area_list> single_base<area_list, int, std::shared_ptr<area>>::m_instance=std::make_shared<area_list>();
 
 struct underground_area:area
 {
-    underground_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type)
-        :area(id,limit_count_person,limit_time_person,scale,mapid,type)
+    underground_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t biz_type)
+        :area(id,limit_count_person,limit_time_person,scale,mapid,biz_type)
 	{
 	}
     virtual bool in_area(const std::shared_ptr<site>&s,const std::shared_ptr<card_location_base>&c, const point & p,int &sarid)
@@ -39,8 +41,8 @@ struct underground_area:area
 
 struct special_area:area
 {
-    special_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type)
-        :area(id,limit_count_person,limit_time_person,scale,mapid,type)
+    special_area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t biz_type)
+        :area(id,limit_count_person,limit_time_person,scale,mapid,biz_type)
 	{}
     virtual bool in_area(const std::shared_ptr<site>&s,const std::shared_ptr<card_location_base>&c, const point & p,int &sarid)
 	{
@@ -64,21 +66,79 @@ struct special_area:area
 
 };
 
-area::area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type)
+area::area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t b_type)
      :m_id(id)
-     ,m_area_type(type)
-     ,m_limit_person_second(limit_time_person)
+     ,m_biz_type(b_type)
+     ,m_limit_person_min(limit_time_person)
      ,m_limit_person_count(limit_count_person)
      ,m_scale(scale)
      ,m_mapid(mapid)
      ,m_person_count(0)
      ,m_vehicle_count(0)
+     ,m_person_show_count(0)
+     ,m_vehicle_show_count(0)
     {
-		m_area_business_list=area_business::get_instance_list(m_area_type,id);
+		m_area_business_list=area_business::get_instance_list(m_biz_type,id);
 		m_event_person_count = false;
 		m_event_vehicle_count = false;
+		m_event_person_show_count = false;
+		m_event_vehicle_show_count = false;
+
+		m_frozen_count.store(0);
     }
+void area::clear()
+{
+    EVENT_TYPE ev = is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
+	EVENT_TYPE ev_ = is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
+    if(m_event_person_count)
+	    event_tool::instance()->handle_event(OT_AREA,ev,m_id,m_limit_person_count,0,false,DT_NORMAL);
+    if(m_event_person_show_count)
+	    event_tool::instance()->handle_event(OT_AREA,ev,m_id,m_limit_person_count,0,false,DT_SPECIAL);
+    if(m_event_vehicle_count)
+	    event_tool::instance()->handle_event(OT_AREA,ev_,m_id,m_limit_vehicle_count,0,false,DT_NORMAL);
+    if(m_event_vehicle_show_count)
+	    event_tool::instance()->handle_event(OT_AREA,ev_,m_id,m_limit_vehicle_count,0,false,DT_SPECIAL);
+
+}
+
+
+void area::change_business(uint32_t new_bits)
+{
+	worker*w=worker::instance();
+
+	uint32_t del=((m_biz_type^new_bits)|m_biz_type)^m_biz_type;
+	uint32_t add=((m_biz_type^new_bits)|new_bits)^new_bits;
+    log_info("change_area_business:area_id:%d,b_type:%d,area_type:%d [del:%d, add:%d]",m_id,new_bits,m_biz_type,del,add);
+
+	if(del==0 && add==0)
+		return;
+
+	task*t =task::alloc<message_change_business>();
+
+	t->m_cmd_code=0x10001; //区域业务类型修改的编码
+	t->m_hash_id=0;        //这个不用
+
+	auto&mcb=t->body<message_change_business>();
+	mcb.area_id=m_id;
+	if(del!=0) 
+	{
+		mcb.del_list=area_business::get_instance_list(del,m_id);
+	}
+
+	if(add!=0) 
+	{
+		mcb.add_list=area_business::get_instance_list(add,m_id);
+	}
+
+	mcb.new_list=area_business::get_instance_list(new_bits,m_id);
+	mcb.ref_count.store(w->num_thread());
+
+	add_frozen_count(w->num_thread()+1);
 
+	this->m_biz_type=new_bits;
+
+	w->broadcast(t);
+}
 
 void area::on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c)
 {
@@ -234,7 +294,7 @@ void area_list::init_monkeycar_area(int id)
             da->m_default_speed = monkeycar_speed;
             da->m_point = init_path(monkeycar_coor,area_id);
             std::shared_ptr<area> ap = std::make_shared<monkey_area>(da,area_id,over_count_person, over_time_person,scale,map_id,b_type);
-            ap->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle);
+            ap->update(over_count_person, over_time_person,scale,map_id,over_count_vehicle,over_time_vehicle);
 
             ap->m_bound=init_path(path,area_id);
             for(const auto &p : ap->m_bound)
@@ -246,22 +306,31 @@ void area_list::init_monkeycar_area(int id)
         }
         else
         {
-			//这里后续需要把猴车得信息传递过去
-            std::shared_ptr<db_area>  da = std::make_shared<db_area>();
-            da->m_default_speed = monkeycar_speed;
-            da->m_point = init_path(monkeycar_coor,area_id);
-			std::shared_ptr<area> ap = std::make_shared<monkey_area>(da,area_id,over_count_person, over_time_person,scale,map_id,b_type);
-			if(auto area_=area_list::instance()->get(id))
-				area_=ap;
-			else
-				area_list::instance()->add(area_id,ap);
 
-            ap->m_bound=init_path(path,area_id);
-            ap->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle);
-            for(const auto &p : ap->m_bound)
-              log_info("point:monkey:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
-            for(const auto &p : da->m_point)
-              log_info("point:monkey_coor:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
+			auto tmp_ptr = area_list::instance()->get(id);
+			bool newobj=false;
+
+			if(!tmp_ptr)
+			{
+				std::shared_ptr<db_area>  da = std::make_shared<db_area>();
+				da->m_default_speed = monkeycar_speed;
+				da->m_point = init_path(monkeycar_coor,area_id);
+				tmp_ptr=std::make_shared<monkey_area>(da,area_id,over_count_person, over_time_person,scale,map_id,b_type);
+
+				newobj=true;
+			}
+
+			tmp_ptr->m_bound=init_path(path,area_id);
+            tmp_ptr->update(over_count_person, over_time_person,scale,map_id, over_count_vehicle,over_time_vehicle);
+
+			if(newobj)
+			{
+				area_list::instance()->add(id, tmp_ptr);
+			}
+			else
+			{
+				tmp_ptr->change_business(b_type);
+			}
 
             log_info("基础数据 monkeycar area增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,\
                      scale:%.2f,map_id:%d,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d",
@@ -295,121 +364,137 @@ std::shared_ptr<area>  area_list::create(int type,int id,int limit_count_person,
 }
 void area_list::init_from_db(int id/*=-1*/)
 {
-    std::string sql = "SELECT a.area_id, a.name, a.map_id, a.area_type_id, a.path,b.scale, \
-            over_count_person, over_count_vehicle, over_time_person, over_time_vehicle, \
-            over_speed_vehicle, is_attendance,business_type, a.is_work_area\
-            FROM dat_area a,dat_map b\
-            where a.map_id = b.map_id and  area_id not in \
-			  (select monkeycar_base_info_id from dat_monkeycar_base_info)";
+	do{
+		std::string sql = "SELECT a.area_id, a.name, a.map_id, a.area_type_id, a.path,b.scale, \
+						   over_count_person, over_count_vehicle, over_time_person, over_time_vehicle, \
+						   over_speed_vehicle, is_attendance,business_type, a.is_work_area\
+						   FROM dat_area a,dat_map b\
+						   where a.map_id = b.map_id and  area_id not in \
+						   (select monkeycar_base_info_id from dat_monkeycar_base_info)";
+
+		if(-1 == id)
+		{
+			sql.append(";");
+		}
+		else
+		{
+			sql.append(" AND a.area_id=");
+			sql.append(std::to_string(id));
+			sql.append(";");
 
-    if(-1 == id)
-    {
-        sql.append(";");
-    }
-    else
-    {
-        sql.append(" AND s.area_id=");
-        sql.append(std::to_string(id));
-        sql.append(";");
+			log_info("基础数据 增加或修改区域 sql=%s", sql.c_str());
+		}
 
-        log_info("基础数据 增加或修改区域 sql=%s", sql.c_str());
-    }
+		std::string Error;
+		YADB::CDBResultSet DBRes;
+		sDBConnPool.Query(sql.c_str(),DBRes,Error);
+		int nCount = DBRes.GetRecordCount( Error );
+		if (nCount < 1)
+		{
+			log_error("基础数据 增加或修改失败,数据库中找不到: area_id=%d:%s", id,sql.c_str());
+			break;
+		}
 
-    std::string Error;
-    YADB::CDBResultSet DBRes;
-    sDBConnPool.Query(sql.c_str(),DBRes,Error);
-    int nCount = DBRes.GetRecordCount( Error );
-    if (nCount < 1)
-    {
-        log_error("基础数据 增加或修改失败,数据库中找不到: area_id=%d:%s", id,sql.c_str());
-        return ;
-    }
+		std::unordered_map<int,std::shared_ptr<area>> map;
+		while ( DBRes.GetNextRecod(Error) )
+		{
+			int area_id  = 0;
+			DBRes.GetField( "area_id",area_id, Error );
 
-    std::unordered_map<int,std::shared_ptr<area>> map;
-    while ( DBRes.GetNextRecod(Error) )
-    {
-        int area_id  = 0;
-        DBRes.GetField( "area_id",area_id, Error );
+			int map_id  = 0;
+			DBRes.GetField( "map_id",map_id, Error );
 
-        int map_id  = 0;
-        DBRes.GetField( "map_id",map_id, Error );
+			unsigned int area_type_id  = 0;
+			DBRes.GetField( "area_type_id",area_type_id, Error );
 
-        unsigned int area_type_id  = 0;
-        DBRes.GetField( "area_type_id",area_type_id, Error );
+			int over_count_person = 0;
+			DBRes.GetField( "over_count_person",over_count_person, Error );
 
-        int over_count_person = 0;
-        DBRes.GetField( "over_count_person",over_count_person, Error );
+			int over_count_vehicle = 0;
+			DBRes.GetField( "over_count_vehicle",over_count_vehicle, Error );
 
-        int over_count_vehicle = 0;
-        DBRes.GetField( "over_count_vehicle",over_count_vehicle, Error );
+			int over_time_person = 0;
+			DBRes.GetField( "over_time_person",over_time_person, Error );
 
-        int over_time_person = 0;
-        DBRes.GetField( "over_time_person",over_time_person, Error );
+			int over_time_vehicle = 0;
+			DBRes.GetField( "over_time_vehicle",over_time_vehicle, Error );
 
-        int over_time_vehicle = 0;
-        DBRes.GetField( "over_time_vehicle",over_time_vehicle, Error );
+			std::string over_speed_vehicle;
+			DBRes.GetField( "over_speed_vehicle",over_speed_vehicle, Error );
 
-        std::string over_speed_vehicle;
-        DBRes.GetField( "over_speed_vehicle",over_speed_vehicle, Error );
+			std::string path;
+			DBRes.GetField( "path",path, Error );
 
-        std::string path;
-        DBRes.GetField( "path",path, Error );
+			double scale = 0;
+			DBRes.GetField( "scale",scale, Error );
 
-        double scale = 0;
-        DBRes.GetField( "scale",scale, Error );
+			uint32_t b_type =0;
+			DBRes.GetField( "business_type",b_type, Error );
 
-		uint32_t b_type =0;
-        DBRes.GetField( "business_type",b_type, Error );
+			int is_work_area = 0;
+			DBRes.GetField( "is_work_area",is_work_area, Error );
 
-        int is_work_area = 0;
-        DBRes.GetField( "is_work_area",is_work_area, Error );
+			log_info("init_area : id:%d,path:%s..speed:%s",area_id, path.c_str(),over_speed_vehicle.c_str());
+			std::map<int,double> map_;
+			auto vp=init_path(over_speed_vehicle,area_id);
+			for(const auto &v:vp)
+				map_.insert({v.x,v.y});
+			if(-1 == id)
+			{
+				std::shared_ptr<area> ap = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
+				ap->m_limit_vehicle_min = over_time_vehicle;
+				ap->m_limit_vehicle_count = over_count_vehicle;
+				ap->m_speed=std::move(map_);
+				ap->m_is_work_area = is_work_area;
 
-        log_info("init_area : id:%d,path:%s..speed:%s",area_id, path.c_str(),over_speed_vehicle.c_str());
-        std::map<int,double> map_;
-        auto vp=init_path(over_speed_vehicle,area_id);
-        for(const auto &v:vp)
-            map_.insert({v.x,v.y});
-        if(-1 == id)
-        {
-            std::shared_ptr<area> ap = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
-            ap->m_limit_vehicle_second = over_time_vehicle;
-            ap->m_limit_vehicle_count = over_count_vehicle;
-            ap->m_speed=std::move(map_);
-            ap->m_is_work_area = is_work_area;
+				ap->m_bound=init_path(path,area_id);
+				for(const auto &p : ap->m_bound)
+					log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
+				map.insert({area_id,ap});
+			}
+			else
+			{
+				auto tmp_ptr = area_list::instance()->get(id);
+				bool newobj=false;
+
+				if(!tmp_ptr)
+				{
+					tmp_ptr = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
+					newobj=true;
+				}
 
-            ap->m_bound=init_path(path,area_id);
-            for(const auto &p : ap->m_bound)
-              log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
-            map.insert({area_id,ap});
-        }
-        else
-        {
-            auto tmp_ptr = area_list::instance()->get(id);
-            if(!tmp_ptr)
-            {
-				tmp_ptr = create(area_type_id,area_id,over_count_person,over_time_person, scale,map_id,b_type);
-                area_list::instance()->add(id, tmp_ptr);
-            }
-            tmp_ptr->update(over_count_person, over_time_person,scale,map_id,area_type_id, over_count_vehicle,over_time_vehicle);
-            tmp_ptr->m_speed=std::move(map_);
-            tmp_ptr->m_bound=init_path(path,area_id);
-            tmp_ptr->m_is_work_area = is_work_area;
-            for(const auto &p : tmp_ptr->m_bound)
-                log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
-
-            log_info("基础数据 增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,scale:%.2f,map_id:%d\
-                     ,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d",
-                     id,over_count_person, over_time_person,scale,map_id,area_type_id,
-                     over_count_vehicle,over_time_vehicle);
-        }
-    }
+				tmp_ptr->update(over_count_person, over_time_person,scale,map_id, over_count_vehicle,over_time_vehicle);
+				tmp_ptr->m_speed=std::move(map_);
+				tmp_ptr->m_bound=init_path(path,area_id);
+				tmp_ptr->m_is_work_area = is_work_area;
 
-    if(-1 == id)
-    {
-        log_info( "init_area. The record count=%d\n", nCount );
-        area_list::instance()->add(map);
-    }
-    init_monkeycar_area(id);
+				for(const auto &p : tmp_ptr->m_bound)
+					log_info("point:area_id:%d--x:%.2f,y:%.2f",area_id,p.x,p.y);
+
+				log_info("基础数据 增加或修改区域成功:区域id:%d,over_count_person:%d over_time_person:%d,scale:%.2f,map_id:%d\
+						,area_type_id:%d,over_count_vehicle:%d,over_time_vehicle:%d",
+						id,over_count_person, over_time_person,scale,map_id,area_type_id,
+						over_count_vehicle,over_time_vehicle);
+
+				if(newobj)
+				{
+					area_list::instance()->add(id, tmp_ptr);
+				}
+				else
+				{
+					tmp_ptr->change_business(b_type);
+				}
+			}
+		}
+
+		if(-1 == id)
+		{
+			log_info( "init_area. The record count=%d\n", nCount );
+			area_list::instance()->add(map);
+		}
+	}while(0);
+
+	init_monkeycar_area(id);
 }
 
 std::vector<point> area_list::init_path(std::string &str_0,int area_id)
@@ -469,7 +554,6 @@ void area_tool::on_point(const std::shared_ptr<card_location_base>& c,const poin
       return;
 	int special_area=-1;
 	std::vector<std::shared_ptr<area>> areas=area_list::instance()->get_area(m_site,c, pt,special_area);
-
 	if(special_area != -1)
 	{
 		areas.clear();
@@ -477,46 +561,84 @@ void area_tool::on_point(const std::shared_ptr<card_location_base>& c,const poin
 		areas.push_back(area_);
 	}
 	else
+	{
 		std::sort(areas.begin(),areas.end(),[](const std::shared_ptr<area>&l,const std::shared_ptr<area>&r){
 				return l->id()<r->id();
 				});
+	}
 
 	auto c1=m_hover_list.begin(),ce=m_hover_list.end();
 	auto a1=areas.begin() ,ae=areas.end();
 
 	std::vector<std::shared_ptr<area_hover>> nlist;
-
 	while (c1!=ce && a1!=ae)
 	{
-		if ((*c1)->id()<(*a1)->id()) 
+		if ((*c1)->id()<(*a1)->id()) //离开区域
 		{ 
-			(*c1)->m_area->on_leave(*c1, c);
+			if((*c1)->m_area->get_frozen_count()==0)//如果该区域未在修改中,调用on_leave
+			{
+				(*c1)->m_area->on_leave(*c1, c);
+			}
+			else//否则,该区域持续保存在卡的区域列表,等待修改完成
+			{
+				nlist.push_back(*c1);
+				log_warn("丢弃离开区域事件,cardid=%d,area_id=%d",c->m_id,(*c1)->id());
+			}
 			++c1;
 		}
-		else if ((*a1)->id()<(*c1)->id()) 
+		else if ((*a1)->id()<(*c1)->id()) //进入新区域
 		{
-			nlist.push_back(std::make_shared<area_hover>(*a1,pt));
-			(*a1)->on_enter(nlist.back(),c);
+			if((*a1)->get_frozen_count()==0)////如果该区域未在修改中,执行正常逻辑
+			{
+				nlist.push_back(std::make_shared<area_hover>(*a1,pt));
+				(*a1)->on_enter(nlist.back(),c);
+			}
+			else//丢弃本次进入的点,等待修改完成
+			{
+				log_warn("丢弃进入区域事件,cardid=%d,area_id=%d",c->m_id,(*a1)->id());
+			}
 			++a1;
 		}
-		else 
+		else //需要持续的区域
 		{ 
 			nlist.push_back(*c1);
-			(*c1)->m_area->on_hover(*c1,c);
+			if((*c1)->m_area->get_frozen_count()==0)//正常情况
+			{
+				(*c1)->m_area->on_hover(*c1,c);
+			}
+			else//丢弃本次on_hover时间
+			{
+				log_warn("丢弃区域行走事件,cardid=%d,area_id=%d",c->m_id,(*c1)->id());
+			}
 			++c1,++a1;
 		}
 	}
 
 	while(c1!=ce)
 	{
-		(*c1)->m_area->on_leave(*c1, c);
+		if((*c1)->m_area->get_frozen_count()==0)
+		{
+			(*c1)->m_area->on_leave(*c1, c);
+		}
+		else
+		{
+			log_warn("丢弃离开区域事件,cardid=%d,area_id=%d",c->m_id,(*c1)->id());
+		}
 		++c1;
 	}
 
 	while(a1!=ae)
 	{
-		nlist.push_back(std::make_shared<area_hover>(*a1,pt));
-		(*a1)->on_enter(nlist.back(),c);
+		if((*a1)->get_frozen_count()==0)
+		{
+			nlist.push_back(std::make_shared<area_hover>(*a1,pt));
+			(*a1)->on_enter(nlist.back(),c);
+		}
+		else
+		{
+			log_warn("丢弃进入区域事件,cardid=%d,area_id=%d",c->m_id,(*a1)->id());
+		}
+
 		++a1;
 	}
 
@@ -560,6 +682,9 @@ void area_tool::set_area_info(int mapid,double scale,int areaid,const point &pt,
 	}
 	else if(1==type)
 	{
+        if(m_mapid != mapid || m_scale!=scale){
+            m_mapid=mapid;m_scale=scale;
+        }
 		set_area_info(mapid,areaid,pt,t);
 	}
 	else if(2==type)
@@ -573,14 +698,41 @@ void area_tool::set_area_info(int mapid,double scale,int areaid,const point &pt,
 		log_info("wrong type..");
 	}
 }
+
 void area_tool::set_area_info(int mapid,int areaid,const point &pt,uint64_t t)
 {
 	auto lm = Landmark_list::instance()->get(mapid,areaid,pt);
 	int landmark_id = std::get<0>(lm);
 	int landmark_dir = std::get<1>(lm);
 	double landmark_dis = std::get<2>(lm)*m_scale;
-	log_info("landmark:%d %d %.2f,(%.2f,%.2f),%f",landmark_id,landmark_dir,landmark_dis,pt.x,pt.y,m_scale);
 	std::tuple<int,int,int,double,uint64_t> tinfo=std::make_tuple(areaid,landmark_id,landmark_dir,landmark_dis,t);
 	m_area_info[areaid].swap(tinfo);
 }
 
+
+void area_tool::on_change_business(const std::shared_ptr<card_location_base>& c, const task&t)
+{
+	auto&mcb=t.body<message_change_business>();
+
+	auto i=std::lower_bound(m_hover_list.begin(),m_hover_list.end(),mcb.area_id ,[&mcb](std::shared_ptr<area_hover>&ah,int id){
+		return ah->m_area->m_id<id;
+	});
+
+	if(i==m_hover_list.end())
+		return ;
+	
+	if((*i)->m_area->m_id!=mcb.area_id)
+		return;
+	
+	log_info("调用调整的区域业务,card_id=%d,area_id=%d", c->m_id, mcb.area_id);
+	for(auto&biz:mcb.add_list)
+	{
+		biz->on_enter(*i,c,(*i)->get_business_data(biz->area_business_type()));
+	}
+
+	for(auto&biz:mcb.del_list)
+	{
+		biz->on_leave(*i,c,(*i)->get_business_data(biz->area_business_type()));
+	}
+}
+

+ 63 - 15
area.h

@@ -8,6 +8,7 @@
 #include <point.h>
 #include "common.h"
 #include <write-copy.h>
+#include <ant.h>
 #include <set>
 #include <map>
 
@@ -23,7 +24,7 @@ struct site;
 */
 struct area
 {
-    area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t type);
+    area(int id,int limit_count_person, int limit_time_person,double scale,int32_t mapid,int32_t b_type);
 
   	virtual void on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c);
 	virtual	void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c);
@@ -50,19 +51,41 @@ struct area
     virtual ~area()
     {}
     double get_speed(int vehicle_category_id) {return m_speed[vehicle_category_id];}
-    void  update(int limit_count_person, int limit_time_person,double scale,int32_t mapid,
-                     int32_t type,int limit_count_vehicle, int limit_time_vehicle)
+    void  update(int limit_count_person, int limit_time_person,double scale,int32_t mapid, int limit_count_vehicle, int limit_time_vehicle)
     {
-        m_area_type=type;
-        m_limit_person_second=limit_time_person;
+        m_limit_person_min=limit_time_person;
         m_limit_person_count=limit_count_person;
         m_scale=scale;
         m_mapid=mapid;
         m_limit_vehicle_count=limit_count_vehicle;
-        m_limit_vehicle_second=limit_time_vehicle;
+        m_limit_vehicle_min=limit_time_vehicle;
     }
 public:
 	std::vector<area_business*> m_area_business_list;
+	std::atomic<int> m_frozen_count;
+
+	void set_business_list(std::vector<area_business*>&&business_list)
+	{
+		m_area_business_list=business_list;	
+	}
+
+	int  get_frozen_count()
+	{
+		return m_frozen_count.load(std::memory_order_acquire);
+	}
+
+	int add_frozen_count(int deta=1)
+	{
+		return m_frozen_count.fetch_add(deta,std::memory_order_release);
+	}
+
+	int sub_frozen_count(int deta=1)
+	{
+		return add_frozen_count(-deta);
+	}
+
+	void change_business(uint32_t new_bits);
+    void clear();
 public:
     std::vector<point> m_bound;
 	//数据库唯一ID
@@ -79,19 +102,21 @@ public:
 		7:禁区[进入时长]
 		8:猴车区域
 	*/
-    int m_area_type;
+    int    m_biz_type=0;
 
 	//人卡超时及超员数量(阀值)
-    int m_limit_person_second;
+    int m_limit_person_min;
     int m_limit_person_count;
     //是否人卡超员已有告警
     bool m_event_person_count;
+    bool m_event_person_show_count;
 
 	//人卡超时及超员数量(阀值)
-    int m_limit_vehicle_second;
+    int m_limit_vehicle_min;
     int m_limit_vehicle_count;
     //是否人卡超员已有告警
     bool m_event_vehicle_count;
+    bool m_event_vehicle_show_count;
     double m_scale;
     int32_t m_mapid;
 
@@ -99,6 +124,10 @@ public:
     std::atomic<int> m_person_count;
     ///区域车卡数
     std::atomic<int> m_vehicle_count;
+    ///区域显示人卡数
+    std::atomic<int> m_person_show_count;
+    ///区域显示车卡数
+    std::atomic<int> m_vehicle_show_count;
 
 
     //区域速度门限
@@ -176,21 +205,40 @@ struct area_hover
 //每张卡包含一个对象
 //在解析出数据点时,调用on_point
 struct site;
+struct task;
 struct area_tool
-{
+{ 
+private:
+	int m_mapid=-1;
+public:
+
+	int get_mapid()const
+	{
+		return m_mapid;
+	}
+
+	double m_scale=2.0;
 	//卡所在的所有area的列表,以id排序小->大
 	std::vector<std::shared_ptr<area_hover>> m_hover_list;
 
 	//推送卡位置时需要推送的所在区域id列表
 	std::map<int,std::tuple<int,int,int,double,uint64_t>> m_area_info;
-	int m_mapid=-1;
-	double m_scale=2.0;
     std::shared_ptr<site> m_site=nullptr;
-    void set(const std::shared_ptr<site>& s)
+    void clear()
     {
-        if(m_site != s)
-          m_site=s;
+        m_area_info.clear();
     }
+
+    void set_site(const std::shared_ptr<site>& s)
+    {
+		if(s == nullptr || m_site == s)
+			return;
+
+        m_site=s;
+		m_mapid=m_site->m_map_id;
+    }
+
+	void on_change_business(const std::shared_ptr<card_location_base>& c, const task&t);
 	void on_point(const std::shared_ptr<card_location_base>& c,const point&pt);
     void on_leave(const std::shared_ptr<card_location_base>& c);
 

+ 13 - 14
area_business.cpp

@@ -20,13 +20,14 @@ struct area_business_factory
 {
 	void regist(int type,area_business* ab)
 	{
+		ab->m_business_type=type;
+
 		if(type>=(int)m_check_list.size())
 		{
 			m_check_list.resize(type+1);
 		}
 
 		assert(!m_check_list[type]);
-
 		m_check_list[type].reset(ab);
 	}
 
@@ -67,19 +68,17 @@ struct area_business_factory
 	std::vector<std::unique_ptr<area_business>> m_check_list;
 	area_business_factory()
 	{
-		regist(1,new area_business_post_area);
-		regist(2,new area_business_person_dwell_checker);
-		regist(3,new area_business_count_checker);
-		regist(4,new area_business_speed_checker);
-		regist(5,new area_business_person_attendance);
-		regist(6,new area_business_car_attendance);
-		regist(7,new area_business_forbid);
-		//regist(8,new area_business_monkey_area);
-		regist(9,new area_business_card_enter_or_leave);
-
-		regist(10, new area_business_motionless_persion);
-		regist(11, new area_business_geofault);
-		regist(12, new area_business_work_rate);
+		regist(0, new area_business_post_area);
+		regist(1, new area_business_person_dwell_checker);
+		regist(2, new area_business_count_checker);
+		regist(3, new area_business_speed_checker);
+		regist(4, new area_business_person_attendance);
+		regist(5, new area_business_car_attendance);
+		regist(6, new area_business_forbid);
+		regist(7, new area_business_card_enter_or_leave);
+		regist(8, new area_business_motionless_persion);
+		regist(9,new area_business_geofault);
+		regist(10,new area_business_work_rate);
 	}
 
 };

+ 5 - 1
area_business.h

@@ -13,7 +13,11 @@ struct area_hover;
 struct card_location_base;
 struct area_business
 {
-	virtual int area_business_type()=0;
+	int m_business_type=0;
+	int area_business_type()
+	{
+		return m_business_type;
+	}
 
 	virtual void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr){}
 	virtual void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr){}

+ 33 - 15
card.cpp

@@ -18,20 +18,20 @@
 #include "mine_business.h"
 
 extern config_file config;
-void card_list::init_staffer(int64_t id64)
+void card_list::init_staffer(const std::string & lszId64)
 {
     std::string strategy = config.get("person.strategy","PS_1");
 
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> 
-		map=std::move(db_card::load_person(id64,strategy));
-
+		map=std::move(db_card::load_person(lszId64,strategy));
+	
 	if(map.empty())
 	{
-		log_error("增加或修改失败,数据库中找不到: card_id=%013lld", id64);
+		log_error("增加或修改失败,数据库中找不到: card_id=%", lszId64.c_str());
 		return ;
 	}
 
-	if(-1 == id64)
+	if("" == lszId64)
 	{
 		log_info( "init_staffer. The record count=%d\n", map.size() );
 		card_list::instance()->add(map);
@@ -39,6 +39,7 @@ void card_list::init_staffer(int64_t id64)
 	else
 	{
 		auto db_person=map.begin()->second;
+        uint64_t id64 = map.begin()->first;
 		auto card_ptr = card_list::instance()->get(id64);
 		if(card_ptr)
 		{
@@ -68,18 +69,18 @@ void card_list::init_staffer(int64_t id64)
 }
 
 
-void card_list::init_vehicle(int64_t id64)
+void card_list::init_vehicle(const std::string & lszId64)
 {
 	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> 
-		map=std::move(db_card::load_car(id64));
+		map=std::move(db_card::load_car(lszId64));
 
 	if(map.empty())
 	{
-		log_error("增加或修改失败,数据库中找不到: card_id=%013lld", id64);
+		log_error("增加或修改失败,数据库中找不到: card_id=%s", lszId64.c_str());
 		return ;
 	}
 
-	if(-1 == id64)
+	if("" == lszId64)
 	{
 		log_info( "init_vehicle. The record count=%d\n", map.size() );
 		card_list::instance()->add(map);
@@ -87,6 +88,7 @@ void card_list::init_vehicle(int64_t id64)
 	else
 	{
 		car* db_car= static_cast<car*>(map.begin()->second.get());
+        uint64_t id64 = map.begin()->first;
 		auto card_ptr = card_list::instance()->get(id64);
 		if(card_ptr)
 		{
@@ -109,8 +111,8 @@ void card_list::init_vehicle(int64_t id64)
 
 void card_list::init_card_from_db()
 {
-    init_staffer(-1);
-    init_vehicle(-1);
+    init_staffer("");
+    init_vehicle("");
 }
 
 void card_list::load_his_card_postion_from_db()
@@ -196,7 +198,7 @@ void card_list::load_his_card_postion_vehicle()
             {
                 auto area_hover_ptr = std::make_shared<area_hover>(sit_ptr->get_area(),*card_ptr);
                 area_tool->m_hover_list.push_back(area_hover_ptr);
-                area_tool->set(sit_ptr);
+                area_tool->set_site(sit_ptr);
             }
 
             //解析area_info
@@ -308,7 +310,7 @@ void card_list::load_his_card_postion_staff()
             {
                 auto area_hover_ptr = std::make_shared<area_hover>(sit_ptr->get_area(),*card_ptr);
                 area_tool->m_hover_list.push_back(area_hover_ptr);
-                area_tool->set(sit_ptr);
+                area_tool->set_site(sit_ptr);
             }
 
             //解析area_info
@@ -351,17 +353,33 @@ void card_list::on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_
 		log_warn("数据库中未定义该卡的信息,card_id=%d, card_type=%d,cardid:%lld",loc.m_card_id,loc.m_card_type,cardid);
 		return;
 	}
-	logn_info(3,"card_message:site=%d,ant=%d,type=%lu,card=%d,ct=%d,tof=%lld,rav=%02X,acc=%02X,rssi=%d,stamp=%llu",
-			loc.m_site_id,loc.m_ant_id,loc.m_card_type,loc.m_card_id,loc.m_card_ct,loc.m_tof,loc.m_rav,loc.m_acc,loc.m_rssi,loc.m_time_stamp);
+	double dist_tof=loc.m_tof*15.65*2.996*1e-4;
+	logn_info(3,"card_message:site=%d,ant=%d,type=%lu,card=%d,ct=%d,tof=%lld(%.2lfm),rav=%02X,acc=%02X,rssi=%d,stamp=%llu",
+			loc.m_site_id,loc.m_ant_id,loc.m_card_type,loc.m_card_id,loc.m_card_ct,loc.m_tof,dist_tof,loc.m_rav,loc.m_acc,loc.m_rssi,loc.m_time_stamp);
 
 	c->on_message(loop,loc,is_history);
 }
 
+//获取卡数据  //标识id 人staff_id 车 vehicle_id
+std::shared_ptr<card_location_base> card_list::get_card_by_cid(int cid)
+{
+    auto t_map = m_map;
+    for(std::pair<int,std::shared_ptr<card_location_base>> me:t_map)
+    {
+        if ((int)me.second->m_cid == cid)
+        {
+            return me.second;
+        }
+    }
+    return nullptr;
+}
+
 bool card_list_visit::visit(std::shared_ptr<card_location_base> c)
 {
 	c->get_card(_flag);
 	return true;	
 }
 
+
 //template<> std::shared_ptr<card_list> single_base<card_list, uint64_t, std::shared_ptr<card_location_base>>::m_instance=std::make_shared<card_list>();
 

+ 6 - 4
card.h

@@ -14,9 +14,9 @@ struct card_list_visit:visitor<std::shared_ptr<card_location_base>>
 
 struct card_list:single_base<card_list,uint64_t,std::shared_ptr<card_location_base>>
 {
-    ///id64=-1为初始化所有卡, id格式为:10000001016
-    void init_staffer(int64_t id64);
-    void init_vehicle(int64_t id64);
+    ///lszId64=为初始化所有卡, lszId64格式为:0010000001016
+    void init_staffer(const std::string & lszId64);
+    void init_vehicle(const std::string & lszId64);
     void on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_history);
     void init_card_from_db();
 
@@ -24,6 +24,8 @@ struct card_list:single_base<card_list,uint64_t,std::shared_ptr<card_location_ba
     void load_his_card_postion_staff();
     void load_his_card_postion_from_db();
 
+    //获取卡数据  //标识id 人staff_id 车 vehicle_id
+    std::shared_ptr<card_location_base> get_card_by_cid(int cid);
     ~card_list(){}
 };
-#endif
+#endif

+ 29 - 15
card_base.cpp

@@ -18,7 +18,7 @@
 #include "common_tool.h"
 #include "ant.h"
 #include "area.h"
-
+#include "cardMgr.h"
 extern config_file config;
 
 card_location_base::card_location_base(const std::string&type,uint32_t id,uint16_t dis,int16_t t,int32_t deptid,int32_t level_id,uint32_t cid)
@@ -44,11 +44,24 @@ void card_location_base::on_location(const std::vector<point>&vp,const std::vect
 		//Msg m;
 		//m.type=m_type;m.x=(int)x;m.y=(int)y;m.cmd=CMD_HANDLE;m.cardid=m_type<<32|m_id;
 		//cardMgr::instance()->tryPut(m);
+
 		double acc = lm[0].m_acc;
         m_acc = lm[0].m_acc;
-		log_info("useful:card_id:%d,ct:%d,timestamp:%llu, loc_point,x:%f,y:%f acc:%.2f",m_id,m_ct,m_time,x,y,acc);
+		log_info("useful:type:%d,card_id:%d,ct:%d,timestamp:%llu, loc_point,x:%f,y:%f acc:%.2f",m_type,m_id,m_ct,m_time,x,y,acc);
 		do_business(lm.front().m_sit, pt, acc);
 	}
+	else
+	{
+		int sid=0;
+		auto site_ptr=get_area_tool()->m_site;
+
+		if(site_ptr)
+		{
+			sid=site_ptr->m_id;
+		}
+		
+		log_warn("坐标不可用:site_id:%d,type:%d,card_id:%d,ct:%d,x:%f,y:%f",sid,m_type,m_id,m_ct,pt.x,pt.y);
+	}
 }
 
 void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history)
@@ -56,17 +69,22 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 	m_ct = loc.m_card_ct;
 	m_time = loc.m_time_stamp;
 	auto site_ptr = sit_list::instance()->get(loc.m_site_id);
-
 	if(!site_ptr)
 	{
+		log_warn("接收到分站%d的数据,CARD=%d, CT=%d,但是分站未定义",loc.m_site_id,m_id,loc.m_card_ct);
 		return;
 	}
 
+
+	auto area_tool=get_area_tool();
+	area_tool->set_site(site_ptr);
+
 	if(site_ptr->is_up_site())
 	{
-		auto area_tool=get_area_tool();
-		area_tool->set(site_ptr);
+        log_info("%d被井上分站[%d]收到",m_id,site_ptr->id());
 		area_tool->on_point(shared_from_this(),point(1,1));
+
+		this->site_hover(loc.m_site_id);
 	}
 	else
 	{
@@ -74,7 +92,6 @@ void card_location_base::on_message(zloop<task*> * loop,const message_locinfo&lo
 		{
 			log_warn("接收到分站%d的数据,CT=%d,但是分站路径为空",site_ptr->id(),loc.m_card_ct);
 		}
-
 		m_message_handle->on_message(loop,loc,is_history);
 	}
 }
@@ -86,13 +103,10 @@ void card_location_base::upt_card_pos(YA::_CARD_POS_&cp, point &pt)
     point _p;
     if(pt.empty())
     {
-        _p=*this;
-        pt=_p;
+         _p=*this;pt=_p;
     }
     else
-	{
-       	 _p=pt;
-	}
+         _p=pt;
 	cp.x = tool_other::round(_p.x,3);
 	cp.y = tool_other::round(_p.y,3);
 	//cp.z = pt.z;
@@ -131,10 +145,11 @@ int  card_location_base::get_stat()
     {
         return  STATUS_CALL;
     }
-    else if(event_list::instance()->get_event_card(m_id, m_type,
-                is_person()? ET_CARD_AREA_OVER_TIME_PERSON: ET_CARD_AREA_OVER_TIME_VEHICLE))
+    else if(is_person())
     {
-        return  STATUS_AREA_OVER_TIME;
+        if(event_list::instance()->get_event_card(m_id, m_type,ET_CARD_AREA_OVER_TIME_PERSON)||
+                event_list::instance()->get_event_card(m_id, m_type,ET_CARD_OVER_TIME_PERSON))
+            return  STATUS_AREA_OVER_TIME;
     }
     else if(event_list::instance()->get_event_card(m_id, m_type, ET_CARD_OVER_SPEED))
     {
@@ -148,7 +163,6 @@ void  card_location_base::clear()
 {
 //	uint16_t m_display;			//1显示0不显示,往前端推送
     m_speed=0;			//速度
-    m_is_attendance=0;	//井上井下状态  0初始状态 1 井上 2 井下
     m_stat=0;			//运动静止状态
     //m_ct;				//ct
     m_time=0;			//时间戳

+ 8 - 2
card_base.h

@@ -3,6 +3,7 @@
 
 #include <vector>
 #include <memory>
+#include <atomic>
 #include "point.h"
 #include "common.h"
 
@@ -35,7 +36,6 @@ struct card:point
 		,m_type(type)
 		,m_display(dis)
 		,m_speed(0)
-		,m_is_attendance(0)
 		,m_stat(0)
 		,m_ct(0)
 		,m_time(0)
@@ -50,7 +50,6 @@ struct card:point
 	uint64_t m_type;			//类型
 	uint16_t m_display;			//1显示0不显示,往前端推送
 	double   m_speed;			//速度
-	int      m_is_attendance;	//井上井下状态  0初始状态 1 井上 2 井下
 	int		 m_stat;			//运动静止状态
 	uint16_t m_ct;				//ct
     uint64_t m_time;			//时间戳 ms
@@ -70,6 +69,13 @@ struct card_location_base:card,std::enable_shared_from_this<card_location_base>
 	std::unique_ptr<card_message_handle> m_message_handle;
 	std::unique_ptr<location_card> m_his_location_card;
 
+	std::atomic<int> m_upmine_flag{0};
+
+	void inc_upmine_flag()
+	{
+		++m_upmine_flag;
+	}
+
     card_location_base()=default;
     card_location_base(const std::string&type,uint32_t id,uint16_t dis,int16_t t,int32_t,int32_t,uint32_t );
 

+ 6 - 17
card_car.cpp

@@ -35,7 +35,6 @@ void car::set_area_info(int mapid,double scale,int areaid,uint64_t t,int type)
 void car::do_business(const std::shared_ptr<site>&site,const point &pt,double acc)
 {
 	m_acc=acc;
-    m_area_tool->set(site);
 	m_area_tool->on_point(shared_from_this(),pt);
 	m_timeval=m_time;
 	m_mine_tool->on_point(m_id, m_type, m_vehicle_category_id);
@@ -58,7 +57,7 @@ void car::handle_three_rates(const point &pt)
 	//const auto lm = m_area_tool->getLandmark();
 //	cp.enter_time = std::get<0>(lm)*1000;
 //	cp.area_id = std::get<3>(lm);
-	cp.map_id = m_area_tool->m_mapid;
+	cp.map_id = m_area_tool->get_mapid();
 	cp.vibration=m_acc;
 	put_three_rates(cp);
 }
@@ -84,17 +83,8 @@ void car::make_package()
 {
 	YA::_CARD_POS_ cp;
 	loc_point pt = getSmoothPoint();
-	//const auto lm = m_area_tool->getLandmark();
-	//cp.enter_area_time = std::get<0>(lm);
-	//cp.rec_time = std::get<1>(lm);
-	//uint32_t map_id = std::get<2>(lm);
-	//uint32_t area_id = std::get<3>(lm);
-	//cp.area_id=area_id;
-	//cp.landmark_id = std::get<4>(lm);
-	//cp.lm_direction = std::get<5>(lm);
-	//cp.landmark_dis=std::get<6>(lm);
 	cp.area_info=m_area_tool->m_area_info;	
-	cp.map_id =m_area_tool->m_mapid;
+	cp.map_id =m_area_tool->get_mapid();
 
 	int32_t biz_stat=m_biz_stat;
 	cp.biz_stat=biz_stat;
@@ -102,11 +92,10 @@ void car::make_package()
 	cp.work_time = m_mine_tool->get_work_time();
 	cp.is_on_duty=m_mine_tool->is_on_duty();
 	upt_card_pos(cp,pt);
-	if(!cp.area_info.empty())
-	{
-		int areaid = cp.area_info.begin()->first;
-		m_his_location_card->push(pt.m_time,pt,areaid,cp.map_id);
-	}
+    int sid=0;
+    if(auto st=m_area_tool->m_site)sid=st->m_area_id;
+	m_his_location_card->push(pt.m_time,pt,sid,cp.map_id);
+
 	uint64_t _now=tool_time::now_to_ms();
 	uint64_t t=_now>m_timeval?_now-m_timeval:m_timeval-_now;
 	if(t>10*1000)

+ 3 - 8
card_message_handle.cpp

@@ -154,17 +154,12 @@ void card_message_handle::on_message(zloop<task*> * loop,const message_locinfo&l
 		log_warn("%s","当前代码没有处理历史消息记录。");
 		return;
 	}
-	//
-	m_card->site_hover(loc.m_site_id);
-
+	STATUS_CARD c_status = STATUS_POWER_NOMARL;
 	if(loc.m_batty_status == 2)
 	{
-		m_card->do_status(STATUS_POWER_LOWER_SERIOUS);
-	}
-	else
-	{
-		m_card->do_status(STATUS_POWER_NOMARL);
+		c_status = STATUS_POWER_LOWER_SERIOUS;
 	}
+	m_card->do_status(c_status);
 
 	if(loc.m_callinfo & 0x80)
 	{

+ 7 - 0
card_message_handle.h

@@ -4,6 +4,8 @@
 
 //一张卡一个ct的所有不同天线的信息
 
+#include <thread>
+
 struct card_location_base;
 struct one_ct_message_handle;
 struct message_locinfo;
@@ -17,6 +19,11 @@ struct card_message_handle
 
 	card_message_handle(card_location_base*card);
 	~card_message_handle();
+
+#ifndef _RELEASE_
+	bool m_first_call=true;
+	std::thread::id m_first_call_thread;
+#endif 
 	
 	void on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history);
 };

+ 16 - 26
card_path.cpp

@@ -439,7 +439,10 @@ static std::vector<base_path> init_path(std::vector<base_path> & ret,vertex_list
 		p0[i].erase(it,p0[i].end());
 
 		for(int j=1,cnt=p0[i].size();j<cnt;j++)
-			ret2.push_back(base_path(p0[i][j-1],p0[i][j]));
+		{
+			ret2.push_back(base_path(p0[i][j - 1], p0[i][j]));
+			ret2.back().sid = ret[i].sid;
+		}
 	}
 
 	ret2.erase(std::remove_if(ret2.begin(),ret2.end(),[&v](base_path&p){
@@ -648,7 +651,7 @@ struct graph
 
 			line_v lv(v[from],v[to]);
 
-			log_info("line:%s\n",lv.to_string().c_str());
+			log_info("graph::init() site:%d line:%s\n",p.sid, lv.to_string().c_str());
 
 			double cos=lv.cos_k();
 			double sin=lv.sin_k();
@@ -819,33 +822,20 @@ struct graph
 	}
 };
 
-
-std::atomic<int> g_init_flag(0);
-graph g_graph;
-
+safe_shared_ptr<graph> g_graph(std::make_shared<graph>());
 }//namespace
 
 void card_path::init()
 {
-    //Ensure only ont thread can init path.
-	int expect=0;
-	if(g_init_flag.compare_exchange_strong(expect,1))
-	{
-		handle_path hp;
-		//std::vector<base_path> opath=init_path(sites,v_list);
-		sit_list::instance()->accept(hp);
-		std::vector<base_path> opath=init_path(hp.ret,hp.v);
-		g_graph.init(hp.v,opath);
+	std::shared_ptr<graph> local_graph=std::make_shared<graph>();
 
-		++g_init_flag;
-	}
-    //if != 2 then wait here until init over.
-	while(g_init_flag.load()!=2)
-	{
-		std::this_thread::sleep_for (std::chrono::seconds(1));
-	}
-}
+	handle_path hp;
+	sit_list::instance()->accept(hp);
+	std::vector<base_path> opath=init_path(hp.ret,hp.v);
+	local_graph->init(hp.v,opath);
 
+	g_graph.set(local_graph);
+}
 
 card_path&card_path::inst()
 {
@@ -855,17 +845,17 @@ card_path&card_path::inst()
 
 std::vector<point> card_path::find_path(const point&from,const point&to)const
 {
-	return g_graph.find(from,to);
+	return g_graph.get()->find(from,to);
 }
 
 bool card_path::is_at_path(const point&pt)const
 {
-	return g_graph.is_at_path(pt);
+	return g_graph.get()->is_at_path(pt);
 }
 
 std::vector<line_v>  card_path::find_possible_path(const point&from,double dist) const
 {
-	return std::move(g_graph.find_possible_path(from,dist));
+	return std::move(g_graph.get()->find_possible_path(from,dist));
 }
 
 #ifdef __DEBUG__

+ 34 - 27
card_person.cpp

@@ -15,6 +15,7 @@
 #include "mine_business.h"
 #include"common_tool.h"
 #include"db/db_tool.h"
+#include "forbid_staff_down_mine.h"
 
 person::person(const std::string &type,uint32_t cardid,uint16_t needdisplay,int16_t t,int32_t deptid,int32_t level_id,uint32_t cid,int wl,const std::string &sname,const std::string &dname,int worketype_id)
 	:card_location_base(type,cardid,needdisplay,t,deptid,level_id,cid)
@@ -32,15 +33,18 @@ person::~person()
 }
 void person::clear()
 {
-	m_area_tool.reset(new area_tool);
-	m_mine_tool.reset(new mine_tool);
+	//m_area_tool.reset(new area_tool);
+	//m_mine_tool.reset(new mine_tool);
+    m_mine_tool->clear();
+    m_area_tool->clear();
 	card_location_base::clear();
     uint64_t id = tool_other::type_id_to_u64(m_type,m_id);
     for(std::uint8_t i=0;i<CARD_EVENT_COUNT_MAX;i++)
     {
         if(m_event[i]!=0)
         {
-            event_tool::instance()->handle_event(OT_CARD,static_cast<EVENT_TYPE>(i),id,0,0,true);
+            log_info("clear_person_card_event:%d,%d",m_id,i);
+            event_tool::instance()->handle_event(OT_CARD,static_cast<EVENT_TYPE>(i),id,0,0,false);
             m_event[i]=0;
         }
     }
@@ -57,26 +61,25 @@ void person::site_hover(int sid)
 //虹膜识别入库功能	
 void person::IKSDK_DB(int sid)
 {
-	auto sit_ptr = sit_list::instance()->get(sid);
-	if(nullptr == sit_ptr)
-	  return;
-	if(sit_ptr->m_reader_type_id == READER_TYPE_ID_UP)
+	time_t now = time(0);
+	if(now - m_iris_recognition_timeval > 5)
 	{
-		time_t now = time(0);
-		if(now - m_iris_recognition_timeval > 5)
+		if (forbid_staff_down_mine::instance()->IsForbid(m_cid,now))
 		{
-			int f=0;
-			if(event_list::instance()->get_event_card(m_id, m_type, ET_CARD_LOW_POWER_SERIOUS))
-			  f=1;
-			std::string card_id = tool_other::type_id_to_str(m_type,m_id);
-			std::string st	    = tool_time::to_str(now);
-			char nsql[256]={0};
-			const char*sql="REPLACE INTO his_att_interface (staff_id,card_id,reader_id,staff_name,dept_name,upt_time,low_power_warn) VALUES (%d,%s,%d,'%s','%s','%s',%d);";
-			snprintf(nsql,256,sql,m_cid,card_id.c_str(),sid,m_stafferName.c_str(),m_deptName.c_str(),st.c_str(),f);
-			db_tool::PushAsync(nsql);
-			logn_info(2,"%s",nsql);
-			m_iris_recognition_timeval = now;
+			log_info("Staff:%d forbid down mine",m_cid); //禁止指定人员下井
+			return;
 		}
+		int f=0;
+		if(event_list::instance()->get_event_card(m_id, m_type, ET_CARD_LOW_POWER_SERIOUS)) {
+			f = 1;
+		}
+		std::string card_id = tool_other::type_id_to_str(m_type,m_id);
+		std::string st	    = tool_time::to_str(now);
+		char nsql[256]={0};
+		const char*sql="REPLACE INTO his_att_interface (staff_id,card_id,reader_id,staff_name,dept_name,upt_time,low_power_warn) VALUES (%d,%s,%d,'%s','%s','%s',%d);";
+		snprintf(nsql,256,sql,m_cid,card_id.c_str(),sid,m_stafferName.c_str(),m_deptName.c_str(),st.c_str(),f);
+		db_tool::PushAsync(nsql);
+		m_iris_recognition_timeval = now;
 	}
 }
 
@@ -87,7 +90,6 @@ std::shared_ptr<mine_tool> person::get_mine_tool()
 
 void person::do_business(const std::shared_ptr<site>&site,const point &pt,double acc)
 {
-    m_area_tool->set(site);
 	m_area_tool->on_point(shared_from_this(),pt);
 	m_timeval=m_time;
 	handle_three_rates(pt);
@@ -119,7 +121,7 @@ void person::on_timer()
 	point pt = getSmoothPoint(_time);
     
 	cp.area_info=m_area_tool->m_area_info;	
-	cp.map_id =m_area_tool->m_mapid;
+	cp.map_id =m_area_tool->get_mapid();
 
 	cp.biz_stat = m_biz_stat;
 	cp.down_time = m_mine_tool->get_down_time();
@@ -127,11 +129,10 @@ void person::on_timer()
 	cp.is_on_duty= m_mine_tool->is_on_duty();
 	upt_card_pos(cp,pt);
 	log_info("on_timer here ...%d,%lld,%.2f,%.2f,%d,%d--",m_id,_time,pt.x,pt.y,cp.map_id,cp.area_info.size());
-	if(!cp.area_info.empty())
-	{
-		int area_id = cp.area_info.begin()->first;
-		m_his_location_card->push(_time,pt,area_id,cp.map_id);
-	}
+    int sid=0;
+    if(auto st=m_area_tool->m_site)sid=st->m_area_id;
+	m_his_location_card->push(_time,pt,sid,cp.map_id);
+
 	uint64_t _now=tool_time::now_to_ms();
 	uint64_t t=_now>m_timeval?_now-m_timeval:m_timeval-_now;
 	if(t>10*1000)
@@ -139,6 +140,12 @@ void person::on_timer()
 		m_area_tool->on_point(shared_from_this(),pt);
 		m_biz_stat=get_stat();
 	}
+
+	if(m_upmine_flag.load())
+	{
+		m_upmine_flag=0;
+		m_area_tool->on_leave(shared_from_this());
+	}
 }
 
 point person::getSmoothPoint(uint64_t& t)

+ 10 - 56
client.cpp

@@ -1,70 +1,24 @@
 
+#include <time.h>
 #include "log.h"
-#include "zio.h"
 #include "message_file.h"
-#include "thread"
-#include "chrono"
+
 
 int main()
 {
-	int sock=zio::build_stream();
-
-	if(zio::connect(sock,"127.0.0.1",4000))
-	//if(zio::connect(sock,"192.168.8.116",4000))
-	{
-		return -1;
-	}
+	message_file  mf(stdin);
 
-	zio::setiobuf(sock,32<<10,64<<10);
-	zio::setblocking(sock,false);
-	int len=1;
-	int count=0x400+2;
-	char buf[8192];
-	uint64_t time;
-#if 0
+	unsigned char b[2048];
+	char m[2048];
+	uint64_t time=0;
+	int len;
 
-	for(int i=0;i<8000;i++)
+	while((len=mf.get_line(&time,(char*)b,sizeof(b),m))>0)
 	{
-		buf[i]='1';
+		mf.put_line(stdout,time,(char*)b,len);
 	}
 
-	buf[0]=0x04;
-	buf[1]=0x00;
-
-	char recv_buf[8192];
-	for(;;)
-	{
-		while(zio::read(sock,recv_buf,sizeof(recv_buf))>0);
-		if(count!=zio::writev(sock,buf,count))
-			break;
-	}
-#else
-	message_file mf(stdin);
-	count=0;
-	uint64_t time_tmp=0;
-	while(len>0)
-	{
-		//while((len=mf.get_line(&time,&buf[count],sizeof(buf)-count)))
-		{
-			std_info("......%lu",time);
-			count+=len;
-			if(count>1024)
-				break;
-		}
-		len=mf.get_line(&time,&buf[count],sizeof(buf)-count);
-		if(0==time_tmp)	
-		  time_tmp =time;
-		std::this_thread::sleep_for(std::chrono::milliseconds(time-time_tmp));
-		log_info("count=%d,time=%llu buf=%s",len,time,buf);
-		if(count!=zio::writev(sock,buf,count))
-			break;
-
-		count=0;
-	}
-#endif
-
-	zio::close(sock);
-
 	return 0;
 }
 
+

+ 11 - 6
common.h

@@ -96,30 +96,35 @@ enum OBJECT_TYPE
     ///标识卡,包括人员、车辆、自组网等
     OT_CARD = 9,
 };
-
+enum EVENT_DIS_TYPE
+{
+    DT_NORMAL=1,//内部显示
+    DT_SPECIAL=2,//外部显示
+    DT_COMMON=3//全显示
+};
 enum EVENT_TYPE{ // 事件类型
     ET_OVER_COUNT_PERSON = 1,       // 井下人员超员
     ET_OVER_COUNT_VEHICLE = 2,      // 井下车辆超员
     ET_AREA_OVER_COUNT_PERSON = 3,	// 区域人员超员
     ET_AREA_OVER_COUNT_VEHICLE = 4,	// 区域车辆超员
     ET_READER_ERROR = 6,
+
     ET_CARD_LOW_POWER_SERIOUS = 12, // 电量极低
     ET_CARD_OVER_TIME_PERSON = 13, // 人员井下超时
-    ET_CARD_OVER_TIME_VEHICLE = 14, // 车辆井下超时
     ET_CARD_AREA_OVER_TIME_PERSON = 15, // 人员区域超时
-    ET_CARD_AREA_OVER_TIME_VEHICLE = 16, // 车辆区域超时
 
     ET_CARD_AREA_FORBIDDEN_PERSON = 19,  // 人员进入禁止区域
     ET_CARD_AREA_FORBIDDEN_VEHICLE = 20, // 车辆进入禁止区域
     ET_CARD_OVER_SPEED = 21, // 车辆超速
     ET_CARD_AREA_OVER_SPEED = 22, // 车辆区域超速
     ET_CARD_HELP = 24, // 人员呼救
-
+    ET_CARD_DRIVINGFACE_WARNING_AREA = 28, //掘进面靠近预警区域告警
     ET_CARD_MOTIONLESS=32,//静止不动告警
     ET_READER_POWER_BY_BATTERY=33,//分站电池:1为电池供电,0为交流电供电,当电池供电需要告警
-	ET_VEHICLE_REAR_END=36,
+	ET_VEHICLE_REAR_END=36,//车辆防追尾告警
+	ET_COALING_DRIVING_DRIVER = 37,//工作面(采煤面和掘进面)司机与车卡告警;
     ET_VEHICLE_NEAR_GEOFAULT=38,//靠近断层告警
-	ET_READER_LOCATION_REVERSAL=39,
+	ET_READER_LOCATION_REVERSAL=39,//掘进面天线反向告警
     CARD_EVENT_COUNT_MAX
 };
 

+ 1 - 1
db/Makefile.am

@@ -1,6 +1,6 @@
 AUTOMAKE_OPTIONS=foreign
 
-noinst_LIBRARIES=libyadb.a
+lib_LIBRARIES=libyadb.a
 
 
 CXXFLAGS=-fPIC -g

+ 1 - 0
db/db_api/CDBConnPool.cpp

@@ -327,6 +327,7 @@ namespace YADB
 		_ASYNC_SQL_* pData = new _ASYNC_SQL_;
 		if ( !pData )
 		{
+            logn_error(2,"PushAsync new pData失败");
 			return false;
 		}
 

+ 6 - 9
db/db_card.cpp

@@ -13,7 +13,7 @@
 extern config_file config;
 namespace db_card
 {
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(int64_t id64)
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(const std::string & lszId64)
 	{
 		std::string sql = "SELECT ve.vehicle_id, ve.card_id, c.card_type_id, \
 						   ve.dept_id, ve.group_id, v.vehicle_type_id, vt.vehicle_level_id, \
@@ -30,16 +30,14 @@ namespace db_card
 
 		std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> map;
 
-		std::string card_id_str = tool_other::to13str(id64);
-
-		if(-1 == id64)
+		if("" == lszId64)
 		{
 			sql.append(";");
 		}
 		else
 		{
 			sql.append(" AND ve.card_id ='");
-			sql.append(card_id_str);
+			sql.append(lszId64);
 			sql.append("';");
 		}
 
@@ -110,7 +108,7 @@ namespace db_card
 		return map;
 	}
 
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(int64_t id64,const std::string&strategy)
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(const std::string & lszId64,const std::string&strategy)
 	{
 		std::string sql = "SELECT s.staff_id, s.card_id, c.card_type_id, s.dept_id, s.group_id, s.occupation_id, \
 						   ol.occupation_level_id,s.worktype_id,s.need_display,s.work_line\
@@ -124,15 +122,14 @@ namespace db_card
 						   WHERE s.duty_id = 0 AND c.state_id = 0";
 
 		std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> map;
-		std::string card_id_str = tool_other::to13str(id64);
-		if(-1 == id64)
+		if("" == lszId64)
 		{
 			sql.append(";");
 		}
 		else
 		{
 			sql.append(" AND s.card_id = '");
-			sql.append(card_id_str);
+			sql.append(lszId64);
 			sql.append("';");
 		}
 

+ 3 - 3
db/db_card.h

@@ -7,9 +7,9 @@ struct card_location_base;
 
 namespace db_card
 {
-
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(int64_t id64,const std::string&); 
-	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(int64_t id64); 
+	//const std::string & lszId64 = 0010000001102
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_person(const std::string & lszId64,const std::string&);
+	std::unordered_map<uint64_t,std::shared_ptr<card_location_base>> load_car(const std::string & lszId64);
 
 }
 

+ 3 - 7
db/db_tool.cpp

@@ -16,7 +16,7 @@ namespace db_tool
         logn_info(2,"sql:[%s]",sql);
         if(!sDBConnPool.PushAsync(sql))
         {
-            log_error( "PushAsync记录到队列中失败\n");
+            logn_error(2,"PushAsync记录到队列中失败");
         }
     }
 
@@ -32,11 +32,7 @@ namespace db_tool
     {
         char sql[LENGTH_SQL] = {0};
 
-        std::string call("add_att_staff");
-        if(card_ptr->is_vehicle())//车卡
-        {
-            call="add_att_vehicle";
-        }
+        std::string call(card_ptr->is_person()?"add_att_staff":"add_att_vehicle");
 
         auto mine_tool_ptr = card_ptr->get_mine_tool();
 
@@ -50,7 +46,7 @@ namespace db_tool
         std::string start_str = tool_time::to_str(start);
         std::string end_str = tool_time::to_str(end);
 		auto map_area_info = card_ptr->get_area_tool()->m_area_info;
-        int landmarkid,landmarkdirect=0;
+        int landmarkid=0,landmarkdirect=0;
         double landmarkdist=0;
 		if(!map_area_info.empty())
 		{

+ 30 - 27
event.cpp

@@ -15,8 +15,7 @@
 
 uint64_t ya_event::get_list_id()
 {
-    uint64_t car_id = tool_other::type_id_to_u64(tool_other::id64_to_type(m_obj_id), tool_other::id64_to_id(m_obj_id));
-    return  event_list::to_list_id(m_ev_type, m_obj_type,car_id);
+    return m_id;
 }
 
 
@@ -26,7 +25,7 @@ struct Event
     Event(OBJECT_TYPE oid)
         :m_oid(oid)
     {}
-    void handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,const std::string &desc="");
+    void handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt,const std::string &desc);
     virtual std::shared_ptr<ya_event> on_message(EVENT_TYPE et,uint64_t id,bool f)=0;
     std::shared_ptr<ya_event> create_event(const std::string&obj_id,EVENT_TYPE ev_type);
     virtual ~Event(){}
@@ -73,9 +72,9 @@ void event_tool::make_event_object()
     m_map[OT_CARD] = std::make_shared<card_event>();
 }
 
-void event_tool::handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,const std::string &desc/*=""*/)
+void event_tool::handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt/*=DT_COMMON*/,const std::string &desc/*=""*/)
 {
-    m_map[ot]->handle_alarm_event(et,id,limit_value,cur_value,f,desc);
+    m_map[ot]->handle_alarm_event(et,id,limit_value,cur_value,f,edt,desc);
 }
 
 std::shared_ptr<ya_event> Event::create_event(const std::string&obj_id,EVENT_TYPE ev_type)
@@ -87,10 +86,10 @@ std::shared_ptr<ya_event> Event::create_event(const std::string&obj_id,EVENT_TYP
     return ev_ptr;
 }
 
-void Event::handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,const std::string &desc/*=""*/)
+void Event::handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt,const std::string &desc)
 {
     std::shared_ptr<ya_event> ev_ptr = nullptr;
-    uint64_t eid = event_list::to_list_id(et,m_oid,id);
+    uint64_t eid = event_list::to_list_id(et,m_oid,id,edt);
     auto event_ptr = event_list::instance()->get(eid);
     if(f)
     {
@@ -115,9 +114,10 @@ void Event::handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,doub
                 ev_ptr->m_limit_value=limit_value;
                 ev_ptr->m_desc=desc;
                 ev_ptr->m_id=eid;
+                ev_ptr->m_dis_type=edt;
+                //保存告警信息
+                event_list::instance()->add(eid,ev_ptr);
             }
-            //保存告警信息
-            event_list::instance()->add(eid,ev_ptr);
         }
     }
     else
@@ -205,29 +205,29 @@ std::shared_ptr<ya_event> card_event::on_message(EVENT_TYPE et,uint64_t id,bool
         std::string card_id = tool_other::get_string_cardid(id);
         if(!card_ptr)
         {
-            log_info("create_event.can not find card:%s",card_id.c_str());
+            log_error("Create_event.can not find card:%s",card_id.c_str());
             return event_ptr;
         }
         event_ptr=create_event(card_id,et);
         event_ptr->x = card_ptr->x;
         event_ptr->y = card_ptr->y;
-        event_ptr->m_is_display = card_ptr->m_display;
+        //event_ptr->m_is_display = card_ptr->m_display;
 
         auto area_info_map = card_ptr->get_area_tool()->m_area_info;
         if(!area_info_map.empty())
         {
             auto lm = area_info_map.begin()->second;
             event_ptr->m_area_id = std::get<0>(lm);
-            event_ptr->m_map_id = card_ptr->get_area_tool()->m_mapid;
+            event_ptr->m_map_id = card_ptr->get_area_tool()->get_mapid();
         }
     }
     return event_ptr;
 }
 
-std::shared_ptr<ya_event> event_list::get_event_card(uint32_t card_id, int card_type, EVENT_TYPE ev_type)
+std::shared_ptr<ya_event> event_list::get_event_card(uint32_t card_id, int card_type, EVENT_TYPE ev_type,EVENT_DIS_TYPE edt)
 {
     uint64_t id64 = tool_other::type_id_to_u64(card_type, card_id);
-    return base::get(to_list_id(ev_type, OT_CARD, id64));
+    return base::get(to_list_id(ev_type, OT_CARD, id64,edt));
 }
 
 void event_list::save_event(std::shared_ptr<ya_event> ev_ptr)
@@ -235,10 +235,10 @@ void event_list::save_event(std::shared_ptr<ya_event> ev_ptr)
     char sql[LENGTH_SQL] = {0};
     std::string _time = tool_time::to_str_ex(ev_ptr->m_cur_time);
     sprintf(sql,
-            "INSERT IGNORE INTO his_event_data(event_id,id, stat, event_type_id, obj_type_id, obj_id, \
+            "INSERT IGNORE INTO his_event_data(event_id,id, stat, event_type_id, obj_type_id, obj_id, dis_type,\
             map_id, area_id, limit_value, cur_value, x, y, cur_time, description) \
-            VALUES(%ld,%ld, %d, %d, %d, %s, %d, %d, %.2f, %.2f, %f, %f, '%s', '%s');",
-            ev_ptr->get_id(),ev_ptr->m_id,ev_ptr->m_status, ev_ptr->m_ev_type, ev_ptr->m_obj_type, ev_ptr->m_obj_id.c_str(),
+            VALUES(%ld,%ld, %d, %d, %d, %s, %d, %d, %d, %.2f, %.2f, %f, %f, '%s', '%s');",
+            ev_ptr->m_ev_id,ev_ptr->m_id,ev_ptr->m_status, ev_ptr->m_ev_type, ev_ptr->m_obj_type, ev_ptr->m_obj_id.c_str(),ev_ptr->m_dis_type,
             ev_ptr->m_map_id, ev_ptr->m_area_id, ev_ptr->m_limit_value, ev_ptr->m_cur_value, ev_ptr->x, ev_ptr->y,
             _time.c_str(), ev_ptr->m_desc.c_str());
 
@@ -248,7 +248,7 @@ void event_list::save_event(std::shared_ptr<ya_event> ev_ptr)
 void event_list::load_his_data_from_db()
 {
     std::unordered_map<uint64_t, std::shared_ptr<ya_event>> map;
-    const char *sql = "SELECT event_id, id,stat,event_type_id,obj_type_id,obj_id,map_id,area_id,\
+    const char *sql = "SELECT event_id, id,stat,event_type_id,obj_type_id,obj_id,dis_type,map_id,area_id,\
             limit_value,cur_value,x,y, cur_time FROM his_event_data \
             WHERE event_id IN (SELECT MAX(event_id) FROM his_event_data \
                                WHERE cur_time > (CASE obj_type_id \
@@ -259,8 +259,9 @@ void event_list::load_his_data_from_db()
                                                  WHEN 10 THEN DATE_SUB(NOW(),INTERVAL 2 DAY) \
                                                  END) \
                                AND cur_time < NOW()\
-                               GROUP BY event_type_id, obj_id) \
-            AND  event_id NOT IN ( SELECT event_id FROM (SELECT * FROM his_event_data WHERE  stat=100) s);";
+                               GROUP BY event_type_id, obj_id,dis_type) \
+            AND  event_id NOT IN ( SELECT event_id FROM his_event_data WHERE  stat=100)\
+            AND event_type_id NOT IN (21,22);";
     std::string Error;
     YADB::CDBResultSet DBRes;
     sDBConnPool.Query(sql,DBRes,Error);
@@ -288,6 +289,9 @@ void event_list::load_his_data_from_db()
             std::string obj_id  = "";
             DBRes.GetField( "obj_id",obj_id, Error );
 
+            int dis_type  = 0;
+            DBRes.GetField( "dis_type",dis_type, Error );
+
             int map_id  = 0;
             DBRes.GetField( "map_id",map_id, Error );
 
@@ -318,6 +322,7 @@ void event_list::load_his_data_from_db()
             ev->m_ev_type = static_cast<EVENT_TYPE>(event_type_id);
 
             ev->m_obj_type = static_cast<OBJECT_TYPE>(obj_type_id);
+            ev->m_dis_type = static_cast<EVENT_DIS_TYPE>(dis_type);
             ev->m_obj_id = tool_other::to13str(obj_id);
             ev->m_cur_time = tool_time::to_time_ex(cur_time);
 
@@ -331,8 +336,8 @@ void event_list::load_his_data_from_db()
             ev->m_id = id;
             
             map.insert(std::make_pair(id, ev));
-            log_info("event_list %lld,%lld,%d,%d,%d,%s,%d,%d,%.2f,%.2f,%.2f,%.2f,%s"
-                     , ev->get_id(),ev->m_id,ev->m_status,ev->m_ev_type,ev->m_obj_type,ev->m_obj_id.c_str()
+            log_info("event_list %lld,%lld,%d,%d,%d,%s,%d,%d,%d,%.2f,%.2f,%.2f,%.2f,%s"
+                     , ev->m_ev_id,ev->m_id,ev->m_status,ev->m_ev_type,ev->m_obj_type,ev->m_obj_id.c_str(),ev->m_dis_type
                      ,ev->m_map_id,ev->m_area_id,ev->m_limit_value,ev->m_cur_value
                      ,ev->x,ev->y
                      ,tool_time::to_str_ex(ev->m_cur_time).c_str());
@@ -351,10 +356,7 @@ std::string event_list::evs_to_json(std::vector<std::shared_ptr<ya_event>> arr)
     auto it=arr.begin();
     for(;it!=arr.end();++it)
     {
-        if((*it)->m_is_display)
-        {
-            _ev_to_node(*it, allocator, data);
-        }
+        _ev_to_node(*it, allocator, data);
     }
 
     doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_EVENT, allocator);
@@ -374,13 +376,14 @@ void event_list::_ev_to_node(std::shared_ptr<ya_event> ev_ptr,
 {
     rapidjson::Value ev(rapidjson::kObjectType);
 
-    ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->get_id(), allocator);
+    ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->m_ev_id, allocator);
     ev.AddMember(JSON_KEY_EVENT_STATUS,ev_ptr->m_status, allocator);
 
     ev.AddMember(JSON_KEY_EVENT_TYPE_ID,ev_ptr->m_ev_type, allocator);
     ev.AddMember(JSON_KEY_EVENT_OBJ_TYPE_ID,ev_ptr->m_obj_type, allocator);
 
     tool_json::add_member(ev, JSON_KEY_EVENT_OBJ_ID, ev_ptr->m_obj_id, allocator);
+    ev.AddMember(JSON_KEY_EVENT_DIS_TYPE_ID,ev_ptr->m_dis_type, allocator);
     ev.AddMember(JSON_KEY_EVENT_MAP_ID,ev_ptr->m_map_id, allocator);
     ev.AddMember(JSON_KEY_EVENT_AREA_ID,ev_ptr->m_area_id, allocator);
     ev.AddMember(JSON_KEY_EVENT_X,ev_ptr->x, allocator);

+ 15 - 19
event.h

@@ -12,8 +12,6 @@
 #include "common.h"
 struct ya_event
 {
-private:
-    uint64_t m_ev_id;
 public:
     ya_event(uint64_t e_id):m_cur_time(std::chrono::system_clock::now())
     {
@@ -28,12 +26,14 @@ public:
         m_desc = "";
 
         m_status=ES_START;
-        m_is_display=true;
+        //m_is_display=true;
         m_is_sent=false;
     }
     ~ya_event(){}
 public:
     //key of event_list. 
+    uint64_t m_ev_id;
+
     uint64_t m_id;
     ///告警状态,开始、结束
     EVENT_STATUS m_status;
@@ -42,6 +42,7 @@ public:
     EVENT_TYPE m_ev_type;
     ///告警对象类型
     OBJECT_TYPE m_obj_type;
+    EVENT_DIS_TYPE m_dis_type;
     /// 告警对象编号,与告警对象类型对应,如告警对象类型为分站,此字段为分站编号
     std::string m_obj_id;
     ///当前时间,为告警事件的触发时间,如果状态为开始,则表示开始时间,否则为结束时间
@@ -62,7 +63,7 @@ public:
     ///描述
     std::string m_desc;
 
-    bool m_is_display;
+    //bool m_is_display;
     //是否已经发送 ture bu发送, false推送. 推送完置为true
     bool m_is_sent;
 
@@ -73,22 +74,17 @@ public:
 
     ///作为事件map列表的id,方便查找;
     uint64_t get_list_id();
-
-    uint64_t get_id()
-    {
-        return m_ev_id;
-    }
 };
 
 class Event;
 struct event_tool
 {
 	template <class UnaryPredicate>
-	void handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,UnaryPredicate p,const std::string &desc="")
+	void handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,UnaryPredicate p,EVENT_DIS_TYPE edt=DT_COMMON,const std::string &desc="")
 	{
-		handle_event(ot,et,id,limit_value,cur_value,p(),desc);
+		handle_event(ot,et,id,limit_value,cur_value,p(),edt,desc);
 	}
-	void handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,const std::string &desc="");
+	void handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt=DT_COMMON,const std::string &desc="");
 	static event_tool * instance();
 private:
     event_tool()
@@ -102,21 +98,21 @@ private:
 struct event_list:single_base<event_list,uint64_t,std::shared_ptr<ya_event>>
 {
 public:
-    static uint64_t to_list_id(EVENT_TYPE ev_type, OBJECT_TYPE obj_type,uint64_t obj_id)
+    static uint64_t to_list_id(EVENT_TYPE ev_type, OBJECT_TYPE obj_type,uint64_t obj_id,EVENT_DIS_TYPE edt)
     {
-        return (static_cast<uint64_t>(ev_type)<<48)|(static_cast<uint64_t>(obj_type)<<40)|obj_id;
+        return (static_cast<uint64_t>(edt)<<58)|(static_cast<uint64_t>(ev_type)<<48)|(static_cast<uint64_t>(obj_type)<<40)|obj_id;
     }
 
-    std::shared_ptr<ya_event> get_event_card(uint32_t card_id, int card_type, EVENT_TYPE ev_type);
+    std::shared_ptr<ya_event> get_event_card(uint32_t card_id, int card_type, EVENT_TYPE ev_type,EVENT_DIS_TYPE edt=DT_COMMON);
 
-    std::shared_ptr<ya_event> get_event_area(int32_t area_id, EVENT_TYPE ev_type)
+    std::shared_ptr<ya_event> get_event_area(int32_t area_id, EVENT_TYPE ev_type,EVENT_DIS_TYPE edt)
     {
-        return base::get(to_list_id(ev_type, OT_AREA, static_cast<uint64_t>(area_id)));
+        return base::get(to_list_id(ev_type, OT_AREA, static_cast<uint64_t>(area_id),edt));
     }
 
-    std::shared_ptr<ya_event> get_event_reader(int32_t reader_id, EVENT_TYPE ev_type)
+    std::shared_ptr<ya_event> get_event_reader(int32_t reader_id, EVENT_TYPE ev_type,EVENT_DIS_TYPE edt=DT_COMMON)
     {
-        return base::get(to_list_id(ev_type,OT_DEVICE_READER, static_cast<uint64_t>(reader_id)));
+        return base::get(to_list_id(ev_type,OT_DEVICE_READER, static_cast<uint64_t>(reader_id),edt));
     }
 
     static void save_event(std::shared_ptr<ya_event> event_ptr);

+ 124 - 0
forbid_staff_down_mine.cpp

@@ -0,0 +1,124 @@
+#include "forbid_staff_down_mine.h"
+#include "log.h"
+#include "tool_time.h"
+#include "db_api/CDBSingletonDefine.h"
+
+void forbid_staff_down_mine::init_forbid_staff(int id /* = -1*/,int etype)
+{
+    std::string sql = "select id,staff_id,start_time,end_time,status,oper_time,lastupdate from rt_person_forbid_down_mine where ";
+    if (id != -1)
+        sql += " id = " + std::to_string(id) + ";";
+    else
+        sql += "status = 1 and end_time > now();";
+    std::string Error;
+    YADB::CDBResultSet DBRes;
+    sDBConnPool.Query(sql.c_str(),DBRes,Error);
+    int nCount = DBRes.GetRecordCount( Error );
+    if (nCount < 1)
+    {
+        log_error("增加或修改失败,数据库中找不到: sql", sql.c_str());
+        return ;
+    }
+    while ( DBRes.GetNextRecod(Error) )
+    {
+        int key = 0;
+        DBRes.GetField("id", key, Error);
+        unsigned int staff_id = 0;
+        DBRes.GetField("staff_id", staff_id, Error);
+        std::string start_time;
+        DBRes.GetField("start_time", start_time, Error);
+        std::string end_time;
+        DBRes.GetField("end_time", end_time, Error);
+        int state;
+        DBRes.GetField("status", state, Error);
+        std::string create_time;
+        DBRes.GetField("oper_time", create_time, Error);
+        std::string update_time;
+        DBRes.GetField("lastupdate", update_time, Error);
+        time_t stime = tool_time::to_time(start_time);
+        time_t etime = tool_time::to_time(end_time);
+        std::shared_ptr<SForbidStaffList> s = forbid_staff_down_mine::instance()->get(staff_id);
+        //如果存在则查找更新。查找不到则插入
+        if (s)
+        {
+            bool f=false;
+            for (SForbidStaffInfo &info : s->forbidList)
+            {
+                //找到记录则更新,停止.找不到,则继续往下走
+                if (info.db_id == key)
+                {
+                    f=true;
+                    info.start_time =stime;
+                    info.end_time =etime;
+                    info.state = state;
+                    log_info("Check Forbid_staff_down_mine DBID:%d Staff:%d State:%d Time:%s -> %s . "
+                                ,key,staff_id,state,start_time.c_str(),end_time.c_str());
+                    break;
+                }
+            }
+            if(f)continue;
+            //ET_UPDATE
+            if(id !=-1 && etype ==2)
+            {
+                time_t now= time(0);
+                if(state!=1 || now>etime)
+                    continue;
+            }
+        }
+        else
+        {
+            s = std::make_shared<SForbidStaffList>();
+            forbid_staff_down_mine::instance()->add(staff_id,s);
+        }
+        s->staff_id = staff_id;
+        SForbidStaffInfo info ;
+        info.staff_id = staff_id;
+        info.db_id = key;
+        info.start_time = stime;
+        info.end_time =etime;
+        info.state = state;
+
+        log_info("Init Forbid_staff_down_mine DBID:%d Staff:%d State:%d Time:%s -> %s . "
+                    ,key,staff_id,state,start_time.c_str(),end_time.c_str());
+        s->forbidList.push_back(info);
+    }
+}
+
+void forbid_staff_down_mine::del_forbid_data(int id,int staff_id)
+{
+    auto s = forbid_staff_down_mine::instance()->get(staff_id);
+    if (s != nullptr)
+    {
+        log_info(" remove Forbid Staff:%d Down mine.DBID=%d",s->staff_id,id);
+        for(auto it = s->forbidList.begin(); it != s->forbidList.end() ; ++it)
+        {
+            if ((*it).db_id == id)
+            {
+                s->forbidList.erase(it);
+                break;
+            }
+        }
+        if(s->forbidList.size() == 0)
+        {
+            forbid_staff_down_mine::instance()->remove(staff_id);
+        }
+    }
+}
+
+//是否禁止状态
+bool forbid_staff_down_mine::IsForbid(int staff_id,time_t cur_time)
+{
+    auto flist = forbid_staff_down_mine::instance()->m_map;
+    auto it = flist.find(staff_id);
+    if (it != flist.end())
+    {
+        for (auto &info : it->second->forbidList)
+        {
+            if (info.state == 1 && cur_time > info.start_time && cur_time < info.end_time)
+            {
+                return true;
+            }
+        }
+    }
+    return false;
+}

+ 51 - 0
forbid_staff_down_mine.h

@@ -0,0 +1,51 @@
+//
+// Created by Administrator on 2019/3/5.
+// 禁止制定人员下井
+//
+
+#ifndef WORKSPACE_FORBID_STAFF_DOWN_MINE_H
+#define WORKSPACE_FORBID_STAFF_DOWN_MINE_H
+
+#include "write-copy.h"
+#include <string>
+#include <map>
+#include <list>
+
+struct SForbidStaffInfo
+{
+    int staff_id;
+    int db_id;
+    time_t start_time;
+    time_t end_time;
+    int state;          //状态 0 = 无效 1 = 有效
+    SForbidStaffInfo()
+    {
+        db_id = 0;
+        staff_id = 0;
+        start_time = 0;
+        end_time = 0;
+        state = 0;
+    }
+};
+
+struct SForbidStaffList
+{
+    int staff_id ;
+    std::list<SForbidStaffInfo> forbidList;
+};
+
+struct forbid_staff_down_mine
+        :single_base<forbid_staff_down_mine,int,std::shared_ptr<SForbidStaffList>>
+{
+public:
+    // 根据数据库中的自增长id
+    void init_forbid_staff(int id = -1,int etype=-1);
+    // 根据数据库中的自增长id
+    void del_forbid_data(int id,int staff_id);
+
+    //是否禁止状态
+    bool IsForbid(int staff_id,time_t cur_time);
+};
+
+
+#endif //WORKSPACE_FORBID_STAFF_DOWN_MINE_H

+ 24 - 6
line.h

@@ -135,9 +135,17 @@ struct line_v:line//线段
 	{
 		v[0]=p0;
 		v[1]=p1;
-        setpoint();
+        recalc();
 	}
-    void setpoint()
+	void swap_point()
+	{
+		point tmp=v[0];
+		v[0]=v[1];
+		v[1]=tmp;
+		recalc();
+	}
+
+    void recalc()
     {
         double dx = v[1].x - v[0].x;
         double dy = v[1].y - v[0].y;
@@ -146,10 +154,15 @@ struct line_v:line//线段
         double sin = dy/r;
         angle = point(cos,sin);
     }
-    double cos() const
-    {return angle.x;}
-    double sin() const
-    {return angle.y;}
+
+	void set_point(int i,const point&p)
+	{
+		v[i]=p;
+		recalc();
+	}
+
+    double cos() const {return angle.x;}
+    double sin() const {return angle.y;}
 	point&operator[](int i) { return v[i]; }
 	const point&operator[](int i)const { return v[i]; }
 
@@ -232,6 +245,11 @@ struct line_v:line//线段
 
 		return v.dist(p);
 	}
+
+	const line &as_line()const
+	{
+		return *this;
+	}
 };
 #endif
 

+ 38 - 41
main.cpp

@@ -20,15 +20,18 @@
 #include "mine_business.h"
 #include "main_test.h"
 #include "ya_setting.h"
+#include "websocket/web_connect.h"
+#include "forbid_staff_down_mine.h"
 
 config_file config;
 void handlereader(uint32_t readerid,bool duration,uint32_t t)
 {
 
 }
+
 //三率模块中告警回调
 void Handle_ThreeRates_Event_Callback(const int evType, const int evId, uint64_t id
-        , double limitVal, double curVal, bool bFalg)
+                                      , double limitVal, double curVal, bool bFalg)
 {
     if (evId >= EVENT_TYPE::CARD_EVENT_COUNT_MAX  || evType > OBJECT_TYPE::OT_CARD)
     {
@@ -41,15 +44,7 @@ struct Init_Setting
 {
     void init()
     {
-        std::string url=config.get("service.websocket_url","ws://127.0.0.1:8086");
-        int32_t send_interval =config.get("service.interval_send_json_postion",1);
-        std_info("json_interval:%d",send_interval);
-        std::vector<std::string> url_list;
-        url_list.push_back(url);
-        if(!wsClientMgr_init(url_list,send_interval))
-		  exit(0);
         YADB::_DB_POOL_SETTING_ DBSetting;
-
         DBSetting.Host = config.get("db.host","127.0.0.1");
         DBSetting.User = config.get("db.user","root");
         DBSetting.PWD = config.get("db.passwd","123456");
@@ -57,13 +52,28 @@ struct Init_Setting
         DBSetting.CharSet = config.get("db.charset","utf8");
         DBSetting.TimeOut = config.get("db.conn_timeout",5);
         DBSetting.PoolSize = config.get("db.pool_size",30);
+        DBSetting.Port = config.get("db.port",3306);
         if(!_mysql_init(DBSetting))
-		  exit(0);
+        {
+            std_info("连接DB[%s:%s] 失败,采集服务器无法启动!",DBSetting.Host.c_str(),DBSetting.User.c_str());
+            exit(0);
+        }
 
+        std::string url=config.get("service.websocket_url","ws://127.0.0.1:8086");
+        int32_t send_interval =config.get("service.interval_send_json_postion",1);
+        std_info("json_interval:%d",send_interval);
+        std::vector<std::string> url_list;
+        url_list.push_back(url);
+        if(!wsClientMgr_init(url_list,send_interval))
+        {
+            std_info("连接webServer[%s] 失败,采集服务器无法启动!",url.c_str());
+            exit(0);
+        }
 		CYaSetting::Init_sys_setting();
         sit_list::instance()->load_from_db();
         card_list::instance()->init_card_from_db();
         area_list::instance()->init_from_db();
+        forbid_staff_down_mine::instance()->init_forbid_staff();
         //point pt(3348,100);
         //int id = area_list::instance()->get_area(pt)->id();
         //std_info("test area:%d",id);
@@ -84,19 +94,24 @@ struct Init_Setting
         dp.CharSet=DBSetting.CharSet ;
         dp.TimeOut=DBSetting.TimeOut;
         dp.PoolSize=DBSetting.PoolSize;
-	init_three_rates(dp);
+		init_three_rates(dp);
+
+
+        log_info("Init_Setting::init  Success. \n" );
 
-        printf("Init_Setting::init  Success. \n" );
     }
+
 	void init_three_rates(const db_para& dbs)
 	{
-		std_info("three_rates ...................");
+		log_info("init three_rates ...................");
 		init_para ip;
 		ip.send_pt = handlereader;
 		ip.driving_face_alarm = Handle_ThreeRates_Event_Callback;
 		three_rates::get_instance()->init(ip,dbs);
 		three_rates::get_instance()->start();
+        std_info("加载三率模块成功");
 	}
+
     bool _mysql_init(YADB::_DB_POOL_SETTING_ &dps)
     {
         std::string szError = "";
@@ -108,38 +123,18 @@ struct Init_Setting
             std_error("数据库线程池创建失败,Err=%s", szError.c_str());
 			flag = false;
         }
+        std_info("数据库线程池创建成功");
 		return flag;
     }
 
     bool wsClientMgr_init(const std::vector<std::string>&uri_list,int32_t st)
     {
-		bool flag = true;
         std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE> MsgFuncList;
-
-        //MsgFuncList.insert( std::make_pair( "req_all_person_on_car", On_req_all_person_on_car ) );
-
         module_mgr::init(config, MsgFuncList);
 
-        swsClientMgr.Build( uri_list, MsgFuncList );
-
-		do{
-			//连接服务器
-			 if ( swsClientMgr.connect() != 0 )
-       		 {
-       		     log_error("web socket init failed.");
-       		     std_error("websocket 初始化失败....");
-	   		 	 flag =false;
-				 break;
-       		 }
-       		 //登录
-       		 swsClientMgr.login();
-       		 //init thread...
-       		 YA::_THREAD_CONFIG_ Config;
-       		 Config.SendInterval = st;
-       		 swsTimerThrd.Init( Config );
-       		 swsTimerThrd.Start();
-		}while(false);
-		return flag;
+        web_connect::init(uri_list, st, MsgFuncList);
+
+        return web_connect::connect();
     }
 };
 
@@ -147,6 +142,7 @@ struct Init_Setting
 void cleanup()
 {
     module_mgr::stop();
+    web_connect::close();
 }
 
 void usage(char ** argv)
@@ -186,16 +182,15 @@ int main(int argc ,char * argv[])
     Init_Setting is;
     is.init();
 
-	card_path::init();
-	test_find_path(point(4600,-75),point(4727,-90));
-
     module_mgr::start();
+    web_connect::start_beatheart_monitor();
     atexit(&cleanup);
 
     net_service mh;
     int port=config.get("service.port",4000);
 
-    printf("\nservice_handle::instance(&mh)->run(%d); \n",port);
+    log_info("service_handle::instance(&mh)->run(%d)",port);
+    std_info("service_handle::instance(&mh)->run(%d)",port);
     service_handle::instance(&mh)->run(port);
     
     sDBConnPool.Close();
@@ -205,3 +200,5 @@ int main(int argc ,char * argv[])
 
     return 0;
 }
+
+

+ 25 - 3
message.cpp

@@ -5,7 +5,21 @@
 
 void message_locinfo::zero_this()
 {
-	memset(this,0,sizeof(*this));
+//	m_time_stamp=
+//	m_site_id=
+	m_site_time=
+
+	m_card_type=
+	m_card_id=
+	m_tof=
+	m_card_ct=
+	m_batty_status=
+	m_callinfo=
+	m_rav=
+	m_acc=
+	m_ant_id=
+	m_sync_ct=
+	m_rssi=0;
 }
 
 void message_locinfo::load(zistream&is,bool tdoa)
@@ -54,12 +68,20 @@ void message_locinfo::load(zistream&is,bool tdoa)
 	uint16_t sp1=0,sp2=0;
 	is>>sp1>>sp2;
 	m_rssi=10*log10(1.*sp1*(1<<17)/pow(sp2-64.,2))-121.74;
-	log_info("timestamp=%llu,type:%d,card_id:%d,ct:%d,status:%d,acc=%d,tof=%llu,ant_id:%d,spq=%d",m_time_stamp,m_card_type,m_card_id,m_card_ct,m_batty_status,m_acc,m_tof,m_ant_id,m_rssi);
+	log_info("timestamp=%llu,type:%d,card_id:%d,site:%d,ct:%d,status:%d,acc=%d,tof=%llu,ant_id:%d,spq=%d",
+			m_time_stamp,m_card_type,m_card_id,m_site_id,m_card_ct,m_batty_status,m_acc,m_tof,m_ant_id,m_rssi);
 }
 
 void message_tdoasync::zero_this()
 {
-	memset(this,0,sizeof(*this));
+	m_local_site_id=
+	m_parent_site_id=
+	m_local_ant_id=
+	m_parent_ant_id=
+	m_sync_ct=
+	m_local_level=
+	m_recv_time=
+	m_send_time=0;
 }
 
 void message_tdoasync::load(zistream&is)

+ 5 - 3
message.h

@@ -2,10 +2,12 @@
 #define __MESSAGE_HPP__
 #include <stdint.h>
 #include <time.h>
+#include "worker.h"
 
 struct zistream;
 
 #define CHAR_LOCATEDATA_TOF_EXTEND 0x843b			// TOF实时定位数据,请求、应答
+#define CHAR_LOCATEDATASMALL_TOF_EXTEND 0x753b		// TOF实时小分站定位数据,请求、应答
 #define CHAR_LOCATEDATAHIS_TOF_EXTEND 0x853b		// TOF历史定位数据,请求、应答
 #define CHAR_LOCATEDATA_TDOA_EXTEND 0x863b			// TDOA实时定位数据,请求、应答
 #define CHAR_LOCATEDATAHIS_TDOA_EXTEND 0x873b		// TDOA历史定位数据,请求、应答
@@ -14,7 +16,7 @@ struct zistream;
 #define CHAR_CTRL_READER_CMD 0x804c					// 向分站发送控制指令,控制分站向上位机发送数据
 
 //	分站传上来的卡定位数据,包括tof,tdoa
-struct message_locinfo
+struct message_locinfo:task
 {
 	uint64_t m_time_stamp;
 	uint32_t m_site_id;
@@ -30,7 +32,7 @@ struct message_locinfo
 	uint8_t  m_acc;
 	uint8_t  m_ant_id;
 	uint16_t m_sync_ct;
-	uint16_t m_rssi;
+	int16_t  m_rssi;
 
 	void zero_this();
     void load(zistream&is,bool tdoa);
@@ -42,7 +44,7 @@ struct message_locinfo
 };
 
 //tdoa分站同步数据
-struct message_tdoasync
+struct message_tdoasync:task
 {
 	uint32_t m_local_site_id;
 	uint32_t m_parent_site_id;

+ 91 - 19
message_file.cpp

@@ -6,8 +6,9 @@
 #include <memory.h>
 #include <time.h>
 #include <stdint.h>
-#include "message_file.h"
 
+#include "message_file.h"
+#include "zstream.h"
 namespace
 {
 char decode[256];
@@ -100,52 +101,123 @@ inline const char* now(char*date_str,uint64_t time)
 	return date_str;
 }
 
-int message_file::put_line(uint64_t time,char*buf,int buflen)
+int message_file::put_line(FILE*fp,uint64_t time,char*buf,int buflen)
 {
 	char b[8192];
 
-	printf("[%s]\n",now(b,time));
+	fprintf(fp,"[%s]\n",now(b,time));
 	int n=0,t;
 	for(int i=0;i<buflen;i++)
 	{
 		t=(int)(unsigned char)buf[i];
 		n+=sprintf(&b[n],"%s ",encode[t]);
+
+		if((i+1)%32 == 0)
+		{
+			n+=sprintf(&b[n],"\n");
+		}
 	}
 
-	printf("%s\n",b);
+	fprintf(fp,"%s\n",b);
 
 	return 0;
 }
 
+int line_type(const char*s)
+{
+	if(s[0]==0 || s[0]=='\n')
+		return 0;
+	
+	if(strncmp("2019-",s,5)==0)
+		return 1;
+	
+	return 2;
+}
+
 int message_file::get_line(uint64_t*time,char*buf,int buflen)
 {
-	const char*p;
-	while(m_last_line[0]!='[')
-	{ 
+	return get_line(time,buf,buflen,0);
+}
+
+int message_file::get_line(uint64_t*time,char*buf,int buflen,char*m)
+{
+	int type=0;
+	
+	while(1)
+	{
 		if(fgets(m_last_line,sizeof(m_last_line),m_file)==nullptr)
 			return 0;
-	}
 
-	{
-		struct tm tm;
-		memset(&tm, 0, sizeof(struct tm));
-		const char*ms=strptime(&m_last_line[1], "%Y-%m-%d %H:%M:%S", &tm);
+		type=line_type(m_last_line);
+
+		if(type==0)
+			continue;
+
+		if(type==1)
+		{
+			struct tm tm;
+			memset(&tm, 0, sizeof(struct tm));
+			const char*ms=strptime(&m_last_line[0], "%Y-%m-%d %H:%M:%S", &tm);
+			*time=1000LL*mktime(&tm)+atoi(ms+1);
+
+			if(m) strcpy(m,m_last_line);
+			continue;
+		}
 
-		*time=1000*mktime(&tm)+atoi(ms+1);
+		break;
 	}
 
 	char*o=buf;
-	for(;;)
+	while(1)
 	{
-		if(nullptr==(p=fgets(m_last_line,sizeof(m_last_line),m_file)))
+		if(line_type(m_last_line)<=1)
+			break;
+
+		o+=convert(m_last_line,o);
+
+		if(fgets(m_last_line,sizeof(m_last_line),m_file)==nullptr)
 			return 0;
+	}
+	return o-buf;
+}
 
-		if(*p=='[')
-			break;
+int message_file::get_card_message(uint32_t card_id,char*b)
+{
+	int len;
+	char buf[2048];
+	uint64_t time=0;
+
+	int ppos=0;
+	while((len=get_line(&time,buf,sizeof(buf)))>0)
+	{
+		zistream is(buf,len-2);
+		uint16_t cmd;
+		is>>skip(2)>>cmd;
+
+		if(cmd!=0x843b && cmd!=0x753b)
+			continue;
+
+		is>>skip(16);
+
+		while(!is.eof())
+		{
+			uint32_t cid;
+			uint32_t gpos=is.pos();
+			is>>skip(1)>>cid;
 
-		o+=convert(p,o);
+			if(cid!=card_id) continue;
+
+			if(ppos==0) memcpy(b,buf,ppos=20); 
+			memcpy(&b[ppos],&buf[gpos],20);
+			ppos+=20;
+		}
+
+		if(ppos==0)  continue;
+
+		ppos+=2;
 	}
 
-	return o-buf;
+	return -1;
 }
 
+

+ 5 - 2
message_file.h

@@ -8,7 +8,7 @@ struct message_file
 private:
 	bool  m_owner;
 	FILE* m_file;
-	char  m_last_line[256];
+	char  m_last_line[1024];
 	message_file(const message_file&);
 public:
 
@@ -17,8 +17,11 @@ public:
 	~message_file();
 	
 	
+	int get_line(uint64_t*time,char*buf,int buflen,char*msg);
 	int get_line(uint64_t*time,char*buf,int buflen);
-	int put_line(uint64_t time,char*buf,int buflen);
+	int put_line(FILE*fp,uint64_t time,char*buf,int buflen);
+	int get_card_message(uint32_t card_id,char*b);
+
 };
 
 #endif

+ 13 - 8
mine.h

@@ -17,17 +17,22 @@ struct card_location_base;
 struct mine_tool
 {
     mine_tool()
-		:m_over_speed_count(0)
-		,m_normal_speed_count(0)
-		,m_status_call(0)
-        ,m_is_attendance(false)
-		,m_attendance_start_time(std::chrono::seconds(0))
-		,m_is_overtime(false)
-		,m_overtime(std::chrono::seconds(0))
     {
-
+        clear();
     }
 
+    void clear()
+    {
+        m_over_speed_count=0;
+		m_over_speed_count=0;
+		m_normal_speed_count=0;
+		m_status_call=0;
+        m_is_attendance=false;
+		m_attendance_start_time=std::chrono::system_clock::time_point(std::chrono::seconds(0));
+		m_is_overtime=false;
+		m_overtime=std::chrono::system_clock::time_point(std::chrono::seconds(0));
+        
+    }
     int    m_over_speed_count;
     int    m_normal_speed_count;
     ///CALL_NONE(0):没有呼叫,CALL_ING(2):正在呼叫,CALL_SUCCESSED(1):呼叫成功

+ 3 - 3
mine_business.cpp

@@ -560,7 +560,7 @@ void rear_end_collision_prevented_business::handle_message()
         {
             log_info("vehicle_alarm_time_ %s",vvid.c_str());
             if (vinfo.is_alarm){
-                event_tool::instance()->handle_event(OT_CARD,ET_VEHICLE_REAR_END,id,0,0,false,vvid);
+                event_tool::instance()->handle_event(OT_CARD,ET_VEHICLE_REAR_END,id,0,0,false,DT_COMMON,vvid);
             }
             it_cv = m_CloserVehicle.erase(it_cv);
             continue;
@@ -581,7 +581,7 @@ void rear_end_collision_prevented_business::handle_message()
             {
                 log_info("vehicle_alarm_backfired_timeout %s",vvid.c_str());
                 if(vinfo.is_alarm){
-                    event_tool::instance()->handle_event(OT_CARD,ET_VEHICLE_REAR_END,id,CYaSetting::m_sys_setting.rear_end_d,dis,false,vvid);
+                    event_tool::instance()->handle_event(OT_CARD,ET_VEHICLE_REAR_END,id,CYaSetting::m_sys_setting.rear_end_d,dis,false,DT_COMMON,vvid);
                 }
                 it_cv = m_CloserVehicle.erase(it_cv);
                 continue;
@@ -598,7 +598,7 @@ void rear_end_collision_prevented_business::handle_message()
                 if (!vinfo.is_alarm)
                 {
                     log_info("vehicle_alarm_real_end_timeout_exec %s",vvid.c_str());
-                    event_tool::instance()->handle_event(OT_CARD,ET_VEHICLE_REAR_END,id,CYaSetting::m_sys_setting.rear_end_d,dis,true,vvid);
+                    event_tool::instance()->handle_event(OT_CARD,ET_VEHICLE_REAR_END,id,CYaSetting::m_sys_setting.rear_end_d,dis,true,DT_COMMON,vvid);
                     vinfo.is_alarm = true;
                 }
             }

+ 0 - 5
module_service/area_business_car_attendance.h

@@ -11,11 +11,6 @@ class area_business_car_attendance:public area_business
 public:
     area_business_car_attendance();
 
-    virtual int area_business_type()
-    {
-        return 6;
-    }
-
     void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 
     //记录进入时间等信息,结束考勤,根据离开的时间和距离,判断是否记录一条新的考勤记录

+ 0 - 5
module_service/area_business_card_enter_or_leave.h

@@ -5,11 +5,6 @@
 
 struct area_business_card_enter_or_leave:area_business
 {
-	int area_business_type()
-	{
-		return 9;
-	}
-
     void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 
 	//进入区域则入库操作

+ 103 - 59
module_service/area_business_count_checker.cpp

@@ -11,32 +11,38 @@
 	整个井下的超员和某个区域的超员都使用这个代码
 */
 
+static void check_event(bool &event_flag,EVENT_TYPE et,EVENT_DIS_TYPE edt,int id)
+{
+    if(!event_flag)
+    {
+        auto ev_p = event_list::instance()->get_event_area(id,et,edt);
+        if (ev_p && !ev_p->is_end())
+            event_flag = true;
+    }
+}
+
 //服务器重启加载数据
 void area_business_count_checker::on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr)
 {
     if (nullptr == a->m_area )
         return ;
-    if (c->is_person() && !a->m_area->m_event_person_count)
+    if (c->is_person())
     {
         EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
-        auto ev_ptr_temp = event_list::instance()->get_event_area(a->m_area->id(),ev);
-        if (ev_ptr_temp && !ev_ptr_temp->is_end())
-            a->m_area->m_event_person_count = true;
-
+        check_event(a->m_area->m_event_person_count,ev,DT_NORMAL,a->m_area->id());
+        check_event(a->m_area->m_event_person_show_count,ev,DT_SPECIAL,a->m_area->id());
     }
-    else if (c->is_vehicle() && !a->m_area->m_event_vehicle_count)
+    else if (c->is_vehicle())
     {
         EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
-        auto ev_ptr_temp = event_list::instance()->get_event_area(a->m_area->id(),ev);
-        if (ev_ptr_temp && !ev_ptr_temp->is_end())
-        {
-            a->m_area->m_event_vehicle_count = true;
-        }
+        check_event(a->m_area->m_event_vehicle_count,ev,DT_NORMAL,a->m_area->id());
+        check_event(a->m_area->m_event_vehicle_show_count,ev,DT_SPECIAL,a->m_area->id());
     }
     on_enter(a,c,ptr);
 }
-
 //增加计数,并进行判断
+//多线程环境有可能同时产生相同的告警。
+//如果多个线程同一时间触发。
 void area_business_count_checker::on_enter(const std::shared_ptr<area_hover>&a,
                                            const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr)
 {
@@ -44,33 +50,61 @@ 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 aid=a->m_area->id();
+        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;
+        }
 		a->m_area->m_person_count ++ ;
+        if(c->m_display)
+		    a->m_area->m_person_show_count ++ ;
         int pc=a->m_area->m_person_count.load();
-		if (!a->m_area->m_event_person_count && pc > a->m_area->m_limit_person_count)
-		{
-			a->m_area->m_event_person_count = true;
-			EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
-			event_tool::instance()->handle_event(OT_AREA,ev,a->m_area->id(),a->m_area->m_limit_person_count,pc,true);
-			log_info("area_business_count_checker::on_enter : Event OVER_COUNT=%d AreaId=%d,Limit=%d,CurNum=%d"
-					,ev,a->m_area->id(),a->m_area->m_limit_person_count,pc);
-		}
+        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(pc>limit_val){
+            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_enter:%d,v_count:%d limit:%d",aid,pc,limit_val);
+        }
+        if(pc_>limit_val){
+            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_enter_show:%d,v_count:%d limit:%d",aid,pc_,limit_val);
+        }
 	}
 	else if (c->is_vehicle())
 	{
+        int limit_val=a->m_area->m_limit_vehicle_count;
+        int aid=a->m_area->id();
+        if(limit_val<=0)
+        {
+            log_warn("on_enter_area_id:%d,limit_vehicle_count is 0.so should not run area_business_count_checker...",aid);
+            return;
+        }
 		a->m_area->m_vehicle_count ++ ;
+        if(c->m_display)
+		    a->m_area->m_vehicle_show_count ++ ;
         int vc=a->m_area->m_vehicle_count.load();
-		log_info("area_id:%d,v_count:%d",a->m_area->m_id,vc);
-		if (vc > a->m_area->m_limit_vehicle_count && !a->m_area->m_event_vehicle_count)
-		{
-			a->m_area->m_event_vehicle_count = true;
-			EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
-			event_tool::instance()->handle_event(OT_AREA,ev,a->m_area->id(),a->m_area->m_limit_vehicle_count,vc,true);
-			log_info("area_business_count_checker::on_enter : Event OVER_COUNT=%d AreaId=%d,Limit=%d,CurNum=%d"
-					,ev,a->m_area->id(),a->m_area->m_limit_vehicle_count,vc);
-		}
+        int vc_=a->m_area->m_vehicle_show_count.load();
+		EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
+        if(vc>limit_val){
+            lock();
+		    event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,vc,a->m_area->m_event_vehicle_count=true,DT_NORMAL);
+            unlock();
+		    log_info("vehicle_count_enter:%d,v_count:%d limit:%d",aid,vc,limit_val);
+        }
+        if(vc_>limit_val){
+            lock();
+		    event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,vc_,a->m_area->m_event_vehicle_show_count=true,DT_SPECIAL);
+            unlock();
+		    log_info("vehicle_count_enter_show:%d,v_count:%d limit:%d",aid,vc_,limit_val);
+        }
 	}
 }
-
 void area_business_count_checker::on_hover(const std::shared_ptr<area_hover>&a,
                                            const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr)
 {
@@ -81,42 +115,52 @@ void area_business_count_checker::on_leave(const std::shared_ptr<area_hover>&a,
                                            const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr)
 {
 	if (nullptr == a->m_area )
-	{
 		return ;
-	}
-	int limitVal = 0;
-	int curVal = 0;
-	bool tmp_event = false;
-	EVENT_TYPE ev = EVENT_TYPE::ET_OVER_COUNT_PERSON;
 	if (c->is_person())
 	{
 		a->m_area->m_person_count -- ;
-		limitVal = a->m_area->m_limit_person_count;
-		curVal = a->m_area->m_person_count.load();
-		tmp_event = a->m_area->m_event_person_count;
-		ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_PERSON : EVENT_TYPE::ET_AREA_OVER_COUNT_PERSON ;
-		if(tmp_event && curVal <= limitVal)
-		{
-			a->m_area->m_event_person_count = false;
-			log_info("area_business_count_checker::on_leave :Cancel Event OVER_COUNT=%d AreaId=%d,Limit=%d,CurNum=%d"
-					,ev,a->m_area->id(),limitVal,curVal);
-			event_tool::instance()->handle_event(OT_AREA,ev,a->m_area->id(),limitVal,curVal,false);
-		}
+        if(c->m_display)
+		    a->m_area->m_person_show_count -- ;
+        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 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){
+            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_leave:%d,v_count:%d limit:%d",aid,pc,limit_val);
+        }
+		if(a->m_area->m_event_person_show_count&& pc_ <= limit_val){
+            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_leave_show:%d,v_count:%d limit:%d",aid,pc,limit_val);
+        }
 	}
 	else if (c->is_vehicle())
 	{
-		a->m_area->m_vehicle_count -- ;
-		limitVal = a->m_area->m_limit_vehicle_count;
-		curVal = a->m_area->m_vehicle_count.load();
-		tmp_event = a->m_area->m_event_vehicle_count;
-		ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
-		if(tmp_event && curVal <= limitVal)
-		{
-			a->m_area->m_event_vehicle_count = false;
-			log_info("area_business_count_checker::on_leave :Cancel Event OVER_COUNT=%d AreaId=%d,Limit=%d,CurNum=%d"
-					,ev,a->m_area->id(),limitVal,curVal);
-			event_tool::instance()->handle_event(OT_AREA,ev,a->m_area->id(),limitVal,curVal,false);
-		}
+        a->m_area->m_vehicle_count -- ;
+        if(c->m_display)
+		    a->m_area->m_vehicle_show_count -- ;
+        int pc=a->m_area->m_vehicle_count.load();
+        int pc_=a->m_area->m_vehicle_show_count.load();
+        int limit_val=a->m_area->m_limit_vehicle_count;
+        int aid=a->m_area->id();
+		EVENT_TYPE ev = a->m_area->is_mine()?EVENT_TYPE::ET_OVER_COUNT_VEHICLE : EVENT_TYPE::ET_AREA_OVER_COUNT_VEHICLE ;
+		if(a->m_area->m_event_vehicle_count&& pc <= limit_val){
+            lock();
+			event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc,a->m_area->m_event_vehicle_count=false,DT_NORMAL);
+            unlock();
+		    log_info("vehicle_count_leave:%d,v_count:%d limit:%d",aid,pc,limit_val);
+        }
+		if(a->m_area->m_event_vehicle_show_count&& pc_ <= limit_val){
+            lock();
+			event_tool::instance()->handle_event(OT_AREA,ev,aid,limit_val,pc_,a->m_area->m_event_vehicle_show_count=false,DT_SPECIAL);
+            unlock();
+		    log_info("vehicle_count_leave_show:%d,v_count:%d limit:%d",aid,pc,limit_val);
+        }
 	}
 }
 

+ 20 - 6
module_service/area_business_count_checker.h

@@ -2,6 +2,7 @@
 #define _area_business_count_checker_hpp_
 
 #include "area_business.h"
+#include "atomic"
 
 /*
 	判断当前区域a中的人数是否超过设定人数,超过后告警
@@ -10,12 +11,10 @@
 */
 struct area_business_count_checker:area_business
 {
-
-	int area_business_type()
-	{
-		return 3;
-	
-	}
+    area_business_count_checker()
+    {
+        m_mutex=0;
+    }
 	//服务器重启加载数据
 	void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 	//增加计数,并进行判断
@@ -23,6 +22,21 @@ struct area_business_count_checker:area_business
 	void on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr);
 	//减少计数
 	void on_leave(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr);
+private:
+	std::atomic<int> m_mutex;
+	void lock()
+	{
+		int expected=0;
+		while(!m_mutex.compare_exchange_strong(expected,1))
+			expected=0;
+		assert(m_mutex.load()==1);
+	}
+
+	void unlock()
+	{
+		m_mutex.store(0);
+	}
+
 };
 
 

+ 0 - 4
module_service/area_business_forbid.h

@@ -6,10 +6,6 @@
 class area_business_forbid : public area_business
 {
 public:
-    virtual int area_business_type()
-    {
-        return 7;
-    }
     void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
     //记录进入时间等信息,生成告警
     void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);

+ 5 - 8
module_service/area_business_geofault.cpp

@@ -58,7 +58,7 @@ void area_business_geofault::on_enter(const std::shared_ptr<area_hover>&area_hov
         ptr_temp->m_far_geofault_count++;
     }
 
-    auto ev_ptr_temp = event_list::instance()->get_event_card(card_ptr->m_id, card_ptr->m_type, ET_VEHICLE_NEAR_GEOFAULT);
+    auto ev_ptr_temp = event_list::instance()->get_event_card(card_ptr->m_id, card_ptr->m_type, ET_VEHICLE_NEAR_GEOFAULT,DT_COMMON);
     ptr_temp->m_is_warning = (nullptr != ev_ptr_temp && !ev_ptr_temp->is_end());
 }
 
@@ -95,13 +95,10 @@ void area_business_geofault::on_hover(const std::shared_ptr<area_hover>&area_hov
     {
         ptr_temp->m_near_geofault_count=_geofault_count_limit;
 
-        if(!ptr_temp->m_is_warning)
-        {
-            ptr_temp->m_is_warning = true;
-            uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id);
-            event_tool::instance()->handle_event(OT_CARD, ET_VEHICLE_NEAR_GEOFAULT, id,
-                                                 CYaSetting::m_sys_setting.geofault_warn_dis, dist, true);
-        }
+        ptr_temp->m_is_warning = true;
+        uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id);
+        event_tool::instance()->handle_event(OT_CARD, ET_VEHICLE_NEAR_GEOFAULT, id,
+                                             CYaSetting::m_sys_setting.geofault_warn_dis, dist, true);
     }
 
     //确定正常

+ 0 - 5
module_service/area_business_geofault.h

@@ -21,11 +21,6 @@ struct area;
 class area_business_geofault:public area_business
 {
 public:
-    int area_business_type()
-    {
-        return 11;
-    }
-
     void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 
     void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);

+ 19 - 9
module_service/area_business_motionless_persion.cpp

@@ -1,5 +1,6 @@
 #include"area_business_motionless_persion.h"
 
+#include<chrono>
 
 #include"common_tool.h"
 #include"log.h"
@@ -10,21 +11,19 @@
 #include"card.h"
 #include"config_file.h"
 
-
 struct motionless_data:business_data
 {
     motionless_data()
-        :m_acc_0count(0)
+        :m_acc_start_time(0)
+        ,m_acc_0count(0)
         ,m_is_warning(false)
     {
-        //        m_acc_0count=0;
-        //        m_acc_start_time=0;
     }
 
     ///;检测到多少次之后定位完全静止
     //   std::atomic<int> m_acc_0count;
-    //    ///检测到多久之后告警
-    //    time_t m_acc_start_time;
+    ///检测到多久之后告警
+    time_t m_acc_start_time;
 
     int m_acc_0count; //连续静止数量
     bool m_is_warning;  //
@@ -34,7 +33,7 @@ void area_business_motionless_persion::init(config_file& config)
 {
     //       sleep_ms = std::stoi(config.get("service.motionless_thread_sleep_ms","5000"));
     _acc_0count_limit = std::stoi(config.get("service.motionless_acc_0count_limit","40"));
-    //        _acc_seconds_limit = std::stoi(config.get("service.motionless_acc_seconds_limit","120"));
+    _acc_seconds_limit = std::stoi(config.get("service.motionless_acc_seconds_limit","120"));
 }
 
 void area_business_motionless_persion::on_load_his(const std::shared_ptr<area_hover>&area_hover_ptr,
@@ -54,7 +53,7 @@ void area_business_motionless_persion::on_enter(const std::shared_ptr<area_hover
     auto ptr_temp = std::make_shared<motionless_data>();
     ptr = ptr_temp;
 
-    auto ev_ptr_temp = event_list::instance()->get_event_card(card_ptr->m_id, card_ptr->m_type, ET_CARD_MOTIONLESS);
+    auto ev_ptr_temp = event_list::instance()->get_event_card(card_ptr->m_id, card_ptr->m_type, ET_CARD_MOTIONLESS,DT_COMMON);
     ptr_temp->m_is_warning = (nullptr != ev_ptr_temp && !ev_ptr_temp->is_end());
 }
 
@@ -81,12 +80,18 @@ void area_business_motionless_persion::on_hover(const std::shared_ptr<area_hover
     else
     {
         ptr_temp->m_acc_0count=0;
+        ptr_temp->m_acc_start_time = 0;
     }
 
     if(ptr_temp->m_acc_0count >= _acc_0count_limit)
     {
         ptr_temp->m_acc_0count = _acc_0count_limit;
-        if(!ptr_temp->m_is_warning)
+        if(ptr_temp->m_acc_start_time == 0)
+        {
+            time(&ptr_temp->m_acc_start_time);
+        }
+        if(!ptr_temp->m_is_warning
+                && tool_time::elapse_seconds(ptr_temp->m_acc_start_time) >= _acc_seconds_limit)
         {
             ptr_temp->m_is_warning = true;
             uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id);
@@ -98,6 +103,9 @@ void area_business_motionless_persion::on_hover(const std::shared_ptr<area_hover
         if(ptr_temp->m_is_warning)
         {
             ptr_temp->m_is_warning = false;
+
+            ptr_temp->m_acc_start_time = 0;
+
             uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id);
             event_tool::instance()->handle_event(OT_CARD, ET_CARD_MOTIONLESS, id, 0, 0, false);
         }
@@ -127,6 +135,8 @@ void area_business_motionless_persion::on_leave(const std::shared_ptr<area_hover
 }
 
 int area_business_motionless_persion::_acc_0count_limit=20;
+int area_business_motionless_persion::_acc_seconds_limit=120;
+
 
 //void module_motionless_persion::deal_alarm(std::shared_ptr<card_location_base>& card_ptr)
 //{

+ 1 - 4
module_service/area_business_motionless_persion.h

@@ -39,12 +39,9 @@ class area_business_motionless_persion : public area_business// : public i_threa
     //    void deal_alarm(std::shared_ptr<card_location_base>& card_ptr);
 private:
     static int _acc_0count_limit;
+    static int _acc_seconds_limit;
 
 public:
-    int area_business_type()
-    {
-        return 10;
-    }
     static void init(config_file& config);
 
     void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);

+ 13 - 99
module_service/area_business_person_attendance.cpp

@@ -47,14 +47,13 @@ void area_business_person_attendance::on_leave(const std::shared_ptr<area_hover>
     if(!mine_tool_ptr->m_is_attendance)
         return;
 
+    log_info("on_leave_person_att:%d",card_ptr->m_id);
     //考勤结束
     mine_tool_ptr->m_is_attendance=false;
 
     //作为一条结束考勤记录保存到数据库
     db_tool::save_attendance(card_ptr, area_hover_ptr);
 
-    auto per = std::dynamic_pointer_cast<person>(card_ptr);
-    per->clear();
 
 
 	YA::_CARD_POS_ cp;
@@ -76,6 +75,8 @@ void area_business_person_attendance::on_leave(const std::shared_ptr<area_hover>
         swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
     }
     
+    auto per = std::dynamic_pointer_cast<person>(card_ptr);
+    per->clear();
 }
 
 /**
@@ -90,66 +91,30 @@ void area_business_person_attendance::handle_up_mine(sio::message::ptr const& da
         return;
     }
 
-//    rapidjson::Document doc(rapidjson::kObjectType);
-//    rapidjson::Value datas(rapidjson::kArrayType);
-//    rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();
-
     std::vector<sio::message::ptr>::const_iterator it_card = card_vec.begin();
     int type = 0;
     std::string s_card_id;
     for(; it_card != card_vec.end(); ++it_card)
     {
         if(!tool_map::try_get_value(s_card_id, JSON_KEY_CALL_CARD_CARD_ID, (*it_card))
-                ||!tool_map::try_get_value(type, JSON_KEY_CALL_CARD_CARD_TYPE_ID, (*it_card)))
+            ||!tool_map::try_get_value(type, JSON_KEY_CALL_CARD_CARD_TYPE_ID, (*it_card))
+            )
         {
             log_error("手工升井,web发来的数据 card_id 或 card_type格式不对");
             continue;
         }
-
-        uint32_t id = tool_other::id64_to_id(s_card_id);
-        auto card_ptr = card_list::instance()->get(tool_other::type_id_to_u64(type, id));
-        if(card_ptr && card_ptr->is_person())
+        log_info("handle_up_card:%s,接收到手动升井的请求",s_card_id.c_str());
+        if(!tool_other::is_person(type))
+            continue;
+        auto card_ptr = card_list::instance()->get(tool_other::card_id_to_u64(s_card_id));
+        if(card_ptr && STATUS_LOST == card_ptr->m_biz_stat)
         {
-            std_debug("手工升井,处理,卡id=%d,卡type=%d", id, type);
-            log_info("手工升井,处理,卡id=%d,卡type=%d", id, type);
-
-            module_meta_date_changed::clear_card(card_ptr);
-            //            auto rea_tool = card_ptr->get_area_tool();
-            //            rea_tool->on_leave(card_ptr);
-            //card_ptr->clear();
-
-            //            auto mine_tool_ptr = card_ptr->get_mine_tool();
-            //            if(mine_tool_ptr->m_is_attendance)
-            //            {
-            //                //考勤结束
-            //                mine_tool_ptr->m_is_attendance=false;
-
-            //                //作为一条结束考勤记录保存到数据库
-            //                db_tool::save_attendance(card_ptr);
-            //            }
-
-            //检查井下是否超员--是否需要取消
-            //CMineCardManager::instance()->OnPersonUp(card_ptr);
-
-            //            auto rea_tool = card_ptr->get_area_tool();
-            //			rea_tool->on_leave(card_ptr);
-            //			card_ptr->clear();
+            log_info("handle_up_card:%s 手工升井,处理",s_card_id.c_str());
+            card_ptr->inc_upmine_flag();
         }
         else
-        {
-            log_error("手工升井,在全局列表中找不到卡,卡id=%d,卡type=%d", id, type);
-        }
+            log_warn("handle_up_card:%s,手动升井的卡找不到,或者该卡不在盲区",s_card_id.c_str());
     }
-
-//    //升井json发给web
-//    if(datas.Size() > 0)
-//    {
-//        doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_UP_MINE, allocator);
-//        //doc.AddMember(JSON_ROOT_KEY_VERSION,INTERFACE_VERSION, allocator);
-//        doc.AddMember(JSON_ROOT_KEY_DATA, datas, allocator);
-
-//        swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
-//    }
 }
 
 ///升井json
@@ -205,54 +170,3 @@ void area_business_person_attendance::_to_json_card_up_one(std::shared_ptr<card_
     out_datas.PushBack(data, allocator);
 }
 
-
-/////升井或收到web的删除卡命令  site_ptr==nullptr表示收到web的删除卡命令
-///// 保存考勤记录,发升井json,清理卡
-//void area_business_person_attendance::up_mine(std::shared_ptr<card_location_base> card_ptr, bool is_web_delete)
-//{
-//    auto mine_tool_ptr = card_ptr->get_mine_tool();
-//    if(!mine_tool_ptr->m_is_attendance)
-//    {
-//        return;
-//    }
-
-//    //考勤结束
-//    mine_tool_ptr->m_is_attendance=false;
-
-//    //作为一条结束考勤记录保存到数据库
-//    db_tool::save_attendance(card_ptr);
-
-//    rapidjson::Document doc(rapidjson::kObjectType);
-//    rapidjson::Value datas(rapidjson::kArrayType);
-//    rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();
-
-//    _to_json_card_up_one(card_ptr, datas, allocator);
-//    //module_meta_date_changed::clear_card(card_ptr);
-
-//    auto rea_tool = card_ptr->get_area_tool();
-//    rea_tool->on_leave(card_ptr);
-//    card_ptr->clear();
-
-//    //升井json发给web
-//    if(datas.Size() > 0)
-//    {
-//        doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_UP_MINE, allocator);
-//        //doc.AddMember(JSON_ROOT_KEY_VERSION,INTERFACE_VERSION, allocator);
-//        doc.AddMember(JSON_ROOT_KEY_DATA, datas, allocator);
-
-//        swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
-//    }
-
-////    if(is_web_delete)
-////    {
-////        log_info("人卡考勤结束:卡id=%d,卡type=%d,分站id=%d,分站reader_type_id=%d,stat_attendance=%d",
-////                 card_ptr->m_id, card_ptr->m_type,
-////                 site_ptr->m_id,site_ptr->m_reader_type_id,mine_tool_ptr->m_is_attendance);
-////    }
-////    else
-////    {
-////        log_info("收到web的删除卡命令,人卡考勤结束:卡id=%d,卡type=%d, stat_attendance=%d",
-////                 card_ptr->m_id, card_ptr->m_type, mine_tool_ptr->m_is_attendance);
-////    }
-//}
-

+ 0 - 6
module_service/area_business_person_attendance.h

@@ -9,12 +9,6 @@
 
 struct area_business_person_attendance:area_business
 {
-    int area_business_type()
-    {
-        return 5;
-    }
-
-
     //记录进入时间等信息,开始考勤
     void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 

+ 13 - 6
module_service/area_business_person_dwell_checker.cpp

@@ -12,7 +12,7 @@ void area_business_person_dwell_checker::on_load_his(const std::shared_ptr<area_
     if(!c->is_person())
       return;
     EVENT_TYPE evType = a->m_area->is_mine() ? EVENT_TYPE::ET_CARD_OVER_TIME_PERSON : EVENT_TYPE::ET_CARD_AREA_OVER_TIME_PERSON;
-    auto ev_ptr_temp = event_list::instance()->get_event_card(c->m_id,c->m_type,evType);
+    auto ev_ptr_temp = event_list::instance()->get_event_card(c->m_id,c->m_type,evType,DT_COMMON);
     if (ev_ptr_temp && !ev_ptr_temp->is_end())
         c->set_event_flag(evType);
 }
@@ -22,19 +22,25 @@ void area_business_person_dwell_checker::on_enter(const std::shared_ptr<area_hov
 							const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr)
 {
     log_info("area_business_person_dwell_checker::on_enter : In Area=%d Card = %d  ",a->m_area->id(),c->m_id);
+
+	if( a->m_area->m_limit_person_min == 0 )
+	{
+		log_warn("区域area_id=%d超时值设置为0,不会检查超时。",a->m_area->m_id);
+	}
 }
 
 //判断是否超时
 void area_business_person_dwell_checker::on_hover(const std::shared_ptr<area_hover>&a,
 							const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr)
 {
-    if(!c->is_person()||a->m_enter_time==0)
+    if(!c->is_person()||a->m_enter_time==0||a->m_area->m_limit_person_min==0)
       return;
 
-	double limit_val = a->m_area->m_limit_person_second;
-	double cur_val = ( tool_time::now_to_seconds() - a->m_enter_time / 1000);
+	int limit_val = a->m_area->m_limit_person_min*60;
+	int cur_val = ( tool_time::now_to_seconds() - a->m_enter_time / 1000);
+
 	EVENT_TYPE evType = a->m_area->is_mine() ? EVENT_TYPE::ET_CARD_OVER_TIME_PERSON : EVENT_TYPE::ET_CARD_AREA_OVER_TIME_PERSON;
-	if (!c->get_event_flag(evType) && limit_val < cur_val)
+	if (limit_val < cur_val)
     {
         c->set_event_flag(evType);
         uint64_t id = tool_other::type_id_to_u64(c->m_type, c->m_id);
@@ -48,8 +54,9 @@ void area_business_person_dwell_checker::on_hover(const std::shared_ptr<area_hov
 void area_business_person_dwell_checker::on_leave(const std::shared_ptr<area_hover>&a,
 							const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr)
 {
-    if(!c->is_person())
+    if(!c->is_person()||a->m_enter_time==0||a->m_area->m_limit_person_min==0)
       return;
+
     EVENT_TYPE evType = a->m_area->is_mine() ? EVENT_TYPE::ET_CARD_OVER_TIME_PERSON:EVENT_TYPE::ET_CARD_AREA_OVER_TIME_PERSON;
     if(c->get_event_flag(evType))
     {

+ 0 - 4
module_service/area_business_person_dwell_checker.h

@@ -10,10 +10,6 @@
 */
 struct area_business_person_dwell_checker:area_business
 {
-	int area_business_type()
-	{
-		return 2;
-	}
 	//服务器重启加载数据
 	virtual void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 	//进入区域,记录进入时间

+ 1 - 1
module_service/area_business_post_area.cpp

@@ -20,7 +20,7 @@ void area_business_post_area::on_enter(const std::shared_ptr<area_hover>&a,
 void area_business_post_area::on_hover(const std::shared_ptr<area_hover>&a,
 						const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr)
 {
-	c->set_area_info(0,0,a->id(),a->m_enter_time,1);
+	c->set_area_info(a->mapid(),a->scale(),a->id(),a->m_enter_time,1);
 }
 
 //从人员数据中清除区域信息

+ 0 - 4
module_service/area_business_post_area.h

@@ -8,10 +8,6 @@
 */
 struct area_business_post_area:area_business
 {
-	int area_business_type()
-	{
-		return 1;
-	}
 	virtual void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 	//将推送区域信息加入人员数据
 	void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);

+ 1 - 1
module_service/area_business_speed_checker.cpp

@@ -32,7 +32,7 @@ void area_business_speed_checker::on_load_his(const std::shared_ptr<area_hover>&
     on_enter(area_hover_ptr, card_ptr, ptr);
 
     EVENT_TYPE ev_type =area_hover_ptr->m_area->is_mine()?ET_CARD_OVER_SPEED: ET_CARD_AREA_OVER_SPEED;
-    auto ev_ptr_temp = event_list::instance()->get_event_card(card_ptr->m_id, card_ptr->m_type, ev_type);
+    auto ev_ptr_temp = event_list::instance()->get_event_card(card_ptr->m_id, card_ptr->m_type, ev_type,DT_COMMON);
     auto ptr_temp = std::dynamic_pointer_cast<over_speed_data>(ptr);
     ptr_temp->m_is_warning = (ev_ptr_temp && !ev_ptr_temp->is_end());
     if(ptr_temp->m_is_warning)

+ 0 - 5
module_service/area_business_speed_checker.h

@@ -7,11 +7,6 @@
 class area_business_speed_checker : public area_business
 {
 public:
-    virtual int area_business_type()
-    {
-        return 4;
-    }
-
     void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
     void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
     void on_hover(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data> ptr);

+ 0 - 5
module_service/area_business_work_rate.h

@@ -9,11 +9,6 @@
 class area_business_work_rate:public area_business
 {
 public:
-    int area_business_type()
-    {
-        return 12;
-    }
-
     void on_load_his(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);
 
     void on_enter(const std::shared_ptr<area_hover>&a,const std::shared_ptr<card_location_base>&c,std::shared_ptr<business_data>&ptr);

+ 3 - 2
module_service/module_call_help.cpp

@@ -43,7 +43,7 @@ void module_call_help::accept_web_deal_help(sio::message::ptr const& data)
     {
         log_info("处理呼救,card_id=%d, type=%d,  ev_id=%d", id, type, ev_id);
 
-        auto ev_ptr = event_list::instance()->get_event_card(id, type, ET_CARD_HELP);
+        auto ev_ptr = event_list::instance()->get_event_card(id, type, ET_CARD_HELP,DT_COMMON);
         if(ev_ptr && ES_DEAL_HELP != ev_ptr->m_status)
         {
             ev_ptr->m_status = ES_DEAL_HELP;
@@ -70,7 +70,8 @@ std::string module_call_help::get_json_help()
     auto it_ev=tmp.begin();
     for(;it_ev!=tmp.end();++it_ev)
     {
-        if(!it_ev->second->m_is_display || ET_CARD_HELP != it_ev->second->m_ev_type)
+        //if(!it_ev->second->m_is_display || ET_CARD_HELP != it_ev->second->m_ev_type)
+        if(ET_CARD_HELP != it_ev->second->m_ev_type)
         {
             continue;
         }

+ 119 - 123
module_service/module_meta_date_changed.cpp

@@ -10,7 +10,11 @@
 #include"ant.h"
 #include"card.h"
 #include"area.h"
-
+#include "forbid_staff_down_mine.h"
+#include <boost/format.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string.hpp>
 
 ///基础数据
 void module_meta_date_changed::accept(sio::message::ptr const& data)
@@ -22,15 +26,14 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
         return;
     }
 
-    std_debug("基础数据 receive meta_data_changed: %s", name.c_str());
-
-    int64_t id=-1;
-    tool_map::try_get_value(id, JSON_KEY_ID, data);
+    std::string szParam = "0";
+    tool_map::try_get_value(szParam,JSON_KEY_ID,data);
 
     std::string op_type="";
     tool_map::try_get_value(op_type, JSON_KEY_OP_TYPE, data);
 
-    if(-1 != id && !op_type.empty())
+    log_info("web发来数据:JSON_CMD_VALUE_META_DATA_CHANGED,%s---%s",szParam.c_str(),op_type.c_str());
+    if(!szParam.empty() && !op_type.empty())
     {
         EDIT_TYPE_ID edit_type_id;
         if(!try_get_edit_type_id(op_type, edit_type_id))
@@ -38,47 +41,59 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
             log_error("web发来的数据: 基础数据op_type字段错误:op_type=%s", op_type.c_str());
             return;
         }
+		log_info("基础数据 receive meta_data_changed: %s, id=%s, op_type=%d"
+		        , name.c_str(), szParam.c_str() , edit_type_id);
 
         if(JSON_KEY_NAME_VEHICLE == name || JSON_KEY_NAME_VEHICLE_EXTEND == name)
         {
-            deal_call_edit_vehicle(id, edit_type_id);
+            deal_call_edit_vehicle_or_staff(szParam, edit_type_id);
         }
         else if(JSON_KEY_NAME_STAFF == name || JSON_KEY_NAME_STAFF_EXTEND == name)
         {
-            deal_call_edit_staff(id, edit_type_id);
+            deal_call_edit_vehicle_or_staff(szParam, edit_type_id);
         }
         else if(JSON_KEY_NAME_CARD == name)
         {
-            deal_call_edit_card(id, edit_type_id);
+            deal_call_edit_card(szParam, edit_type_id);
         }
         else if(JSON_KEY_NAME_AREA == name)
         {
-            deal_call_edit_area(id, edit_type_id);
+            deal_call_edit_area(szParam, edit_type_id);
         }
         else if(JSON_KEY_NAME_READER == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_reader(id, edit_type_id);
         }
         else if ("antenna" == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_antenna(id,edit_type_id);
         }
         else if(JSON_KEY_NAME_PATH == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_path(id, edit_type_id);
         }
         else if(JSON_KEY_NAME_MAP == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_map(id, edit_type_id);
         }
         else if (JSON_KEY_NAME_LIGHT == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_light(id,edit_type_id);///待实现
         }
         else if ("lights_group" == name)
         {
+            int id = std::stoi(szParam);
             deal_call_edit_lights_group(id,edit_type_id);///待实现
         }
+        else if (JSON_KEY_NAME_FORBID_PERSON_DOWN_MINE == name)
+        {
+            deal_call_edit_forbid_person_down_mine(szParam,edit_type_id);
+        }
         else
         {
             log_error("web发来的数据: 基础数据name字段错误:name=%s", name.c_str());
@@ -100,79 +115,65 @@ void module_meta_date_changed::accept(sio::message::ptr const& data)
 
 ///3.清除卡相关信息,区域相关,分站相关,考勤相关,清除定时器,
 ///速度,状态 呼救 呼叫 告警相关。即保留基础信息,其他的重置。
-void module_meta_date_changed::clear_card(std::shared_ptr<card_location_base> card_ptr)
+void module_meta_date_changed::clear_card(const std::shared_ptr<card_location_base>& card_ptr)
 {
-    auto rea_tool = card_ptr->get_area_tool();
-    rea_tool->on_leave(card_ptr);
-    //card_ptr->clear();
-
-    //    //删除
-    //    //card_ptr->del_card_pos();
-    // 升井 删除所有报警信息
-    for(int i=0; i < CARD_EVENT_COUNT_MAX; i++ )
-    {
-        if (i == EVENT_TYPE::ET_CARD_LOW_POWER_SERIOUS)
-        {
-            continue;
-        }
-
-        uint64_t id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id);
-        event_tool::instance()->handle_event(OT_CARD, static_cast<EVENT_TYPE>(i), id, 0, 0, false);
-
-        //        auto ev_ptr = event_list::instance()->get_event_card(
-        //                card_ptr->m_id, card_ptr->m_type, static_cast<EVENT_TYPE>(i));
-        //        if(ev_ptr && !ev_ptr->is_end()) //
-        //        {
-        //            event_list::copy_event(card_ptr, ev_ptr);
-
-        //            ev_ptr->m_status = ES_END;
-
-        //            event_list::save_event(ev_ptr);
-        //        }
-    }
+    card_ptr->get_area_tool()->on_leave(card_ptr);
 }
-
-
-void module_meta_date_changed::deal_call_edit_vehicle(int64_t id64, EDIT_TYPE_ID edit_type_id)
+/*
+ * 修改车及卡的数据
+ * id64 = ;员工ID或者车ID;卡ID=101;0010000001198  分号间隔
+ */
+void module_meta_date_changed::deal_call_edit_vehicle_or_staff(const std::string & id64, EDIT_TYPE_ID edit_type_id)
 {
-    if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
+    std::vector<std::string> vecSegTag;
+    boost::split(vecSegTag, id64, boost::is_any_of(";"));
+    if (vecSegTag.size() == 1)  //数据发生错误
     {
-        card_list::instance()->init_vehicle(id64);
-    }
-    else if(ET_DELETE == edit_type_id)
-    {
-        auto str = tool_other::to13str(id64);
-
-        remove_card(tool_other::id64_to_id(str), tool_other::id64_to_type(str));
+        log_errno("Web Send Data Error!(%s)", id64.c_str());
+        return;
     }
-}
-
-void module_meta_date_changed::deal_call_edit_staff(int64_t id64, EDIT_TYPE_ID edit_type_id)
-{
+    std::string lsz_card_id = vecSegTag[1];
+    int cid = std::stoi(vecSegTag[0].c_str());
     if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
     {
-        card_list::instance()->init_staffer(id64);
+        if (ET_UPDATE == edit_type_id)
+        {
+            auto c = card_list::instance()->get_card_by_cid(cid);
+            if (nullptr != c && tool_other::type_id_to_str(c->m_type,c->m_id) != lsz_card_id)
+            {
+                //如果修改了卡号,则删除原来的卡的数据
+                remove_card(c);
+            }
+        }
+        int c_type = tool_other::id64_to_type(lsz_card_id);
+        if (tool_other::is_vehicle(c_type))
+        {
+            card_list::instance()->init_vehicle(lsz_card_id);
+        }
+        else if (tool_other::is_person(c_type))
+        {
+            card_list::instance()->init_staffer(lsz_card_id);
+        }
     }
-    else if(ET_DELETE == edit_type_id)
+    else
     {
-        auto str = tool_other::to13str(id64);
-
-        remove_card(tool_other::id64_to_id(str), tool_other::id64_to_type(str));
+        remove_card(tool_other::id64_to_id(lsz_card_id), tool_other::id64_to_type(lsz_card_id));
     }
 }
 
-void module_meta_date_changed::deal_call_edit_card(int64_t id64, EDIT_TYPE_ID edit_type_id)
+void module_meta_date_changed::deal_call_edit_card(std::string & id64, EDIT_TYPE_ID edit_type_id)
 {
-    std::string card_id64_str = tool_other::to13str(static_cast<uint64_t>(id64));
+    std::string card_id64_str = tool_other::to13str(id64);
     int type = tool_other::id64_to_type(card_id64_str);
-
-    if(tool_other::is_person(type))
-    {
-        deal_call_edit_staff(id64, edit_type_id);
-    }
-    else if(tool_other::is_vehicle(type))
+    if(tool_other::is_person(type) || tool_other::is_vehicle(type))
     {
-        deal_call_edit_vehicle(id64, edit_type_id);
+        auto c = card_list::instance()->get(tool_other::card_id_to_u64(card_id64_str));
+        if (nullptr == c) {
+            log_info("web edit card:%s Not bind staff or vehicle. editType:%d", card_id64_str.c_str(), edit_type_id);
+            return ;
+        }
+        std::string lsz = std::to_string(c->m_cid) + ";" + card_id64_str;
+        deal_call_edit_vehicle_or_staff(lsz,edit_type_id);
     }
     else
     {
@@ -180,30 +181,21 @@ void module_meta_date_changed::deal_call_edit_card(int64_t id64, EDIT_TYPE_ID ed
     }
 }
 
-void module_meta_date_changed::deal_call_edit_area(int id, EDIT_TYPE_ID edit_type_id)
+void module_meta_date_changed::deal_call_edit_area(const std::string& id, EDIT_TYPE_ID edit_type_id)
 {
+    int aid=std::stoi(id);
     if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
     {
-        if(is_monkeycar_area(id))
-        {
-            area_list::instance()->init_monkeycar_area(id);
-        }
-        else
-        {
-            area_list::instance()->init_from_db(id);
-        }
+        area_list::instance()->init_from_db(aid);
     }
     else if(ET_DELETE == edit_type_id)
     {
-        auto area_ptr = area_list::instance()->get(id);
-        if(!area_ptr)
+        if(auto area_ptr = area_list::instance()->get(aid))
         {
-            log_info("区域已经删除:areaid=%d", id);
-            return;
+            log_info("区域删除:areaid=%d", aid);
+            area_ptr->clear();
+            area_list::instance()->remove(aid);
         }
-        //删除告警
-        delete_area_event(area_ptr);
-        area_list::instance()->remove(id);
     }
 }
 
@@ -215,8 +207,6 @@ void module_meta_date_changed::deal_call_edit_reader(int id, EDIT_TYPE_ID edit_t
     }
     else if(ET_DELETE == edit_type_id)
     {
-        //删除告警
-
         sit_list::instance()->remove(id);
     }
 }
@@ -246,14 +236,7 @@ void module_meta_date_changed::deal_call_edit_path(int id, EDIT_TYPE_ID edit_typ
     }
     else if(ET_DELETE == edit_type_id)
     {
-        auto sit_ptr = sit_list::instance()->get(id);
-        if(sit_ptr)
-        {
-            sit_ptr->clear_path();
-        }
-
-        log_info("path删除成功,分站id=%d", id);
-        std_debug("path删除成功,分站id=%d", id);
+        sit_list::instance()->read_ant_path(id);
     }
 }
 
@@ -299,21 +282,50 @@ void module_meta_date_changed::deal_call_edit_lights_group(int id, EDIT_TYPE_ID
     }
 }
 
+// 禁止指定人员下井 id = (rt_person_forbid_down_mine)数据库中自增长ID
+void module_meta_date_changed::deal_call_edit_forbid_person_down_mine(const std::string & lszId,EDIT_TYPE_ID edit_type_id)
+{
+    std::vector<std::string> vecSegTag;
+    boost::split(vecSegTag, lszId, boost::is_any_of(";"));
+    if (vecSegTag.size() == 1)  //数据发生错误
+    {
+        log_errno("Web Send Data Error!(%s)", lszId.c_str());
+        return;
+    }
+    int db_id = std::stoi(vecSegTag[0].c_str());
+    int staff_id = std::stoi(vecSegTag[1].c_str());
+
+    if(ET_INSERT == edit_type_id || ET_UPDATE == edit_type_id)
+    {
+        forbid_staff_down_mine::instance()->init_forbid_staff(db_id,edit_type_id);
+    }
+    else if(ET_DELETE == edit_type_id)
+    {
+        forbid_staff_down_mine::instance()->del_forbid_data(db_id,staff_id);
+    }
+}
+
 void module_meta_date_changed::init_setting()
 {
     //pRes = getMysqlRes("select setting_id, name, type, value from dat_setting;");
 }
 
-void module_meta_date_changed::remove_card(uint32_t id, int32_t type)
-{
+void module_meta_date_changed::remove_card(uint32_t id, int32_t type) {
     uint64_t card_id = tool_other::type_id_to_u64(type, id);
     auto card_ptr = card_list::instance()->get(card_id);
-    if(!card_ptr)
-    {
+    if (!card_ptr) {
         log_error("基础数据, 在全局列表中删除卡,全局列表中已经不存在此卡, id=%d, type=%d", id, type);
         return;
     }
-
+    remove_card(card_ptr);
+}
+void module_meta_date_changed::remove_card(std::shared_ptr<card_location_base> card_ptr)
+{
+    if (!card_ptr)
+    {
+        return;
+    }
+    log_info("基础数据, 在全局列表中删除卡成功, id=%d, type=%d",card_ptr->m_type, card_ptr->m_id);
     //    auto area_hover_ptr = card_ptr->get_area_hover();
     //    if(area_hover_ptr && 0!=area_hover_ptr->id() && 0!=area_hover_ptr->mapid())
     //    {
@@ -330,11 +342,10 @@ void module_meta_date_changed::remove_card(uint32_t id, int32_t type)
 
     //        module_meta_date_changed::clear_card(card_ptr);
     //    }
-
     module_meta_date_changed::clear_card(card_ptr);
     // 避免状态重置
+    uint64_t card_id = tool_other::type_id_to_u64(card_ptr->m_type, card_ptr->m_id);
     card_list::instance()->remove(card_id);
-    log_info("基础数据, 在全局列表中删除卡成功, id=%d, type=%d", id, type);
 }
 
 bool module_meta_date_changed::try_get_edit_type_id(const std::string& op_type, EDIT_TYPE_ID& out_edit_type_id)
@@ -359,29 +370,14 @@ bool module_meta_date_changed::try_get_edit_type_id(const std::string& op_type,
     return true;
 }
 
-bool module_meta_date_changed::is_monkeycar_area(int area_id)
-{
-    char sql[1024] = {'\0'};
-    sprintf(sql,"select monkeycar_areaid from dat_monkeycar_base_info where monkeycar_areaid=%d;", area_id);
-    std::string Error;
-    YADB::CDBResultSet DBRes;
-    sDBConnPool.Query(sql,DBRes,Error);
-    int64_t nCount = DBRes.GetRecordCount( Error );
-
-    log_info("monkeycar_area区域查询:nCount=%d,sql=%s", nCount, sql);
-    std_debug("monkeycar_area区域查询:nCount=%d,sql=%s", nCount, sql);
-
-    return  (nCount > 0);
-}
-
 ///删除区域所有报警信息
-void module_meta_date_changed::delete_area_event(std::shared_ptr<area> area_ptr)
-{
-    for(int i=0; i < CARD_EVENT_COUNT_MAX; i++ )
-    {
-        event_tool::instance()->handle_event(OT_AREA, static_cast<EVENT_TYPE>(i), area_ptr->id(), 0, 0, false);
-    }
-}
+//void module_meta_date_changed::delete_area_event(std::shared_ptr<area> area_ptr)
+//{
+//    for(int i=0; i < CARD_EVENT_COUNT_MAX; i++ )
+//    {
+//        event_tool::instance()->handle_event(OT_AREA, static_cast<EVENT_TYPE>(i), area_ptr->id(), 0, 0, false);
+//    }
+//}
 
 void module_meta_date_changed::delete_antenna(int id)
 {

+ 12 - 13
module_service/module_meta_date_changed.h

@@ -40,17 +40,17 @@ public:
 
     ///3.清除卡相关信息,区域相关,分站相关,考勤相关,清除定时器,
     ///速度,状态 呼救 呼叫 告警相关。即保留基础信息,其他的重置。
-    static void clear_card(std::shared_ptr<card_location_base> card_ptr);
+    static void clear_card(const std::shared_ptr<card_location_base> &card_ptr);
 
 private:
-    ///id64格式为:10000001016
-    void deal_call_edit_vehicle(int64_t id64, EDIT_TYPE_ID edit_type_id);
-
-    ///id64格式为:10000001016
-    void deal_call_edit_staff(int64_t id64, EDIT_TYPE_ID edit_type_id);
+    /*
+     * 修改车及卡的数据
+     * id64 = ;员工ID或者车ID;卡ID=101;0010000001198  分号间隔
+     */
+    void deal_call_edit_vehicle_or_staff(const std::string & id64, EDIT_TYPE_ID edit_type_id);
 
     ///id64格式为10000006666
-    void deal_call_edit_card(int64_t id64, EDIT_TYPE_ID edit_type_id);
+    void deal_call_edit_card(std::string & id64, EDIT_TYPE_ID edit_type_id);
 
     void deal_call_edit_reader(int id, EDIT_TYPE_ID edit_type_id);
 
@@ -59,7 +59,7 @@ private:
 
     void deal_call_edit_antenna(int id,EDIT_TYPE_ID edit_type_id);
 
-    void deal_call_edit_area(int id, EDIT_TYPE_ID edit_type_id);
+    void deal_call_edit_area(const std::string & id, EDIT_TYPE_ID edit_type_id);
 
     void deal_call_edit_map(int id, EDIT_TYPE_ID edit_type_id);
 
@@ -69,18 +69,17 @@ private:
     ///待实现
     void deal_call_edit_lights_group(int id,EDIT_TYPE_ID edit_type_id);
 
+    // 禁止指定人员下井
+    void deal_call_edit_forbid_person_down_mine(const std::string & lszId,EDIT_TYPE_ID edit_type_id);
+
     ///待实现
     void init_setting();
 
     void remove_card(uint32_t id, int32_t type);
+    void remove_card(std::shared_ptr<card_location_base> card_ptr);
 
     bool try_get_edit_type_id(const std::string& op_type, EDIT_TYPE_ID& out_edit_type_id);
 
-    bool is_monkeycar_area(int area_id);
-
-    ///删除区域所有报警信息
-    static void delete_area_event(std::shared_ptr<area> area_ptr);
-
     void delete_antenna(int id);
 
     bool is_cur_map(int id);

+ 1 - 1
module_service/module_web.cpp

@@ -138,7 +138,7 @@ void module_web::_delete_end(std::vector<std::shared_ptr<ya_event>>& arr)
         }
     }
 
-    if(todelete.size())
+    if(!todelete.empty())
     {
         event_list::instance()->remove(todelete);
     }

+ 30 - 8
net-service.cpp

@@ -48,6 +48,7 @@ void net_service::on_timer()
 
 void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t len)
 {
+	bool message_handled=true;
 	try
 	{
 		zistream is(data,len-2);
@@ -56,16 +57,32 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 		switch(cmd)
 		{
 			case CHAR_LOCATEDATA_TOF_EXTEND://tof-扩展
+            case CHAR_LOCATEDATASMALL_TOF_EXTEND:
 				{
 					uint32_t site_id;
 					uint8_t  power;
+
 					is>>site_id>>skip(11)>>power;
 					auto site_ptr = sit_list::instance()->get(static_cast<int32_t>(site_id));
 					if(!site_ptr)
 					{
-						log_error("在全局分站列表中找不到分站:分站id=%d", site_id);
+						logn_error(1,"在全局分站列表中找不到分站:%d", site_id);
+						break;
+					}
+
+					if(!site_ptr->check_timestamp(data+10))
+					{
+						logn_error(1,"分站数据时间戳错误:%s",clt->name().c_str());
 						break;
 					}
+
+					{
+						char timebuf[64];
+						unsigned char*t=(unsigned char*)data+10;
+						sprintf(timebuf,"%d-%d %d:%d:%d",*(t+4)+1,*(t+3),*(t+2),*(t+1),*(t+0));
+						logn_info(1,"分站数据信息:%s net=%s,sid=%d,tm=%s,sct=%d",(power&1)==0?"true":"false",clt->name().c_str(),site_id,timebuf,((*t-2)<<8)|*(t-1));
+					}
+
 					site_ptr->set_client(clt);
 					site_ptr->on_power_status((power&1)==0);
 
@@ -79,15 +96,15 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 						index++;
 						task*t=task::alloc<message_locinfo>();
 						message_locinfo&m=t->body<message_locinfo>();
-						m.load(is,false);
-						m.m_time_stamp=tstamp;
 						m.m_site_id=site_id;
+						m.m_time_stamp=tstamp;
+						m.load(is,false);
 						//t_site->m_site_data = 0;
 
 						t->m_cmd_code=cmd;
 						t->m_hash_id=m.m_card_id;
 						if(m.m_card_type==5)
-							mine_business::inst()->make_reverse_condition(m.m_card_type,m.m_card_id,m.m_ant_id,m.m_card_ct,m.m_tof,m.m_site_id);
+						mine_business::inst()->make_reverse_condition(m.m_card_type,m.m_card_id,m.m_ant_id,m.m_card_ct,m.m_tof,m.m_site_id);
 						m_loc_worker->request(t);
 					}
 				}
@@ -119,17 +136,22 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 				break;
 			case CHAR_LOCATEDATAHIS_TOF_EXTEND://tof his
 			case CHAR_LOCATEDATAHIS_TDOA_EXTEND://tdoa his
-				break;
 			case CHAR_CTRL_READER_CMD://ctrl site message
-				break;
 			case CHAR_ADHOC://自组网数据
-				break;
+			default:
+				message_handled=false;
 		}
+
 	}
 	catch(const std::exception&e)
 	{
-		log_error("parse site message error,will close the connection:%s",clt->name().c_str());
+		logn_error(1,"分站数据处理失败,将关闭分站连接:%s",clt->name().c_str());
 		clt->close();
 	}
+
+	if(!message_handled)
+	{
+		logn_error(1,"分站数据未被处理,site=%s",clt->name().c_str());
+	}
 }
 

+ 8 - 5
select_tool.cpp

@@ -158,7 +158,7 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
        std::array<solpoint,4> res;
        for(int i=0;i<2;i++)
 	   {
-           int x = i==0?3:2;
+           int x = i+2;
 			double d=vp[i].dist(vp[x]);
 			if(d<sit->ant_dist()*3)
 			{
@@ -194,14 +194,17 @@ bool select_point_object::select_solution(const std::vector<point> &vp,const sit
     //
 	//std_info("revise_by_history:::%llu",m_d(0).m_time);
     bool fg=revise_by_history(pt,sit,m_d(0).m_time);
+	if(!fg)
+	{
+		log_warn("out of site path:t=%ld,sit=%d,card_id=%d,ct=%d,tof1=%d,tof2=%d,pt=(%f,%f)\n", m_d(0).m_time, m_d(0).m_sid,m_d(0).m_cid,m_d(0).m_ct, m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
+	
+	}
+
     if(!card_path::inst().is_at_path(pt))
 	{
 		m_d(0).set_cl(0);
 
-		//printf("out of path:t=%ld,sit=%d,ct=%d,"
-		//"tof1=%d,tof2=%d,pt=(%f,%f)\n",
-		//m_d(0).m_time, m_d(0).m_sid,m_d(0).m_ct,
-		//m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
+		log_warn("out of path:t=%ld,sit=%d,card_id=%d,ct=%d,tof1=%d,tof2=%d,pt=(%f,%f)\n", m_d(0).m_time, m_d(0).m_sid,m_d(0).m_cid,m_d(0).m_ct, m_d(0).m_tof[0], m_d(0).m_tof[1], pt.x, pt.y);
 		return false;
 	}
 

+ 4 - 2
select_tool.h

@@ -217,7 +217,9 @@ struct person_point_filter:select_point_object
 		//log_info("lemon test revise preson:cardid:%d sit:%d sitid:%d  %0X",m_d(0).m_cid,sit->m_id,m_d(0).m_sid,sit);
 		point dstp = sit->get_dstp(pt);
 		if(dstp.empty())
-		  log_error("person.dstp empty()");
+		{
+		  log_warn("person.dstp empty,");
+		}
 
 		push_data_point dp;
 		dp.dstp.set(dstp);
@@ -350,7 +352,7 @@ struct car_point_filter:select_point_object
 		//sit_location.set(sit->x,sit->y);
 		sit_location = sit->get_dstp(m_turning_pt);
 		if(sit_location.empty())
-		  std_error("get_dstp point error.....");
+		  std_error("%d get_dstp point error.....",sit->m_id);
 		double dist1=sit_location.dist(rpt);
 		double dist2=sit_location.dist(m_turning_pt);
 		double dist3=m_turning_pt.dist(rpt);	// dist1 is supposed to be = dist2+dist3

+ 159 - 276
test.cpp

@@ -1,351 +1,234 @@
 #include <unistd.h>
 #include <limits.h>
 #include <stdlib.h>
-#include <stdint.h>
 
-#include <clock.h>
-#include <zio.h>
-#include <log.h>
-#include <zloop.h>
+#include <stdint.h>
 
-#include "base64.h"
-#include "io_buf.h"
+#include <sstream>
+#include <vector>
+#include <line.h>
 
-struct web_client_http:ev::io
+#define log_error printf
+#define log_info printf
+struct path
 {
-	in_buff m_buff;
-	int m_data_len=-1;
-	int m_mask_pos=-1;
-	int m_data_pos=-1;
-	int m_fd,m_status;
-
-	web_client_http()
-		:m_buff(8192)
-	{
-		m_fd=-1;
-	}
-
-	int connect_tcp(const char*ip,int port)
-	{
-		int fd=zio::build_stream();
-		if(zio::connect(fd,ip,port))
-		{
-			zio::close(fd);
-			return m_fd=-1;
-		}
-
-		zio::setiobuf(fd,16<<10,16<<10);
-		zio::setblocking(fd,false);
-
-		return m_fd=fd;
-	}
+    std::array<line_v,2>	m_line;
+    path()
+    {
+    }
+
+    std::string to_str() const
+    {
+        std::stringstream ss;
+        for(int i=0;i<2;i++)
+        {
+            ss<<"line:" <<m_line[i].to_string()<<"slope:"<<m_line[i][0].z<< " cos:"<<m_line[i].cos()<<" sin:"<<m_line[i].sin()<<" | ";
+        }
+        return ss.str();
+    }
+    bool vaild() const
+    {
+        return !m_line[0].empty();
+    }
+    line_v & operator[](int i)
+    {
+        return m_line[i];
+    }
+    const line_v & operator[](int i) const
+    {
+        return m_line[i];
+    }
+};
 
-	void ws_reset()
-	{
-		if(m_data_pos+m_data_len>0)
-		{
-			m_buff.free(m_data_len+m_data_pos);
-		}
+struct tant:point
+{
+int m_id;
 
-		m_data_len=-1;
-		m_mask_pos=-1;
-		m_data_pos=-1;
-	}
+void set_path(const std::vector<line_v>&v_line,std::vector<line_v>::const_iterator itm)
+{
+	std::array<path,2> m_path;
 
-	bool ws_fin()const
-	{
-		return (m_buff[0]&0x80) != 0;
-	}
+	auto 
 
-	bool ws_more()const
-	{
-		return (m_buff[0]&0xF) ==0 ;
-	}
+	it=itm;
+	for(int i=0;i<2 && it!=v_line.end();++it,++i)
+		m_path[0][i]=*it;
 
-	bool ws_text()const
+	it=itm-1;
+	for(int i=0;i<2 && it>=v_line.begin();--it,++i)
 	{
-		return (m_buff[0]&0xF) ==1 ;
+		m_path[1][i]=*it;
+		m_path[1][i].swap_point();
 	}
 
-	bool ws_bin()const
+	for(auto&p:m_path)
 	{
-		return (m_buff[0]&0xF) ==2 ;
+		log_info("%s\n",p.to_str().c_str());
 	}
+}
 
-	bool ws_ping()const
+void set_path2(const std::vector<line_v>&v_line_)
+{
+	std::vector<line_v> vl(v_line_);
+	vl.reserve(vl.size()+2);
+	//找到距离天线最近的端点
+	auto min_it=vl.begin();
+	double dist=10;
+	for(auto it=vl.begin();it!=vl.end();it++)
 	{
-		return (m_buff[0]&0xF) ==9 ;
+		double d=it->as_line().dist(*this);
+		if(d<dist)
+		{
+			dist=d;
+			min_it=it;
+		}
 	}
 
-	bool ws_pong()const
+	if(min_it==vl.end())
 	{
-		return (m_buff[0]&0xF) ==10 ;
+		log_error("分站路径距离分站太远site_id=%d",m_id);
+		return;
 	}
 
-	bool ws_close()const
+	if(abs(min_it->v[0].dist(*this)-dist)<1)
 	{
-		return (m_buff[0]&0xF) ==8 ;
+		set_path(vl,min_it);
 	}
-
-	bool ws_mask()const
+	else if(abs(min_it->v[1].dist(*this)-dist)<1)
 	{
-		return (m_buff[1]&0x80) !=0 ;
+		set_path(vl,min_it+1);
 	}
-
-	int parse_length()
+	else
 	{
-		if(m_buff.len_data()<2)
-			return -1;
-
-		if(m_data_pos>0)
-			return 0;
+		point proj=min_it->projection(*this);
+		vl.insert(min_it+1,line_v(proj,min_it->v[1]));
+		min_it->set_point(1,proj);
 
-		if((m_buff[1]&0x7F)<=125)
+		if(min_it->v[0].z)//slope ..555
 		{
-			m_mask_pos=ws_mask()?2:-1;
-			m_data_pos=ws_mask()?6:2;
-
-			m_data_len=m_buff[1]&0x7F;
-		}
-		else
-		if((m_buff[1]&0x7F)==126)
-		{
-			if(m_buff.len_data()<4)
-				return -1;
-
-			m_mask_pos=ws_mask()?4:-1;
-			m_data_pos=ws_mask()?8:4;
-
-			m_data_len=(m_buff[2]<<8) | m_buff[3];
-		}
-		else
-		{
-			if(m_buff.len_data()<9)
-				return -1;
-
-			m_mask_pos=ws_mask()?9:-1;
-			m_data_pos=ws_mask()?13:9;
-
-			//不考虑大于20G的数据
-			m_data_len=(m_buff[6]<<24)|(m_buff[7]<<16)|(m_buff[8]<<8)|(m_buff[9]);
+			double slope=min_it->v[0].z;
+			double len_a=min_it->v[0].dist((min_it+1)->v[1]);
+			double len_0=slope*min_it->length()/len_a;
+			double len_1=slope-len_0;
+			
+			min_it->v[0].z=min_it->v[1].z=len_0;
+			(min_it+1)->v[0].z=(min_it+1)->v[1].z=len_1;
 		}
-		
-		int i=0;
-		for(i=0;i<m_data_len;i++)
-		{
-			uint8_t b=m_buff[m_data_pos+i];
-			if(b>=0x30 && b<=0x39)
-				continue;
-			break;
-		}
-
-		m_data_len-=i;
-		m_data_pos+=i;
 
-		return 0;
+		set_path(vl,min_it+1);
 	}
+}
+};
 
-	void mask(const uint8_t*m,uint8_t*d,int len)
+void print_vl(const std::vector<line_v>&vl)
+{
+	printf("-----------------------------------\n");
+	for(auto&v:vl)
 	{
-		for(int i=0;i<len;i++)
-			d[i]=d[i]^m[i&3];
+		printf("%s\n",v.to_string().c_str());
 	}
 
-	int ws_parse()
-	{
-		if(parse_length()<0)
-			return -1;
-
-		if(m_buff.len_data()<m_data_pos+m_data_len)
-			return -1;
+}
 
-		if(ws_mask())
-		{
-			mask(&m_buff[m_mask_pos],&m_buff[m_data_pos],m_data_len);
-		}
+void set_path(const std::vector<line_v>&v_line,const std::vector<double>&slope)
+{
+	if(v_line.empty())
+		return;
 
-		for(int i=0;i<m_data_len;i++)
+	const auto&find_line=[](const point&pt,int first,std::vector<line_v>&vl){
+		for(auto it=vl.begin();it!=vl.end();it++)
 		{
-			printf("%c",m_buff[m_data_pos+i]);
+			if(it->v[first].dist(pt)<1)
+				return it;
+			if(it->v[first?0:1].dist(pt)<1)
+			{
+				point p=it->v[0];
+				it->v[0]=it->v[1];
+				it->v[1]=p;
+				return it;
+			}
 		}
 
-		printf("\n\n");
+		return vl.end();
+	};
+	
+	//构造一个首尾相连的结构
 
-		return 0;
-	}
+	print_vl(v_line);
+	std::vector<line_v> vl(v_line.begin()+1,v_line.end());
+	std::vector<line_v> target(v_line.begin(),v_line.begin()+1);
 
+	target[0][0].z=target[0][1].z=slope[0];
+	for(int i=0,c=vl.size();i<c;i++)
+		vl[i][0].z=vl[i][1].z=slope[i+1];
 
-	int connect_ws(const char*ip,int port)
+	for(;;)
 	{
-		unsigned char k[16], k6[128];
-
-		for(size_t i=0;i<sizeof(k);i++)
-			k[i]=rand();
-
-		base64::encode(k,sizeof(k),k6);
-
-		const char*fmt=
-			"GET /socket.io/?EIO=3&transport=websocket HTTP/1.1\r\n"
-			"Host: %s:%d\r\n"
-			"Connection: Upgrade\r\n"
-			"Pragma: no-cache\r\n"
-			"Cache-Control: no-cache\r\n"
-			"Upgrade: websocket\r\n"
-			"Origin: http://%s:%d\r\n"
-			"Sec-WebSocket-Version: 13\r\n"
-			"Accept-Encoding: gzip, deflate\r\n"
-			"Accept-Language: zh-CN,zh;q=0.9\r\n"
-			"Sec-WebSocket-Key: %s\r\n"
-			"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n";
-
-		if(connect_tcp(ip,port)<0)	
-			return -1;
-
-		char buf[512];
-		int len=sprintf(buf,fmt,ip,port,ip,port,k6);
-
-		if(len!=zio::writev(m_fd, buf, len))
-		{
-			close();
-			return -1;
-		}
-
-		sleep(1);
-		if(read_until("\r\n\r\n")<=0)
-		{
-			close();
-			return -1;
-		}
-
-		if(m_buff.find("101 Switching Protocols\r\n"))
-		{
-			m_buff.skip(m_buff.find("\r\n\r\n"));
-			return 0;
-		}
+		auto it=find_line(target.back().v[1],0,vl);
+		if(it==vl.end())
+			break;
 
-		close();
-		return -1;
+		target.insert(target.end(),it,it+1);
+		vl.erase(it);
 	}
 
-	int read_until(const char*what,int timeout=10*1000)
+	for(;;)
 	{
-		int rc=0;
-		zclock c;
-		for(;;)
-		{
-			buff_t b=m_buff.alloc();
-			if(b.empty())
-			{
-				m_buff.grow(1024);
-				b=m_buff.alloc();
-			}
-
-			int len=zio::read(m_fd,b.ptr(),b.len());
-
-			if((int)c.count_ms()>timeout)
-			{
-				log_error("websocket read timeout in %dms",timeout);
-				return -1;
-			}
+		auto it=find_line(target.front().v[0],1,vl);
+		if(it==vl.end())
+			break;
 
-			if(len==-1)
-			{
-				return -1;
-			}
+		target.insert(target.begin(),it,it+1);
+		vl.erase(it);
+	}
 
-			if(len==-2)
-				continue;
+	print_vl(target);
 
-			if(len==0)
-			{
-				log_info("remote close the socket");
-				return 0;
-			}
+	tant ta;
 
-			m_buff.commit(len);
-			rc+=len;
+	ta.set(100,100);
+	ta.set_path2(target);
+}
 
-			if(m_buff.find(what))
-				return rc;
-		}
-	}
 
 
-	void close()
-	{
-		zio::close(m_fd);
-	}
+int main()
+{
+{
+	std::vector<line_v> vl;
 
-	~web_client_http()
-	{
-		close();
-	}
-};
+	vl.push_back(line_v(point(-10,0),point(0,0)));
+	vl.push_back(line_v(point(0,0),point(100,100.1)));
 
-int realpath_test()
+	print_vl(vl);
+	set_path(vl,{10,20});
+}
 {
-	char buf[4096];
+	std::vector<line_v> vl;
 
-	realpath(".",buf);
-	log_info("curpath=%s",buf);
+	vl.push_back(line_v(point(200,200),point(100,100.1)));
+	vl.push_back(line_v(point(200,200),point(200,220)));
 
-	return 0;
-}
 
-#if 0
-std::string test_json()
+	set_path(vl,{10,20});
+}
 {
-	struct json
-	{
-		json&put(const char*k,const json&n)
-		{
-		
-			return *this;
-		}
-	
-		json&put(const char*k,int v)
-		{
-		
-			return *this;
-		}
-		json&put(const char*k,const char*v)
-		{
-		
-			return *this;
-		}
+	std::vector<line_v> vl;
 
-		std::string to_string()const
-		{
-			return std::string();
-		}
-	};
+	vl.push_back(line_v(point(-10,0),point(0,0)));
+	vl.push_back(line_v(point(0,0),point(200,200)));
 
-	return json().put("cmd","login")
-				 .put("data",json()
-				 	 .put("uname","wyj")
-					 .put("passwd",111111)
-				  ).to_string();
-}
-#endif
 
-int main()
+	set_path(vl,{10,20});
+}
 {
-	unsigned char buf[32];
-	const char*s64="puVOuWb7rel6z2AVZBKnfw==";
+	std::vector<line_v> vl;
 
-	int blen=32;
-	base64::decode((char*)s64,strlen(s64),buf,blen);
+	vl.push_back(line_v(point(0,0),point(200,200)));
 
-	web_client_http client;
-	client.connect_ws("60.220.238.150",8086);
 
-	for(;;)
-	{
-		while(client.ws_parse()==0)
-			client.ws_reset();
-
-		client.read_until("\n");
-	}
+	set_path(vl,{10});
+}
 
 	return 0;
 }

+ 2 - 2
tool_time.h

@@ -46,7 +46,7 @@ public:
     {
         char _time[25] = {0};
         time_t tt = std::chrono::system_clock::to_time_t(time);
-        struct tm local_time;
+        struct tm local_time={0};
         localtime_r(&tt, &local_time);
         strftime(_time, 22, "%Y-%m-%d %H:%M:%S", &local_time);
 
@@ -64,7 +64,7 @@ public:
     static time_t to_time(const std::string&str)
     {
         time_t t_;
-        tm tm_;
+        tm tm_={0};
         strptime(str.c_str(), "%Y-%m-%d %H:%M:%S", &tm_); //将字符串转换为tm时间
         t_ = mktime(&tm_); //将tm时间转换为秒时间
 

+ 1 - 1
websocket/Makefile.am

@@ -7,7 +7,7 @@ CXXFLAGS=-g
 AM_CPPFLAGS=-Wall -pthread -m64 -std=c++11  -I${prefix}/include -I. -I.. -I./sio
 AM_LDFLAGS =-Wall -pthread -m64 -std=c++11  -L${prefix}/lib  
 
-libwebsocket_a_SOURCES= jsonBuilder.cpp wsClient.cpp wsClientMgr.cpp wsTimerThread.cpp \
+libwebsocket_a_SOURCES= web_connect.cpp jsonBuilder.cpp wsClient.cpp wsClientMgr.cpp wsTimerThread.cpp \
 					 sio/sio_client.cpp sio/sio_socket.cpp  \
 					 sio/internal/sio_client_impl.cpp sio/internal/sio_packet.cpp
 

+ 6 - 2
websocket/constdef.h

@@ -53,7 +53,7 @@
 #define JSON_KEY_NAME "name"
 #define JSON_KEY_NAME_MAP "map"
 #define JSON_KEY_NAME_AREA "area"
-#define JSON_KEY_NAME_PATH "path"
+#define JSON_KEY_NAME_PATH "reader_path_tof_n"
 #define JSON_KEY_NAME_READER "reader"
 #define JSON_KEY_NAME_CARD "card"
 #define JSON_KEY_NAME_STAFF "staff"
@@ -71,6 +71,9 @@
 #define JSON_KEY_NAME_DRIVINGFACE "drivingface_vehicle"
 #define JSON_KEY_NAME_DRIVINGFACE_WARNING_POINT "dat_drivingface_warning_point"
 #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_CALL_CARD_CALL_TYPE "call_type_id"
 #define JSON_KEY_CALL_CARD_CALL_TIME_OUT "call_time_out"
@@ -142,6 +145,7 @@
 #define JSON_KEY_EVENT_TYPE_ID "type_id"
 #define JSON_KEY_EVENT_OBJ_TYPE_ID "obj_type_id"
 #define JSON_KEY_EVENT_OBJ_ID "obj_id"
+#define JSON_KEY_EVENT_DIS_TYPE_ID "dis_type_id"
 #define JSON_KEY_EVENT_MAP_ID "map_id"
 #define JSON_KEY_EVENT_AREA_ID "area_id"
 #define JSON_KEY_EVENT_X "x"
@@ -190,4 +194,4 @@
 #define JSON_CMD_REQ_ALL_PERSON_ON_CAR "req_all_person_on_car"
 #define JSON_CMD_RESP_ALL_PERSON_ON_CAR "resp_all_person_on_car"
 
-#endif // !_SERVER_CONST_DEF_H_
+#endif // !_SERVER_CONST_DEF_H_

+ 4 - 4
websocket/jsonBuilder.cpp

@@ -434,10 +434,10 @@ namespace YA
 		for ( mit_card = CardPosList.begin(); mit_card != CardPosList.end(); mit_card++ )
 		{
 			//不显示的卡不往前端推送
-			if ( !mit_card->second.display )
-			{
-				continue;
-			}
+			//if ( !mit_card->second.display )
+			//{
+			//	continue;
+			//}
 
 			rapidjson::Value DetailItem;
 			if ( !__BuildDetail( mit_card->second, Allocator, DetailItem ) )

+ 104 - 0
websocket/web_connect.cpp

@@ -0,0 +1,104 @@
+#include "web_connect.h"
+
+#include<thread>
+#include<chrono>
+
+#include"log.h"
+#include"wsClientMgr.h"
+#include"wsTimerThread.h"
+
+#define BEATHEART_COUNT_NUM 1000
+
+web_connect::web_connect()
+{
+}
+
+std::atomic<int> web_connect::_beatheart_count;
+
+void web_connect::init(const std::vector<std::string>&uri_list,int32_t st, std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE>& MsgFuncList)
+{
+    MsgFuncList.insert( std::make_pair( "beatheart", &web_connect::_beatheart_callback ) );
+
+    swsClientMgr.Build( uri_list, MsgFuncList );
+
+    //init thread...
+    YA::_THREAD_CONFIG_ Config;
+    Config.SendInterval = st;
+    swsTimerThrd.Init( Config );
+}
+
+void web_connect::start_beatheart_monitor()
+{
+    auto th = std::thread(&web_connect::_beatheart_thread);
+    th.detach();
+}
+
+void web_connect::close()
+{
+    swsTimerThrd.Stop();
+    swsClientMgr.close();
+}
+
+bool web_connect::connect()
+{
+    //连接服务器
+    if ( swsClientMgr.connect() != 0 )
+    {
+        log_error("web socket 连接失败....");
+        std_error("websocket 连接失败....");
+        return false;
+    }
+    //登录
+    swsClientMgr.login();
+
+    swsTimerThrd.Start();
+
+    return true;
+}
+
+void web_connect::_beatheart_callback( int ID, std::string const& name,
+                    sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp )
+{
+    _beatheart_count=BEATHEART_COUNT_NUM;
+}
+
+void web_connect::_beatheart_thread()
+{
+    while (true)
+    {
+        std::this_thread::sleep_for(std::chrono::seconds(3));
+        if(_beatheart_count==0)//一次都没收到web的心跳信号
+        {
+            log_info("没有收到web心跳信号");
+            continue;
+        }
+
+        if(_beatheart_count==BEATHEART_COUNT_NUM)
+        {
+            _beatheart_count++;
+            log_info("接收到web心跳信号");
+            continue;
+        }
+
+        _beatheart_count=0;
+
+        int count=0;
+        while (true)
+        {
+            count++;
+            if(count>=10000)
+            {
+                count=10000;
+            }
+
+            close();
+            log_error("web连接异常中断, 开始重连web(第%d次)", count);
+            std::this_thread::sleep_for(std::chrono::seconds(2));
+            if(connect())
+            {
+                log_info("重连web ok");
+                break;
+            }
+        }
+    }
+}

+ 34 - 0
websocket/web_connect.h

@@ -0,0 +1,34 @@
+#ifndef WEB_CONNECT_H
+#define WEB_CONNECT_H
+
+#include<atomic>
+#include<vector>
+#include<string>
+#include<memory>
+
+#include"sio_message.h"
+#include"wsClient.h"
+
+class web_connect
+{
+public:
+    web_connect();
+
+    static void init(const std::vector<std::string>&uri_list,int32_t st, std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE>& MsgFuncList);
+
+    static void start_beatheart_monitor();
+
+    static bool connect();
+
+    static void close();
+
+private:
+    static void _beatheart_callback( int ID, std::string const& name,
+                           sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp );
+
+    static void _beatheart_thread();
+
+    static std::atomic<int> _beatheart_count;
+};
+
+#endif // WEB_CONNECT_H

+ 6 - 3
websocket/wsClient.cpp

@@ -3,6 +3,7 @@
 #include <thread>
 #include <chrono>
 #include <boost/locale.hpp>
+#include"log.h"
 
 
 namespace YA
@@ -96,7 +97,6 @@ namespace YA
 
 	void wsClient::login()
 	{
-		char szError[512] = { 0 };
 
 		if ( !IsConnected() )
 		{
@@ -121,7 +121,6 @@ namespace YA
 
 		std::this_thread::sleep_for( std::chrono::milliseconds( _LOGIN_SLEEP_TIME_ ) );
 		
-		int nRet = 0;
 		YA::_JS_LOGIN_ Login;
 		Login.user_name = JSON_VALUE_USERNAME;
 		Login.user_password = JSON_VALUE_PASSWORD;
@@ -130,8 +129,10 @@ namespace YA
 		strLogin += "\n";
 		sio::socket::ptr skt_ptr;
 		skt_ptr = __wsclient.socket();
-		skt_ptr->emit( JSON_CMD_VALUE_USER, strLogin, [&]( sio::message::list const& msglist )
+		skt_ptr->emit( JSON_CMD_VALUE_USER, strLogin, [this]( sio::message::list const& msglist )
 		{
+		    int nRet = 0;
+		    char szError[512] = { 0 };
 			sio::message::ptr msg_ptr = msglist[0];
 			nRet = ( int ) msg_ptr->get_map()["code"]->get_int();
 			if ( 0 == nRet )
@@ -166,11 +167,13 @@ namespace YA
 
 	void wsClient::_on_close( sio::client::close_reason const & reason )
 	{
+        log_info("websocket %d close()",__ID);
 		_reset();
 	}
 
 	void wsClient::_on_reconnect( unsigned p1, unsigned p2 )
 	{
+        log_info("websocket %d reconnect()",__ID);
 		_reset();
 	}
 

+ 13 - 14
websocket/wsTimerThread.cpp

@@ -10,11 +10,6 @@ namespace YA
 	wsTimerThread::wsTimerThread()
 	{
 		__Reset();
-
-		__LastSendTime = { 0 };
-		__LastSendTime.tm_year = 1970 - 1900;
-		__LastSendTime.tm_mon  = 1;
-		__LastSendTime.tm_mday = 1;
 	}
 
 	wsTimerThread::~wsTimerThread()
@@ -26,12 +21,18 @@ namespace YA
 	{
 		__Running = true;
 		__Thread.reset( new boost::thread( boost::bind( &wsTimerThread::_ThreadFunc, this, this ) ) );
-		__Thread->detach();
+        //__Thread->detach();
 	}
 
 	void wsTimerThread::Stop()
 	{
-		std::cout << "::Stop() begin" << std::endl;
+        if(__Thread==nullptr)
+        {
+            return;
+        }
+        __Thread->interrupt();
+        __Running = false;
+		std::cout << "wsTimerThread::Stop() begin" << std::endl;
 
 		__Enable = false;
 
@@ -42,8 +43,9 @@ namespace YA
 		}
 
 		__Reset();
+        __Thread=nullptr;
 
-		std::cout << "::Stop() end" << std::endl;
+		std::cout << "wsTimerThread::Stop() end" << std::endl;
 	}
 
 	void wsTimerThread::__Reset()
@@ -75,16 +77,13 @@ namespace YA
 	{	
 		while ( pOwner->__Enable )
 		{
-			std::tm *Now;
-			std::time_t t;
-			t = time( 0 );
-			Now = localtime( &t );
-			int seconds = (int)std::difftime( mktime( Now ), mktime( &__LastSendTime ) );
+			std::time_t t = time( 0 );
+			int seconds = (int)std::difftime( t, __LastSendTime );
 
 			if ( seconds >= pOwner->__Config.SendInterval )
 			{
 				pOwner->__SendCardPos();
-				__LastSendTime = *Now;
+				__LastSendTime = t;
 			}
 
 			boost::this_thread::sleep( boost::posix_time::millisec( 1 ) );

+ 1 - 1
websocket/wsTimerThread.h

@@ -47,7 +47,7 @@ namespace YA
 		boost::mutex __ExitMutex;//锁(配合__ExitCond)
 		_THREAD_CONFIG_ __Config;//线程配置
 		thread_safe_map<uint64_t, _CARD_POS_> __CardPosList;//卡位置列表
-		std::tm __LastSendTime;//上一次发送的时间
+        std::time_t  __LastSendTime{0};//上一次发送的时间
 		jsonBuilder __jsBuilder;//json构造器类
 	private:
 		/**

+ 58 - 7
worker.cpp

@@ -14,6 +14,7 @@
 #include "card_base.h"
 #include "card.h"
 #include "zloop.h"
+#include "area.h"
 
 struct hash_thread
 {
@@ -65,11 +66,10 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 		for(task*t:task_list)
 		{
 			do_task(*t);
-			free(t);
 		}
 	}
 
-	void on_timeout()
+	void update_local_cards()
 	{
 		int version=card_list::instance()->version();
 		if(m_card_list_version!=version)
@@ -77,7 +77,11 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 			m_card_list_version=version;
 			init_local_card_list();
 		}
+	}
 
+	void on_timeout()
+	{
+		update_local_cards();
 		for(auto&c:m_local_card_list)
 		{
 			c->on_timer();
@@ -98,9 +102,11 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 	{
 		m_local_card_list.clear();
 		card_list::instance()->accept(*this);
+
+		log_info("update local cards,count=%d",m_local_card_list.size());
 	}
 
-	void do_task(const task&t)
+	void do_task(task&t)
 	{
 		switch(t.m_cmd_code)
 		{
@@ -108,6 +114,7 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 			case 0x863b://tdoa
 				log_info("card loc message%04X",t.m_cmd_code);
 				card_list::instance()->on_message(this,t.body<message_locinfo>(),false);
+				t.destroy();
 
 				//card_message::on_loc_message(this,t.m_param1);
 			break;
@@ -116,11 +123,36 @@ struct worker_thread: zloop<task*> ,visitor<std::shared_ptr<card_location_base>>
 				log_info("site history message%04X",t.m_cmd_code);
 					card_list::instance()->on_message(this,t.body<message_locinfo>(),true);
 				//site_message::on_sync(this,t.m_param1);
+				t.destroy();
 			break;
 
 			case 0x804c://ctrl site message
 				log_info("ctrl site message%04X",t.m_cmd_code);
+				t.destroy();
 			break;
+
+			case 0x10001://区域业务类型修改
+			{
+				update_local_cards();
+				for(auto&c:m_local_card_list)
+				{
+					c->get_area_tool()->on_change_business(c,t);
+				}
+
+				auto&mcb=t.body<message_change_business>();
+				std::shared_ptr<area> a=area_list::instance()->get(mcb.area_id);
+
+				if(a && a->sub_frozen_count()==2)
+				{
+					a->set_business_list(std::move(mcb.new_list));
+					a->sub_frozen_count();
+				}
+
+				if(mcb.ref_count.fetch_sub(1)==1)
+				{
+					t.destroy();
+				}
+			}
 		}
 	}
 
@@ -157,11 +189,27 @@ struct worker_impl:worker
 		return *m_threads[g_hash.hash_code(i)];
 	}
 
+	virtual int  num_thread()
+	{
+		return std::thread::hardware_concurrency();
+	}
+
+	bool running()
+	{
+		return m_init_flag.load()==0;
+	}
+
 	virtual void request(task*t)
 	{
 		hash(t->m_hash_id).async_request(t);
 	}
 
+	virtual void broadcast(task*tk) 
+	{
+		for(auto&thr:m_threads)
+			thr->async_request(tk);
+	}
+
 	void init(int num_thread)
 	{
 		int exp=-2;
@@ -184,11 +232,14 @@ struct worker_impl:worker
 worker_impl _worker_impl;
 worker*worker::instance()
 {
-	int num_thread=std::thread::hardware_concurrency()*2;
+	int num_thread=_worker_impl.num_thread();
+	if(!_worker_impl.running())
+	{
+		log_info("worker thread count=%d",num_thread);
+		g_hash.set_num_thread(num_thread);
+		_worker_impl.init(num_thread);
+	}
 
-	log_info("worker thread count=%d",num_thread);
-	g_hash.set_num_thread(num_thread);
-	_worker_impl.init(num_thread);
 	return &_worker_impl;
 }
 

+ 33 - 12
worker.h

@@ -1,45 +1,66 @@
 #ifndef _WORKER_HPP_
 #define _WORKER_HPP_
 #include <ev++.h>
+#include <atomic>
+#include <vector>
 
 struct task
 {
 	uint32_t m_cmd_code;
 	uint32_t m_hash_id;
-	char     m_d[1];
 
-	void destroy()
+	task(uint32_t hash_id,uint32_t cmd_code)
+		:m_cmd_code(cmd_code)
+		,m_hash_id(hash_id)
 	{
-		free(this);
 	}
 
-	template<typename T> const T&body()const
+	task()
+	{}
+
+	void destroy()
 	{
-		const void*x=&m_d[0];
-		return *(T*)x;
+		delete this;
 	}
 
-	template<typename T> T&body()
+	template<typename T> const T&body()const
 	{
-		void*x=&m_d[0];
-		return *(T*)x;
+		return *(T*)this;
 	}
 
-	static size_t align(size_t n)
+	template<typename T> T&body()
 	{
-		return (n+31)&~0x1F;
+		return *(T*)this;
 	}
 
 	template<typename T> static task*alloc()
 	{
-		return (task*)malloc(align(sizeof(T)+sizeof(task)));
+		return new T();
 	}
+
+	virtual ~task(){}
+};
+
+struct area_business;
+struct message_change_business:task
+{
+	int area_id;
+	std::atomic<int> ref_count;
+	std::vector<area_business*> del_list,add_list,new_list;
 };
 
 struct worker
 {
 	virtual void stop()=0;
 	virtual void request(task*tk)=0;
+	virtual void broadcast(task*tk) 
+	{
+	}
+
+	virtual int  num_thread()
+	{
+		return 1;
+	}
 
 	static worker*instance();
 };

+ 146 - 44
znet.cpp

@@ -1,6 +1,7 @@
 #include <log.h>
 #include <unistd.h>
 #include <signal.h>
+#include <sys/time.h>
 #include <stdio.h>
 #include <list>
 #include <vector>
@@ -10,6 +11,7 @@
 #include <atomic>
 #include <algorithm>
 #include <fstream>
+#include <time.h>
 
 #include <zio.h>
 #include <znet.h>
@@ -21,12 +23,15 @@
 #include "crc.h"
 
 extern config_file config;
+int site_sync=config.get("site_sync",0);//分站时间同步,考虑到双IP双机情况,缺省关闭
+int site_sync_freq=config.get("site_sync.freq",60);//分站时间同步间隔
 struct client_ex:client
 {
 	virtual void on_notify()=0;
 	virtual void close_impl()=0;
 };
 
+
 struct io_context: zloop<std::shared_ptr<client>> ,service_handle
 {
 private:
@@ -41,7 +46,7 @@ public:
 	{
 		m_thread_clts.reserve(2048);
 		m_timer.set<io_context,&io_context::on_timer>(this);
-		m_timer.start(20,1);
+		m_timer.start(0,1);
 	}
 
 	virtual ~io_context()
@@ -50,7 +55,7 @@ public:
 
 	void boardcast(const std::vector<char>&msg)
 	{
-		for(auto i:m_thread_clts)
+		for(const auto&i:m_thread_clts)
 		{
 			std::vector<char> tmp(msg);
 			i->send(std::move(tmp));
@@ -94,7 +99,7 @@ public:
 
 	void close_all()
 	{
-		for(auto clt:m_thread_clts)
+		for(const auto&clt:m_thread_clts)
 		{
 			if(!clt)
 				continue;
@@ -105,7 +110,7 @@ public:
 
 	void on_async(const std::list<std::shared_ptr<client>>&notify_clts)
 	{
-		for(auto&clt:notify_clts)
+		for(const auto&clt:notify_clts)
 		{
 			((client_ex*)clt.get())->on_notify();
 		}
@@ -185,9 +190,11 @@ struct sock_client:fd_io,client_ex
 	char  *m_b{0};
 	int   m_clen{0};
 	int   m_size{1<<16};
-	int   m_max_package_size{4096};
+	int   m_max_package_size{2048};
+	int   m_recv_time_out;
 
 	ev::timer  m_recv_timer;
+	ev::timer  m_sync_timer;
 //	ev::timer  m_send_timer;
 	
 	std::mutex m_mutex;
@@ -196,18 +203,27 @@ struct sock_client:fd_io,client_ex
 	size_t m_opos=0;
 	bool   m_can_write{false};
 
+//	char m_timestamp[8];
+
 	sock_client(io_context&ic,const char*name,int fd,int recv_time_out,int max_package_size)
 		:fd_io(ic,fd,EV_READ|EV_WRITE)
 		,m_ic(ic)
 		,m_name(name)
 		,m_recv_timer(ic)
+		,m_sync_timer(ic)
 	{ 
 		m_max_package_size=max_package_size;
+		m_recv_time_out=recv_time_out;
 
 //		m_recv_timer.set(ic);
-		m_recv_timer.set(recv_time_out,0);
 		m_recv_timer.set<sock_client,&sock_client::on_recv_timeout>(this);
-		m_recv_timer.start();
+		m_recv_timer.start(recv_time_out,0);
+
+		m_sync_timer.set<sock_client,&sock_client::on_sync_timeout>(this);
+		if(site_sync)
+		{
+			m_sync_timer.start(0,site_sync_freq);
+		}
 
 //		m_send_timer.set(ic);
 //		m_send_timer.set(5,0);
@@ -215,6 +231,7 @@ struct sock_client:fd_io,client_ex
 //		m_send_timer.start();
 
 		m_b=(char*)malloc(m_size);
+//		m_timestamp[0]=0;
 	}
 
 	~sock_client()
@@ -222,6 +239,28 @@ struct sock_client:fd_io,client_ex
 		free(m_b);
 	}
 
+#if 0
+	bool check_timestamp(const char*time)
+	{
+		//秒、分、时、天、周、月、年, 脑残的设计
+		
+		char buf[6];
+		buf[0]=time[6];
+		buf[1]=time[5];
+		buf[2]=time[3];
+		buf[3]=time[2];
+		buf[4]=time[1];
+		buf[5]=time[0];
+
+		if(memcmp(m_timestamp,buf,6)<=0)
+		{
+			memcpy(m_timestamp,buf,6);
+			return true;
+		}
+		return false;
+	}
+#endif
+
 	int type()
 	{
 		return m_type;
@@ -242,6 +281,38 @@ struct sock_client:fd_io,client_ex
 		m_ic.async_request(shared_from_this());
 	}
 
+	void on_sync_timeout()
+	{
+//	从第一个字节开始,分别表示毫秒(2字节)、秒、分、时、天、月、年
+		char buf[14]={0,12,0x78,0x3b};
+
+		struct timeval tv;
+		gettimeofday(&tv,0);
+
+		struct tm buff={0};
+		const struct tm*t=localtime_r(&tv.tv_sec,&buff);
+
+		int p=4;
+		buf[p++]=(tv.tv_usec/1000)>>8;
+		buf[p++]=(tv.tv_usec/1000)&0xff;
+
+		//为防止分站重启时发送上来过大的时间
+		buf[p++]=t->tm_sec;
+		buf[p++]=t->tm_min;
+		buf[p++]=t->tm_hour;
+		buf[p++]=t->tm_mday;
+		buf[p++]=t->tm_mon;
+		buf[p++]=t->tm_year;
+
+		uint16_t ccrc=do_crc((unsigned char*)buf+2,10);
+
+		buf[p++]=ccrc>>8;
+		buf[p++]=ccrc&0xff;
+
+		std::vector<char> tmp(buf,buf+14);
+		send(std::move(tmp));
+	}
+
 	void on_send_timeout()
 	{
 		m_ic.on_send_timeout(shared_from_this());
@@ -250,6 +321,8 @@ struct sock_client:fd_io,client_ex
 	void on_recv_timeout()
 	{
 		m_ic.on_recv_timeout(shared_from_this());
+		logn_warn(1,"socket %s recv timeout.",m_name.c_str());
+		close_impl();
 	}
 
 	std::string name()
@@ -293,11 +366,11 @@ struct sock_client:fd_io,client_ex
 
 			if(rc==0)
 			{
-				log_info("socket %d(%s) close by remote",m_fd,m_name.c_str());
+				logn_info(1,"socket %d(%s) close by remote",m_fd,m_name.c_str());
 			}
 			else if(rc==-1)
 			{
-				log_errno("hava a error on socket %d(%s)",m_fd,m_name.c_str());
+				logn_warn(1,"hava a error on socket %d(%s)",m_fd,m_name.c_str());
 			}
 			return -1;
 		}
@@ -308,9 +381,9 @@ struct sock_client:fd_io,client_ex
 	void close_impl()
 	{
 		m_recv_timer.stop();
-//		m_send_timer.stop();
 		fd_io::stop();
 		m_ic.on_close(shared_from_this());
+		logn_info(1,"socket %s closed.",m_name.c_str());
 	}
 
 	size_t calc_length(uint8_t*b)const
@@ -323,30 +396,47 @@ struct sock_client:fd_io,client_ex
 		if(read_clt()<0)
 			return -1;
 
-		int msg_len;
-		for(;m_clen>=2;)
+		try
 		{
-			msg_len=calc_length((uint8_t*)m_b)+2;
+			int msg_len;
+			for(;m_clen>=2;)
+			{
+				msg_len=calc_length((uint8_t*)m_b)+2;
 
-			if(msg_len>m_max_package_size)
-				return -1;
+				if(msg_len>m_max_package_size)
+				{
+					logn_error(1,"package too big:%d/%d,close socket. site=%s.",msg_len,m_max_package_size,m_name.c_str());
+					return -1;
+				}
 
-			if(m_clen<msg_len)
-				break;
+				if(msg_len<=8)
+				{
+					logn_error(1,"package too small:%d,close socket. site=%s.",msg_len,m_name.c_str());
+					return -1;
+				}
 
-			logn_bin(1,name().c_str(),m_b,msg_len);//输出二进制日志
-			if(check_crc(m_b,msg_len))
-			{
-				on_message(m_b,msg_len);
-			}
-			else
-			{
-				log_errno("check_crc_error,socket close... site=%s.",m_name.c_str());
-				return -1;
-			}
+				if(m_clen<msg_len)
+					break;
 
-			memmove(m_b,&m_b[msg_len],m_clen-msg_len);
-			m_clen-=msg_len;
+				logn_bin(1,name().c_str(),m_b,msg_len);//输出二进制日志
+				if(check_crc(m_b,msg_len))
+				{
+					on_message(m_b,msg_len);
+				}
+				else
+				{
+					logn_error(1,"check_crc_error,close socket. site=%s.",m_name.c_str());
+					return -1;
+				}
+
+				memmove(m_b,&m_b[msg_len],m_clen-msg_len);
+				m_clen-=msg_len;
+			}
+		}
+		catch(const std::exception&e)
+		{
+			logn_error(1,"package error,close socket. site=%s,err_info=%s",m_name.c_str(),e.what());
+			return -1;
 		}
 
 		return 0;
@@ -394,7 +484,7 @@ struct sock_client:fd_io,client_ex
 			}
 			else
 			{
-				log_errno("zio::write(%d,ptr,%d)",m_fd,m_obuf.size()-m_opos);
+				logn_errno(1,"zio::write(%d,ptr,%d)",m_fd,m_obuf.size()-m_opos);
 				return -1;
 			}
 		}
@@ -412,7 +502,7 @@ struct sock_client:fd_io,client_ex
 	{
 		if(flag & EV_WRITE)
 		{
-			log_debug("socket %d(%s) can write,flag=%d." ,m_fd,m_name.c_str(),flag);
+			logn_debug(1,"socket %d(%s) can write,flag=%d." ,m_fd,m_name.c_str(),flag);
 			m_can_write=true;
 //			m_send_timer.stop();
 			if(io_write()<0)
@@ -433,7 +523,7 @@ struct sock_client:fd_io,client_ex
 			}
 
 //			log_info("use time %d ms.",c.count_us());
-			m_recv_timer.set(5);
+			m_recv_timer.start(m_recv_time_out);
 		}
 	}
 
@@ -471,7 +561,7 @@ struct sock_listen: fd_io
 {
 	sock_listen(io_context&ic,int fd):fd_io(ic,fd){}
 
-	int recv_time_out=config.get("service.recv_timeout",30);
+	int recv_time_out=config.get("service.recv_timeout",10);
 	int max_package_size=config.get("service.max_package",2048);
 
 	void operator()(ev::io &w, int)
@@ -479,10 +569,15 @@ struct sock_listen: fd_io
 		char name[32];
 		int fd=zio::accept(m_fd,name);
 		if(fd<0)
+		{
+			logn_errno(1,"socket %s connect error.",name);
 			return;
+		}
 
 		zio::setiobuf(fd,32<<10,32<<10);
 		m_ic.on_connect(std::make_shared<sock_client>(m_ic,name,fd,recv_time_out,max_package_size));
+
+		logn_info(1,"socket %s connected.",name);
 	}
 };
 
@@ -531,7 +626,24 @@ struct main_loop:io_context
 
 		block_sig(SIGPIPE);
 		signal_w sint(*this,SIGINT),term(*this,SIGTERM);
-		ev::dynamic_loop::run(0);
+
+
+		while(!check_stop_flag())
+		{
+			try
+			{
+			ev::dynamic_loop::run(0);
+			}
+			catch(const std::exception&e)
+			{
+				log_error("捕获到异常:%s",e.what());
+			}
+			catch(...)
+			{
+				log_error("捕获到未知异常");
+			}
+		}
+
 		_1.stop();
 		close_all();
 
@@ -559,13 +671,3 @@ service_handle*service_handle::instance(service_callback*sc)
 }
 
 
-
-
-
-
-
-
-
-
-
-

+ 2 - 0
znet.h

@@ -14,6 +14,8 @@ struct client:std::enable_shared_from_this<client>
 	virtual void close()=0;
 	virtual void send(std::vector<char>&&b)=0;
 
+//	virtual bool check_timestamp(const char*)=0;
+
 	virtual ~client(){}
 };
 

+ 2 - 0
zstream.h

@@ -208,6 +208,7 @@ public:
 	{ 
 		if(is.m_np <= 0)
 			return is;
+
 		is.load(x,is.m_np);
 		is.m_np.reset();
 
@@ -216,6 +217,7 @@ public:
 
 	friend zistream& operator>>(zistream&is, const skip&s)
 	{ 
+		is.assert_buff_size(s.m_count);
 		is.m_pos+=s.m_count;
 
 		return is;