Jelajahi Sumber

业务模块

daiyueteng 6 tahun lalu
induk
melakukan
28cd4816e2
45 mengubah file dengan 2763 tambahan dan 2029 penghapusan
  1. 25 19
      CMakeLists.txt
  2. 1 1
      CMakeLists.txt.user
  3. 5 41
      ant.cpp
  4. 19 20
      ant.h
  5. 8 7
      area.cpp
  6. 135 144
      area.h
  7. 88 13
      card.cpp
  8. 32 15
      card.h
  9. 17 0
      common.h
  10. 444 0
      common_tool.h
  11. 12 8
      main.cpp
  12. 7 0
      mine.cpp
  13. 34 0
      mine.h
  14. 0 92
      module_service/module_area.cpp
  15. 66 52
      module_service/module_area.h
  16. 96 0
      module_service/module_area_over_person.h
  17. 0 3
      module_service/module_area_over_speed.cpp
  18. 0 127
      module_service/module_area_over_speed.h
  19. 0 3
      module_service/module_area_overman.cpp
  20. 0 92
      module_service/module_area_overman.h
  21. 0 3
      module_service/module_area_timeout.cpp
  22. 0 97
      module_service/module_area_timeout.h
  23. 108 0
      module_service/module_area_timeout_person.h
  24. 0 9
      module_service/module_attendance_person.cpp
  25. 171 78
      module_service/module_attendance_person.h
  26. 0 2
      module_service/module_attendance_vehicle.cpp
  27. 47 20
      module_service/module_attendance_vehicle.h
  28. 170 132
      module_service/module_call.cpp
  29. 284 49
      module_service/module_call.h
  30. 0 8
      module_service/module_call_help.cpp
  31. 81 85
      module_service/module_call_help.h
  32. 0 6
      module_service/module_const.cpp
  33. 21 562
      module_service/module_const.h
  34. 0 2
      module_service/module_mgr.cpp
  35. 77 11
      module_service/module_mgr.h
  36. 44 0
      module_service/module_mine.h
  37. 159 0
      module_service/module_over_speed_vehicle.h
  38. 92 0
      module_service/module_site.h
  39. 49 36
      module_service/module_web.cpp
  40. 27 274
      module_service/module_web.h
  41. 10 0
      net-service.cpp
  42. 6 13
      site_area.cpp
  43. 38 5
      site_area.h
  44. 107 0
      ya_event.cpp
  45. 283 0
      ya_event.h

+ 25 - 19
CMakeLists.txt

@@ -57,32 +57,38 @@ set(SRC_YASL "ant.cpp" "ant.h" "base64.cpp" "base64.h" "card.cpp" "card.h" "cloc
     )
 
 set(SRC_MODULE
-
-    "module_service/module_area.h" "module_service/module_area.cpp"
-    "module_service/module_area_over_speed.h" "module_service/module_area_over_speed.cpp"
-    "module_service/module_area_overman.h" "module_service/module_area_overman.cpp"
-    "module_service/module_area_timeout.h" "module_service/module_area_timeout.cpp"
-    "module_service/module_attendance_person.h" "module_service/module_attendance_person.cpp"
-    "module_service/module_attendance_vehicle.h" "module_service/module_attendance_vehicle.cpp"
+    "mine.h" "mine.cpp"
+    "ya_event.h" "ya_event.cpp"
+    "common_tool.h"
+
+    "module_service/module_area.h"
+    "module_service/module_site.h"
+    "module_service/module_area_over_person.h"
+    "module_service/module_area_timeout_person.h"
+    "module_service/module_attendance_person.h"
+    "module_service/module_attendance_vehicle.h"
     "module_service/module_call.h" "module_service/module_call.cpp"
-    "module_service/module_call_help.cpp" "module_service/module_call_help.h"
-    "module_service/module_const.cpp" "module_service/module_const.h"
-    "module_service/module_web.cpp" "module_service/module_web.h"
-    "module_service/module_mgr.cpp" "module_service/module_mgr.h"
+    "module_service/module_call_help.h"
+    "module_service/module_const.h"
+    "module_service/module_web.h" "module_service/module_web.cpp"
+    "module_service/module_mgr.h"
+
+    "module_service/module_mine.h"
+    "module_service/module_over_speed_vehicle.h"
     )
 
 add_executable(${PROJECT_NAME} "main.cpp" ${SRC_YASL}  ${SRC_MODULE})
 
-target_link_libraries (${PROJECT_NAME}  zlog rt ev boost_system boost_thread mysqlclient)
+target_link_libraries (${PROJECT_NAME}  zlog rt ev boost_chrono boost_system boost_thread mysqlclient)
 
-file(COPY data_reader_antenna.txt DESTINATION ${PROJECT_BINARY_DIR})
-file(COPY path_tof.txt DESTINATION ${PROJECT_BINARY_DIR})
+#file(COPY data_reader_antenna.txt DESTINATION ${PROJECT_BINARY_DIR})
+#file(COPY path_tof.txt DESTINATION ${PROJECT_BINARY_DIR})
 
-file(COPY /root/projection/out/bin/logger DESTINATION ${PROJECT_BINARY_DIR})
-file(COPY /root/projection/out/etc DESTINATION ${PROJECT_SOURCE_DIR})
-file(COPY /root/projection/out/log DESTINATION ${PROJECT_SOURCE_DIR})
-file(COPY /root/projection/out/include/log.h DESTINATION ${PROJECT_SOURCE_DIR})
-file(COPY /root/projection/out/include/config_file.h DESTINATION ${PROJECT_SOURCE_DIR})
+#file(COPY /root/projection/out/bin/logger DESTINATION ${PROJECT_BINARY_DIR})
+#file(COPY /root/projection/out/etc DESTINATION ${PROJECT_SOURCE_DIR})
+#file(COPY /root/projection/out/log DESTINATION ${PROJECT_SOURCE_DIR})
+#file(COPY /root/projection/out/include/log.h DESTINATION ${PROJECT_SOURCE_DIR})
+#file(COPY /root/projection/out/include/config_file.h DESTINATION ${PROJECT_SOURCE_DIR})
 
 
 

+ 1 - 1
CMakeLists.txt.user

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.7.0, 2018-09-20T15:06:48. -->
+<!-- Written by QtCreator 4.7.0, 2018-10-07T19:16:37. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>

+ 5 - 41
ant.cpp

@@ -171,18 +171,17 @@ void sit_list::read_ant_path(const char*fname)
 void sit_list::init_site()
 {
     const char *sql = "SELECT reader_id, reader_type_id, dat_reader.map_id, \
-            area_id, brief_name, name, x, \
-            y,z,angle, state, ip, device_type_id, isSpecial,dimension, dat_map.scale\
+            area_id, device_type_id, dimension, dat_map.scale\
             FROM dat_reader, dat_map where \
             dat_reader.map_id=dat_map.map_id and state=0;";
 
     std::string Error;
     YADB::CDBResultSet DBRes;
     sDBConnPool.Query(sql,DBRes,Error);
-    int nCount = DBRes.GetRecordCount( Error );
+    uint64_t nCount = DBRes.GetRecordCount( Error );
     if (nCount > 0)
     {
-        log_info( "init_site. The record count=%d\n", nCount );
+        log_info( "init_site. The record count=%ld\n", nCount );
 
         while ( DBRes.GetNextRecod(Error) )
         {
@@ -205,36 +204,9 @@ void sit_list::init_site()
             int area_id  = 0;
             DBRes.GetField( "area_id",area_id, Error );
 
-            std::string brief_name;
-            DBRes.GetField( "brief_name",brief_name, Error );
-
-            std::string name;
-            DBRes.GetField( "name",name, Error );
-
-            double x= 0;
-            DBRes.GetField( "x",x, Error );
-
-            double y= 0;
-            DBRes.GetField( "y",y, Error );
-
-            double z= 0;
-            DBRes.GetField( "z",z, Error );
-
-            double angle= 0;
-            DBRes.GetField( "angle",angle, Error );
-
-            int state  = 0;
-            DBRes.GetField( "state",state, Error );
-
-            std::string ip;
-            DBRes.GetField( "ip",ip, Error );
-
             int device_type_id  = 0;
             DBRes.GetField( "device_type_id",device_type_id, Error );
 
-            int isSpecial  = 0;
-            DBRes.GetField( "isSpecial",isSpecial, Error );
-
             int dimension  = 0;
             DBRes.GetField( "dimension",dimension, Error );
 
@@ -244,17 +216,9 @@ void sit_list::init_site()
             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_brief_name = brief_name;
-//            site_ptr->m_name = name;
-//            site_ptr->x = x;
-//            site_ptr->y = y;
-//            site_ptr->z = z;
-
-//            site_ptr->m_angle = angle;
-//            site_ptr->m_state = state;
-//            site_ptr->m_ip = ip;
+
             site_ptr->m_device_type_id = device_type_id;
-//            site_ptr->m_isSpecial = isSpecial;
+
             site_ptr->m_dimension = dimension;
             site_ptr->m_scale = scale;
         }

+ 19 - 20
ant.h

@@ -12,6 +12,8 @@
 #include "line.h"
 #include "point.h"
 #include "write-copy.h"
+#include"net-service.h"
+#include"common.h"
 
 struct path
 {
@@ -101,17 +103,6 @@ struct ant :point
 
 };
 
-/**
- * @brief 分站位置 1井上,2井下
- */
-enum READER_TYPE_ID
-{
-    ///井上分站
-    READER_TYPE_ID_UP=1,
-    ///井下分站
-    READER_TYPE_ID_DOWN=2
-};
-
 struct site:point
 {
     static algo_config g_config[];
@@ -141,21 +132,29 @@ struct site:point
     int m_reader_type_id = 0;
     int m_map_id = 0;
     int m_area_id = 0;
-    std::string m_brief_name = "";
-    std::string m_name = "";
-
-    double m_angle;
-    /// 状态 0 正常, 1 故障
-    int m_state=0;
-    std::string m_ip="";
 
     /// 设备类型,分站、通信分站、交通灯等
     int m_device_type_id=0;
-    /// 是否为特殊分站,定位结果与分站间距4米以内,如果是特殊分站就将定位点定位在分站附近,否则抛弃计算结果
-    int m_isSpecial=0;
+
     /// 指定分站定位类型:一维定位,二维定位,三维定位
     int m_dimension=0;
 
+    std::shared_ptr<client> m_clt=nullptr;
+    void set_client(std::shared_ptr<client> clt)
+    {
+        m_clt = clt;
+    }
+
+    std::shared_ptr<client> get_client()
+    {
+        return m_clt;
+    }
+
+    bool is_up_site()
+    {
+        return READER_TYPE_ID_UP == m_reader_type_id;
+    }
+
     point get_dstp(const point pt) const
     {
         point tmp;

+ 8 - 7
area.cpp

@@ -16,7 +16,7 @@
 template<> std::shared_ptr<area_list> 
 single_base<area_list, int, std::shared_ptr<area>>::m_instance=std::make_shared<area_list>();
 
-void area::on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+void area::on_hover(uint32_t card_id,std::shared_ptr<area_hover>&c,double speed,int32_t type)
  {
  	//check超时
 	log_info("on_hover..%d  areaId:%d",card_id,m_id);
@@ -26,10 +26,10 @@ void area::on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,u
 // 		c->m_is_over_time=true;
 // 		//产生告警
 // 	}
-    module_area::instance()->on_hover(card_id,c,speed,type);
+    module_area::on_hover(card_id,c,type);
  }
 
-void area::on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+void area::on_enter(uint32_t card_id,std::shared_ptr<area_hover>&c,double speed,int32_t type)
 {
 	log_info("on_enter..%d  areaId:%d",card_id,m_id);
 //	//入库 : 进入区域
@@ -38,10 +38,10 @@ void area::on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,u
 //	m_card_count.store(cu);
 //	//check超员
 
-    module_area::instance()->on_enter(card_id,c,speed,type);
+    module_area::on_enter(card_id,c,type);
 }
 
-void area::on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
+void area::on_leave(uint32_t card_id,std::shared_ptr<area_hover>&c,double speed,int32_t type)
 {
 	log_info("on_leave..%d  areaId:%d",card_id,m_id);
 	//入库 : 出 区域
@@ -53,7 +53,7 @@ void area::on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,u
     //	{
     //		//取消告警
     //	}
-        module_area::instance()->on_leave(card_id,c,speed,type);
+        module_area::on_leave(card_id,c,type);
 }
 bool area::in_area(const point & p)
 {
@@ -86,6 +86,7 @@ bool area::in_area(const point & p)
 area_list::area_list()
 {
 }
+
 void area_list::init_monkeycar_area()
 {
 	std::unordered_map<int,std::shared_ptr<area>> map;
@@ -255,7 +256,7 @@ std::shared_ptr<area> area_list::get_area(const point&pt)
 }
 
 
-void area_tool::on_point(int64_t card_id,const point&pt,double speed,int16_t type)
+void area_tool::on_point(uint32_t card_id,const point&pt,double speed,int16_t type)
 {
 	log_info("on_point...cardid:%d,type:%d",card_id,type);
 	//获取地标信息

+ 135 - 144
area.h

@@ -34,34 +34,32 @@ struct area
         ,m_limit_person_count(limit_count_person)
         ,m_scale(scale)
         ,m_mapid(mapid)
-        ,m_limit_speed(0)
         ,m_person_count(0)
         ,m_vehicle_count(0)
-        ,m_is_over_person(0)
-    {
-    }
-
-    virtual void on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
-    virtual void on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
-    virtual void on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
-	bool in_area(const point & p);
-	int id()const
-	{
-		return m_id;
-	}
-	int mapid()const
-	{
-		return m_mapid;
-	}
-	double scale()const
-	{
-		return m_scale;
-	}
-	bool special()const
-	{
-		return m_area_type == AREA_TYPE_NO_COVER;
-	}
-	virtual ~area()
+    {
+    }
+
+    virtual void on_hover(uint32_t card_id,std::shared_ptr<area_hover>&c,double speed,int32_t type);
+    virtual void on_enter(uint32_t card_id,std::shared_ptr<area_hover>&c,double speed,int32_t type);
+    virtual void on_leave(uint32_t card_id,std::shared_ptr<area_hover>&c,double speed,int32_t type);
+    bool in_area(const point & p);
+    int id()const
+    {
+        return m_id;
+    }
+    int mapid()const
+    {
+        return m_mapid;
+    }
+    double scale()const
+    {
+        return m_scale;
+    }
+    bool special()const
+    {
+        return m_area_type == AREA_TYPE_NO_COVER;
+    }
+    virtual ~area()
     {}
     ///区域卡数
     int card_count()const
@@ -76,146 +74,139 @@ public:
     ///区域类型  AREA_TYPE
     int m_area_type;
 
-
-    ///区域人卡数
-    std::atomic<int> m_person_count;
-    ///区域车卡数
-    std::atomic<int> m_vehicle_count;
-    std::atomic<bool> m_is_over_person;
-
     ///区域超时门限
     int m_limit_time_second;
     ///人数门限
     int m_limit_person_count;
     double m_scale;
     int32_t m_mapid;
-    ///速度门限
-    double m_limit_speed;
+
+    ///区域人卡数
+    std::atomic<int> m_person_count;
+    ///区域车卡数
+    std::atomic<int> m_vehicle_count;
 };
 
 struct area_list:single_base<area_list,int,std::shared_ptr<area>>
 {
-	area_list();
+    area_list();
 
-	std::shared_ptr<area> get_area(const point&pt);
-	std::vector<point> init_path(std::string  &str);
-	void init_from_db();
-	void init_monkeycar_area();
+    std::shared_ptr<area> get_area(const point&pt);
+    std::vector<point> init_path(std::string  &str);
+    void init_from_db();
+    void init_monkeycar_area();
 };
 
 struct area_hover
 {
-	std::shared_ptr<area>  m_area;
+    std::shared_ptr<area>  m_area;
     time_t m_enter_time,m_last_time;
-	point  m_enter_point,m_last_point;
-	int    m_num_speeding;
-	bool   m_is_over_time;
-
-	int landmark_id;
-	int landmark_dir;
-	double landmark_dis;
-  	area_hover()=default;
-	area_hover(std::shared_ptr<area>&area,const point&pt,double speed)
-		:m_area(area)
-	{
-		m_enter_time=m_last_time=time(0);
-		m_enter_point=m_last_point=pt;
-		m_num_speeding=0;
-		landmark_id=0;
-		landmark_dir=0;
-		landmark_dis=0;
-	}
-
-	int id()const
-	{
-		return m_area->id();
-	}
-	int mapid()const
-	{
-		return m_area->mapid();
-	}
-	double scale()const
-	{
-		return m_area->scale();
-	}
-	bool operator == (const area_hover&o)const
-	{
-		return m_area->id()==o.m_area->id();
-	}
-
-	bool operator < (const area_hover&o)const
-	{
-		return m_area->id()<o.m_area->id();
-	}
-	std::tuple<time_t,time_t,int,int,int,int,double> getLandmark()
-	{
-		return std::make_tuple(m_enter_time,m_last_time,mapid(),id(),landmark_id,landmark_dir,landmark_dis);
-	}
-	void setLandmark(const point &pt);
-	void set(const point&pt)
-	{
-		m_last_time=time(0);
-		m_last_point = pt;
-	}
+    point  m_enter_point,m_last_point;
+
+    int landmark_id;
+    int landmark_dir;
+    double landmark_dis;
+    area_hover()=default;
+    area_hover(std::shared_ptr<area>&area,const point&pt,double speed)
+        :m_area(area)
+    {
+        m_enter_time=m_last_time=time(0);
+        m_enter_point=m_last_point=pt;
+        landmark_id=0;
+        landmark_dir=0;
+        landmark_dis=0;
+    }
+
+    int id()const
+    {
+        return m_area->id();
+    }
+    int mapid()const
+    {
+        return m_area->mapid();
+    }
+    double scale()const
+    {
+        return m_area->scale();
+    }
+    bool operator == (const area_hover&o)const
+    {
+        return m_area->id()==o.m_area->id();
+    }
+
+    bool operator < (const area_hover&o)const
+    {
+        return m_area->id()<o.m_area->id();
+    }
+    std::tuple<time_t,time_t,int,int,int,int,double> getLandmark()
+    {
+        return std::make_tuple(m_enter_time,m_last_time,mapid(),id(),landmark_id,landmark_dir,landmark_dis);
+    }
+    void setLandmark(const point &pt);
+    void set(const point&pt)
+    {
+        m_last_time=time(0);
+        m_last_point = pt;
+    }
 };
 
 //每张卡包含一个对象
 //在解析出数据点时,调用on_point
 struct area_tool
 {
-	std::shared_ptr<area_hover> m_area_hover=nullptr;
-	void on_point(int64_t card_id,const point&pt,double speed,int16_t type);
-	void setLandmark(const point &pt)
-	{
-		if(m_area_hover)
-		{
-			m_area_hover->setLandmark(pt);
-		}
-	}
-	//special area or no area att.,return true;else return false.
-	bool special_area()
-	{
-		if(m_area_hover==nullptr)
-		  return true;
-		return m_area_hover->m_area->special();
-	}
-	std::tuple<time_t,time_t,int,int,int,int,double> getLandmark()
-	{
-		if(m_area_hover)
-			return m_area_hover->getLandmark();
-		else
-		  return std::make_tuple(0,0,0,0,0,0,0);
-		
-	}
-	//检测是否超时
-	void on_timer(int64_t card_id)
-	{
-
-	}
-
-	void do_hover_biz(int64_t card_id,double speed,int16_t type)
-    {
-		m_area_hover->m_area->on_hover(card_id,m_area_hover,speed,type);
-	}
-
-	void do_enter_biz(int64_t card_id,double speed,int16_t type)
-	{
-		m_area_hover->m_area->on_enter(card_id,m_area_hover,speed,type);
-	}
-
-	void do_leave_biz(int64_t card_id,double speed,int16_t type)
-	{
-		m_area_hover->m_area->on_leave(card_id,m_area_hover,speed,type);
-	}
-
-	void change_area(int64_t card_id,double speed,int16_t type,int32_t new_areaid)
-	{
-		do_leave_biz(card_id,speed,type);
-		auto area = area_list::instance()->get(new_areaid);
-		point pt;
-		m_area_hover.reset(new area_hover(area,pt,speed));
-		do_enter_biz(card_id,speed,type);
-	}
+    std::shared_ptr<area_hover> m_area_hover=nullptr;
+    void on_point(uint32_t card_id,const point&pt,double speed,int16_t type);
+    void setLandmark(const point &pt)
+    {
+        if(m_area_hover)
+        {
+            m_area_hover->setLandmark(pt);
+        }
+    }
+    //special area or no area att.,return true;else return false.
+    bool special_area()
+    {
+        if(m_area_hover==nullptr)
+            return true;
+        return m_area_hover->m_area->special();
+    }
+    std::tuple<time_t,time_t,int,int,int,int,double> getLandmark()
+    {
+        if(m_area_hover)
+            return m_area_hover->getLandmark();
+        else
+            return std::make_tuple(0,0,0,0,0,0,0);
+
+    }
+    //检测是否超时
+    void on_timer(int64_t card_id)
+    {
+
+    }
+
+    void do_hover_biz(uint32_t card_id,double speed,int16_t type)
+    {
+        m_area_hover->m_area->on_hover(card_id,m_area_hover,speed,type);
+    }
+
+    void do_enter_biz(uint32_t card_id,double speed,int16_t type)
+    {
+        m_area_hover->m_area->on_enter(card_id,m_area_hover,speed,type);
+    }
+
+    void do_leave_biz(uint32_t card_id,double speed,int16_t type)
+    {
+        m_area_hover->m_area->on_leave(card_id,m_area_hover,speed,type);
+    }
+
+    void change_area(uint32_t card_id,double speed,int16_t type,int32_t new_areaid)
+    {
+        do_leave_biz(card_id,speed,type);
+        auto area = area_list::instance()->get(new_areaid);
+        point pt;
+        m_area_hover.reset(new area_hover(area,pt,speed));
+        do_enter_biz(card_id,speed,type);
+    }
 };
 
 #endif

+ 88 - 13
card.cpp

@@ -16,6 +16,8 @@
 #include "monkey_car/monkeycar_area.h"
 #include "monkey_car/monkeycar_person.h"
 #include "special_area.h"
+#include "mine.h"
+#include "module_service/module_mgr.h"
 
 extern config_file config;
 //一张卡一个ct的所有不同天线的信息
@@ -158,13 +160,19 @@ struct card_message_handle
 		//
 		m_card->site_hover(loc.m_site_id);
 
-        if(loc.m_batty_status == 2) 
+        if(loc.m_batty_status == 2)
         {
-            m_card->do_status(STA_TYPE::STATUS_LOW_POWER_);
+            //m_card->do_status(STA_TYPE::STATUS_LOW_POWER_);
+            m_card->do_status(STATUS_POWER_LOWER);
         }
         else if(loc.m_callinfo == 0x80)
         {
-            m_card->do_status(STA_TYPE::STATUS_HELP_);
+            //m_card->do_status(STA_TYPE::STATUS_HELP_);
+            m_card->do_status(STATUS_HELP);
+        }
+        else if(loc.m_callinfo == 0x01 || loc.m_callinfo == 0x02)
+        {
+            m_card->do_status(STATUS_CALL);
         }
 
 		m_ct_list[loc.m_card_ct&(m_ct_list.size()-1)]->on_message(loop,loc);
@@ -176,10 +184,12 @@ struct card_area
 	card_area()
 	{
 		m_site_area.reset(new site_area_hover);
-		m_area_tool.reset(new area_tool);
+        m_area_tool.reset(new area_tool);
+        m_mine_tool.reset(new mine_tool);
 	}
 	std::shared_ptr<site_area_hover> m_site_area=nullptr;
 	std::shared_ptr<area_tool> m_area_tool=nullptr;
+    std::shared_ptr<mine_tool> m_mine_tool=nullptr;
 };
 
 struct person:card_location_base,private card_area
@@ -196,6 +206,19 @@ struct person:card_location_base,private card_area
 	{
 		m_message_handle->on_message(loop,loc,is_history);
 	}
+
+    void clear()
+    {
+        //清除定时器
+        m_timer.stop();
+        m_loop = nullptr;
+
+        m_site_area.reset(new site_area_hover);
+        m_area_tool.reset(new area_tool);
+        m_mine_tool.reset(new mine_tool);
+
+        card_location_base::clear();
+    }
 	
 	virtual void site_hover(int sid)
 	{
@@ -211,6 +234,16 @@ struct person:card_location_base,private card_area
         return m_area_tool->m_area_hover;
     }
 
+    virtual std::shared_ptr<mine_tool> get_mine_tool()
+    {
+        return m_mine_tool;
+    }
+
+    virtual std::shared_ptr<site_area_hover> get_site_area()
+    {
+        return m_site_area;
+    }
+
 	virtual void do_business(const point &pt)
 	{
 		//区域
@@ -305,10 +338,22 @@ struct car:card_location_base,private card_area
         return m_area_tool->m_area_hover;
     }
 
+    virtual std::shared_ptr<mine_tool> get_mine_tool()
+    {
+        return m_mine_tool;
+    }
+
+    virtual std::shared_ptr<site_area_hover> get_site_area()
+    {
+        return m_site_area;
+    }
+
 	virtual void do_business(const point &pt)
 	{
 		m_area_tool->on_point(m_id,pt,m_speed,m_type);
         m_site_area->on_point(m_id,0,this, m_type);
+
+        m_mine_tool->on_point(m_id, m_type, m_vehicle_category_id);
 	}
 
 	void set(ev::dynamic_loop * loop)
@@ -558,6 +603,12 @@ card_location_base::card_location_base(std::string type,uint32_t id,uint16_t dis
 {
     select_tool_manage::instance()->create_tool(type,m_sel_tool,m_smo_tool);
 }
+
+void card_location_base::do_status(STATUS_CARD st)
+{
+    module_mgr::do_status(st, m_id, m_type);
+}
+
 void card_location_base::on_location(const std::vector<point>&vp,const std::vector<loc_message> &lm )
 {
 	//ct timestamp;
@@ -602,15 +653,39 @@ void card_location_base::upt_card_pos(YA::_CARD_POS_ &cp,const point &pt)
 int  card_location_base::get_stat()
 {
 	//盲区>呼救>呼叫>超时>超速>正常
-	int status=STATUS_NORMAL;
-	if(false)
-		status = STATUS_CALL;
-	if(false)
-		status = STATUS_HELP;
-
-	uint64_t now = time(0)*1000;
-	status=(now-m_time>CARD_LOST_TIME_OUT)?STATUS_LOST:STATUS_NORMAL;
-	return status;
+    uint64_t now = time(0)*1000;
+    if(now-m_time>CARD_LOST_TIME_OUT)
+    {
+        return STATUS_LOST;
+    }
+    else if(auto ev_ptr = event_list::instance()->get(m_id, ET_CARD_HELP))
+    {
+        return  (ES_DEAL_HELP == ev_ptr->m_status) ?  STATUS_HELP_DEALED : STATUS_HELP;
+    }
+    else if(0 != get_mine_tool()->m_status_call)
+    {
+        return  STATUS_CALL;
+    }
+    else if(event_list::instance()->get(m_id, ET_CARD_AREA_OVER_TIME_PERSON))
+    {
+        return  STATUS_AREA_OVER_TIME;
+    }
+    else if(event_list::instance()->get(m_id, ET_CARD_OVER_SPEED))
+    {
+        return  STATUS_OVER_SPEED;
+    }
+
+    return STATUS_NORMAL;
+}
+
+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;			//时间戳
 }
 card_location_base::~card_location_base()
 {

+ 32 - 15
card.h

@@ -8,7 +8,9 @@
 #include "write-copy.h"
 #include "websocket/ws_common.h"
 #include "common.h"
-#include"area.h"
+#include "area.h"
+#include "mine.h"
+#include "site_area.h"
 
 #define CARD_LOST_TIME_OUT (30*1000)
 
@@ -30,8 +32,6 @@ struct card:point
 		,m_ct(0)
 		,m_time(0)
 		,m_deptid(deptid)
-        ,m_stat_attendance(AS_INIT)
-        ,m_attendance_start_time(std::chrono::seconds(0))
 	{}
 	uint32_t m_id;				//卡号
 	int16_t  m_type;			//类型
@@ -42,11 +42,6 @@ struct card:point
 	uint16_t m_ct;				//ct
 	uint64_t m_time;			//时间戳
 	int32_t  m_deptid;			//部门编号
-
-    ///考勤状态  0初始状态 1 没在考勤 2 考勤;参看ATTENDANCE_STATUS
-    int m_stat_attendance;
-    ///考勤开始时间
-    std::chrono::system_clock::time_point m_attendance_start_time;
 };
 struct card_location_base:card
 {
@@ -63,19 +58,27 @@ struct card_location_base:card
 	virtual void set(ev::dynamic_loop * loop)=0;
 	virtual void site_hover(int sid)=0;
     virtual std::shared_ptr<area_hover> get_area_hover()=0;
+    virtual std::shared_ptr<mine_tool> get_mine_tool()=0;
+    virtual std::shared_ptr<site_area_hover> get_site_area()=0;
+
+    virtual void clear();
+
 	virtual void reset(std::shared_ptr<monkey_person> mp){}
 
     void on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history);
     void on_location(const std::vector<point>&vp,const std::vector<loc_message> &lm );
-    void do_status(STA_TYPE st)
-    {
-        if(STATUS_HELP_==st)
-        {
-            //module_call_help::ins
-        }
-    }
+    void do_status(STATUS_CARD st);
 	void upt_card_pos(YA::_CARD_POS_ &,const point &pt);
 	int get_stat();
+    bool is_person() const
+    {
+        return CT_PERSON == m_type;
+    }
+
+    bool is_vehicle() const
+    {
+        return CT_VEHICLE == m_type;
+    }
 	virtual ~card_location_base();
 };
 
@@ -86,6 +89,20 @@ struct card_list:single_base<card_list,uint64_t,std::shared_ptr<card_location_ba
     uint64_t getId(uint32_t cardid,uint64_t);
     void on_message(zloop<task*> *loop,const message_locinfo&loc,bool is_history);
     void init_card_from_db();
+
+    /// (类型<<32)|卡号
+    static uint64_t to_id64(int32_t type, uint32_t id)
+    {
+        return (static_cast<uint64_t>(type)<<32)|id;
+    }
+
+    static std::string to_id64_str(int32_t type, uint32_t id)
+    {
+        char sql[15] = {'\0'};
+        sprintf(sql, "%03d%010d", type, id);
+
+        return std::string(sql);
+    }
     ~card_list(){}
 };
 

+ 17 - 0
common.h

@@ -1,6 +1,20 @@
 #ifndef COMMON_HPP__
 #define COMMON_HPP__
 
+#define LENGTH_SQL 2000
+#define SPEED_COUNT_LIMIT 5
+
+/**
+ * @brief 分站位置 1井上,2井下
+ */
+enum READER_TYPE_ID
+{
+    ///井上分站
+    READER_TYPE_ID_UP=1,
+    ///井下分站
+    READER_TYPE_ID_DOWN=2
+};
+
 enum STA_TYPE
 {
 	STATUS_HELP_=0,
@@ -9,12 +23,15 @@ enum STA_TYPE
 enum STATUS_CARD
 {
 	STATUS_NORMAL=0,
+    STATUS_POWER_LOWER = 1,			//电量低
 	STATUS_OVER_SPEED=8,
 	STATUS_AREA_OVER_TIME=16,
 	STATUS_HELP=128,
+    STATUS_HELP_DEALED = 256,		//呼救已处理
 	STATUS_CALL=512,
 	STATUS_LOST=1024
 };
+
 /**
  * @brief 0初始状态 1 没在考勤 2 考勤
  */

+ 444 - 0
common_tool.h

@@ -0,0 +1,444 @@
+#ifndef COMMON_TOOL_H
+#define COMMON_TOOL_H
+
+#include"common.h"
+#include"log.h"
+#include"card.h"
+#include<chrono>
+#include<string>
+#include<sys/time.h>
+#include "db_api/CDBConnPool.h"
+#include "websocket/wsClientMgr.h"
+
+class tool_time
+{
+public:
+    static uint32_t elapse_seconds(std::chrono::system_clock::time_point &start)
+    {
+        return static_cast<uint32_t>( std::chrono::duration_cast<std::chrono::seconds>
+                (std::chrono::system_clock::now() - start).count() );
+    }
+
+    static uint64_t elapse_ms(std::chrono::system_clock::time_point &start)
+    {
+        return static_cast<uint64_t>( std::chrono::duration_cast<std::chrono::milliseconds>
+                (std::chrono::system_clock::now() - start).count() );
+    }
+
+    static uint32_t now_to_seconds()
+    {
+        return static_cast<uint32_t>( std::chrono::duration_cast<std::chrono::seconds>
+                (std::chrono::system_clock::now().time_since_epoch()).count() );
+    }
+
+    static uint64_t now_to_ms()
+    {
+        return static_cast<uint64_t>( std::chrono::duration_cast<std::chrono::milliseconds>
+                (std::chrono::system_clock::now().time_since_epoch()).count() );
+    }
+
+    static uint64_t now_to_us()
+    {
+        return static_cast<uint64_t>( std::chrono::duration_cast<std::chrono::microseconds>
+                (std::chrono::system_clock::now().time_since_epoch()).count() );
+    }
+
+    static uint64_t to_ms(const std::chrono::system_clock::time_point &time)
+    {
+        return static_cast<uint64_t>( std::chrono::duration_cast<std::chrono::milliseconds>
+                (time.time_since_epoch()).count() );
+    }
+
+    static std::string to_str(const std::chrono::system_clock::time_point &time)
+    {
+        char _time[25] = {0};
+        time_t tt = std::chrono::system_clock::to_time_t(time);
+        struct tm local_time;
+        localtime_r(&tt, &local_time);
+        strftime(_time, 22, "%Y-%m-%d %H:%M:%S", &local_time);
+
+        return std::string(_time);
+    }
+
+    //"%Y-%m-%d %H:%M:%S"
+    static time_t to_time(std::string str)
+    {
+        time_t t_;
+        tm tm_;
+        strptime(str.c_str(), "%Y-%m-%d %H:%M:%S", &tm_); //将字符串转换为tm时间
+        t_ = mktime(&tm_); //将tm时间转换为秒时间
+
+        return t_;
+    }
+
+    ////"%d-%02d-%02d %02d:%02d:%02d.%03d"
+    static std::chrono::system_clock::time_point to_time_ex(std::string str)
+    {
+        uint64_t pos = str.length()-3;
+
+        time_t t_;
+        tm tm_;
+        strptime(str.substr(0,pos).c_str(), "%Y-%m-%d %H:%M:%S", &tm_); //将字符串转换为tm时间
+        t_ = mktime(&tm_); //将tm时间转换为秒时间
+
+        int milli = std::stoi(str.substr(pos));
+
+        return std::chrono::system_clock::time_point(std::chrono::milliseconds(t_*1000 + milli));
+    }
+
+    //"%d-%02d-%02d %02d:%02d:%02d.%03d"
+    static std::string to_str_ex(uint64_t ms)
+    {
+        int32_t mill = ms%1000;
+
+        char _time[25] = {0};
+        time_t tt = ms/1000;
+        struct tm *local_time=localtime(&tt);
+        //strftime(_time, 22, "%Y-%m-%d %H:%M:%S", local_time);
+        sprintf(_time, "%d-%02d-%02d %02d:%02d:%02d.%03d", local_time->tm_year+1900,
+                local_time->tm_mon+1, local_time->tm_mday, local_time->tm_hour,
+                local_time->tm_min, local_time->tm_sec, mill);
+
+        return std::string(_time);
+    }
+
+    //"%d-%02d-%02d %02d:%02d:%02d.%03d"
+    static std::string to_str_ex(std::chrono::system_clock::time_point time)
+    {
+        return to_str_ex(to_ms(time));
+    }
+
+    static int elapse_seconds(time_t &start)
+    {
+        time_t now;
+        time(&now);
+        return static_cast<int>(std::difftime(now, start));
+    }
+
+    //"%Y-%m-%d %H:%M:%S"
+    static std::string to_str(const std::time_t &time)
+    {
+        char _time[25] = {0};
+        struct tm local_time;
+        localtime_r(&time, &local_time);
+        strftime(_time, 22, "%Y-%m-%d %H:%M:%S", &local_time);
+
+        return std::string(_time);
+    }
+};
+
+class tool_other
+{
+public:
+    static void send_json(const std::string& cmd, const std::string& data)
+    {
+        std_debug("发送json: cmd=%s, data=%s\n", cmd.c_str(), data.c_str());
+        log_info("发送json: cmd=%s, data=%s\n", cmd.c_str(), data.c_str());
+        swsClientMgr.send(cmd, data);
+    }
+
+    static std::string to13str(std::string& str)
+    {
+        uint64_t tmp = std::stoull(str);
+        char ss[20]={0};
+        sprintf(ss, "%013ld", tmp);
+
+        return std::string(ss);
+    }
+
+    static uint32_t id64_to_id(std::string& str)
+    {
+        return static_cast<uint32_t>(std::stoul(to13str(str).substr(3)));
+    }
+
+    static int id64_to_type(std::string& str)
+    {
+        return std::stoi(to13str(str).substr(0, 3));
+    }
+};
+
+
+class tool_db
+{
+public:
+    static void PushAsync(char* sql)
+    {
+        //std_debug("PushAsync记录到队列中:%s\n", sql);
+        //log_info("PushAsync记录到队列中:%s\n", sql);
+
+        if(!sDBConnPool.PushAsync(sql))
+        {
+            log_error( "PushAsync记录到队列中失败\n");
+        }
+    }
+
+    static void save_attendance(const std::shared_ptr<card_location_base> card_ptr)
+    {
+        char sql[LENGTH_SQL] = {0};
+
+        std::string call("add_att_staff");
+        if(card_ptr->is_vehicle())//车卡
+        {
+            call="add_att_vehicle";
+        }
+
+        auto site_area_ptr = card_ptr->get_site_area();
+
+        auto start = site_area_ptr->m_attendance_start_time;
+        auto end = site_area_ptr->m_attendance_start_time;
+        if(!site_area_ptr->is_attendance())//考勤结束时间
+        {
+            end = std::chrono::system_clock::time_point(std::chrono::milliseconds(card_ptr->m_time));
+        }
+
+        std::string start_str = tool_time::to_str(start);
+        std::string end_str = tool_time::to_str(end);
+
+        int landmarkid = 0;
+        int landmarkdirect=0;
+        double landmarkdist=0;
+        auto area_hover_ptr = card_ptr->get_area_hover();
+        if(area_hover_ptr)
+        {
+            landmarkid = area_hover_ptr->landmark_id;
+            landmarkdirect = area_hover_ptr->landmark_dir;
+            landmarkdist = area_hover_ptr->landmark_dis;
+        }
+
+        sprintf(sql, "CALL %s(%s, %d, '%s', '%s', %d, %d, %.3f);", call.c_str(),
+                card_list::to_id64_str(card_ptr->m_type, card_ptr->m_id).c_str(),
+                card_ptr->m_id, start_str.c_str(), end_str.c_str(),
+                landmarkid, landmarkdirect, landmarkdist);
+
+        PushAsync(sql);
+    }
+};
+
+class tool_map
+{
+public:
+    static bool try_get_value(sio::message::ptr& out_data,
+                              const char* key, sio::message::ptr const& data)
+    {
+        auto map=data->get_map()[key];
+        if(map && sio::message::flag_object == map->get_flag())
+        {
+            out_data = map;
+            return true;
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(int64_t& out_data, const char* key, sio::message::ptr const& data)
+    {
+        auto map=data->get_map()[key];
+        if(map && sio::message::flag_integer == map->get_flag())
+        {
+            out_data = map->get_int();
+            return true;
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(uint32_t& out_data, const char* key, sio::message::ptr const& data)
+    {
+        auto map=data->get_map()[key];
+        if(map && sio::message::flag_integer == map->get_flag())
+        {
+            out_data = static_cast<uint32_t>(map->get_int());
+            return true;
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(int& out_data, const char* key, sio::message::ptr const& data)
+    {
+        auto map=data->get_map()[key];
+        if(map && sio::message::flag_integer == map->get_flag())
+        {
+            out_data = static_cast<int>(map->get_int());
+            return true;
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(std::string& out_data, const char* key, sio::message::ptr const& data)
+    {
+        auto map=data->get_map()[key];
+        if(map && sio::message::flag_string == map->get_flag())
+        {
+            out_data = map->get_string();
+            return true;
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(double& out_data, const char* key, sio::message::ptr const& data)
+    {
+        auto map=data->get_map()[key];
+        if(map && sio::message::flag_double == map->get_flag())
+        {
+            out_data = map->get_double();
+            return true;
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(std::vector<sio::message::ptr>& out_data,
+                               const char* key, sio::message::ptr const& data)
+    {
+        auto map=data->get_map()[key];
+        if(map && sio::message::flag_array == map->get_flag())
+        {
+            out_data = map->get_vector();
+            return true;
+        }
+
+        return false;
+    }
+};
+
+class tool_json
+{
+public:
+    static void add_member(rapidjson::Value& out_data, const char* key, std::string value,
+                              rapidjson::Document::AllocatorType& allocator)
+    {
+        rapidjson::Value name;
+        name.SetString(key, allocator);
+
+        rapidjson::Value data;
+        data.SetString(value.c_str(), allocator);
+
+        out_data.AddMember(name, data, allocator);
+    }
+
+    static void push_back(rapidjson::Value& out_data, std::string value,
+                              rapidjson::Document::AllocatorType& allocator)
+    {
+        rapidjson::Value data;
+        data.SetString(value.c_str(), allocator);
+
+        out_data.PushBack(data, allocator);
+    }
+
+    static bool try_get_iter(const char* key, const rapidjson::Value& node,
+                             rapidjson::Value::ConstMemberIterator& out_iter)
+    {
+        if(node.IsObject())
+        {
+            out_iter = node.FindMember(key);
+            if(node.MemberEnd() == out_iter)
+            {
+                return false;
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(int& d, const char* key, const rapidjson::Value& node)
+    {
+        rapidjson::Value::ConstMemberIterator iter;
+        if(try_get_iter(key, node, iter))
+        {
+            if(iter->value.IsInt())
+            {
+                d = iter->value.GetInt();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    static bool try_get_value(uint64_t& d, const char* key, const rapidjson::Value& node)
+    {
+        rapidjson::Value::ConstMemberIterator iter;
+        if(try_get_iter(key, node, iter))
+        {
+            if(iter->value.IsUint64())
+            {
+                d = iter->value.GetUint64();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static bool try_get_value(double& d, const char* key, const rapidjson::Value& node)
+    {
+        rapidjson::Value::ConstMemberIterator iter;
+        if(try_get_iter(key, node, iter))
+        {
+            if(iter->value.IsDouble())
+            {
+                d = iter->value.GetDouble();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static bool try_get_value(std::string& d, const char* key, const rapidjson::Value& node)
+    {
+        rapidjson::Value::ConstMemberIterator iter;
+        if(try_get_iter(key, node, iter))
+        {
+            if(iter->value.IsString())
+            {
+                d = iter->value.GetString();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    static int get_value(const char* key, const int& default_data, const rapidjson::Value& node)
+    {
+        rapidjson::Value::ConstMemberIterator iter;
+        if(try_get_iter(key, node, iter))
+        {
+            if(iter->value.IsInt())
+            {
+                return  iter->value.GetInt();
+            }
+        }
+
+        return default_data;
+    }
+
+    static std::string get_value(const char* key, const std::string& default_data, const rapidjson::Value& node)
+    {
+        rapidjson::Value::ConstMemberIterator iter;
+        if(try_get_iter(key, node, iter))
+        {
+            if(iter->value.IsString())
+            {
+                return iter->value.GetString();
+            }
+        }
+
+        return default_data;
+    }
+
+    static std::string doc_to_json(rapidjson::Document& doc)
+    {
+        rapidjson::StringBuffer sb;
+        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+        doc.Accept(writer);
+
+        return sb.GetString();
+    }
+};
+
+#endif // COMMON_TOOL_H

+ 12 - 8
main.cpp

@@ -11,6 +11,10 @@
 #include "card_path.h"
 #include "landmark.h"
 #include "special_area.h"
+#include "mine.h"
+#include "ya_event.h"
+#include"module_service/module_area.h"
+#include"module_service/module_mgr.h"
 
 #include <config_file.h>
 
@@ -55,8 +59,8 @@ struct Init_Setting
 		special_area_list::instance()->init_from_db();
 		auto s = special_area_list::instance()->get_special_id(1013,point(4727,-254),2);
 		std_info("test special_area:%d",s);
-		
 
+        event_list::instance()->load_his_data_from_db();
 	}
 
 	void _mysql_init(YADB::_DB_POOL_SETTING_ &dps)
@@ -75,10 +79,9 @@ struct Init_Setting
 		std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE> MsgFuncList;
 	
         //MsgFuncList.insert( std::make_pair( "req_all_data", On_req_all_data ) );
-		//MsgFuncList.insert( std::make_pair( "req_all_person_on_car", On_req_all_person_on_car ) );
-
-        //module_mgr::instance()->init(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 );
 	
@@ -104,6 +107,8 @@ struct Init_Setting
 
 void cleanup() 
 { 
+    module_mgr::stop();
+
 	ev_loop_destroy(ev_default_loop());
 }
 
@@ -117,12 +122,11 @@ int main()
 	
 	atexit(&cleanup);
 
-    //module_mgr::instance()->init();
-    //module_mgr::instance()->start();
-
 	card_path::init();
-	net_service mh;
 
+    module_mgr::start();
+
+	net_service mh;
 	int port=config.get("service.port",4000);
 	service_handle::instance(&mh)->run(port);
 

+ 7 - 0
mine.cpp

@@ -0,0 +1,7 @@
+#include "mine.h"
+#include <module_service/module_mine.h>
+
+void mine_tool::on_point(uint32_t card_id, int32_t type, int vehicle_category_id)
+{
+    module_mine::on_point(card_id, type, vehicle_category_id);
+}

+ 34 - 0
mine.h

@@ -0,0 +1,34 @@
+#ifndef MINE_H
+#define MINE_H
+
+/**
+ * @brief 矿井里相关的业务
+ * @author 戴月腾
+ * @date 2018-09-24
+ */
+
+#include <unordered_map>
+#include "db_api/CDBConnPool.h"
+#include <log.h>
+
+struct mine_tool
+{
+    mine_tool():
+        m_over_speed_count(0)
+      ,m_normal_speed_count(0)
+      ,m_status_call(0)
+    {
+
+    }
+
+    int    m_over_speed_count;
+    int    m_normal_speed_count;
+    ///CALL_NONE(0):没有呼叫,CALL_ING(2):正在呼叫,CALL_SUCCESSED(1):呼叫成功
+    int m_status_call;
+
+    void on_point(uint32_t card_id, int32_t type, int vehicle_category_id);
+};
+
+
+
+#endif // MINE_H

+ 0 - 92
module_service/module_area.cpp

@@ -1,92 +0,0 @@
-#include "module_area.h"
-#include"module_attendance_vehicle.h"
-
-//#include"module_area_overman.h"
-//#include"module_area_timeout.h"
-//#include"module_area_over_speed.h"
-
-
-void module_area::on_enter(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
-{
-    auto card_ptr=card_list::instance()->get(tool_other::to_uint64_cardid(type, card_id));
-    if(!card_ptr)
-    {
-        log_error("卡不存在card_id=%d", card_id);
-        return;
-    }
-
-    log_debug("module_area::on_enter  card_ptr->m_type=%d", card_ptr->m_type);
-
-    if(tool_other::is_person(card_ptr->m_type))//统计人卡
-    {
-        c->m_area->m_person_count++;
-
-        //        //区域人卡超员
-        //        module_area_overman::instance()->on_enter(card_ptr, c, speed);
-        //        //区域人卡超时
-        //        module_area_timeout::instance()->on_enter(card_ptr, c, speed);
-    }
-
-    if(tool_other::is_vehicle(card_ptr->m_type))//统计车卡
-    {
-        c->m_area->m_vehicle_count++;
-        //车卡考勤
-        module_attendance_vehicle::instance()->on_enter(card_ptr, c, speed);
-
-        //        //区域车卡超速
-        //        module_area_over_speed::instance()->on_enter(card_ptr, c, speed);
-    }
-
-    log_debug("module_area::on_enter  车卡数=%d, 人卡数=%d",
-              c->m_area->m_vehicle_count.load(), c->m_area->m_person_count.load());
-}
-
-void module_area::on_hover(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
-{
-    auto card_ptr=card_list::instance()->get(tool_other::to_uint64_cardid(type, card_id));
-    if(!card_ptr)
-    {
-        log_error("卡不存在card_id=%d", card_id);
-        return;
-    }
-
-    if(tool_other::is_person(card_ptr->m_type))//统计人卡
-    {
-        //        //区域人卡超时
-        //        module_area_timeout::instance()->on_hover(card_ptr, c, speed, _map);
-    }
-
-    if(tool_other::is_vehicle(card_ptr->m_type))//统计车卡
-    {
-        //        //区域车卡超速
-        //        module_area_over_speed::instance()->on_hover(card_ptr, c, speed, _map);
-    }
-}
-
-void module_area::on_leave(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
-{
-    auto card_ptr=card_list::instance()->get(tool_other::to_uint64_cardid(type, card_id));
-    if(!card_ptr)
-    {
-        log_error("卡不存在card_id=%d", card_id);
-        return;
-    }
-
-    if(tool_other::is_person(card_ptr->m_type))//统计人卡
-    {
-        c->m_area->m_person_count--;
-
-        //        //区域人卡超员
-        //        module_area_overman::instance()->on_leave(card_ptr, c, speed);
-        //        //区域人卡超时
-        //        module_area_timeout::instance()->on_leave(card_ptr, c, speed);
-    }
-
-    if(tool_other::is_vehicle(card_ptr->m_type))//统计车卡
-    {
-        c->m_area->m_vehicle_count--;
-
-        //        //区域车卡超速
-        //        module_area_over_speed::instance()->on_leave(card_ptr, c, speed);
-    }
-}

+ 66 - 52
module_service/module_area.h

@@ -9,9 +9,13 @@
 
 #include"area.h"
 #include"module_const.h"
-//#include"module_web.h"
+#include"module_web.h"
 
-class module_area:public i_thread, public singleton_base<module_area>
+#include"module_attendance_vehicle.h"
+#include"module_area_over_person.h"
+#include"module_area_timeout_person.h"
+
+class module_area: public singleton_base<module_area>
 {
 private:
     friend class singleton_base<module_area>;
@@ -20,68 +24,78 @@ private:
     }
 
 public:
-    void on_hover(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
-    void on_enter(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
-    void on_leave(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type);
-
-    /**
-     * @brief 读取数据库中的告警,初始化告警列表
-     */
-    void init()
-    {}
-
-    /**
-     * @brief web前端有用户登录时,反馈给web所有信息
-     */
-    std::string response_login()
+    static void on_enter(uint32_t card_id,std::shared_ptr<area_hover>&c, int32_t type)
     {
-        //        std::vector<std::shared_ptr<ya_event>> arr;
-        //        get_all_events(arr);
+        auto card_ptr=card_list::instance()->get(card_list::to_id64(type, card_id));
+        if(!card_ptr)
+        {
+            log_error("卡不存在card_id=%d", card_id);
+            return;
+        }
 
-        //        if(!arr.empty())//发送给web端
-        //        {
-        //            return tool_json::evs_to_json(arr);
-        //        }
+        if(card_ptr->is_person())//统计人卡
+        {
+            c->m_area->m_person_count++;
 
-        //        return "";
+            //区域人卡超员
+            module_area_over_person::instance()->on_enter(card_ptr, c);
+            //区域人卡超时
+            module_area_timeout_person::instance()->on_enter(card_ptr, c);
+        }
+
+        if(card_ptr->is_vehicle())//统计车卡
+        {
+            c->m_area->m_vehicle_count++;
+            //车卡考勤
+            module_attendance_vehicle::instance()->on_enter(card_ptr, c);
+        }
     }
-private:
-    /**
-     * @brief 线程函数
-     */
-    void run()
+
+    static void on_hover(uint32_t card_id,std::shared_ptr<area_hover>&c, int32_t type)
     {
-        //        std::vector<std::shared_ptr<ya_event>> arr;
-        //        get_all_events(arr);
+        auto card_ptr=card_list::instance()->get(card_list::to_id64(type, card_id));
+        if(!card_ptr)
+        {
+            log_error("卡不存在card_id=%d", card_id);
+            return;
+        }
+
+        if(card_ptr->is_person())//人卡
+        {
+            //区域人卡超时
+            module_area_timeout_person::instance()->on_hover(card_ptr, c);
+        }
+
+        if(card_ptr->is_vehicle())//车卡
+        {
 
-        //        if(!arr.empty())//发送给web端
-        //        {
-        //            swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::evs_to_json(arr));
-        //        }
+        }
     }
 
-    /**
-     * @brief 获取所有的告警事件
-     * @param out_data
-     */
-    void get_all_events(std::vector<std::shared_ptr<ya_event>>& arr)
+    static void on_leave(uint32_t card_id, std::shared_ptr<area_hover>&c, int32_t type)
     {
+        auto card_ptr=card_list::instance()->get(card_list::to_id64(type, card_id));
+        if(!card_ptr)
         {
-            std::lock_guard<std::mutex> lock(_mutex);
-
-            auto it_map = _map.begin();
-            for(;it_map!=_map.end();++it_map)
-            {
-                arr.push_back(it_map->second);
-                if(ES_DEAL_HELP== it_map->second->m_status)//删除掉已经处理的
-                {
-                    _map.erase(it_map--);
-                }
-            }
+            log_error("卡不存在card_id=%d", card_id);
+            return;
         }
-    }
 
-    std::map<uint64_t, std::shared_ptr<ya_event>> _map;
+        if(card_ptr->is_person())//统计人卡
+        {
+            c->m_area->m_person_count--;
+
+            //区域人卡超员
+            module_area_over_person::instance()->on_leave(card_ptr, c);
+            //区域人卡超时
+            module_area_timeout_person::instance()->on_leave(card_ptr, c);
+        }
+
+        if(card_ptr->is_vehicle())//统计车卡
+        {
+            c->m_area->m_vehicle_count--;
+        }
+    }
 };
 
 #endif // MODULE_AREA_H

+ 96 - 0
module_service/module_area_over_person.h

@@ -0,0 +1,96 @@
+#ifndef MODULE_AREA_OVER_PERSON_H
+#define MODULE_AREA_OVER_PERSON_H
+
+
+/**
+  *@brief 区域超员模块:当某个区域人数超过指定值时开始告警,当低于指定值时停止告警
+  *@author 戴月腾
+  *@date 2018-08-26
+*/
+
+#include <string>
+#include <memory>
+#include <atomic>
+#include <mutex>
+#include <map>
+#include "module_const.h"
+
+/**
+ * @brief 区域超员模块:当某个区域人数超过指定值时开始告警,当低于指定值时停止告警
+ */
+class module_area_over_person:public singleton_base<module_area_over_person>
+{
+private:
+    friend class singleton_base<module_area_over_person>;
+    module_area_over_person()
+    {
+    }
+
+public:
+
+    void on_enter(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+    {
+        auto area_ptr = c->m_area;
+        if(area_ptr->m_limit_person_count <= area_ptr->m_person_count)//超员
+        {
+            auto ev_ptr = event_list::instance()->get(static_cast<uint32_t>(area_ptr->id()), ET_AREA_OVER_COUNT_PERSON);
+            if(ev_ptr)
+            {
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value=area_ptr->m_limit_person_count;
+                ev_ptr->m_cur_value=area_ptr->m_person_count;
+            }
+            else//从没有告警状态转化为告警状态
+            {
+                auto ev_ptr = event_list::create_event_not_card(OT_AREA, area_ptr->id(), ET_AREA_OVER_COUNT_PERSON);
+
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value = area_ptr->m_limit_person_count;
+                ev_ptr->m_cur_value = area_ptr->m_person_count;
+
+                //保存到数据库
+                event_list::save_event(ev_ptr);
+
+                event_list::instance()->add(ev_ptr->get_list_id(),ev_ptr);
+
+                log_info("区域人卡超员开始:区域id=%d,区域人卡门限=%d,当前人卡数=%d",
+                         area_ptr->id(), area_ptr->m_limit_person_count, area_ptr->m_person_count.load());
+            }
+        }
+    }
+
+//    void on_hover(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+//    {
+
+//    }
+
+    void on_leave(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+    {
+        auto area_ptr = c->m_area;
+
+        if(area_ptr->m_limit_person_count > area_ptr->m_person_count)//没有超员
+        {
+            //取消告警状态
+            auto ev_ptr = event_list::instance()->get(static_cast<uint32_t>(area_ptr->id()), ET_AREA_OVER_COUNT_PERSON);
+            if(ev_ptr)
+            {
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value=area_ptr->m_limit_person_count;
+                ev_ptr->m_cur_value = area_ptr->m_person_count;
+
+                ev_ptr->m_status = ES_END;
+
+                //保存到数据库
+                event_list::save_event(ev_ptr);
+
+                log_info("区域人卡超员结束:区域id=%d,区域人卡门限=%d,当前人卡数=%d",
+                         area_ptr->id(), area_ptr->m_limit_person_count, area_ptr->m_person_count.load());
+            }
+        }
+    }
+};
+
+#endif // MODULE_AREA_OVER_PERSON_H

+ 0 - 3
module_service/module_area_over_speed.cpp

@@ -1,3 +0,0 @@
-#include "module_area_over_speed.h"
-
-

+ 0 - 127
module_service/module_area_over_speed.h

@@ -1,127 +0,0 @@
-#ifndef MODULE_AREA_OVER_SPEED_H
-#define MODULE_AREA_OVER_SPEED_H
-
-/**
-  *@brief 区域超速模块
-  * 当某张车卡速度超过某个区域的最大速度时,发出告警
-  * @author 戴月腾
-  * @date 2018-08-08
-*/
-
-#include <mutex>
-#include <map>
-#include <chrono>
-#include <boost/thread.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include "module_const.h"
-
-/**
- * @brief 区域超速类。当某张车卡速度超过某个区域的最大速度时,发出告警, 单例
- */
-class module_area_over_speed:public singleton_base<module_area_over_speed>
-{
-private:
-    friend class singleton_base<module_area_over_speed>;
-    module_area_over_speed()
-    {
-    }
-
-public:
-
-    void on_enter(std::shared_ptr<card> card_ptr,std::shared_ptr<area_hover>&c,double speed)
-    {
-//        card_ptr->m_speed = speed;
-//        c->m_vehicle_area_over_speed_count=0;
-//        c->m_vehicle_area_normal_speed_count=0;
-//        c->m_is_area_over_speed_vehicle=false;
-
-//        auto area_ptr = c->m_area;
-//        if(area_ptr->m_limit_speed > speed)//速度正常
-//        {
-//            c->m_vehicle_area_normal_speed_count++;
-//        }
-//        else//超速
-//        {
-//            c->m_vehicle_area_over_speed_count++;
-//        }
-    }
-
-    void on_hover(std::shared_ptr<card> card_ptr,std::shared_ptr<area_hover>&c,double speed,
-                  std::map<uint64_t, std::shared_ptr<ya_event>>& ev_map)
-    {
-        card_ptr->m_speed = speed;
-
-//        auto area_ptr = c->m_area;
-//        if(area_ptr->m_limit_speed > speed)//速度正常
-//        {
-//            c->m_vehicle_area_normal_speed_count++;
-//        }
-//        else//超速
-//        {
-//            c->m_vehicle_area_over_speed_count++;
-//        }
-
-//        //确定超速
-//        if(global_constant::AREA_SPEED_COUNT_LIMIT <= c->m_vehicle_area_over_speed_count)
-//        {
-//            c->m_vehicle_area_over_speed_count=global_constant::AREA_SPEED_COUNT_LIMIT;
-
-//            auto ev_ptr = tool_other::find_event(card_ptr->m_id, ET_CARD_AREA_OVER_SPEED, ev_map);
-//            if(ev_ptr)
-//            {
-//                ev_ptr->m_limit_value=area_ptr->m_limit_speed;
-//                ev_ptr->m_cur_value=card_ptr->m_speed;
-//            }
-//            else//从没有告警状态转化为告警状态
-//            {
-//                c->m_is_area_over_speed_vehicle=true;
-//                c->m_vehicle_area_normal_speed_count=0;
-
-//                auto ev_ptr = tool_other::create_event(OT_CARD, card_ptr->m_id, ET_CARD_AREA_OVER_SPEED);
-
-//                tool_other::copy_event(card_ptr, ev_ptr);
-
-//                ev_ptr->m_limit_value = area_ptr->m_limit_speed;
-//                ev_ptr->m_cur_value = card_ptr->m_speed;
-
-//                //保存到数据库
-//                tool_db::save_event(ev_ptr);
-
-//                tool_other::insert_event(ev_ptr, ev_map);
-//            }
-//        }
-
-//        //确定速度正常
-//        if(global_constant::AREA_SPEED_COUNT_LIMIT <= c->m_vehicle_area_normal_speed_count)
-//        {
-//            c->m_vehicle_area_normal_speed_count=global_constant::AREA_SPEED_COUNT_LIMIT;
-
-//            if(c->m_is_area_over_speed_vehicle)
-//            {
-//                c->m_is_area_over_speed_vehicle = false;
-//                c->m_vehicle_area_over_speed_count=0;
-
-//                auto ev_ptr = tool_other::find_event(card_ptr->m_id, ET_CARD_AREA_OVER_SPEED, ev_map);
-//                if(ev_ptr)
-//                {
-//                    ev_ptr->m_status = ES_END;
-
-//                    ev_ptr->m_limit_value = area_ptr->m_limit_speed;
-//                    ev_ptr->m_cur_value = speed;
-//                    ev_ptr->m_cur_time = std::chrono::system_clock::now();
-
-//                    //保存到数据库
-//                    tool_db::save_event(ev_ptr);
-//                }
-//            }
-//        }
-    }
-
-    void on_leave(std::shared_ptr<card> card_ptr,std::shared_ptr<area_hover>&c,double speed)
-    {
-
-    }
-};
-typedef std::shared_ptr<module_area_over_speed> module_area_over_speed_ptr;
-
-#endif

+ 0 - 3
module_service/module_area_overman.cpp

@@ -1,3 +0,0 @@
-#include "module_area_overman.h"
-#include"module_const.h"
-

+ 0 - 92
module_service/module_area_overman.h

@@ -1,92 +0,0 @@
-#ifndef MODULE_AREA_OVERMAN_H
-#define MODULE_AREA_OVERMAN_H
-
-/**
-  *@brief 区域超员模块:当某个区域人数超过指定值时开始告警,当低于指定值时停止告警
-  *@author 戴月腾
-  *@date 2018-08-26
-*/
-
-#include <string>
-#include <memory>
-#include <atomic>
-#include <mutex>
-#include <map>
-#include "module_const.h"
-
-/**
- * @brief 区域超员模块:当某个区域人数超过指定值时开始告警,当低于指定值时停止告警
- */
-class module_area_overman:public singleton_base<module_area_overman>
-{
-private:
-    friend class singleton_base<module_area_overman>;
-    module_area_overman()
-    {
-    }
-
-public:
-
-    void on_enter(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
-    {
-
-    }
-
-    void on_hover(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed,
-                  std::map<uint64_t, std::shared_ptr<ya_event>>& ev_map)
-    {
-        auto area_ptr = c->m_area;
-        if(area_ptr->m_limit_person_count <= area_ptr->m_person_count)//超员
-        {
-            auto ev_ptr = tool_other::find_event(area_ptr->id(), ET_AREA_OVER_COUNT_PERSON,ev_map);
-            if(ev_ptr)
-            {
-                ev_ptr->m_limit_value=area_ptr->m_limit_person_count;
-                ev_ptr->m_cur_value=area_ptr->m_person_count;
-            }
-            else//从没有告警状态转化为告警状态
-            {
-                area_ptr->m_is_over_person = true;
-                auto ev_ptr = tool_other::create_event(OT_AREA, area_ptr->id(), ET_AREA_OVER_COUNT_PERSON);
-
-                tool_other::copy_event(card_ptr, ev_ptr);
-
-                ev_ptr->m_limit_value = area_ptr->m_limit_person_count;
-                ev_ptr->m_cur_value = area_ptr->m_person_count;
-
-                //保存到数据库
-                tool_db::save_event(ev_ptr);
-
-                tool_other::insert_event(ev_ptr, ev_map);
-            }
-        }
-        else//取消告警状态
-        {
-            if(area_ptr->m_is_over_person)
-            {
-                area_ptr->m_is_over_person = false;
-                auto ev_ptr = tool_other::find_event(area_ptr->id(), ET_AREA_OVER_COUNT_PERSON,ev_map);
-                if(ev_ptr)
-                {
-                    ev_ptr->m_status = ES_END;
-
-                    ev_ptr->m_limit_value=area_ptr->m_limit_person_count;
-                    ev_ptr->m_cur_value = area_ptr->m_person_count;
-                    ev_ptr->m_cur_time = std::chrono::system_clock::now();
-
-                    //保存到数据库
-                    tool_db::save_event(ev_ptr);
-                }
-            }
-        }
-    }
-
-    void on_leave(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
-    {
-
-    }
-};
-typedef std::shared_ptr<module_area_overman>  module_area_overman_ptr;
-
-
-#endif // MODULE_AREA_OVERMAN_H

+ 0 - 3
module_service/module_area_timeout.cpp

@@ -1,3 +0,0 @@
-#include "module_area_timeout.h"
-#include <boost/bind.hpp>
-

+ 0 - 97
module_service/module_area_timeout.h

@@ -1,97 +0,0 @@
-#ifndef MODULE_AREA_TIMEOUT_H
-#define MODULE_AREA_TIMEOUT_H
-
-/**
-  *@brief 区域超时模块 2018-08-26 戴月腾修改
-  * 当某张人卡在某个区域的时间超过指定值时,会发出区域超时告警
-  * @author 陈欧美
-  * @date 2018-08-05
-*/
-
-#include <mutex>
-#include <map>
-#include <chrono>
-#include <boost/thread.hpp>
-#include <boost/enable_shared_from_this.hpp>
-#include "point.h"
-#include "module_const.h"
-#include"module_const.h"
-
-
-/**
- * @brief 当某张人卡在某个区域的时间超过指定值时,会发出区域超时告警
- */
-class module_area_timeout:public singleton_base<module_area_timeout>
-{
-private:
-    friend class singleton_base<module_area_timeout>;
-    module_area_timeout()
-    {
-    }
-
-public:
-    void on_enter(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
-    {
-        //c->m_is_area_over_time_person=false;
-    }
-
-    void on_hover(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed,
-                  std::map<uint64_t, std::shared_ptr<ya_event>>& ev_map)
-    {
-        auto area_ptr = c->m_area;
-
-        //int seconds = tool_time::elapse_seconds(c->m_enter_time);
-
-//        if(seconds > area_ptr->m_limit_time_second)//发生告警
-//        {
-//            auto ev_ptr = tool_other::find_event(card_ptr->m_id, ET_CARD_AREA_OVER_TIME_PERSON, ev_map);
-//            if(ev_ptr)
-//            {
-//                ev_ptr->m_limit_value=area_ptr->m_limit_time_second;
-//                ev_ptr->m_cur_value=seconds;
-//            }
-//            else//从没有告警状态转化为告警状态
-//            {
-//                c->m_is_area_over_time_person=true;//发生告警
-//                auto ev_ptr = tool_other::create_event(OT_CARD, card_ptr->m_id, ET_CARD_AREA_OVER_TIME_PERSON);
-
-//                tool_other::copy_event(card_ptr, ev_ptr);
-
-//                ev_ptr->m_limit_value = area_ptr->m_limit_time_second;
-//                ev_ptr->m_cur_value = seconds;
-
-//                //保存到数据库
-//                tool_db::save_event(ev_ptr);
-
-//                tool_other::insert_event(ev_ptr, ev_map);
-//            }
-//        }
-//        else
-//        {
-//            if(c->m_is_area_over_time_person)
-//            {
-//                c->m_is_area_over_time_person = false;
-//                auto ev_ptr = tool_other::find_event(card_ptr->m_id, ET_CARD_AREA_OVER_TIME_PERSON, ev_map);
-//                if(ev_ptr)
-//                {
-//                    ev_ptr->m_status = ES_END;
-
-//                    ev_ptr->m_limit_value = area_ptr->m_limit_time_second;
-//                    ev_ptr->m_cur_value = seconds;
-//                    ev_ptr->m_cur_time = std::chrono::system_clock::now();
-
-//                    //保存到数据库
-//                    tool_db::save_event(ev_ptr);
-//                }
-//            }
-//        }
-    }
-
-    void on_leave(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
-    {
-
-    }
-};
-typedef std::shared_ptr<module_area_timeout> module_area_timeout_ptr;
-
-#endif // MODULE_AREA_TIMEOUT_H

+ 108 - 0
module_service/module_area_timeout_person.h

@@ -0,0 +1,108 @@
+#ifndef MODULE_AREA_TIMEOUT_PERSON_H
+#define MODULE_AREA_TIMEOUT_PERSON_H
+
+/**
+  *@brief 区域超时模块 2018-08-26 戴月腾修改
+  * 当某张人卡在某个区域的时间超过指定值时,会发出区域超时告警
+  * @author 陈欧美
+  * @date 2018-08-05
+*/
+
+#include <mutex>
+#include <map>
+#include <chrono>
+#include <boost/thread.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "point.h"
+#include "module_const.h"
+#include"module_const.h"
+
+
+/**
+ * @brief 当某张人卡在某个区域的时间超过指定值时,会发出区域超时告警
+ */
+class module_area_timeout_person:public singleton_base<module_area_timeout_person>
+{
+private:
+    friend class singleton_base<module_area_timeout_person>;
+    module_area_timeout_person()
+    {
+    }
+
+public:
+    void on_enter(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+    {
+        //中途服务器宕机处理
+        if(auto ev_ptr = event_list::instance()->get(card_ptr->m_id, ET_CARD_AREA_OVER_TIME_PERSON))
+        {
+            c->m_enter_time = std::chrono::system_clock::to_time_t(ev_ptr->m_cur_time);
+        }
+        else
+        {
+            std::time(&c->m_enter_time);
+        }
+    }
+
+    void on_hover(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+    {
+       auto area_ptr = c->m_area;
+
+        int seconds = tool_time::elapse_seconds(c->m_enter_time);
+
+        if(seconds > area_ptr->m_limit_time_second)//发生告警
+        {
+            auto ev_ptr = event_list::instance()->get(card_ptr->m_id, ET_CARD_AREA_OVER_TIME_PERSON);
+            if(ev_ptr)
+            {
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value = area_ptr->m_limit_time_second;
+                ev_ptr->m_cur_value = seconds;
+            }
+            else//从没有告警状态转化为告警状态
+            {
+                auto ev_ptr = event_list::create_event_card(card_ptr->m_id, card_ptr->m_type, ET_CARD_AREA_OVER_TIME_PERSON);
+
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value = area_ptr->m_limit_time_second;
+                ev_ptr->m_cur_value = seconds;
+
+                //保存到数据库
+                event_list::save_event(ev_ptr);
+
+                event_list::instance()->add(ev_ptr->get_list_id(),ev_ptr);
+
+                log_info("人卡区域超时开始:卡id=%d,卡type=%d,区域id=%d,时间门限=%d,呆的时间长度=%d",
+                         card_ptr->m_id, card_ptr->m_type,
+                         area_ptr->id(), area_ptr->m_limit_time_second, seconds);
+            }
+        }
+    }
+
+    void on_leave(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+    {
+        auto ev_ptr = event_list::instance()->get(card_ptr->m_id, ET_CARD_AREA_OVER_TIME_PERSON);
+        if(ev_ptr)//有超时告警就删除
+        {
+            auto area_ptr = c->m_area;
+
+            event_list::copy_event(card_ptr, ev_ptr);
+
+            ev_ptr->m_limit_value = area_ptr->m_limit_time_second;
+            ev_ptr->m_cur_value = tool_time::elapse_seconds(c->m_enter_time);
+
+            ev_ptr->m_status = ES_END;
+
+            //保存到数据库
+            event_list::save_event(ev_ptr);
+
+            log_info("人卡区域超时结束:卡id=%d,卡type=%d,区域id=%d,时间门限=%d",
+                     card_ptr->m_id, card_ptr->m_type,
+                     area_ptr->id(), area_ptr->m_limit_time_second);
+        }
+    }
+};
+
+
+#endif // MODULE_AREA_TIMEOUT_PERSON_H

+ 0 - 9
module_service/module_attendance_person.cpp

@@ -1,9 +0,0 @@
-#include "module_attendance_person.h"
-#include "log.h"
-#include"module_const.h"
-#include <time.h>
-#include<chrono>
-#include<stdio.h>
-#include<db_api/CDBConnPool.h>
-
-

+ 171 - 78
module_service/module_attendance_person.h

@@ -8,6 +8,7 @@
   *@date 2018-08-03
 */
 
+#include"math.h"
 #include <memory>
 #include <mutex>
 #include <map>
@@ -34,116 +35,208 @@ private:
 public:
     /**
      * @brief 进入分站覆盖区域处理,考勤
-     * @param card_id
-     * @param enter_site
+     * @param card_ptr
+     * @param site_ptr
      */
-    void enter_site(uint64_t card_id,int enter_site,uint64_t type)
+    void enter_site(std::shared_ptr<card_location_base> card_ptr, std::shared_ptr<site> site_ptr)
     {
-        if(!tool_other::is_person(type))
-        {
-            return;
-        }
-
-        auto card_ptr=card_list::instance()->get(tool_other::to_uint64_cardid(type, card_id));
-        if(!card_ptr)
-        {
-            log_error("卡不存在card_id=%ld, type=%ld", card_id, type);
-            return;
-        }
-
-        auto site_ptr=sit_list::instance()->get(enter_site);
-        if(!site_ptr)
-        {
-            log_error("在分站列表中找不到分站,分站id=%d", enter_site);
-            return;
-        }
+        auto site_area_ptr = card_ptr->get_site_area();
 
         // 从井下切换到井上为考勤结束
-        if(tool_other::is_up_site(site_ptr->m_reader_type_id))
+        if(site_ptr->is_up_site())
         {
-            if(tool_other::is_attendance(card_ptr->m_stat_attendance))
+            if(site_area_ptr->is_attendance())
             {
                 //考勤结束
-                card_ptr->m_stat_attendance=AS_NOT_ATTENDANCE;
+                site_area_ptr->m_stat_attendance=AS_NOT_ATTENDANCE;
 
                 //作为一条结束考勤记录保存到数据库
                 tool_db::save_attendance(card_ptr);
 
-                log_debug("人卡考勤结束:site_id=%d,reader_type_id=%d,stat_attendance=%d",
-                          site_ptr->m_id,site_ptr->m_reader_type_id,card_ptr->m_stat_attendance);
+                person_card_up_mine(card_ptr);
+
+                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,site_area_ptr->m_stat_attendance);
             }
         }
-
-        // 从井上切换到井下为考勤开始
-        if(!tool_other::is_up_site(site_ptr->m_reader_type_id))
+        else// 从井上切换到井下为考勤开始
         {
-            if(!tool_other::is_attendance(card_ptr->m_stat_attendance))
+            if(!site_area_ptr->is_attendance())
             {
                 //考勤开始
-                card_ptr->m_stat_attendance=AS_ATTENDANCE;
-                //card_ptr->m_attendance_start_time=std::chrono::system_clock::now();
-                std::time_t start= card_ptr->m_time/1000;
-                card_ptr->m_attendance_start_time=std::chrono::system_clock::from_time_t(start);
+                site_area_ptr->m_stat_attendance=AS_ATTENDANCE;
+
+                site_area_ptr->m_attendance_start_time=
+                        std::chrono::system_clock::time_point(std::chrono::milliseconds(card_ptr->m_time));
 
                 //作为一条开始考勤记录保存到数据库
                 tool_db::save_attendance(card_ptr);
 
-                log_debug("人卡考勤开始:site_id=%d,reader_type_id=%d,stat_attendance=%d",
-                          site_ptr->m_id,site_ptr->m_reader_type_id,card_ptr->m_stat_attendance);
+                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,site_area_ptr->m_stat_attendance);
             }
         }
     }
 
+//    /**
+//     * @brief 离开现有分站处理,记录现有分站的进出时间和地点
+//     * @param card_ptr
+//     * @param site_ptr
+//     */
+//    void leave_site(std::shared_ptr<card_location_base> card_ptr, std::shared_ptr<site> site_ptr)
+//    {
+
+//    }
+
     /**
-     * @brief 离开现有分站处理,记录现有分站的进出时间和地点
-     * @param card_id
-     * @param enter_site
+     * @brief 手工升井函数
      */
-    void leave_site(uint64_t card_id,int enter_site,uint64_t type)
+    void handle_up_mine(sio::message::ptr const& data)
     {
+        std::vector<sio::message::ptr> card_vec;
+        if(!tool_map::try_get_value(card_vec, JSON_ROOT_KEY_DATA, data) || card_vec.size() == 0)
+        {
+            log_error("手工升井,web发来的数据data字段为空 或者不是数组");
+            return;
+        }
+
+        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)))
+            {
+                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(card_list::to_id64(type, id));
+            if(card_ptr && card_ptr->is_person())
+            {
+                std_debug("手工升井,处理,卡id=%d,卡type=%d", id, type);
+                log_info("手工升井,处理,卡id=%d,卡type=%d", id, type);
 
+                auto site_area_ptr = card_ptr->get_site_area();
+                if(site_area_ptr->is_attendance())
+                {
+                    //考勤结束
+                    site_area_ptr->m_stat_attendance=AS_NOT_ATTENDANCE;
+
+                    //作为一条结束考勤记录保存到数据库
+                    tool_db::save_attendance(card_ptr);
+                }
+
+                person_card_up_mine(card_ptr);
+            }
+            else
+            {
+                log_error("手工升井,在全局列表中找不到卡,卡id=%d,卡type=%d", id, type);
+            }
+        }
     }
-    /**
-     * @brief 手工升井函数
-     */
-    void up_well(std::vector<std::string>& card_ids)
+
+private:
+    ///1.人卡升井要发送json串给前端。 具体看card_up_mine函数,
+    ///3.人卡升井要清除卡相关信息,区域相关,分站相关,考勤相关,清除定时器,
+    ///速度,状态 呼救 呼叫 告警相关。即保留基础信息,其他的重置。
+    static void person_card_up_mine(std::shared_ptr<card_location_base> card_ptr)
     {
-        //    std::chrono::system_clock::time_point time_current = std::chrono::system_clock::now();
-        //    std::vector<std::string> ids;
-
-        //    {
-        //        //std::lock_guard<std::mutex> lock(m_mutex);
-        //        for(auto iter = card_ids.begin(); iter != card_ids.end(); ++iter)
-        //        {
-        //            auto iter_card = g_card_map_ptr->find(*iter);
-        //            if(g_card_map_ptr->end() == iter_card)
-        //            {
-        //                continue;
-        //            }
-        //            if(!iter_card->second->is_attendance) // 该卡当前没在井下,不能形成考勤记录
-        //            {
-        //                // 该卡当前没在井下,不能形成考勤记录
-        //                continue;
-        //            }
-
-        ////            // 添加到考勤处理列表
-        ////            iter_card->second->last_status_well = enum_status_well::STATUS_WELL_UP;
-        ////            iter_card->second->time_end = time_current;
-        ////            attendances.push_back(iter_card->second);
-
-        //            ids.push_back(*iter);
-        //        }
-        //    }
-
-        //    // 插入考勤记录到数据库
-        //    for(auto iter = ids.begin(); iter != ids.end(); ++iter)
-        //    {
-        //        g_card_map_ptr->erase(*iter);
-
-        //        // 插入考勤记录到数据库
-        //    }
+        if (card_ptr->m_display)
+        {
+            std::string str = to_json_card_up(card_ptr);
+            if(!str.empty())
+            {
+                tool_other::send_json(JSON_CMD_VALUE_PUSH, str);
+            }
+        }
+
+        // 升井 删除所有报警信息
+        for(int i=0; i < CARD_EVENT_COUNT_MAX; i++ )
+        {
+            if (i == EVENT_TYPE::ET_CARD_LOW_POWER_SERIOUS)
+            {
+                continue;
+            }
+
+            auto ev_ptr = event_list::instance()->get(card_ptr->m_id, static_cast<EVENT_TYPE>(i));
+            if(ev_ptr) //
+            {
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_status = ES_END;
+
+                event_list::save_event(ev_ptr);
+            }
+        }
+
+        card_ptr->clear();
     }
 
+    ///升井json发给web
+    static std::string to_json_card_up(std::shared_ptr<card_location_base> card_ptr)
+    {
+        auto site_area_ptr = card_ptr->get_site_area();
+        if(!site_area_ptr || site_area_ptr->is_invalid())
+        {
+            return "";
+        }
+
+        rapidjson::Document doc(rapidjson::kObjectType);
+        rapidjson::Value data(rapidjson::kArrayType);
+        rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();
+
+        //卡号
+        std::string id = card_list::to_id64_str(card_ptr->m_type, card_ptr->m_id);
+        tool_json::push_back(data, id, allocator);
+
+        //x,y坐标
+        data.PushBack(card_ptr->x, allocator);
+        data.PushBack(card_ptr->y, allocator); //CFunctions::round(card->y_offset_after(),2)
+
+        //入井时间戳
+        uint64_t t = tool_time::to_ms(site_area_ptr->m_attendance_start_time);	//转为ms
+        data.PushBack(t, allocator);
+
+        //进入区域时间戳
+        data.PushBack(0, allocator);
+
+        //接收时间戳
+        data.PushBack(0, allocator);
+        //工作时长
+        t = tool_time::elapse_ms(site_area_ptr->m_attendance_start_time);	//转为ms
+        data.PushBack(t, allocator);
+
+        //地图编号
+        data.PushBack(0, allocator);
+        //区域编号
+        data.PushBack(0, allocator);
+        //部门编号
+        data.PushBack(card_ptr->m_deptid, allocator);
+
+        //状态
+        data.PushBack(0, allocator);
+        //运行状态
+        data.PushBack(card_ptr->m_stat, allocator);
+        //业务状态
+        data.PushBack(0, allocator);
+        //速度
+        data.PushBack(card_ptr->m_speed, allocator);
+
+        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, data, allocator);
+
+        rapidjson::StringBuffer sb;
+        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+        doc.Accept(writer);
+
+        return sb.GetString();
+    }
 };
 
 #endif // MODULE_ATTENDANCE_PERSON_H

+ 0 - 2
module_service/module_attendance_vehicle.cpp

@@ -1,2 +0,0 @@
-#include "module_attendance_vehicle.h"
-

+ 47 - 20
module_service/module_attendance_vehicle.h

@@ -16,6 +16,7 @@
 #include <vector>
 #include <set>
 #include "module_const.h"
+#include "common_tool.h"
 
 /**
  * @brief 车辆进入某些特定区域,结束考勤;从特定区域进入其他区域,开始考勤, 单例
@@ -29,54 +30,80 @@ private:
     }
 
 public:
-    void on_enter(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
+    void on_enter(std::shared_ptr<card_location_base> card_ptr, std::shared_ptr<area_hover>&c)
     {
+        auto site_area_ptr = card_ptr->get_site_area();
+        if(!site_area_ptr || site_area_ptr->is_invalid())
+        {
+            return;
+        }
+
         auto area_ptr = c->m_area;
 
         //从考勤状态转换为结束考勤
-        if(!tool_other::is_attendance_area(area_ptr->m_id, card_ptr->m_id))
+        if(!is_attendance_area(area_ptr->m_id, card_ptr->m_id))
         {
-            if(tool_other::is_attendance(card_ptr->m_stat_attendance))
+            if(site_area_ptr->is_attendance())
             {
                 //考勤结束
-                card_ptr->m_stat_attendance=AS_NOT_ATTENDANCE;
+                site_area_ptr->m_stat_attendance=AS_NOT_ATTENDANCE;
 
                 //作为一条结束考勤记录保存到数据库
                 tool_db::save_attendance(card_ptr);
 
-                log_debug("车卡考勤结束:area_id=%d,card_id=%d,stat_attendance=%d",
-                          area_ptr->m_id,card_ptr->m_id,card_ptr->m_stat_attendance);
+                log_info("车卡考勤结束:卡id=%d,卡type=%d,区域id=%d, stat_attendance=%d",
+                          card_ptr->m_id, card_ptr->m_type,
+                          area_ptr->m_id,site_area_ptr->m_stat_attendance);
             }
         }
-
-        if(tool_other::is_attendance_area(area_ptr->m_id, card_ptr->m_id))//没在考勤状态转换为考勤状态
+        else//没在考勤状态转换为考勤状态
         {
-            if(!tool_other::is_attendance(card_ptr->m_stat_attendance))
+            if(!site_area_ptr->is_attendance())
             {
                 //考勤开始
-                card_ptr->m_stat_attendance=AS_ATTENDANCE;
-                //card_ptr->m_attendance_start_time=std::chrono::system_clock::now();
-                std::time_t start= card_ptr->m_time/1000;
-                card_ptr->m_attendance_start_time=std::chrono::system_clock::from_time_t(start);
+                site_area_ptr->m_stat_attendance=AS_ATTENDANCE;
+                site_area_ptr->m_attendance_start_time=
+                        std::chrono::system_clock::time_point(std::chrono::milliseconds(card_ptr->m_time));
 
                 //作为一条开始考勤记录保存到数据库
                 tool_db::save_attendance(card_ptr);
 
-                log_debug("车卡考勤开始:area_id=%d,card_id=%d,stat_attendance=%d",
-                          area_ptr->m_id,card_ptr->m_id,card_ptr->m_stat_attendance);
+                log_info("车卡考勤开始:卡id=%d,卡type=%d,区域id=%d, stat_attendance=%d",
+                          card_ptr->m_id, card_ptr->m_type,
+                          area_ptr->m_id,site_area_ptr->m_stat_attendance);
             }
         }
     }
 
-    void on_hover(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
-    {
-    }
+//    void on_hover(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+//    {
+//    }
 
 
-    void on_leave(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
+//    void on_leave(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c)
+//    {
+//    }
+
+private:
+    bool is_attendance_area(int area_id, uint32_t vehicle_id)
     {
+        char sql[1024] = {'\0'};
+
+        sprintf(sql,
+                "select vt.att_rule_id  from dat_att_rule_area a, dat_att_rule_vehicle_type  vt, dat_vehicle v\
+                where a.area_id=%d and v.vehicle_id=%d \
+                and vt.vehicle_type_id=v.vehicle_type_id \
+                and a.att_rule_id=vt.att_rule_id;",
+                area_id, vehicle_id);
+        std::string Error;
+        YADB::CDBResultSet DBRes;
+        sDBConnPool.Query(sql,DBRes,Error);
+        uint64_t nCount = DBRes.GetRecordCount( Error );
+
+        std_debug("车卡考勤区域查询:nCount=%d,sql=%s", nCount, sql);
+
+        return  (nCount > 0);
     }
 };
-typedef std::shared_ptr<module_attendance_vehicle>  module_attendance_vehicle_ptr;
 
 #endif // MODULE_ATTENDANCE_VEHICLE_H

+ 170 - 132
module_service/module_call.cpp

@@ -7,44 +7,6 @@
 #include <chrono>
 #include<algorithm>
 
-/**
- * @brief 呼叫类型 全员 定员
- */
-enum CALL_CARD_TYPE
-{
-    /// 全员呼叫
-    CCT_CALL_ALL = 0,
-    /// 定员
-    CCT_CALL_APOINT=1,
-};
-
-/**
- * @brief 呼叫等级 一般呼叫  紧急呼叫
- */
-enum CALL_CARD_LEVEL
-{
-    /// 呼叫等级: 1  一般呼叫
-    CALL_LEVEL_NORMAL=1,
-    /// 呼叫等级: 2  紧急呼叫
-    CALL_LEVEL_CRITICAL=2
-};
-
-/**
- * @brief 呼叫状态
- */
-enum CALL_STATE{
-    ///无呼叫信息
-    CALL_NONE = 0,
-    ///呼叫成功
-    CALL_SUCCESSED = 1,
-    ///呼叫中
-    CALL_ING = 2,
-    ///呼叫失败
-    CALL_FAILED = 3,
-
-    ///呼叫结束
-    CALL_END=100
-};
 
 void module_call::run()
 {
@@ -57,9 +19,21 @@ void module_call::run()
         return ;
     }
     //转发给web
-    swsClientMgr.send(JSON_CMD_VALUE_PUSH, to_call_card_list_json(arr));
+    tool_other::send_json(JSON_CMD_VALUE_PUSH, to_call_card_list_json(arr));
 
     //将呼叫命令发送给标识卡终端
+    call_site_map site_map;
+    get_site_map(arr, site_map);
+
+    if(!site_map.empty())
+    {
+        send_to_sites(site_map);
+    }
+}
+
+void module_call::rev_from_card_resp(std::shared_ptr<card_location_base> card_ptr)
+{
+    card_ptr->get_mine_tool()->m_status_call = CALL_SUCCESSED;
 }
 
 /*
@@ -77,28 +51,31 @@ web发给采集:发起呼叫
     }
 }
 */
-void module_call::accept_call(const rapidjson::Document& node_data)
+void module_call::accept_call(sio::message::ptr const& data)
 {
-    int call_type = -1, call_level = -1, call_time_out;
+    int call_type = -1, call_level = -1, call_time_interval=-1;
+    uint32_t call_time_out = 0;
     std::string user_name;
 
-    if(!tool_json::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, node_data)
-            || !tool_json::try_get_value(call_level, JSON_KEY_CALL_CARD_CALL_LEVEL, node_data)
-            || !tool_json::try_get_value(call_time_out, JSON_KEY_CALL_CARD_CALL_TIME_OUT, node_data)
-            || !tool_json::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, node_data)
+    if(!tool_map::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, data)
+            || !tool_map::try_get_value(call_level, JSON_KEY_CALL_CARD_CALL_LEVEL, data)
+            || !tool_map::try_get_value(call_time_out, JSON_KEY_CALL_CARD_CALL_TIME_OUT, data)
+            || !tool_map::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, data)
+            || !tool_map::try_get_value(call_time_interval, JSON_KEY_CALL_CARD_CALL_TIME, data)
             )
     {
-        log_error("收到的json不对,解析不出int call_type = -1, call_level = -1, call_time_out,user_name");
-        return;
+        log_error("发起呼叫: 收到的json不对,解析不出call_type = -1, call_level = -1, \
+                  call_time_out=-1, call_time_interval=-1,user_name");
+                return;
     }
 
     if(user_name.empty())
     {
-        log_error("user_name用户名为空");
+        log_error("发起呼叫: user_name用户名为空");
         return;
     }
 
-    std::vector<call_card_ptr> arr;//结果集
+    std::vector<call_card_ptr> result_arr;//结果集
 
     call_user_ptr user_ptr;
     if(CCT_CALL_ALL==call_type)// 全员
@@ -107,6 +84,7 @@ void module_call::accept_call(const rapidjson::Document& node_data)
 
         user_ptr->call_time=std::chrono::system_clock::now();
         user_ptr->call_time_out=call_time_out;
+        user_ptr->call_time_interval = call_time_interval;
         user_ptr->call_type_id=call_type;
         user_ptr->call_level_id=call_level;
         user_ptr->user_name=user_name;
@@ -114,11 +92,12 @@ void module_call::accept_call(const rapidjson::Document& node_data)
         call_card_ptr temp(new call_card());
         copy(user_ptr, temp);
         temp->cardid = CCT_CALL_ALL; //全员卡
+        temp->call_state = CALL_ING;
 
-        arr.push_back(temp);//增加到结果集中
+        result_arr.push_back(temp);//增加到结果集中
 
         //添加全员卡
-        user_ptr->cards.insert(std::make_pair(CCT_CALL_ALL, temp));
+        user_ptr->cards.insert(std::make_pair(temp->cardid, temp));
 
         //更新用户信息
         std::lock_guard<std::mutex> lock(_mutex);
@@ -129,7 +108,7 @@ void module_call::accept_call(const rapidjson::Document& node_data)
         std::lock_guard<std::mutex> lock(_mutex);
 
         auto user_map_ptr = _map.find(user_name);
-        if(user_map_ptr==_map.end())//没有这个用户就新建并加入
+        if(_map.end() == user_map_ptr)//没有这个用户就新建并加入
         {
             user_ptr=call_user_ptr(new call_user());
             _map[user_name]=user_ptr;
@@ -138,7 +117,8 @@ void module_call::accept_call(const rapidjson::Document& node_data)
         {
             user_ptr=user_map_ptr->second;
             // 如果有全员,定员不生效
-            if(user_ptr->cards.size()==1 && CCT_CALL_ALL == user_ptr->cards[CCT_CALL_ALL]->cardid)
+            auto card_temp = user_ptr->cards.find(CCT_CALL_ALL);
+            if(user_ptr->cards.end() != card_temp)
             {
                 return;
             }
@@ -147,33 +127,30 @@ void module_call::accept_call(const rapidjson::Document& node_data)
         //更新用户信息
         user_ptr->call_time=std::chrono::system_clock::now();
         user_ptr->call_time_out=call_time_out;
+        user_ptr->call_time_interval = call_time_interval;
         user_ptr->call_type_id=call_type;
         user_ptr->call_level_id=call_level;
         user_ptr->user_name=user_name;
 
-        auto node_cards_ptr = node_data.FindMember(JSON_KEY_CALL_CARD_CARDS);
-        if(node_data.MemberEnd()==node_cards_ptr)
-        {
-            return;
-        }
-        const rapidjson::Value& node_cards = node_cards_ptr->value;
-        if(!node_cards.IsArray())
+        std::vector<sio::message::ptr> card_vec;
+        if(!tool_map::try_get_value(card_vec, JSON_KEY_CALL_CARD_CARDS, data) || card_vec.size() == 0)
         {
+            log_error("发起呼叫,web发来的数据JSON_KEY_CALL_CARD_CARDS字段为空 或者不是数组");
             return;
         }
 
-        add_cards_to_user(call_level, node_cards, user_ptr);
+        add_cards_to_user(card_vec, user_ptr);
 
         for(auto& it:user_ptr->cards)//添加到结果集中
         {
-            arr.push_back(it.second);
+            result_arr.push_back(it.second);
         }
     }
 
     //组装json发送给web
-    if(!arr.empty())
+    if(!result_arr.empty())
     {
-        response_accept_call(arr);
+        response_accept_call(result_arr);
     }
 }
 
@@ -203,7 +180,7 @@ void module_call::response_accept_call(std::vector<call_card_ptr> cards)
     doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator);
     doc.AddMember(JSON_ROOT_KEY_DATA, node_cards, allocator);
 
-    swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
+    tool_other::send_json(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
 }
 
 
@@ -218,29 +195,31 @@ void module_call::response_accept_call(std::vector<call_card_ptr> cards)
 //	  cards: this.cards // 取消呼叫卡  //旧代码为map格式 [{ stationid: 0 }]
 //	}
 //}
-void module_call::accept_cancel(const rapidjson::Document& node_data)
+void module_call::accept_cancel(sio::message::ptr const& node_data)
 {
-    int call_type = -1, call_level = -1;
+    int call_type = -1;//, call_level = -1;
     std::string user_name;
+    int64_t call_time;
 
-    if(!tool_json::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, node_data)
-            || !tool_json::try_get_value(call_level, JSON_KEY_CALL_CARD_CALL_LEVEL, node_data)
-            || !tool_json::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, node_data)
+    if(!tool_map::try_get_value(call_type, JSON_KEY_CALL_CARD_CALL_TYPE, node_data)
+            || !tool_map::try_get_value(call_time, JSON_KEY_CALL_CARD_CALL_TIME, node_data)
+            || !tool_map::try_get_value(user_name, JSON_KEY_CALL_CARD_USER_NAME, node_data)
             )
     {
-        log_error("收到的json不对,解析不出int call_type = -1, call_level = -1,user_name");
+        log_error("取消呼叫: 收到的json不对,解析不出int call_type = -1, call_level = -1,user_name");
         return;
     }
 
     if(user_name.empty())
     {
-        log_error("user_name用户名为空");
+        log_error("取消呼叫: user_name用户名为空");
         return;
     }
 
     call_user_ptr result_user_ptr(new call_user());
     result_user_ptr->call_type_id=call_type;
-    result_user_ptr->call_level_id=call_level;
+    //    result_user_ptr->call_level_id=call_level;
+    result_user_ptr->call_time = std::chrono::system_clock::time_point(std::chrono::milliseconds(call_time));
     result_user_ptr->user_name=user_name;
 
     //取消呼叫有两种:
@@ -254,14 +233,10 @@ void module_call::accept_cancel(const rapidjson::Document& node_data)
     }
     else// 取消定员呼叫
     {
-        auto node_cards_ptr = node_data.FindMember(JSON_KEY_CALL_CARD_CARDS);
-        if(node_data.MemberEnd()==node_cards_ptr)
-        {
-            return;
-        }
-        const rapidjson::Value& node_cards = node_cards_ptr->value;
-        if(!node_cards.IsArray())
+        std::vector<sio::message::ptr> card_vec;
+        if(!tool_map::try_get_value(card_vec, JSON_KEY_CALL_CARD_CARDS, node_data) || card_vec.size() == 0)
         {
+            log_error("取消呼叫: web发来的数据cards字段为空 或者不是数组");
             return;
         }
 
@@ -274,22 +249,29 @@ void module_call::accept_cancel(const rapidjson::Document& node_data)
             user_ptr=it_map->second;
         }
 
-        uint64_t id_card;
-        for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i)
+        std::vector<sio::message::ptr>::const_iterator it_card = card_vec.begin();
+        std::string s_card_id;
+        for(; it_card != card_vec.end(); ++it_card)
         {
-            if(!tool_json::try_get_value( id_card, JSON_KEY_CALL_CARD_CARD_ID, node_cards[i])
-                    || 0==id_card
-                    )
+            if(!tool_map::try_get_value(s_card_id, JSON_KEY_CALL_CARD_CARD_ID, (*it_card)))
             {
+                log_error("取消呼叫: web发来的数据 card_id 格式不对");
                 continue;
             }
 
+            uint32_t id = tool_other::id64_to_id(s_card_id);
+            int type= tool_other::id64_to_type(s_card_id);
+
+            std_debug("取消呼叫: cardid=%d, cardtype=%d", id, type);
+            log_info("取消呼叫: cardid=%d, cardtype=%d", id, type);
+
             call_card_ptr card_ptr(new call_card());
-            card_ptr->cardid = id_card;
+            card_ptr->cardid = id;
+            card_ptr->cardtype = type;
 
-            result_user_ptr->cards[id_card]=card_ptr;//增加到结果集中
+            result_user_ptr->cards[card_ptr->cardid]=card_ptr;//增加到结果集中
 
-            user_ptr->cards.erase(id_card);//删除这个卡
+            user_ptr->cards.erase(card_ptr->cardid);//删除这个卡
         }
 
         // 没有呼叫信息,删除该用户记录
@@ -302,8 +284,8 @@ void module_call::accept_cancel(const rapidjson::Document& node_data)
     //如果要取消呼叫的用户下没有卡,建一张CCT_CALL_ALL卡返回
     if(result_user_ptr->cards.empty())
     {
-        result_user_ptr->call_level_id=call_level;
-        result_user_ptr->call_time=std::chrono::system_clock::now();
+        //        result_user_ptr->call_level_id=call_level;
+        //result_user_ptr->call_time=std::chrono::system_clock::now();
         result_user_ptr->call_time_out=0;
         result_user_ptr->call_type_id=call_type;
         result_user_ptr->user_name=user_name;
@@ -333,8 +315,10 @@ void module_call::response_accept_cancel(const call_user_ptr user_ptr)
     auto& allocator = doc.GetAllocator();
     rapidjson::Value node_data(rapidjson::kObjectType);
 
-    node_data.AddMember(JSON_KEY_CALL_CARD_USER_NAME, rapidjson::StringRef(user_ptr->user_name.c_str()), allocator);
+    tool_json::add_member(node_data, JSON_KEY_CALL_CARD_USER_NAME, user_ptr->user_name, allocator);
+
     node_data.AddMember(JSON_KEY_CALL_CARD_CALL_TIME, tool_time::to_ms(user_ptr->call_time), allocator);
+    node_data.AddMember(JSON_KEY_CALL_CARD_CALL_TYPE, user_ptr->call_type_id, allocator);
 
     rapidjson::Value node_cards(rapidjson::kArrayType);
 
@@ -343,7 +327,9 @@ void module_call::response_accept_cancel(const call_user_ptr user_ptr)
     for(;iter != user_ptr->cards.end();++iter)
     {
         rapidjson::Value node_card(rapidjson::kObjectType);
-        node_card.AddMember(JSON_KEY_CALL_CARD_CARD_ID,iter->second->cardid, allocator);
+
+        tool_json::add_member(node_card, JSON_KEY_CALL_CARD_CARD_ID, iter->second->to_id64_str(), allocator);
+        node_card.AddMember(JSON_KEY_CALL_CARD_CARD_TYPE_ID,iter->second->cardtype, allocator);
 
         node_cards.PushBack(node_card,allocator);
     }
@@ -355,30 +341,9 @@ void module_call::response_accept_cancel(const call_user_ptr user_ptr)
     doc.AddMember(JSON_ROOT_KEY_DATA, node_data, allocator);
 
     //转发给web
-    swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
+    tool_other::send_json(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
 }
 
-//void module_call::get_cancel_user_info(const call_user_ptr user_ptr,
-//                                       const rapidjson::Value& node_cards, call_user_ptr& result_user_ptr)
-//{
-//    copy(user_ptr, result_user_ptr);
-
-//    uint16_t cardid;
-//    for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i)
-//    {
-//        call_card_ptr card_ptr;
-//        const rapidjson::Value& node = node_cards[i];
-//        if(!node.IsUint64() || !find_card(user_ptr, cardid=node.GetUint64(), card_ptr))
-//        {
-//            continue;
-//        }
-
-//        user_ptr->cards.erase(cardid);//从呼叫用户卡中删除
-
-//        result_user_ptr->cards[cardid]=card_ptr;
-//    }
-//}
-
 /*
 登陆时,采集发送web:井下所有呼叫
 {"cmd":"callcardlist","data":[
@@ -420,20 +385,28 @@ std::string module_call::to_call_card_list_json(std::vector<call_card_ptr> arr)
     return tool_json::doc_to_json(doc);
 }
 
-void module_call::add_cards_to_user(int call_level, const rapidjson::Value& node_cards, call_user_ptr user_ptr)
+void module_call::add_cards_to_user(const std::vector<sio::message::ptr>& card_vec, call_user_ptr user_ptr)
 {
-    uint64_t id_card;
-    for(rapidjson::SizeType i = 0; i < node_cards.Size(); ++i)
+    std::vector<sio::message::ptr>::const_iterator it_card = card_vec.begin();
+    for(; it_card != card_vec.end(); ++it_card)
     {
-        if(!tool_json::try_get_value( id_card, JSON_KEY_CALL_CARD_CARD_ID, node_cards[i])
-                || 0==id_card
-                )
+        std::string s_card_id;
+        if(!tool_map::try_get_value(s_card_id, JSON_KEY_CALL_CARD_CARD_ID, (*it_card))
+                ||s_card_id.empty())
         {
+            log_error("发起呼叫,web发来的数据 card_id 格式不对 或为空");
             continue;
         }
 
+        uint32_t id = tool_other::id64_to_id(s_card_id);
+        int type= tool_other::id64_to_type(s_card_id);
+
+        std_debug("发起呼叫 cardid=%d, cardtype=%d", id, type);
+        log_info("发起呼叫 cardid=%d, cardtype=%d", id, type);
+
         call_card_ptr card_ptr(new call_card());
-        card_ptr->cardid = id_card;
+        card_ptr->cardid = id;
+        card_ptr->cardtype = type;
         copy(user_ptr, card_ptr);
 
         card_ptr->call_state = CALL_ING;
@@ -443,17 +416,21 @@ void module_call::add_cards_to_user(int call_level, const rapidjson::Value& node
 }
 
 void module_call::get_user_all_call_cards(call_user_ptr& user_ptr,
-                    const std::unordered_map<uint64_t,std::shared_ptr<card_location_base>>& cardlist,
-                    std::vector<call_card_ptr>& out_data)
+                                          const std::unordered_map<uint64_t,std::shared_ptr<card_location_base>>& cardlist,
+                                          std::vector<call_card_ptr>& out_data)
 {
     auto& cards=user_ptr->cards;
     int status = CALL_ING;
+
     //如果是全员呼叫,增加所有卡
-    if(cards.size()==1 && CCT_CALL_ALL == cards[0]->cardid)
+    auto card_it = cards.find(CCT_CALL_ALL);
+    if(cards.end()!=card_it)
     {
-        uint32_t seconds = tool_time::elapse_seconds(user_ptr->call_time);
-        if(seconds > user_ptr->call_time_out*60)//呼叫超时, 清空全员卡, 并设置呼叫状态为结束
+        if(user_ptr->is_timeout())//呼叫超时, 清空全员卡, 并设置呼叫状态为结束
         {
+            log_info("全员呼叫发送线程:呼叫用户超时,用户名=%s", user_ptr->user_name.c_str());
+            std_debug("全员呼叫发送线程:呼叫用户超时,用户名=%s", user_ptr->user_name.c_str());
+
             cards.clear();
             status=CALL_END;
         }
@@ -461,12 +438,34 @@ void module_call::get_user_all_call_cards(call_user_ptr& user_ptr,
         auto g_it=cardlist.begin();
         for(;g_it!=cardlist.end();++g_it)//如果是全员呼叫,增加所有卡
         {
+            auto site_ptr = g_it->second->get_site_area();
+            if(!site_ptr || site_ptr->is_invalid())
+            {
+                continue;
+            }
+
             call_card_ptr card_ptr(new call_card());
             copy(user_ptr, card_ptr);
             card_ptr->cardid = g_it->second->m_id;
-            //card_ptr->stationid=g_it->second->m_site_id;
+            card_ptr->cardtype = g_it->second->m_type;
+
+            card_ptr->stationid=site_ptr->site_id();
 
             card_ptr->call_state=status;
+            if(CALL_SUCCESSED == g_it->second->get_mine_tool()->m_status_call)
+            {
+                card_ptr->call_state = CALL_SUCCESSED;
+            }
+            else
+            {
+                g_it->second->get_mine_tool()->m_status_call = CALL_ING;
+            }
+
+            if(card_ptr->is_timeout())
+            {
+                g_it->second->get_mine_tool()->m_status_call = 0;
+            }
+            card_ptr->is_display = g_it->second->m_display;
 
             out_data.push_back(card_ptr);
         }
@@ -474,29 +473,68 @@ void module_call::get_user_all_call_cards(call_user_ptr& user_ptr,
         return;
     }
 
+    //定员呼叫
     auto iter_card = cards.begin();
     for(;iter_card!=cards.end();++iter_card)
     {
         //增加到结果集中
         out_data.push_back(iter_card->second);
 
-        auto g_card = cardlist.find(iter_card->second->cardid);
+        auto g_card = cardlist.find(iter_card->second->to_id64());
         if(cardlist.end()==g_card)//在全局卡列表中没有这张卡,
         {
+            log_error("定员呼叫发送线程:全局卡列表中没有这张卡,卡id=%d,卡类型=%d",
+                      iter_card->second->cardid, iter_card->second->cardtype);
+            std_debug("定员呼叫发送线程:全局卡列表中没有这张卡,卡id=%d,卡类型=%d",
+                      iter_card->second->cardid, iter_card->second->cardtype);
+
             iter_card->second->call_state = CALL_FAILED;
+            cards.erase(iter_card--); //在用户下删除这张卡
+
+            continue;
+        }
+
+        auto site_ptr = g_card->second->get_site_area();
+        if(!site_ptr || site_ptr->is_invalid())
+        {
+            log_error("定员呼叫发送线程:全局卡列表中这张卡已经上井或无效,卡id=%d,卡类型=%d",
+                      iter_card->second->cardid, iter_card->second->cardtype);
+            std_debug("定员呼叫发送线程:全局卡列表中这张卡已经上井或无效,卡id=%d,卡类型=%d",
+                      iter_card->second->cardid, iter_card->second->cardtype);
 
+            iter_card->second->call_state = CALL_FAILED;
             cards.erase(iter_card--); //在用户下删除这张卡
+
             continue;
         }
 
         //更新卡的分站id
-        //iter_card->second->stationid = g_card->second->m_site_id;
+        iter_card->second->stationid = site_ptr->site_id();
 
-        uint32_t seconds = tool_time::elapse_seconds(iter_card->second->call_time);
-        if(seconds > iter_card->second->call_time_out*60)//呼叫超时
+        if(CALL_SUCCESSED == g_card->second->get_mine_tool()->m_status_call)
         {
-            iter_card->second->call_state = CALL_END;
+            iter_card->second->call_state = CALL_SUCCESSED;
+        }
+        else
+        {
+            g_card->second->get_mine_tool()->m_status_call = CALL_ING;
+        }
+
+        if(iter_card->second->is_timeout())//呼叫超时
+        {
+            log_info("定员呼叫发送线程:呼叫卡超时,用户名=%s,卡id=%d,卡类型=%d",
+                     iter_card->second->user_name.c_str(),
+                     iter_card->second->cardid, iter_card->second->cardtype);
+            std_debug("定员呼叫发送线程:呼叫卡超时,用户名=%s,卡id=%d,卡类型=%d",
+                      iter_card->second->user_name.c_str(),
+                      iter_card->second->cardid, iter_card->second->cardtype);
 
+            iter_card->second->call_state = CALL_END;
+            if(CALL_SUCCESSED == g_card->second->get_mine_tool()->m_status_call)
+            {
+                iter_card->second->call_state = CALL_SUCCESSED;
+                g_card->second->get_mine_tool()->m_status_call = 0;
+            }
             cards.erase(iter_card--);//在用户下删除这张卡
         }
     }

+ 284 - 49
module_service/module_call.h

@@ -19,6 +19,45 @@
 #include"module_const.h"
 #include"module_web.h"
 
+/**
+ * @brief 呼叫类型 全员 定员
+ */
+enum CALL_CARD_TYPE
+{
+    /// 全员呼叫
+    CCT_CALL_ALL = 0,
+    /// 定员
+    CCT_CALL_APOINT=1,
+};
+
+/**
+ * @brief 呼叫等级 一般呼叫  紧急呼叫
+ */
+enum CALL_CARD_LEVEL
+{
+    /// 呼叫等级: 1  一般呼叫
+    CALL_LEVEL_NORMAL=1,
+    /// 呼叫等级: 2  紧急呼叫
+    CALL_LEVEL_CRITICAL=2
+};
+
+/**
+ * @brief 呼叫状态
+ */
+enum CALL_STATE{
+    ///无呼叫信息
+    CALL_NONE = 0,
+    ///呼叫成功
+    CALL_SUCCESSED = 1,
+    ///呼叫中
+    CALL_ING = 2,
+    ///呼叫失败
+    CALL_FAILED = 3,
+
+    ///呼叫结束
+    CALL_END=100
+};
+
 /**
  * @brief 呼叫模块
  */
@@ -38,21 +77,49 @@ private:
     {
         /// 呼叫卡号 0为全员
         uint32_t cardid;
+        int32_t cardtype;
         /// 分站号  0为全员
         int stationid;
+        ///呼叫类型 全员0, 定员1   CALL_CARD_TYPE
+        int call_type_id;
         /// 呼叫类型:一般1,紧急2  CALL_CARD_LEVEL
         int call_level_id;
         /// 呼叫时长,单位分钟
-        int call_time_out;
+        uint32_t call_time_out;
+
+        int call_time_interval;
         /// 呼叫开始时间
         std::chrono::system_clock::time_point call_time;
         /// 呼叫状态,正在呼叫、呼叫成功
         int call_state;
         ///呼叫人
         std::string user_name;
+
+        bool is_display = true;
+
+        bool is_call_all()
+        {
+            return CCT_CALL_ALL == call_type_id;
+        }
+
+        uint64_t to_id64()
+        {
+            return card_list::to_id64(cardtype, cardid);
+        }
+
+        std::string to_id64_str()
+        {
+            return card_list::to_id64_str(cardtype, cardid);
+        }
+
+        bool is_timeout()
+        {
+            uint32_t seconds = tool_time::elapse_seconds(call_time);
+            return (seconds >= call_time_out*60);
+        }
     };
     typedef std::shared_ptr<call_card>  call_card_ptr;
-    typedef std::map<uint64_t,call_card_ptr>  call_card_map;
+    typedef std::map<int64_t,call_card_ptr>  call_card_map;
 
     /**
      * @brief 呼叫用户信息
@@ -66,34 +133,73 @@ private:
         /// 呼叫等级:一般1,紧急2  CALL_CARD_LEVEL
         int call_level_id;
         /// 呼叫时长,单位分钟
-        int call_time_out;
+        uint32_t call_time_out;
+
+        int call_time_interval;
         /// 呼叫开始时间
         std::chrono::system_clock::time_point call_time;
         ///呼叫卡列表
         call_card_map cards;
+
+        bool is_timeout()
+        {
+            uint32_t seconds = tool_time::elapse_seconds(call_time);
+            return (seconds >= call_time_out*60);
+        }
+
+        bool is_call_all()
+        {
+            return CCT_CALL_ALL == call_type_id;
+        }
     };
     typedef std::shared_ptr<call_user>  call_user_ptr;
     typedef std::map<std::string, call_user_ptr> call_user_map;
 
-public:
+    struct call_site
+    {
+        int32_t site_id;
+        ///呼叫类型 全员0, 定员1   CALL_CARD_TYPE
+        int call_type_id;
+        /// 呼叫等级:一般1,紧急2  CALL_CARD_LEVEL
+        int call_level_id;
+
+        call_card_map cards;
+
+        bool is_call_all()
+        {
+            return CCT_CALL_ALL == call_type_id;
+        }
+    };
+    typedef std::shared_ptr<call_site>  call_site_ptr;
+    typedef std::map<int32_t, call_site_ptr> call_site_map;
 
+public:
     /**
      * @brief web发给采集:发起呼叫
      * @param node_data
      */
-    void accept_call(const rapidjson::Document& node_data);
+    void accept_call(sio::message::ptr const& data);
 
     /**
      * @brief web发给采集:取消呼叫
      * @param node_data
      */
-    void accept_cancel(const rapidjson::Document& node_data);
+    void accept_cancel(sio::message::ptr const& data);
 
     /**
      * @brief 登陆时,采集发送web:请求井下所有呼叫
      */
     std::string accept_login();
 
+    void rev_from_card_resp(std::shared_ptr<card_location_base> card_ptr);
+    /**
+     * @brief
+     */
+    void init(config_file& config)
+    {
+        sleep_ms = std::stoi(config.get("send_call_interval","5000"));
+    }
+
 private:
     /**
      * @brief 采集回复web发起呼叫
@@ -107,9 +213,8 @@ private:
      */
     void response_accept_cancel(const call_user_ptr user_ptr);
 
-
-
-    void add_cards_to_user(int call_level, const rapidjson::Value& node_cards, call_user_ptr user_ptr);
+    void add_cards_to_user(const std::vector<sio::message::ptr>& card_vec,
+                           call_user_ptr user_ptr);
 
     /**
      * @brief 线程函数
@@ -132,8 +237,10 @@ private:
         des->call_time = src->call_time;
         des->call_time_out = src->call_time_out;
         des->cardid = src->cardid;
+        des->cardtype = src->cardtype;
         des->user_name = src->user_name;
         des->stationid = src->stationid;
+        des->call_type_id = src->call_type_id;
     }
 
     void copy(const call_user_ptr src, call_card_ptr des)
@@ -142,8 +249,10 @@ private:
         //des->call_state = src->call_state;
         des->call_time = src->call_time;
         des->call_time_out = src->call_time_out;
+        des->call_time_interval = src->call_time_interval;
         //des->cardid = src->cardid;
         des->user_name = src->user_name;
+        des->call_type_id = src->call_type_id;
     }
 
     /**
@@ -153,8 +262,8 @@ private:
      * @param out_data
      */
     void get_user_all_call_cards(call_user_ptr& user_ptr,
-                        const std::unordered_map<uint64_t,std::shared_ptr<card_location_base>>& cardlist,
-                        std::vector<call_card_ptr>& out_data);
+                                 const std::unordered_map<uint64_t,std::shared_ptr<card_location_base>>& cardlist,
+                                 std::vector<call_card_ptr>& out_data);
 
     /**
      * @brief 获取所有的呼叫卡
@@ -163,8 +272,8 @@ private:
      * @param out_data
      */
     void get_all_call_cards(call_user_map& user_map,
-                        const std::unordered_map<uint64_t,std::shared_ptr<card_location_base>>& cardlist,
-                        std::vector<call_card_ptr>& out_data)
+                            const std::unordered_map<uint64_t,std::shared_ptr<card_location_base>>& cardlist,
+                            std::vector<call_card_ptr>& out_data)
     {
         auto iter_m_map=user_map.begin();
         for(;iter_m_map!=user_map.end();++iter_m_map)
@@ -204,28 +313,32 @@ private:
      * ]
     */
     static void to_node_element(rapidjson::Value& out_elemet,
-                                           const std::shared_ptr<call_card> card_ptr,
-                                           rapidjson::Document::AllocatorType& allocator)
+                                const std::shared_ptr<call_card> card_ptr,
+                                rapidjson::Document::AllocatorType& allocator)
     {
-
-        out_elemet.PushBack(rapidjson::StringRef(card_ptr->user_name.c_str()), allocator);
-        out_elemet.PushBack(card_ptr->cardid, allocator);
+        tool_json::push_back(out_elemet, card_ptr->user_name, allocator);
+        tool_json::push_back(out_elemet, card_ptr->to_id64_str(), allocator);
 
         out_elemet.PushBack(card_ptr->stationid, allocator);
-        out_elemet.PushBack(tool_time::to_ms(card_ptr->call_time), allocator);
+        out_elemet.PushBack(card_ptr->call_time_interval, allocator);
 
-        out_elemet.PushBack(0, allocator);
+        out_elemet.PushBack(card_ptr->call_type_id, allocator);
         out_elemet.PushBack(card_ptr->call_state, allocator);
     }
 
     static void to_node_array(rapidjson::Value& out_array,
-                                                    const std::vector<std::shared_ptr<call_card>> cards,
-                                                    rapidjson::Document::AllocatorType& allocator)
+                              const std::vector<std::shared_ptr<call_card>> cards,
+                              rapidjson::Document::AllocatorType& allocator)
     {
         std::vector<std::shared_ptr<call_card>>::size_type i;
 
         for(i=0; i<cards.size(); i++)
         {
+            if(!cards[i]->is_display)
+            {
+                continue;
+            }
+
             rapidjson::Value node_card(rapidjson::kArrayType);
 
             to_node_element(node_card, cards[i], allocator);
@@ -241,33 +354,155 @@ private:
      */
     std::string to_call_card_list_json(std::vector<call_card_ptr> cards);
 
-//    /**
-//     * @brief 获取取消用户的信息,主要包括用户下要取消呼叫的卡信息
-//     * @param user_ptr
-//     * @param node_cards
-//     * @param result_user_ptr
-//     */
-//    void get_cancel_user_info(const call_user_ptr user_ptr,
-//                              const rapidjson::Value& node_cards, call_user_ptr& result_user_ptr);
-
-//    /**
-//     * @brief 根据卡id在用户下查找是否有此卡
-//     * @param user_ptr
-//     * @param cardid
-//     * @param card_ptr
-//     * @return
-//     */
-//    bool find_card(const call_user_ptr user_ptr, const uint64_t cardid, call_card_ptr& card_ptr)
-//    {
-//        auto it = user_ptr->cards.find(cardid);
-//        if(it!=user_ptr->cards.end())
-//        {
-//            card_ptr = it->second;
-//            return true;
-//        }
-
-//        return false;
-//    }
+    void get_site_map(const std::vector<call_card_ptr>& arr, call_site_map& out_site_map)
+    {
+        auto card_ptr = arr.begin();
+        for(;card_ptr!=arr.end();++card_ptr)
+        {
+            if((*card_ptr)->stationid<1)
+            {
+                continue;
+            }
+
+            auto iter = out_site_map.find((*card_ptr)->stationid);
+            if(out_site_map.end()==iter)
+            {
+                call_site_ptr site_ptr(new call_site());
+                site_ptr->site_id = (*card_ptr)->stationid;
+                site_ptr->call_type_id = (*card_ptr)->call_type_id;
+                site_ptr->call_level_id = (*card_ptr)->call_level_id;
+
+                out_site_map.insert(std::make_pair(site_ptr->site_id, site_ptr));
+
+                iter = out_site_map.find((*card_ptr)->stationid);
+            }
+
+            if(iter->second->is_call_all())
+            {
+                continue;
+            }
+
+            if((*card_ptr)->is_call_all())
+            {
+
+                iter->second->call_type_id = (*card_ptr)->call_type_id;
+                iter->second->cards.clear();
+                continue;
+            }
+
+            iter->second->cards[(*card_ptr)->cardid]=(*card_ptr);
+        }
+    }
+
+    ///发呼叫的报文数据给分站
+    void send_to_sites(call_site_map& site_map)
+    {
+        auto iter_site = site_map.begin();
+
+        for(; iter_site != site_map.end(); ++iter_site)
+        {
+            if(iter_site->second->cards.size() > 254)
+            {
+                log_error("呼叫:分站下卡数量过多:分站id=%d, 卡数=%d",
+                          iter_site->first, iter_site->second->cards.size());
+                continue;
+            }
+
+            std::vector<char> arr;
+
+            //分站地址 4字节,支持大小分站呼叫协议;added by zhuyf 2018/06/04
+            //大小分站的全员呼叫,分站id要求4字节全为FF
+            uint32_t anchor_id = (iter_site->second->is_call_all()? 0xffffffff : static_cast<uint32_t>(iter_site->first));
+            memcpy_uint32(arr,anchor_id);
+
+            //卡数
+            arr.push_back(static_cast<char>(iter_site->second->cards.size()));
+            //呼叫类型
+            arr.push_back(static_cast<char>(iter_site->second->call_type_id));
+
+            if(!iter_site->second->is_call_all())
+            {
+                //循环添加卡信息
+                auto it_card = iter_site->second->cards.begin();
+                for(; it_card != iter_site->second->cards.end(); ++it_card)
+                {
+                    //呼叫类型
+                    arr.push_back(static_cast<char>(it_card->second->call_level_id));
+                    //卡类型
+                    arr.push_back(static_cast<char>(it_card->second->cardtype));
+                    //卡ID长度
+                    int id_len = 4;
+                    arr.push_back(static_cast<char>(id_len));
+                    //卡ID
+                    memcpy_uint32(arr, it_card->second->cardid);
+                }
+            }
+
+            auto sit_ptr = sit_list::instance()->get(iter_site->first);
+            if(!sit_ptr || !sit_ptr->m_clt)
+            {
+                log_error("在全局分站列表中找不到分站 或者sit_ptr->m_clt==null:分站id=%d", iter_site->first);
+            }
+
+            //std::vector<char> arr2 = arr;
+            sit_ptr->m_clt->send(std::move(arr));
+
+            //print_test(std::move(arr2), iter_site->first);
+        }
+    }
+
+    static void print_test(std::vector<char>&& arr, int siteid)
+    {
+        std::string str("呼叫发送的数据帧,分站号=");
+        str.append(std::to_string(siteid));
+        str.append(":");
+
+        char a[4]={0};
+        for(std::vector<char>::size_type i=0; i<arr.size(); i++)
+        {
+            sprintf(a, "%02X ", static_cast<unsigned char>(arr[i]));
+
+            str.append(std::string(a));
+        }
+
+        log_info("%s", str.c_str());
+        std_debug("%s", str.c_str());
+    }
+
+    void static memcpy_uint32(std::vector<char>& arr, uint32_t dwSrc)
+    {
+        char bt = HIBYTE(HIWORD(dwSrc));
+        arr.push_back(bt);
+
+        bt = LOBYTE(HIWORD(dwSrc));
+        arr.push_back(bt);
+
+        bt = HIBYTE(LOWORD(dwSrc));
+        arr.push_back(bt);
+
+        bt = LOBYTE(LOWORD(dwSrc));
+        arr.push_back(bt);
+    }
+
+    static char HIBYTE(uint16_t dwSrc)
+    {
+        return static_cast<char>(dwSrc>>8);
+    }
+
+    static char LOBYTE(uint16_t dwSrc)
+    {
+        return static_cast<char>(dwSrc);
+    }
+
+    static uint16_t HIWORD(uint32_t dwSrc)
+    {
+        return static_cast<uint16_t>(dwSrc>>16);
+    }
+
+    static uint16_t LOWORD(uint32_t dwSrc)
+    {
+        return static_cast<uint16_t>(dwSrc);
+    }
 
 private:
     /// 呼叫用户列表

+ 0 - 8
module_service/module_call_help.cpp

@@ -1,8 +0,0 @@
-#include "module_call_help.h"
-#include "log.h"
-#include <boost/bind.hpp>
-
-
-
-
-

+ 81 - 85
module_service/module_call_help.h

@@ -20,7 +20,7 @@
  * @brief 呼救类
  * 把呼救消息保存到数据库,同时推送给web, 单例
  */
-class module_call_help : public i_thread, public singleton_base<module_call_help>
+class module_call_help : public singleton_base<module_call_help>
 {
 private:
     friend class singleton_base<module_call_help>;
@@ -30,119 +30,115 @@ private:
 
 public:
     /**
-     * @brief 接收到呼救请求
+     * @brief //1.如果已经有呼救告警
+    //2.web取消告警。status_help && status_help_cancel 置为status_help_dealed
+    //3.如果底层已经没有呼救则,取消后,不会再次进行呼救。因为status_help已经不会置为status_error。
+    //4.如果底层还在呼救。这时候不管status_help是何种状态,极大的可能是error.status_help_cancel的存在都会取消。
+    //并且还要保证等待线程把json传送到前端
      */
-    void rev_help(std::shared_ptr<card> card_ptr)
+    void rev_from_card_help(std::shared_ptr<card_location_base> card_ptr)
     {
-//        if(ES_START != card_ptr->m_stat_call_help)
-//        {
-//            card_ptr->m_stat_call_help = ES_START;
-//            //保存到数据库
-//            auto ev_ptr = tool_other::create_event(OT_CARD, card_ptr->m_id, ET_CARD_HELP);
-
-//            tool_other::copy_event(card_ptr, ev_ptr);
+        auto ev_ptr = event_list::instance()->get(card_ptr->m_id, ET_CARD_HELP);
+        if(!ev_ptr)
+        {
+            auto ev_ptr = event_list::create_event_card(card_ptr->m_id, card_ptr->m_type, ET_CARD_HELP);
 
-////            ev_ptr->status = ES_START;
-////            ev_ptr->cur_time = std::chrono::system_clock::now();
+            event_list::copy_event(card_ptr, ev_ptr);
 
-//            //保存到数据库
-//            tool_db::save_event(ev_ptr);
-//            //转发给web
-//            swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::ev_to_json(ev_ptr));
+            //保存到数据库
+            event_list::save_event(ev_ptr);
 
-//            std::lock_guard<std::mutex> lock(_mutex);
-//            tool_other::insert_event(ev_ptr, _map);
-//        }
+            event_list::instance()->add(ev_ptr->get_list_id(), ev_ptr);
+        }
     }
 
     /**
      * @brief 接收到web端发来的处理呼救请求
      * @param data_map
      */
-    void accept_deal_help(std::map<std::string, sio::message::ptr> data_map)
+    void accept_web_deal_help(sio::message::ptr const& data)
     {
-//        uint32_t cardid = data_map[JSON_KEY_ID]->get_int();
-//        //uint64_t ev_id = data_map[JSON_KEY_EVENT_EVENT_ID]->get_int();
-
-//        auto card_ptr = card_list::instance()->get(tool_other::to_uint64_cardid(CT_PERSON, cardid));
-//        if(card_ptr)
-//        {
-//            card_ptr->m_stat_call_help = ES_DEAL_HELP;
-
-//            std::lock_guard<std::mutex> lock(_mutex);
-//            auto ev_ptr = tool_other::find_event(cardid, ET_CARD_HELP, _map);
-//            if(ev_ptr)
-//            {
-//                ev_ptr->m_status = ES_DEAL_HELP;
-//                tool_db::save_event(ev_ptr);
-//            }
-//        }
-////        else
-////        {
-////            std::lock_guard<std::mutex> lock(_mutex);
-////            _map.erase(ev_id);
-////        }
-    }
+        int64_t ev_id = 0;
+        std::string s_card_id;
+        if(!tool_map::try_get_value(s_card_id, JSON_KEY_ID, data)
+                ||!tool_map::try_get_value(ev_id, JSON_KEY_EVENT_EVENT_ID, data))
+        {
+            log_error("处理呼救,web发来的数据 card_id 或 ev_id格式不对");
+            return;
+        }
 
-    /**
-     * @brief web前端有用户登录时,反馈给web所有信息
-     */
-    std::string response_login()
-    {
-        std::vector<std::shared_ptr<ya_event>> arr;
-        get_all_events(arr);
+        uint32_t id = tool_other::id64_to_id(s_card_id);
+        int type = tool_other::id64_to_type(s_card_id);
 
-        if(!arr.empty())//发送给web端
+        auto card_ptr = card_list::instance()->get(card_list::to_id64(type, id));
+        if(card_ptr)
         {
-            return tool_json::evs_to_json(arr);
-        }
+            std_debug("处理呼救,card_id=%d, type=%d,  ev_id=%d", id, type, ev_id);
+            log_info("处理呼救,card_id=%d, type=%d,  ev_id=%d", id, type, ev_id);
 
-        return "";
-    }
+            auto ev_ptr = event_list::instance()->get(id, ET_CARD_HELP);
+            if(ev_ptr && ES_DEAL_HELP != ev_ptr->m_status)
+            {
+                event_list::copy_event(card_ptr, ev_ptr);
 
-    /**
-     * @brief 读取数据库中的告警,初始化告警列表
-     */
-    void init()
-    {}
+                ev_ptr->m_status = ES_DEAL_HELP;
 
-private:
-    /**
-     * @brief 线程函数
-     */
-    void run()
-    {
-        std::vector<std::shared_ptr<ya_event>> arr;
-        get_all_events(arr);
+                event_list::save_event(ev_ptr);
 
-        if(!arr.empty())//发送给web端
+                //删除
+                //event_list::instance()->remove(ev_ptr->get_list_id(), ev_ptr);
+            }
+        }
+        else
         {
-            swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::evs_to_json(arr));
+            log_error("处理呼救,在全局列表中找不到卡,卡id=%d,卡type=%d", id, type);
         }
     }
 
-    /**
-     * @brief 获取所有的告警事件
-     * @param out_data
-     */
-    void get_all_events(std::vector<std::shared_ptr<ya_event>>& arr)
+    static std::string get_json_help()
     {
-        {
-            std::lock_guard<std::mutex> lock(_mutex);
+        rapidjson::Document doc(rapidjson::kObjectType);
+        rapidjson::Value data(rapidjson::kArrayType);
+        rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();
 
-            auto it_map = _map.begin();
-            for(;it_map!=_map.end();++it_map)
+        auto tmp = event_list::instance()->m_map;
+        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)
             {
-                arr.push_back(it_map->second);
-                if(ES_DEAL_HELP== it_map->second->m_status)//删除掉已经处理的
-                {
-                    _map.erase(it_map--);
-                }
+                continue;
             }
+
+            std::string obj_id = it_ev->second->m_obj_id;
+            int type= tool_other::id64_to_type(obj_id);
+
+            rapidjson::Value alarm(rapidjson::kObjectType);
+
+            tool_json::add_member(alarm, JSON_KEY_CARD_ID,it_ev->second->m_obj_id, allocator);
+            alarm.AddMember(JSON_KEY_CARD_TYPE_ID,type, allocator);
+
+            std::string time = tool_time::to_str(it_ev->second->m_cur_time);
+            tool_json::add_member(alarm, "start_time",time, allocator);
+
+            data.PushBack(alarm, allocator);
         }
-    }
 
-    std::map<uint64_t, std::shared_ptr<ya_event>> _map;
+        if(!data.Size())
+        {
+            return "";
+        }
+
+        doc.AddMember(JSON_ROOT_KEY_CMD,"helpme_req", allocator);
+        doc.AddMember(JSON_ROOT_KEY_VERSION,INTERFACE_VERSION, allocator);
+        doc.AddMember(JSON_ROOT_KEY_DATA,data, allocator);
+
+        rapidjson::StringBuffer sb;
+        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+        doc.Accept(writer);
+
+        return sb.GetString();
+    }
 };
 
 

+ 0 - 6
module_service/module_const.cpp

@@ -1,6 +0,0 @@
-#include "module_const.h"
-
-
-int global_constant::AREA_SPEED_COUNT_LIMIT=0;
-
-

+ 21 - 562
module_service/module_const.h

@@ -21,560 +21,9 @@
 
 #include"card.h"
 #include"area.h"
+#include"ya_event.h"
 #include"constdef.h"
-
-#define LENGTH_SQL 2000
-
-///全局常量
-class global_constant
-{
-public:
-//    ///区域超速最小次数门限
-//    static int AREA_SPEED_COUNT_MIN;
-    ///区域超速最大次数门限
-    static int AREA_SPEED_COUNT_LIMIT;
-//    ///区域超速最小时间门限
-//    static int AREA_SPEED_TIME_MIN;
-//    ///区域超速最大时间门限
-//    static int AREA_SPEED_TIME_MAX;
-
-//    ///车辆考勤最小次数门限
-//    static int ATTENDANCE_VEHICLE_COUNT_MIN;
-    ///车辆考勤最大次数门限
-    static int ATTENDANCE_VEHICLE_COUNT_LIMIT;
-//    ///车辆考勤最小时间门限
-//    static int ATTENDANCE_VEHICLE_TIME_MIN;
-//    ///车辆考勤最大时间门限
-//    static int ATTENDANCE_VEHICLE_TIME_MAX;
-};
-
-/**
- * @brief 事件状态
- */
-enum EVENT_STATUS
-{
-    ///事件开始
-    ES_START = 0,
-    ///呼救已处理状态
-    ES_DEAL_HELP = 1,
-    ///事件结束
-    ES_END = 100
-};
-
-//enum STATUS_CARD
-//{
-//    STATUS_NORMAL = 0,				//正常
-//    STATUS_ERROR = 1,
-//    STATUS_ERROR_SERIOUS = 2,
-
-//    STATUS_POWER_LOWER = 1,			//电量低
-//    STATUS_POWER_LOWER_SERIOUS = 2, //电量极低
-//    STATUS_OVER_TIME = 4,			//超时
-//    //STATUS_OVER_COUNT = 1,
-//    STATUS_OVER_SPEED = 8,			//超速
-//    STATUS_AREA_OVER_TIME = 16,		//区域超时
-//    //STATUS_AREA_OVER_COUNT = 1,
-//    STATUS_AREA_OVER_SPEED = 32,	//区域超速
-//    STATUS_AREA_FORBIDDEN = 64,		//进入限制区域
-//    ////STATUS_HELP = 128,				//呼救
-//    STATUS_HELP_DEALED = 256,		//呼救已处理
-//    STATUS_CALL = 512,				//呼叫
-//    STATUS_LOST = 1024				//进入盲区
-//    //STATUS_ERROR_DEALED,
-//};
-
-
-enum EVENT_TYPE{ // 事件类型
-    ET_UNKNOWN = 0,
-    ET_OVER_COUNT_PERSON = 1, // 井下人员超员mp_card_list_over_count_person
-    ET_OVER_COUNT_VEHICLE = 2,    // 井下车辆超员mp_card_list_over_count_person
-
-    ET_AREA_OVER_COUNT_PERSON = 3,	// 区域人员超员
-    ET_AREA_OVER_COUNT_VEHICLE = 4,	// 区域车辆超员
-
-    ET_SECTION_OVER_COUNT = 5, // 路段拥堵
-
-    ET_READER_ERROR = 6, // 分站通信异常
-    ET_ctrl_reader_ERROR = 7, // 控制分站异常
-    ET_LIGHT_ERROR = 8, // 交通灯异常
-    ET_READER_CALL = 9, // 分站呼叫标识卡
-    ET_READER_CALL_CANCEL = 10, // 取消呼叫分站
-
-    ET_CARD_LOW_POWER = 11, // 电量低
-    ET_CARD_LOW_POWER_SERIOUS = 12, // 电量极低
-
-    ET_CARD_OVER_TIME_PERSON = 13, // 人员井下超时mp_card_list_over_time_person
-    ET_CARD_OVER_TIME_VEHICLE = 14, // 车辆井下超时mp_card_list_over_time_vehicle
-    ET_CARD_AREA_OVER_TIME_PERSON = 15, // 人员区域超时
-    ET_CARD_AREA_OVER_TIME_VEHICLE = 16, // 车辆区域超时
-    ET_CARD_AREA_LIMIT_PERSON = 17, // 人员进入限制区域
-    ET_CARD_AREA_LIMIT_VEHICLE = 18, // 车辆进入限制区域
-    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_RUN_THE_RED_LIGHT = 23, // 车辆闯红灯
-    ET_CARD_HELP = 24, // 人员呼救
-    ET_CARD_CALLED = 25, // 人员已被呼叫
-    ET_CARD_PATROL_ERROR = 26, // 人员巡检异常
-    ET_CARD_LOST = 27, // 标识卡信号丢失
-    ET_CARD_DRIVINGFACE_WARNING_AREA = 28,  // 掘进面靠近预警区域告警
-    ET_CARD_NEAR_DRIVINGFACE_VEHICLE=29,// 人员靠近掘进机告警
-    ET_CARD_NEAR_DRIVINGFACE_OVERCOUNT=30,//掘进机附近人员超员
-    ET_UWB_MORE_CARD = 31,
-    ET_CARD_MOTIONLESS=32,
-    CARD_EVENT_COUNT_MAX,
-};
-
-/**
- * @brief 对象类型
- */
-enum OBJECT_TYPE
-{
-    ///矿井
-    OT_MINE = 1,
-    ///区域
-    OT_AREA = 2,
-    ///路段
-    OT_SECTION = 3,
-    ///分站
-    OT_DEVICE_READER = 4,
-    ///交通灯
-    OT_DEVICE_LIGHT = 5,
-    ///控制分站
-    OT_DEVICE_ctrl_reader = 6,
-    ///led屏
-    OT_DEVICE_LED = 7,
-    ///防爆音箱
-    OT_DEVICE_SPEAKER = 8,
-    ///标识卡,包括人员、车辆、自组网等
-    OT_CARD = 9,
-    ///
-    OT_DRIVINGFACE_AREA=10,
-    ///
-    OT_UWB_MORE_CARD=11,
-};
-
-/**
- * @brief 告警事件
- */
-class ya_event
-{
-private:
-    uint64_t m_ev_id;
-public:
-    ya_event(uint64_t e_id):m_cur_time(std::chrono::system_clock::now())
-    {
-        m_ev_id = e_id;
-
-        m_obj_id = 0;
-        m_map_id = 0;
-        m_area_id = 0;
-        x = 0;
-        y = 0;
-        m_limit_value = 0;
-        m_cur_value = 0;
-        m_desc = "";
-        m_landmarkid = 0;
-        m_landmarkdirect = 0;
-        m_landmarkdist = 0;
-
-        m_status=ES_START;
-    }
-    ~ya_event(){}
-public:
-    ///告警状态,开始、结束
-    EVENT_STATUS m_status;
-
-    ///告警类型
-    EVENT_TYPE m_ev_type;
-    ///告警对象类型
-    OBJECT_TYPE m_obj_type;
-    /// 告警对象编号,与告警对象类型对应,如告警对象类型为分站,此字段为分站编号
-    uint64_t m_obj_id;
-    ///当前时间,为告警事件的触发时间,如果状态为开始,则表示开始时间,否则为结束时间
-    std::chrono::system_clock::time_point m_cur_time;
-
-    ///告警所在地图
-    int m_map_id;
-    ///告警所在区域
-    int m_area_id;
-    ///位置
-    double x;
-    ///位置
-    double y;
-    ///告警阈值
-    double m_limit_value;
-    ///当前值
-    double m_cur_value;
-    ///描述
-    std::string m_desc;
-
-    /// 地标信息
-    int m_landmarkid;
-    /// 与地标的距离
-    double m_landmarkdist;
-    /// 所处地标的方向
-    int m_landmarkdirect;
-
-    ///作为事件map列表的id,方便查找;(obj_type<<32| obj_id)
-    uint64_t m_list_id;
-
-    uint64_t get_id(){return m_ev_id;}
-};
-typedef std::shared_ptr<ya_event> event_ptr;
-typedef std::map<uint64_t, std::shared_ptr<ya_event>> event_map;
-typedef std::shared_ptr<event_map> event_map_ptr;
-
-class tool_time
-{
-public:
-    static uint32_t elapse_seconds(std::chrono::system_clock::time_point &start)
-    {
-        return std::chrono::duration_cast<std::chrono::seconds>
-                     (std::chrono::system_clock::now() - start).count();
-    }
-
-    static uint64_t elapse_ms(std::chrono::system_clock::time_point &start)
-    {
-        return std::chrono::duration_cast<std::chrono::milliseconds>
-                     (std::chrono::system_clock::now() - start).count();
-    }
-
-    static uint32_t now_to_seconds()
-    {
-        return std::chrono::duration_cast<std::chrono::seconds>
-                     (std::chrono::system_clock::now().time_since_epoch()).count();
-    }
-
-    static uint64_t now_to_ms()
-    {
-        return std::chrono::duration_cast<std::chrono::milliseconds>
-                     (std::chrono::system_clock::now().time_since_epoch()).count();
-    }
-
-    static uint64_t to_ms(const std::chrono::system_clock::time_point &time)
-    {
-        return std::chrono::duration_cast<std::chrono::milliseconds>
-                     (time.time_since_epoch()).count();
-    }
-
-    static std::string to_str(const std::chrono::system_clock::time_point &time)
-    {
-        char _time[25] = {0};
-        time_t tt = std::chrono::system_clock::to_time_t(time);
-        struct tm *local_time=localtime(&tt);
-        strftime(_time, 22, "%Y-%m-%d %H:%M:%S", local_time);
-
-        return std::string(_time);
-    }
-
-    ///"%u-%u-%u %u:%u:%u.%u"
-    static std::string to_str_ex(const std::chrono::system_clock::time_point &time)
-    {
-        uint64_t mill = std::chrono::duration_cast<std::chrono::milliseconds>(time.time_since_epoch()).count()
-                -std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count()*1000;
-
-        char _time[25] = {0};
-        time_t tt = std::chrono::system_clock::to_time_t(time);
-        struct tm *local_time=localtime(&tt);
-        //strftime(_time, 22, "%Y-%m-%d %H:%M:%S", local_time);
-        sprintf(_time, "%d-%02d-%02d %02d:%02d:%02d.%d", local_time->tm_year+1900,
-                local_time->tm_mon+1, local_time->tm_mday, local_time->tm_hour,
-                local_time->tm_min, local_time->tm_sec, mill);
-
-        return std::string(_time);
-    }
-};
-
-
-class tool_other
-{
-public:
-
-    static bool is_person(int32_t type)
-    {
-        return CT_PERSON == type;
-    }
-
-    static bool is_vehicle(int32_t type)
-    {
-        return CT_VEHICLE == type;
-    }
-
-    static bool is_up_site(int32_t reader_type_id)
-    {
-        return READER_TYPE_ID_UP == reader_type_id;
-    }
-
-    static bool is_attendance(int32_t stat_attendance)
-    {
-        return AS_ATTENDANCE == stat_attendance;
-    }
-
-    static uint64_t to_uint64_cardid(uint64_t type, uint64_t id)
-    {
-        return (type<<32)|id; ////// (类型<<32)|卡号
-    }
-
-    static std::string to_uint64_cardid_str(uint64_t type, uint64_t id)
-    {
-        char sql[15] = {'\0'};
-        sprintf(sql, "%03d%010d", type, id);
-
-        return std::string(sql);
-    }
-
-    static bool is_attendance_area(int area_id, uint64_t vehicle_id)
-    {
-        char sql[1024] = {'\0'};
-
-        sprintf(sql,
-                "select vt.att_rule_id  from dat_att_rule_area a, dat_att_rule_vehicle_type  vt, dat_vehicle v\
-                where a.area_id=%d and v.vehicle_id=%d \
-                and vt.vehicle_type_id=v.vehicle_type_id \
-                and a.att_rule_id=vt.att_rule_id;",
-                area_id, vehicle_id);
-        std::string Error;
-        YADB::CDBResultSet DBRes;
-        sDBConnPool.Query(sql,DBRes,Error);
-        int nCount = DBRes.GetRecordCount( Error );
-
-        log_debug("车卡考勤区域查询:nCount=%d,sql=%s", nCount, sql);
-
-        return  (nCount > 0);
-    }
-
-    static uint64_t to_event_list_id(int obj_id, EVENT_TYPE ev_type)
-    {
-        return (static_cast<uint64_t>(ev_type)<<32)|static_cast<uint64_t>(obj_id);
-    }
-
-    static event_ptr create_event(OBJECT_TYPE obj_type, int obj_id, EVENT_TYPE ev_type)
-    {
-        auto ev_ptr = std::make_shared<ya_event>(tool_time::now_to_ms());
-
-        ev_ptr->m_ev_type = ev_type;
-        ev_ptr->m_obj_type = obj_type;
-        ev_ptr->m_obj_id = static_cast<OBJECT_TYPE>(obj_id);
-
-        ev_ptr->m_list_id = to_event_list_id(obj_id, ev_type);
-
-        return ev_ptr;
-    }
-
-    static void insert_event(const event_ptr ev_ptr, event_map& out_ev_map)
-    {
-        out_ev_map.insert(std::make_pair(ev_ptr->m_list_id, ev_ptr));
-    }
-
-    static void copy_event(const std::shared_ptr<card> card_ptr, event_ptr ev_ptr)
-    {
-        ev_ptr->x = card_ptr->x;
-        ev_ptr->y = card_ptr->y;
-
-//        if(nullptr!=card_ptr->m_area_hover)
-//        {
-//           ev_ptr->m_area_id =  card_ptr->m_area_hover->m_area->id();
-//        }
-
-//        ev_ptr->m_landmarkid = card_ptr->m_landmarkid;
-//        ev_ptr->m_landmarkdist = card_ptr->m_landmarkdist;
-//        ev_ptr->m_landmarkdirect = card_ptr->m_landmarkdirect;
-    }
-
-    static event_ptr find_event(int obj_id, EVENT_TYPE ev_type, const event_map& ev_map)
-    {
-        auto it = ev_map.find(to_event_list_id(obj_id, ev_type));
-        if(ev_map.end() == it)
-        {
-            return nullptr;
-        }
-
-        return it->second;
-    }
-};
-
-
-class tool_db
-{
-private:
-    //void CYAServerDlg::load_his_event_data()
-    //load_alarm_reader()
-
-    static void PushAsync(char* sql)
-    {
-        log_debug("PushAsync记录到队列中:%s\n", sql);
-
-        if(!sDBConnPool.PushAsync(sql))
-        {
-            log_error( "PushAsync记录到队列中失败\n");
-        }
-    }
-
-public:
-    static void save_event(const event_ptr ev_ptr)
-    {
-        char sql[LENGTH_SQL] = {'\0'};
-
-        std::string _time = tool_time::to_str(ev_ptr->m_cur_time);
-
-        sprintf(sql,
-                "INSERT IGNORE INTO his_event_data(event_id, stat, event_type_id, obj_type_id, obj_id, \
-                map_id, area_id, limit_value, cur_value, x, y, cur_time, description, \
-                landmark_id, landmark_dist,direction_mapper_id )\
-                VALUES(%ld, %d, %d, %d, %ld, %d, %d, %.2f, %.2f, %f, %f, '%s', '%s', %d, %d, %10.3f);",
-        ev_ptr->get_id(), ev_ptr->m_status, ev_ptr->m_ev_type, ev_ptr->m_obj_type, ev_ptr->m_obj_id,
-                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(),
-                ev_ptr->m_landmarkid, ev_ptr->m_landmarkdirect, ev_ptr->m_landmarkdist);
-
-        PushAsync(sql);
-    }
-
-    static void save_attendance(const std::shared_ptr<card_location_base> card_ptr)
-    {
-        char sql[LENGTH_SQL] = {0};
-
-        std::string call("add_att_staff");
-        if(tool_other::is_vehicle(card_ptr->m_type))//车卡
-        {
-            call="add_att_vehicle";
-        }
-
-        auto start = card_ptr->m_attendance_start_time;
-        auto end = card_ptr->m_attendance_start_time;
-        if(!tool_other::is_attendance(card_ptr->m_stat_attendance))//考勤结束时间
-        {
-            std::time_t end_t= card_ptr->m_time/1000;
-            end = std::chrono::system_clock::from_time_t(end_t);
-        }
-
-        std::string start_str = tool_time::to_str(start);
-        std::string end_str = tool_time::to_str(end);
-
-        int landmarkid = 0;
-        int landmarkdirect=0;
-        double landmarkdist=0;
-        auto area_hover_ptr = card_ptr->get_area_hover();
-        if(area_hover_ptr)
-        {
-            landmarkid = area_hover_ptr->landmark_id;
-            landmarkdirect = area_hover_ptr->landmark_dir;
-            landmarkdist = area_hover_ptr->landmark_dis;
-        }
-
-        sprintf(sql, "CALL %s(%s, %d, '%s', '%s', %d, %d, %.3f);", call.c_str(),
-                tool_other::to_uint64_cardid_str(card_ptr->m_type, card_ptr->m_id).c_str(),
-                card_ptr->m_id, start_str.c_str(), end_str.c_str(),
-                landmarkid, landmarkdirect, landmarkdist);
-
-        PushAsync(sql);
-    }
-
-    static void save_his_raw_data(const std::shared_ptr<card> card_ptr)
-    {
-//        char sql[LENGTH_SQL] = {0};
-//        std::string _time = tool_time::to_str(card_ptr->m_deal_time);
-
-//        sprintf(sql,
-//                "INSERT IGNORE INTO his_raw_data(card_id, reader_id, antenna_id, reader_stamp, card_stamp, \
-//                fly_time, distance, ranging_type, power_state, accelerate, his_time, rec_time ) \
-//                VALUES(%d, %d, %d, %d, %d, %ld, %4.f, %d, %d, %d, '%s', '%s');",
-//                card_ptr->m_id, card_ptr->m_site_id, card_ptr->m_antenna_id,
-//                card_ptr->m_reader_tickcount, card_ptr->m_time_stamp,
-//                card_ptr->m_flying_time, card_ptr->m_distance, card_ptr->m_ranging_type, card_ptr->m_power_state,
-//                card_ptr->m_accelerate_state,
-//                card_ptr->m_str_his_time.c_str(), card_ptr->m_str_rec_time.c_str());
-    }
-
-
-    static void save_his_location(const std::shared_ptr<card_location_base> card_ptr)
-    {
-//        sprintf_s(_time,
-//            STR_LEN_TIME,
-//            "%u-%u-%u %u:%u:%u.%u",
-//            card->deal_time.wYear,card->deal_time.wMonth,card->deal_time.wDay,
-//            card->deal_time.wHour,card->deal_time.wMinute,card->deal_time.wSecond,card->deal_time.wMilliseconds);
-
-//        if(card->map_id != 0 && card->area_id != 0){
-//            b_exec = true;
-//            switch (card->card_type)
-//            {
-//            case CT_PERSON:
-//                sprintf_s(sql, LENGTH_SQL,
-//                    "INSERT IGNORE INTO his_location_staff(card_id, staff_id, cur_time, x, y, z, map_id, area_id, state,speed,mileage, landmark_id, direction_mapper_id, landmark_dist) VALUES(%s, %d, '%s', %.3f, %.3f, %.3f, %d, %d, %d,%.3f,%.4f, %d, %d, %.4f);",
-//                    card->card_id.c_str(), card->id, _time, card->x_offset_after(), card->y_offset_after(), card->z_offset_after(), card->map_id, card->area_id, card->state,card->get_speed(),card->mileage, card->landmark_id, card->landmark_direction, card->landmark_dis);
-//                break;
-//            case CT_VEHICLE:
-//                sprintf_s(sql, LENGTH_SQL,
-//                    "INSERT IGNORE INTO his_location_vehicle(card_id, vehicle_id, cur_time, x, y, z, map_id, area_id, state,speed,mileage, landmark_id, direction_mapper_id, landmark_dist) VALUES(%s, %d, '%s', %.3f, %.3f, %.3f, %d, %d, %d,%.3f,%.4f, %d, %d, %.4f);",
-//                    card->card_id.c_str(), card->id, _time, card->x_offset_after(), card->y_offset_after(), card->z_offset_after(), card->map_id, card->area_id, card->state,card->get_speed(),card->mileage, card->landmark_id, card->landmark_direction, card->landmark_dis);
-//                break;
-//            }
-//        }
-    }
-
-    static void save_his_area_location_enter(const std::shared_ptr<card_location_base> card_ptr)
-    {
-//        sprintf_s(_time,
-//            STR_LEN_TIME,
-//            "%u-%u-%u %u:%u:%u.%u",
-//            card->deal_time.wYear,card->deal_time.wMonth,card->deal_time.wDay,
-//            card->deal_time.wHour,card->deal_time.wMinute,card->deal_time.wSecond,card->deal_time.wMilliseconds);
-
-//        if(card->map_id != 0 && card->area_id != 0){
-//            b_exec = true;
-//            switch (card->card_type)
-//            {
-//            case CT_PERSON:
-//                sprintf_s(sql, LENGTH_SQL,
-//                    "call add_area_staff(%s, %d, %d, %d, '%s','%s');",
-//                    card->card_id.c_str(), card->id, card->area_id, card->map_id, _time, _time);
-//                break;
-//            case CT_VEHICLE:
-//                sprintf_s(sql, LENGTH_SQL,
-//                    "call add_area_vehicle(%s, %d, %d, %d, '%s','%s');",
-//                    card->card_id.c_str(), card->id, card->area_id, card->map_id, _time, _time);
-//                break;
-//            }
-//        }
-    }
-
-    static void save_his_area_location_leave(const std::shared_ptr<card_location_base> card_ptr)
-    {
-//        sprintf_s(_time,
-//            STR_LEN_TIME,
-//            "%u-%u-%u %u:%u:%u.%u",
-//            card->deal_time.wYear,card->deal_time.wMonth,card->deal_time.wDay,
-//            card->deal_time.wHour,card->deal_time.wMinute,card->deal_time.wSecond,card->deal_time.wMilliseconds);
-
-//        if(card->map_id != 0 && card->area_id != 0){
-//            b_exec = true;
-//            sprintf_s(_time_ex,
-//                STR_LEN_TIME,
-//                "%u-%u-%u %u:%u:%u.%u",
-//                card->enter_area_time.wYear,card->enter_area_time.wMonth,card->enter_area_time.wDay,
-//                card->enter_area_time.wHour,card->enter_area_time.wMinute,card->enter_area_time.wSecond,card->enter_area_time.wMilliseconds);
-
-//            switch (card->card_type)
-//            {
-//            case CT_PERSON:
-//                sprintf_s(sql, LENGTH_SQL,
-//                    "call add_area_staff(%s, %d, %d, %d, '%s','%s');",
-//                    card->card_id.c_str(), card->id, card->area_id, card->map_id, _time_ex, _time);
-//                break;
-//            case CT_VEHICLE:
-//                sprintf_s(sql, LENGTH_SQL,
-//                    "call add_area_vehicle(%s, %d, %d, %d, '%s','%s');",
-//                    card->card_id.c_str(), card->id, card->area_id, card->map_id, _time_ex, _time);
-//                break;
-//            }
-//        }
-    }
-};
-
-
+#include"config_file.h"
 
 /**
  * @brief 线程接口类,重写run函数,改变睡眠时间 sleep_ms
@@ -584,7 +33,7 @@ class i_thread
 public:
     i_thread()
     {
-        sleep_ms=10*1000;
+        sleep_ms=5*1000;
     }
 
     virtual ~i_thread(){}
@@ -596,7 +45,7 @@ public:
     {
         _thread_flag=true;
 
-        _thread_handler=std::thread(&i_thread::thread_proc, this);
+        _thread_handler=boost::thread(&i_thread::thread_proc, this);
     }
 
     /**
@@ -605,7 +54,7 @@ public:
     void stop()
     {
         _thread_flag=false;
-        _thread_handler.join();
+        _thread_handler.interrupt();
     }
 
     ///线程睡眠时间 毫秒
@@ -622,7 +71,7 @@ protected:
 
 private:
     /// 线程句柄
-    std::thread _thread_handler;
+    boost::thread _thread_handler;
     /// 线程标志
     std::atomic<bool> _thread_flag;
 
@@ -630,9 +79,19 @@ private:
     {
         while(_thread_flag)
         {
-            run();
+            try
+            {
+                run();
 
-            std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms));
+                boost::this_thread::sleep_for(boost::chrono::milliseconds(sleep_ms));
+            }
+            catch (boost::thread_interrupted&)
+            {
+            }
+            catch(std::exception&)
+            {
+                log_error("thread_proc exception 结束线程 i_thread");
+            }
         }
     }
 };
@@ -661,11 +120,11 @@ public:
 protected:
     //使继承者无法public构造函数和析构函数
     singleton_base(){}
-    virtual ~singleton_base(){}
+    //virtual ~singleton_base(){}
 private:
     //禁止拷贝构造和赋值运算符
-    singleton_base(const singleton_base& src){}
-    singleton_base &operator=(const singleton_base& src){}
+    singleton_base(const singleton_base&){}
+    singleton_base &operator=(const singleton_base&){}
 
     //它的唯一工作就是在析构函数中析构Singleton的实例,所以private
     class Garbo

+ 0 - 2
module_service/module_mgr.cpp

@@ -1,2 +0,0 @@
-#include "module_mgr.h"
-

+ 77 - 11
module_service/module_mgr.h

@@ -13,6 +13,8 @@
 #include"module_web.h"
 #include"module_area.h"
 #include"module_call_help.h"
+#include"module_call.h"
+#include"module_over_speed_vehicle.h"
 
 class module_mgr: public singleton_base<module_mgr>
 {
@@ -24,31 +26,95 @@ private:
 
 public:
     /**
-     * @brief 注册web回调函数,读数据库初始化事件列表
+     * @brief 注册web回调函数,读配置文件,启动向web发送线程
      */
-    void init(std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE>& MsgFuncList)
+    static void init(config_file& config, std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE>& MsgFuncList)
     {
-        module_web::instance()->init(MsgFuncList);
-        module_area::instance()->init();
-        module_call_help::instance()->init();
+        module_web::instance()->init(config, MsgFuncList);
+        module_call::instance()->init(config);
     }
 
     /**
      * @brief 启动线程start:向web发送事件
      */
-    void start()
+    static void start()
     {
-        module_area::instance()->start();
-        module_call_help::instance()->start();
+        module_over_speed_vehicle::instance()->init_vehicle_category_from_db();
+        init_attendance_from_db();
+
+        module_web::instance()->start();
+        module_call::instance()->start();
     }
 
     /**
      * @brief 结束线程stop
      */
-    void stop()
+    static void stop()
+    {
+        module_web::instance()->stop();
+        module_call::instance()->stop();
+    }
+
+    static void do_status(STATUS_CARD st, uint32_t card_id, int32_t type)
     {
-        module_area::instance()->stop();
-        module_call_help::instance()->stop();
+        auto card_ptr=card_list::instance()->get(card_list::to_id64(type, card_id));
+        if(!card_ptr)
+        {
+            log_error("卡不存在card_id=%d", card_id);
+            return;
+        }
+
+        if(STATUS_HELP == st)
+        {
+            module_call_help::instance()->rev_from_card_help(card_ptr);
+        }
+        else if(STATUS_CALL == st)
+        {
+            module_call::instance()->rev_from_card_resp(card_ptr);
+        }
+    }
+
+private:
+    static void init_attendance_from_db()
+    {
+        const char *sql = "select card_id, start_time, end_time from rt_att_staff;";
+        std::string Error;
+        YADB::CDBResultSet DBRes;
+        sDBConnPool.Query(sql,DBRes,Error);
+        int nCount = DBRes.GetRecordCount( Error );
+        if (nCount > 0)
+        {
+            log_info( "init_attendance. The record count=%d\n", nCount );
+
+            while ( DBRes.GetNextRecod(Error) )
+            {
+                std::string card_id;
+                DBRes.GetField( "card_id",card_id, Error );
+
+                std::string end_time;
+                DBRes.GetField( "end_time",end_time, Error );
+
+                if(end_time.empty())
+                {
+                    uint32_t id = tool_other::id64_to_id(card_id);
+                    int32_t type = tool_other::id64_to_type(card_id);
+
+                    auto card_ptr = card_list::instance()->get(card_list::to_id64(type, id));
+                    if(card_ptr)
+                    {
+                        std::string start_time;
+                        DBRes.GetField( "start_time",start_time, Error );
+
+                        auto site_area_ptr = card_ptr->get_site_area();
+
+                        site_area_ptr->m_attendance_start_time = tool_time::to_time_ex(start_time);
+                        site_area_ptr->m_stat_attendance = AS_ATTENDANCE;
+                        //std_debug("%s",
+                        //   tool_time::to_str_ex(tool_time::to_ms(site_area_ptr->m_attendance_start_time)).c_str());
+                    }
+                }
+            }
+        }
     }
 };
 

+ 44 - 0
module_service/module_mine.h

@@ -0,0 +1,44 @@
+#ifndef MODULE_MINE_H
+#define MODULE_MINE_H
+/**
+ * @brief 简要说明
+ * @author 戴月腾
+ * @date 2018-09-21
+ */
+
+#include "module_const.h"
+#include "module_over_speed_vehicle.h"
+
+class module_mine: public singleton_base<module_mine>
+{
+private:
+    friend class singleton_base<module_mine>;
+    module_mine()
+    {
+    }
+
+public:
+    static void on_point(uint32_t card_id,int32_t type, int vehicle_category_id)
+    {
+        auto card_ptr=card_list::instance()->get(card_list::to_id64(type, card_id));
+        if(!card_ptr)
+        {
+            log_error("卡不存在card_id=%d", card_id);
+            return;
+        }
+
+        if(card_ptr->is_person())//人卡
+        {
+
+        }
+
+        if(card_ptr->is_vehicle())//车卡
+        {
+            //区域车卡超速
+            module_over_speed_vehicle::instance()->on_hover(card_ptr, vehicle_category_id);
+        }
+    }
+};
+
+
+#endif // MODULE_MINE_H

+ 159 - 0
module_service/module_over_speed_vehicle.h

@@ -0,0 +1,159 @@
+#ifndef MODULE_OVER_SPEED_VEHICLE_H
+#define MODULE_OVER_SPEED_VEHICLE_H
+/**
+  *@brief 车卡超速模块
+  * @author 戴月腾
+  * @date 2018-08-08
+*/
+
+#include <mutex>
+#include <map>
+#include <chrono>
+#include <boost/thread.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "module_const.h"
+
+/**
+ * @brief 区域超速类。当某张车卡速度超过某个区域的最大速度时,发出告警, 单例
+ */
+class module_over_speed_vehicle:public singleton_base<module_over_speed_vehicle>
+{
+private:
+    friend class singleton_base<module_over_speed_vehicle>;
+    module_over_speed_vehicle()
+    {
+    }
+
+public:
+    void on_hover(std::shared_ptr<card_location_base> card_ptr, int vehicle_category_id)
+    {
+        auto mine_tool_ptr = card_ptr->get_mine_tool();
+
+        if(is_over_speed(vehicle_category_id, card_ptr->m_speed))//超速
+        {
+            mine_tool_ptr->m_over_speed_count++;
+        }
+        else//速度正常
+        {
+            mine_tool_ptr->m_normal_speed_count++;
+        }
+
+        //确定超速
+        if(SPEED_COUNT_LIMIT <= mine_tool_ptr->m_over_speed_count)
+        {
+            mine_tool_ptr->m_over_speed_count=SPEED_COUNT_LIMIT;
+
+            auto ev_ptr = event_list::instance()->get(card_ptr->m_id, ET_CARD_OVER_SPEED);
+            if(ev_ptr)
+            {
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value=limit_speed(vehicle_category_id);
+                ev_ptr->m_cur_value=card_ptr->m_speed;
+            }
+            else//从没有告警状态转化为告警状态
+            {
+                mine_tool_ptr->m_normal_speed_count=0;
+
+                auto ev_ptr = event_list::create_event_card(card_ptr->m_id, card_ptr->m_type, ET_CARD_OVER_SPEED);
+
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value = limit_speed(vehicle_category_id);
+                ev_ptr->m_cur_value = card_ptr->m_speed;
+
+                //保存到数据库
+                event_list::save_event(ev_ptr);
+
+                event_list::instance()->add(ev_ptr->get_list_id(),ev_ptr);
+
+                log_info("车卡矿井内超速开始:卡id=%d,卡type=%d,卡速=%f,卡category_id=%d,卡速门限=%f",
+                         card_ptr->m_id, card_ptr->m_type,card_ptr->m_speed,vehicle_category_id,
+                         limit_speed(vehicle_category_id));
+            }
+        }
+
+        //确定速度正常
+        if(SPEED_COUNT_LIMIT <= mine_tool_ptr->m_normal_speed_count)
+        {
+            mine_tool_ptr->m_normal_speed_count=SPEED_COUNT_LIMIT;
+
+            auto ev_ptr = event_list::instance()->get(card_ptr->m_id, ET_CARD_OVER_SPEED);
+            if(ev_ptr)
+            {
+                mine_tool_ptr->m_over_speed_count=0;
+
+                event_list::copy_event(card_ptr, ev_ptr);
+
+                ev_ptr->m_limit_value = limit_speed(vehicle_category_id);
+                ev_ptr->m_cur_value = card_ptr->m_speed;
+
+                ev_ptr->m_status = ES_END;
+
+                //保存到数据库
+                event_list::save_event(ev_ptr);
+
+                log_info("车卡矿井内超速结束:卡id=%d,卡type=%d,卡速=%f,卡category_id=%d,卡速门限=%f",
+                         card_ptr->m_id, card_ptr->m_type,card_ptr->m_speed,vehicle_category_id,
+                         limit_speed(vehicle_category_id));
+            }
+        }
+    }
+
+    void init_vehicle_category_from_db()
+    {
+        const char *sql = "SELECT vehicle_category_id, over_speed FROM dat_vehicle_category;";
+        std::string Error;
+        YADB::CDBResultSet DBRes;
+        sDBConnPool.Query(sql,DBRes,Error);
+        if(!Error.empty())
+            log_error("init_vehicle_category Error,%s",Error.c_str());
+        uint64_t nCount = DBRes.GetRecordCount( Error );
+        if (nCount > 0)
+        {
+            log_info( "init_vehicle_category. The record count=%ld\n", nCount );
+
+            while ( DBRes.GetNextRecod(Error) )
+            {
+                int vehicle_category_id  = 0;
+                DBRes.GetField( "vehicle_category_id",vehicle_category_id, Error );
+
+                double over_speed = 0;
+                DBRes.GetField( "over_speed",over_speed, Error );
+
+                _vehicle_category_map.insert({vehicle_category_id,over_speed});
+            }
+
+            for(const auto &p : _vehicle_category_map)
+                std_debug("dat_vehicle_category:category_id:%d--over_speed:%.2f",p.first,p.second);
+        }
+    }
+
+private:
+    bool is_over_speed(int category_id, double speed)
+    {
+        auto serch = _vehicle_category_map.find(category_id);
+        if(serch == _vehicle_category_map.end())
+        {
+            return false;
+        }
+
+        return serch->second <= speed;
+    }
+
+    double limit_speed(int category_id) const
+    {
+        auto serch = _vehicle_category_map.find(category_id);
+        if(serch == _vehicle_category_map.end())
+        {
+            return 0;
+        }
+
+        return serch->second;
+    }
+
+private:
+    std::unordered_map<int,double> _vehicle_category_map;
+};
+
+#endif // MODULE_OVER_SPEED_VEHICLE_H

+ 92 - 0
module_service/module_site.h

@@ -0,0 +1,92 @@
+#ifndef MODULE_SITE_H
+#define MODULE_SITE_H
+
+#include"math.h"
+#include <memory>
+#include <mutex>
+#include <map>
+#include <string>
+#include <chrono>
+#include <vector>
+#include<card.h>
+#include"ant.h"
+#include"area.h"
+#include"site_area.h"
+#include"module_const.h"
+#include"module_attendance_person.h"
+
+class module_site : public singleton_base<module_site>
+{
+private:
+    friend class singleton_base<module_site>;
+    module_site()
+    {
+    }
+
+public:
+    /**
+     * @brief 进入分站覆盖区域处理,考勤
+     * @param card_id
+     * @param enter_site
+     */
+    static void enter_site(uint32_t card_id,int enter_site,int32_t type)
+    {
+        auto card_ptr=card_list::instance()->get(card_list::to_id64(type, card_id));
+        if(!card_ptr)
+        {
+            log_error("卡不存在card_id=%ld, type=%ld", card_id, type);
+            return;
+        }
+
+        auto site_ptr=sit_list::instance()->get(enter_site);
+        if(!site_ptr)
+        {
+            log_error("在分站列表中找不到分站,分站id=%d", enter_site);
+            return;
+        }
+
+        if(card_ptr->is_person())
+        {
+            module_attendance_person::instance()->enter_site(card_ptr, site_ptr);
+        }
+
+        if(card_ptr->is_vehicle())
+        {
+
+        }
+    }
+
+    /**
+     * @brief 离开现有分站处理,记录现有分站的进出时间和地点
+     * @param card_id
+     * @param enter_site
+     */
+    static void leave_site(uint32_t card_id,int enter_site, int32_t type)
+    {
+        auto card_ptr=card_list::instance()->get(card_list::to_id64(type, card_id));
+        if(!card_ptr)
+        {
+            log_error("卡不存在card_id=%ld, type=%ld", card_id, type);
+            return;
+        }
+
+        auto site_ptr=sit_list::instance()->get(enter_site);
+        if(!site_ptr)
+        {
+            log_error("在分站列表中找不到分站,分站id=%d", enter_site);
+            return;
+        }
+
+        if(card_ptr->is_person())
+        {
+
+        }
+
+        if(card_ptr->is_vehicle())
+        {
+
+        }
+    }
+};
+
+#endif // MODULE_SITE_H

+ 49 - 36
module_service/module_web.cpp

@@ -3,61 +3,59 @@
 #include"module_call_help.h"
 #include"module_call.h"
 #include"module_area.h"
-
-
+#include"module_attendance_person.h"
 
 void module_web::accept( int ID, std::string const& name,
                          sio::message::ptr const& data, bool need_ack, sio::message::list &ack_resp )
 {
-    log_debug("收到web发来的数据 ");
-
     if(data->get_flag() != sio::message::flag_object)
     {
-        log_error("发来的数据不是对象");
+        log_error("web发来的数据不是对象");
         return;
     }
 
-    std::string cmd = data->get_map()[JSON_ROOT_KEY_CMD]->get_string();
-    if(cmd.empty())
+    std::string cmd = "";
+    if(!tool_map::try_get_value(cmd, JSON_ROOT_KEY_CMD, data) || cmd.empty())
     {
-        log_error("cmd字段为空");
+        log_error("web发来的数据cmd字段为空");
         return;
     }
 
-    log_info(data->get_map()[JSON_ROOT_KEY_DATA]->get_string().c_str());
+    std_debug("web发来的数据 cmd=%s", cmd.c_str());
+    log_info("web发来的数据 cmd=%s", cmd.c_str());
 
-    if (JSON_CMD_VALUE_REQUEST_ALL_DATA == cmd)//web登录请求所有信息
+    if(JSON_CMD_VALUE_CLEAR_CARD == cmd)//手动升井
     {
-        module_web::instance()->response_login();
+        module_attendance_person::instance()->handle_up_mine(data);
     }
-    else if(JSON_CMD_VALUE_DEAL_HELP == cmd) // 处理呼救信息
+    else if (JSON_CMD_VALUE_REQUEST_ALL_DATA == cmd)//web登录请求所有信息
     {
-        module_call_help::instance()->accept_deal_help(data->get_map()[JSON_ROOT_KEY_DATA]->get_map());
+        module_web::instance()->response_login();
     }
     else
     {
-        std::string json=data->get_map()[JSON_ROOT_KEY_DATA]->get_string();
-        rapidjson::Document doc;
-        doc.Parse(json.c_str());
-
-        if(doc.HasParseError())
+        sio::message::ptr data_value;
+        if(!tool_map::try_get_value(data_value, JSON_ROOT_KEY_DATA, data))
         {
-            log_error("发来的data字段数据有错误");
+            log_error("web发来的数据data字段格式不对, 不是map");
             return;
         }
 
-        if(JSON_CMD_VALUE_CALL_CARD_REQUEST == cmd)//呼叫
+        if(JSON_CMD_VALUE_DEAL_HELP == cmd) // 处理呼救信息
         {
-            module_call::instance()->accept_call(doc);
+            module_call_help::instance()->accept_web_deal_help(data_value);
+        }
+        else if(JSON_CMD_VALUE_CALL_CARD_REQUEST == cmd)//呼叫
+        {
+            module_call::instance()->accept_call(data_value);
         }
         else if(JSON_CMD_VALUE_CALL_CARD_CANCEL_REQUEST == cmd)//取消呼叫
         {
-            module_call::instance()->accept_cancel(doc);
+            module_call::instance()->accept_cancel(data_value);
         }
     }
 }
 
-
 void module_web::response_login()
 {
     rapidjson::Document doc(rapidjson::kObjectType);
@@ -68,21 +66,15 @@ void module_web::response_login()
     std::string str=module_call::instance()->accept_login();
     if(!str.empty())
     {
-        nodes.PushBack(rapidjson::StringRef(str.c_str()), allocator);
-    }
-
-    //所有的呼救信息
-    str=module_call_help::instance()->response_login();
-    if(!str.empty())
-    {
-        nodes.PushBack(rapidjson::StringRef(str.c_str()), allocator);
+        tool_json::push_back(nodes, str, allocator);
     }
 
-    //所有其他告警
-    str=module_area::instance()->response_login();
-    if(!str.empty())
+    //所有告警
+    std::vector<std::shared_ptr<ya_event>> arr;
+    get_all_events(arr);
+    if(!arr.empty())
     {
-        nodes.PushBack(rapidjson::StringRef(str.c_str()), allocator);
+        tool_json::push_back(nodes, event_list::evs_to_json(arr), allocator);
     }
 
     if(nodes.Size()>0)
@@ -91,10 +83,31 @@ void module_web::response_login()
         doc.AddMember(JSON_ROOT_KEY_VERSION, INTERFACE_VERSION, allocator);
         doc.AddMember(JSON_ROOT_KEY_DATA, nodes, allocator);
 
-        swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
+        tool_other::send_json(JSON_CMD_VALUE_PUSH, tool_json::doc_to_json(doc));
     }
 }
 
+void module_web::run()
+{
+    std::vector<std::shared_ptr<ya_event>> arr;
+    get_all_events(arr);
+
+    if(!arr.empty())//发送给web端
+    {
+        delete_end(arr);
+
+        tool_other::send_json(JSON_CMD_VALUE_PUSH, event_list::evs_to_json(arr));
+    }
+
+    std::string help = module_call_help::get_json_help();
+    if(!help.empty())
+    {
+        tool_other::send_json(JSON_CMD_VALUE_PUSH, help);
+    }
+}
+
+
+
 
 
 

+ 27 - 274
module_service/module_web.h

@@ -13,121 +13,9 @@
 
 #include "rapidjson/prettywriter.h"
 #include "rapidjson/document.h"
-
 #include "websocket/wsClientMgr.h"
 
-//#define JSON_ROOT_KEY_CMD "cmd"
-//#define JSON_ROOT_KEY_VERSION "version"
-//#define INTERFACE_VERSION "1.0.0.2"
-//#define JSON_ROOT_KEY_DATA "data"
-
-////呼叫命令
-//#define JSON_CMD_VALUE_CALL_CARD_REQUEST "call_card_req"
-//#define JSON_CMD_VALUE_CALL_CARD_RESPONSE "call_card_resp"
-//#define JSON_CMD_VALUE_CALL_CARD_CANCEL_REQUEST "call_card_cancel_req"
-//#define JSON_CMD_VALUE_CALL_CARD_CANCEL_RESPONSE "call_card_cancel_resp"
-//#define JSON_CMD_VALUE_CALL_CARD_LIST "callcardlist"
-
-//#define JSON_KEY_CALL_CARD_CALL_TYPE "call_type_id"
-//#define JSON_KEY_CALL_CARD_CALL_TIME_OUT "call_time_out"
-//#define JSON_KEY_CALL_CARD_CALL_TIME "call_time"
-//#define JSON_KEY_CALL_CARD_CALL_LEVEL "call_level_id"
-//#define JSON_KEY_CALL_CARD_USER_NAME "user_name"
-//#define JSON_KEY_CALL_CARD_STATIONS "stations"
-//#define JSON_KEY_CALL_CARD_STATION_ID "stationid"
-//#define JSON_KEY_CALL_CARD_CARDS "cards"
-//#define JSON_KEY_CALL_CARD_CARD_ID "cardid"
-//#define JSON_KEY_CALL_CARD_CARD_TYPE_ID "cardtype"
-
-//#define JSON_KEY_CALL_LIGHT_TASK_ID "task_id"
-//#define JSON_KEY_CALL_LIGHT_OBJ_TYPE "obj_type"
-//#define JSON_KEY_CALL_LIGHT_CTRL_TYPE "ctrl_type"
-//#define JSON_KEY_CALL_LIGHT_LIGHT_STATE "light_state"
-//#define JSON_KEY_CALL_LIGHT_USER_ID "user_id"
-//#define JSON_KEY_CALL_LIGHT_LIGHTS "lights"
-//#define JSON_KEY_CALL_LIGHT_ID "id"
-
-//#define JSON_KEY_ID "id"
-//#define JSON_KEY_OP_TYPE "op_type"
-//#define JSON_KEY_OP_TYPE_INSERT "INSERT"
-//#define JSON_KEY_OP_TYPE_UPDATE "UPDATE"
-//#define JSON_KEY_OP_TYPE_DELETE "DELETE"
-
-//// 采集端接收接口
-//#define JSON_CMD_VALUE_CLEAR_CARD "clear_card"
-//#define JSON_CMD_VALUE_DEAL_HELP "helpme_done"   //deal_help
-//#define JSON_CMD_VALUE_DEAL_HELP_RESPONSE "helpme_done_rsp"   //deal_help
-//#define JSON_CMD_VALUE_REQUEST_ALL_POSTION "request_all_postion"
-//#define JSON_CMD_VALUE_REQUEST_ALL_DATA "req_all_data"
-//#define JSON_CMD_VALUE_RESPONSE_ALL_DATA "resp_all_data"
-//#define JSON_CMD_VALUE_CALL_CARD_START "call_card_start"
-//#define JSON_CMD_VALUE_CALL_CARD_CANCEL "call_card_cancel"
-//#define  JSON_CMD_VALUE_LEADER_ARRANGE "leader_arrange"
-////呼叫命令
-//#define JSON_CMD_VALUE_CALL_CARD_REQUEST "call_card_req"
-//#define JSON_CMD_VALUE_CALL_CARD_RESPONSE "call_card_resp"
-//#define JSON_CMD_VALUE_CALL_CARD_CANCEL_REQUEST "call_card_cancel_req"
-//#define JSON_CMD_VALUE_CALL_CARD_CANCEL_RESPONSE "call_card_cancel_resp"
-//#define JSON_CMD_VALUE_CALL_CARD_LIST "callcardlist"
-
-//#define JSON_CMD_VALUE_META_DATA_CHANGED "meta_data_changed"
-//#define JSON_CMD_VALUE_LIGHTS_CTRL_REQUEST "light_control"
-//#define JSON_CMD_VALUE_LIGHTS_CTRL_RESPONSE "lights_ctrl_res"
-//#define JSON_CMD_VALUE_HAND_UP_RESPONSE "deal_hand_up_res"
-
-//// id, name, type, map_id
-//#define JSON_KEY_AREA_ID "area_id" // "区域编号"
-//#define JSON_KEY_AREA_IS_SPECIAL "is_special_area" // "区域名称"
-//// down_mine,up_mine
-//#define JSON_CMD_VALUE_DOWN_MINE "down_mine"
-//#define JSON_CMD_VALUE_UP_MINE "up_mine"
-//#define JSON_CMD_VALUE_SPECIAL_AREA_UP_MINE "special_area_up_mine"
-//#define JSON_CMD_VALUE_DEV_STATE "device_state"
-//#define JSON_CMD_VALUE_EVENT "event"
-//#define JSON_CMD_VALUE_CALL "CALL"
-//#define JSON_CMD_VALUE_PUSH "PUSH"
-//#define JSON_CMD_VALUE_USER "USER"
-//#define JSON_CMD_DRIVING_FACE_STATE "tunneller_stat"
-
-
-//#define JSON_ROOT_KEY_TOTAL "total"
-//#define JSON_ROOT_KEY_STATISTIC_VEHICLE_DATA "v"
-//#define JSON_ROOT_KEY_STATISTIC_STAFF_DATA "s"
-//#define JSON_ROOT_KEY_STATISTIC_STAT "stat"
-//#define JSON_ROOT_KEY_STATISTIC_DETAIL "detail"
-//#define JSON_ROOT_KEY_STATISTIC_GLOBAL "glbl"
-//#define JSON_ROOT_KEY_STATISTIC_DEPT "dept"
-//#define JSON_ROOT_KEY_STATISTIC_SUM "sum"
-//#define JSON_ROOT_KEY_STATISTIC_AREA "area"
-//#define JSON_ROOT_KEY_STATISTIC_LEVEL "occupation_level"
-
-//// 告警事件
-//#define JSON_KEY_EVENT_EVENT_ID "event_id"
-//#define JSON_KEY_EVENT_STATUS "status"
-//#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_MAP_ID "map_id"
-//#define JSON_KEY_EVENT_AREA_ID "area_id"
-//#define JSON_KEY_EVENT_X "x"
-//#define JSON_KEY_EVENT_Y "y"
-//#define JSON_KEY_EVENT_LIMIT_VALUE "limit_value"
-//#define JSON_KEY_EVENT_CUR_VALUE "cur_value"
-//#define JSON_KEY_EVENT_CUR_TIME "cur_time"
-//#define JSON_KEY_EVENT_LANDMARK_ID "lmid"
-//#define JSON_KEY_EVENT_LANDMARK_DIRECTION "lmdirect"
-//#define JSON_KEY_EVENT_LANDMARK_DISTANCE "lmdistance"
-//#define JSON_KEY_EVENT_READER_POS_CHANGE    "reader_pos_change"
-
-//// alarm
-//#define JSON_KEY_ALARM_OVER_COUNT_PERSON "over_count_person"
-//#define JSON_KEY_ALARM_OVER_COUNT_VEHICLE "over_count_vehicle"
-//#define JSON_KEY_ALARM_OVER_TIME_PERSON "over_time_person"
-//#define JSON_KEY_ALARM_OVER_TIME_VEHICLE "over_time_vehicle"
-//#define JSON_KEY_ALARM_OVER_SPEED_VEHICLE "over_speed_vehicle"
-
-
-class module_web : public singleton_base<module_web>
+class module_web : public i_thread, public singleton_base<module_web>
 {
 private:
     friend class singleton_base<module_web>;
@@ -151,192 +39,57 @@ public:
      * @brief 注册web请求回调函数
      * @param MsgFuncList
      */
-    void init(std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE>& MsgFuncList)
+    void init(config_file& config, std::map<std::string, YA::MSG_HANDLE_FUNC_TYPE>& MsgFuncList)
     {
+        sleep_ms = std::stoi(config.get("interval_send_json_alarm","10000"));
+
         MsgFuncList.insert( std::make_pair( JSON_CMD_VALUE_REQUEST_ALL_DATA, &module_web::accept ) );
         MsgFuncList.insert( std::make_pair( JSON_CMD_VALUE_DEAL_HELP, &module_web::accept ) );
         MsgFuncList.insert( std::make_pair( JSON_CMD_VALUE_CALL_CARD_REQUEST, &module_web::accept ) );
         MsgFuncList.insert( std::make_pair( JSON_CMD_VALUE_CALL_CARD_CANCEL_REQUEST, &module_web::accept ) );
+
+        MsgFuncList.insert( std::make_pair( JSON_CMD_VALUE_CLEAR_CARD, &module_web::accept ) );//手动升井
     }
 
     /// web前端有用户登录时,反馈给web所有信息
     void response_login();
-};
-
-class tool_json
-{
-public:
-    static bool try_get_iter(const char* key, const rapidjson::Value& node,
-                             rapidjson::Value::ConstMemberIterator& out_iter)
-    {
-        if(node.IsObject())
-        {
-            out_iter = node.FindMember(key);
-            if(node.MemberEnd() == out_iter)
-            {
-                return false;
-            }
-
-            return true;
-        }
-
-        return false;
-    }
-
-    static bool try_get_value(int& d, const char* key, const rapidjson::Value& node)
-    {
-        rapidjson::Value::ConstMemberIterator iter;
-        if(try_get_iter(key, node, iter))
-        {
-            if(iter->value.IsInt())
-            {
-                d = iter->value.GetInt();
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    static bool try_get_value(uint64_t& d, const char* key, const rapidjson::Value& node)
-    {
-        rapidjson::Value::ConstMemberIterator iter;
-        if(try_get_iter(key, node, iter))
-        {
-            if(iter->value.IsUint64())
-            {
-                d = iter->value.GetUint64();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static bool try_get_value(double& d, const char* key, const rapidjson::Value& node)
-    {
-        rapidjson::Value::ConstMemberIterator iter;
-        if(try_get_iter(key, node, iter))
-        {
-            if(iter->value.IsDouble())
-            {
-                d = iter->value.GetDouble();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    static bool try_get_value(std::string& d, const char* key, const rapidjson::Value& node)
-    {
-        rapidjson::Value::ConstMemberIterator iter;
-        if(try_get_iter(key, node, iter))
-        {
-            if(iter->value.IsString())
-            {
-                d = iter->value.GetString();
-                return true;
-            }
-        }
 
-        return false;
-    }
+private:
+    /**
+     * @brief 线程函数
+     */
+    void run();
 
-    static int get_value(const char* key, const int& default_data, const rapidjson::Value& node)
+    ///获取所有的告警事件
+    void get_all_events(std::vector<std::shared_ptr<ya_event>>& arr)
     {
-        rapidjson::Value::ConstMemberIterator iter;
-        if(try_get_iter(key, node, iter))
+        auto _map = event_list::instance()->m_map;
+        auto it_map = _map.begin();
+        for(;it_map!=_map.end();++it_map)
         {
-            if(iter->value.IsInt())
-            {
-                return  iter->value.GetInt();
-            }
+            arr.push_back(it_map->second);
         }
-
-        return default_data;
     }
 
-    static std::string get_value(const char* key, const std::string& default_data, const rapidjson::Value& node)
+    ///在全局列表中删除已经处理或结束了的告警
+    void delete_end(std::vector<std::shared_ptr<ya_event>>& arr)
     {
-        rapidjson::Value::ConstMemberIterator iter;
-        if(try_get_iter(key, node, iter))
+        std::vector<uint64_t> todelete;
+        auto arr_iter = arr.begin();
+        for(;arr_iter!=arr.end();++arr_iter)
         {
-            if(iter->value.IsString())
+            if((*arr_iter)->is_end())//删除掉已经处理的
             {
-                return iter->value.GetString();
+                todelete.push_back((*arr_iter)->get_list_id());
             }
         }
 
-        return default_data;
-    }
-
-    static std::string doc_to_json(rapidjson::Document& doc)
-    {
-        rapidjson::StringBuffer sb;
-        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
-        doc.Accept(writer);
-
-        return sb.GetString();
-    }
-
-    static std::string ev_to_json(std::shared_ptr<ya_event> ev_ptr)
-    {
-        std::vector<std::shared_ptr<ya_event>> evs;
-        evs.push_back(ev_ptr);
-        return evs_to_json(evs);
-    }
-
-    static std::string evs_to_json(std::vector<std::shared_ptr<ya_event>> evs)
-    {
-        rapidjson::Document doc(rapidjson::kObjectType);
-        rapidjson::Value data(rapidjson::kArrayType);
-        rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();
-
-        auto it=evs.begin();
-        for(;it!=evs.end();++it)
+        if(todelete.size())
         {
-            ev_to_node(*it, allocator, data);
+            event_list::instance()->remove(todelete);
         }
-
-        doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_EVENT, allocator);
-        doc.AddMember(JSON_ROOT_KEY_VERSION,INTERFACE_VERSION, allocator);
-        doc.AddMember(JSON_ROOT_KEY_DATA,data, allocator);
-
-        rapidjson::StringBuffer sb;
-        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
-        doc.Accept(writer);
-
-        return sb.GetString();
     }
-
-private:
-    static void ev_to_node(std::shared_ptr<ya_event> ev_ptr,
-                                        rapidjson::Document::AllocatorType& allocator,
-                                        rapidjson::Value& out_data)
-    {
-        rapidjson::Value ev(rapidjson::kObjectType);
-
-        ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->get_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);
-        ev.AddMember(JSON_KEY_EVENT_OBJ_ID,ev_ptr->m_obj_id, 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);
-        ev.AddMember(JSON_KEY_EVENT_Y,ev_ptr->y, allocator);
-
-        ev.AddMember(JSON_KEY_EVENT_LIMIT_VALUE,ev_ptr->m_limit_value, allocator);
-        ev.AddMember(JSON_KEY_EVENT_CUR_VALUE,ev_ptr->m_cur_value, allocator);
-        ev.AddMember(JSON_KEY_EVENT_CUR_TIME,tool_time::to_ms(ev_ptr->m_cur_time), allocator);
-
-        ev.AddMember(JSON_KEY_EVENT_LANDMARK_ID,ev_ptr->m_landmarkid, allocator);
-        ev.AddMember(JSON_KEY_EVENT_LANDMARK_DIRECTION,ev_ptr->m_landmarkdirect, allocator);
-        ev.AddMember(JSON_KEY_EVENT_LANDMARK_DISTANCE,ev_ptr->m_landmarkdist, allocator);
-
-        out_data.PushBack(ev, allocator);
-    }
-
 };
 
+
 #endif // MODULE_WEB_H

+ 10 - 0
net-service.cpp

@@ -14,6 +14,7 @@
 #include "worker.h"
 #include "tdoa_sync.h"
 #include "net-service.h"
+#include "ant.h"
 
 net_service::net_service()
 {
@@ -43,6 +44,15 @@ void net_service::on_message(std::shared_ptr<client> clt,const char*data,size_t
 			{
 				uint32_t site_id;
 				is>>site_id>>skip(12);
+
+                auto site_ptr = sit_list::instance()->get(static_cast<int32_t>(site_id));
+                if(!site_ptr)
+                {
+                    log_error("在全局分站列表中找不到分站:分站id=%d", site_id);
+                    break;
+                }
+                site_ptr->set_client(clt);
+
 				struct timeval tv;
 				gettimeofday(&tv,NULL);
 				uint64_t t = tv.tv_sec*1000 + tv.tv_usec/1000;

+ 6 - 13
site_area.cpp

@@ -1,19 +1,13 @@
 
 #include "site_area.h"
 #include "card.h"
-#include "module_service/module_attendance_person.h"
+#include "module_service/module_site.h"
 
 //每张卡包含这样一个对象,保存最后一个分站区域
 //1、记录卡进出分站的时间,地点
 //2、用于考勤
-site_area_hover::site_area_hover()
-	:m_site_id(-1)
-	,m_enter_time(0)
-	,m_last_time(0)
-{
-}
 
-void site_area_hover::on_point(uint64_t card_id,int site_id,const point*pt,uint64_t type)
+void site_area_hover::on_point(uint32_t card_id,int site_id,const point*pt,int32_t type)
 {
 	if(pt!=nullptr)
 	{
@@ -42,15 +36,14 @@ void site_area_hover::on_point(uint64_t card_id,int site_id,const point*pt,uint6
 	}
 }
 
-void site_area_hover::enter_site(uint64_t card_id,int enter_site,uint64_t type)
+void site_area_hover::enter_site(uint32_t card_id,int enter_site,int32_t type)
 {
-    module_attendance_person::instance()->enter_site(card_id, enter_site, type);
+    module_site::enter_site(card_id, enter_site, type);
 }
 
-void site_area_hover::leave_site(uint64_t card_id,int enter_site,uint64_t type)
+void site_area_hover::leave_site(uint32_t card_id,int enter_site,int32_t type)
 {
-
-
+    module_site::leave_site(card_id, enter_site, type);
 }
 
 

+ 38 - 5
site_area.h

@@ -1,23 +1,56 @@
 #ifndef __SITE_AREA_HOVER_HPP__
 #define __SITE_AREA_HOVER_HPP__
 #include <point.h>
+#include<chrono>
+#include "common.h"
+
 //每张卡包含这样一个对象,保存最后一个分站区域;只有tof一维有这个需求
 //1、记录卡进出分站的时间,地点
 //2、用于考勤
 struct site_area_hover
 {
-	site_area_hover();
+    site_area_hover()
+        :m_site_id(-1)
+        ,m_enter_time(0)
+        ,m_last_time(0)
+        ,m_stat_attendance(AS_INIT)
+        ,m_attendance_start_time(std::chrono::seconds(0))
+    {
+    }
 	//调用时机:
 	//1、tof一维收到第一个数据点时,以pt=0调用
 	//2、数据点解析完毕之后调用
-    void on_point(uint64_t card_id,int site_id,const point*pt,uint64_t type);
+    void on_point(uint32_t card_id,int site_id,const point*pt,int32_t type);
 private:
-    void enter_site(uint64_t card_id,int enter_site,uint64_t type);
-    void leave_site(uint64_t card_id,int enter_site,uint64_t type);
+    void enter_site(uint32_t card_id,int enter_site,int32_t type);
+    void leave_site(uint32_t card_id,int enter_site,int32_t type);
 
-	int    m_site_id;
+private:
+    int    m_site_id;
 	time_t m_enter_time,m_last_time;
 	point  m_enter_point,m_last_point;
+
+public:
+    ///考勤状态  0初始状态 1 没在考勤 2 考勤;参看ATTENDANCE_STATUS
+    int m_stat_attendance;
+    ///考勤开始时间
+    std::chrono::system_clock::time_point m_attendance_start_time;
+
+public:
+    int site_id() const
+    {
+        return m_site_id;
+    }
+
+    bool is_invalid()
+    {
+        return -1==m_site_id;
+    }
+
+    bool is_attendance()
+    {
+        return AS_ATTENDANCE == m_stat_attendance;
+    }
 };
 #endif
 

+ 107 - 0
ya_event.cpp

@@ -0,0 +1,107 @@
+#include "ya_event.h"
+
+
+uint64_t ya_event::get_list_id()
+{
+    return event_list::to_list_id(static_cast<uint32_t>(std::stoi(m_obj_id.substr(3))), m_ev_type);
+}
+
+void event_list::load_his_data_from_db()
+{
+    const char *sql = "SELECT event_id, stat,event_type_id,obj_type_id,obj_id,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 \
+                                                 WHEN 1 THEN DATE_SUB(NOW(),INTERVAL 2 DAY) \
+                                                 WHEN 2 THEN DATE_SUB(NOW(),INTERVAL 2 DAY)\
+                                                 WHEN 4 THEN DATE_SUB(NOW(),INTERVAL 1 MONTH)\
+                                                 WHEN 9 THEN DATE_SUB(NOW(),INTERVAL 2 DAY) \
+                                                 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);";
+    std::string Error;
+    YADB::CDBResultSet DBRes;
+    sDBConnPool.Query(sql,DBRes,Error);
+    if(!Error.empty())
+        log_error("初始化事件列表 Error,%s",Error.c_str());
+    uint64_t nCount = DBRes.GetRecordCount( Error );
+    if (nCount > 0)
+    {
+        log_info( "init_vehicle_category. The record count=%ld\n", nCount );
+
+        while ( DBRes.GetNextRecod(Error) )
+        {
+            long long event_id  = 0;
+            DBRes.GetField( "event_id",event_id, Error );
+
+            int event_type_id  = 0;
+            DBRes.GetField( "event_type_id",event_type_id, Error );
+
+            int obj_type_id  = 0;
+            DBRes.GetField( "obj_type_id",obj_type_id, Error );
+
+            std::string obj_id  = "";
+            DBRes.GetField( "obj_id",obj_id, Error );
+
+            int map_id  = 0;
+            DBRes.GetField( "map_id",map_id, Error );
+
+            int area_id  = 0;
+            DBRes.GetField( "area_id",area_id, Error );
+
+            double limit_value = 0;
+            DBRes.GetField( "limit_value",limit_value, Error );
+
+            double cur_value = 0;
+            DBRes.GetField( "cur_value",cur_value, Error );
+
+            double x = 0;
+            DBRes.GetField( "x",x, Error );
+
+            double y = 0;
+            DBRes.GetField( "y",y, Error );
+
+            std::string cur_time  = "";
+            DBRes.GetField( "cur_time",cur_time, Error );
+
+            int stat  = 0;
+            DBRes.GetField( "stat",stat, Error );
+
+
+            std::shared_ptr<ya_event> ev = std::make_shared<ya_event>(event_id);
+            ev->m_status = static_cast<EVENT_STATUS>(stat);
+            ev->m_ev_type = static_cast<EVENT_TYPE>(event_type_id);
+
+            ev->m_obj_type = static_cast<OBJECT_TYPE>(obj_type_id);
+            ev->m_obj_id = tool_other::to13str(obj_id);
+            ev->m_cur_time = tool_time::to_time_ex(cur_time);
+
+            ev->m_cur_value = cur_value;
+            ev->m_limit_value = limit_value;
+
+            ev->m_map_id = map_id;
+            ev->m_area_id = area_id;
+            ev->x = x;
+            ev->y = y;
+
+            m_map.insert(std::make_pair(ev->get_list_id(), ev));
+        }
+
+        for(auto&iter: m_map)
+        {
+            auto ev = iter.second;
+            log_info("event list %lld,%d,%d,%d,%s,%d,%d,%f,%f,%f,%f,%s"
+                     , ev->get_id(),ev->m_status,ev->m_ev_type,ev->m_obj_type,ev->m_obj_id.c_str()
+                     ,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());
+        }
+    }
+}
+
+template<> std::shared_ptr<event_list>
+single_base<event_list, uint64_t, std::shared_ptr<ya_event>>::m_instance=std::make_shared<event_list>();
+
+

+ 283 - 0
ya_event.h

@@ -0,0 +1,283 @@
+#ifndef YA_EVENT_H
+#define YA_EVENT_H
+
+/**
+ * @brief 告警事件类型
+ * @author 戴月腾
+ * @date 2018-09-24
+ */
+
+#include<map>
+#include<chrono>
+#include<memory>
+#include"write-copy.h"
+#include"log.h"
+#include "db_api/CDBConnPool.h"
+#include"card.h"
+#include"common_tool.h"
+
+/**
+ * @brief 事件状态
+ */
+enum EVENT_STATUS
+{
+    ///事件开始
+    ES_START = 0,
+    ///呼救已处理状态
+    ES_DEAL_HELP = 1,
+    ///事件结束
+    ES_END = 100
+};
+
+enum EVENT_TYPE{ // 事件类型
+    ET_AREA_OVER_COUNT_PERSON = 3,	// 区域人员超员
+
+    ET_CARD_LOW_POWER_SERIOUS = 12, // 电量极低
+
+    ET_CARD_AREA_OVER_TIME_PERSON = 15, // 人员区域超时
+    ET_CARD_OVER_SPEED = 21, // 车辆超速
+    ET_CARD_HELP = 24, // 人员呼救
+
+    CARD_EVENT_COUNT_MAX,
+};
+
+/**
+ * @brief 对象类型
+ */
+enum OBJECT_TYPE
+{
+    ///矿井
+    OT_MINE = 1,
+    ///区域
+    OT_AREA = 2,
+    ///分站
+    OT_DEVICE_READER = 4,
+    ///标识卡,包括人员、车辆、自组网等
+    OT_CARD = 9,
+};
+
+/**
+ * @brief 告警事件
+ */
+struct ya_event
+{
+private:
+    uint64_t m_ev_id;
+public:
+    ya_event(uint64_t e_id):m_cur_time(std::chrono::system_clock::now())
+    {
+        m_ev_id = e_id;
+
+        m_obj_id = "";
+        m_map_id = 0;
+        m_area_id = 0;
+        x = 0;
+        y = 0;
+        m_limit_value = 0;
+        m_cur_value = 0;
+        m_desc = "";
+        m_landmarkid = 0;
+        m_landmarkdirect = 0;
+        m_landmarkdist = 0;
+
+        m_status=ES_START;
+        m_is_display=true;
+    }
+    ~ya_event(){}
+public:
+    ///告警状态,开始、结束
+    EVENT_STATUS m_status;
+
+    ///告警类型
+    EVENT_TYPE m_ev_type;
+    ///告警对象类型
+    OBJECT_TYPE m_obj_type;
+    /// 告警对象编号,与告警对象类型对应,如告警对象类型为分站,此字段为分站编号
+    std::string m_obj_id;
+    ///当前时间,为告警事件的触发时间,如果状态为开始,则表示开始时间,否则为结束时间
+    std::chrono::system_clock::time_point m_cur_time;
+
+    ///告警所在地图
+    int m_map_id;
+    ///告警所在区域
+    int m_area_id;
+    ///位置
+    double x;
+    ///位置
+    double y;
+    ///告警阈值
+    double m_limit_value;
+    ///当前值
+    double m_cur_value;
+    ///描述
+    std::string m_desc;
+
+    /// 地标信息
+    int m_landmarkid;
+    /// 与地标的距离
+    double m_landmarkdist;
+    /// 所处地标的方向
+    int m_landmarkdirect;
+
+    bool m_is_display;
+
+    bool is_end()
+    {
+        return ES_END == m_status;
+    }
+
+    ///作为事件map列表的id,方便查找;(obj_type<<32| obj_id)
+    uint64_t get_list_id();
+
+    uint64_t get_id(){return m_ev_id;}
+};
+typedef std::shared_ptr<ya_event> event_ptr;
+typedef std::map<uint64_t, std::shared_ptr<ya_event>> event_map;
+typedef std::shared_ptr<event_map> event_map_ptr;
+
+
+struct event_list:single_base<event_list,uint64_t,std::shared_ptr<ya_event>>
+{
+public:
+    ///作为事件map列表的id,方便查找;(ev_type<<32| obj_id)
+    static uint64_t to_list_id(uint32_t obj_id, EVENT_TYPE ev_type)
+    {
+        return (static_cast<uint64_t>(ev_type)<<32)|static_cast<uint64_t>(obj_id);
+    }
+
+    ///创建与卡无关的警告
+    static event_ptr create_event_not_card(OBJECT_TYPE obj_type, int obj_id, EVENT_TYPE ev_type)
+    {
+        return create_event(obj_type, obj_id, 0, ev_type);
+    }
+
+    ///创建与卡有关的警告,需要卡类型
+    static event_ptr create_event_card(uint32_t card_id, int32_t card_type, EVENT_TYPE ev_type)
+    {
+        return create_event(OT_CARD, static_cast<int32_t>(card_id), card_type, ev_type);
+    }
+
+    static void copy_event(const std::shared_ptr<card_location_base> card_ptr, event_ptr ev_ptr)
+    {
+        ev_ptr->x = card_ptr->x;
+        ev_ptr->y = card_ptr->y;
+        ev_ptr->m_cur_time = std::chrono::system_clock::now();
+        ev_ptr->m_is_display = card_ptr->m_display;
+
+        auto hover = card_ptr->get_area_hover();
+        if(nullptr!=hover)
+        {
+            ev_ptr->m_area_id =  hover->m_area->id();
+            ev_ptr->m_map_id = hover->m_area->mapid();
+
+            ev_ptr->m_landmarkid = hover->landmark_dir;
+            ev_ptr->m_landmarkdist = hover->landmark_dis;
+            ev_ptr->m_landmarkdirect = hover->landmark_dir;
+        }
+    }
+
+    std::shared_ptr<ya_event> get(uint32_t obj_id, EVENT_TYPE ev_type)
+    {
+        return base::get(to_list_id(obj_id, ev_type));
+    }
+
+    void load_his_data_from_db();
+
+    static void save_event(const event_ptr 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, stat, event_type_id, obj_type_id, obj_id, \
+                map_id, area_id, limit_value, cur_value, x, y, cur_time, description, \
+                landmark_id, landmark_dist,direction_mapper_id )\
+                VALUES(%ld, %d, %d, %d, %s, %d, %d, %.2f, %.2f, %f, %f, '%s', '%s', %d, %10.3f, %d);",
+        ev_ptr->get_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_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(),
+                ev_ptr->m_landmarkid, ev_ptr->m_landmarkdist, ev_ptr->m_landmarkdirect);
+
+        tool_db::PushAsync(sql);
+    }
+
+    ~event_list(){}
+
+    static std::string ev_to_json(std::shared_ptr<ya_event> ev_ptr)
+    {
+        std::vector<std::shared_ptr<ya_event>> evs;
+        evs.push_back(ev_ptr);
+        return evs_to_json(evs);
+    }
+
+    static std::string evs_to_json(std::vector<std::shared_ptr<ya_event>> arr)
+    {
+        rapidjson::Document doc(rapidjson::kObjectType);
+        rapidjson::Value data(rapidjson::kArrayType);
+        rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();
+
+        auto it=arr.begin();
+        for(;it!=arr.end();++it)
+        {
+            if((*it)->m_is_display)
+            {
+                ev_to_node(*it, allocator, data);
+            }
+        }
+
+        doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_EVENT, allocator);
+        doc.AddMember(JSON_ROOT_KEY_VERSION,INTERFACE_VERSION, allocator);
+        doc.AddMember(JSON_ROOT_KEY_DATA,data, allocator);
+
+        rapidjson::StringBuffer sb;
+        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
+        doc.Accept(writer);
+
+        return sb.GetString();
+    }
+
+private:
+    static void ev_to_node(std::shared_ptr<ya_event> ev_ptr,
+                           rapidjson::Document::AllocatorType& allocator,
+                           rapidjson::Value& out_data)
+    {
+        rapidjson::Value ev(rapidjson::kObjectType);
+
+        ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->get_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_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);
+        ev.AddMember(JSON_KEY_EVENT_Y,ev_ptr->y, allocator);
+
+        ev.AddMember(JSON_KEY_EVENT_LIMIT_VALUE,ev_ptr->m_limit_value, allocator);
+        ev.AddMember(JSON_KEY_EVENT_CUR_VALUE,ev_ptr->m_cur_value, allocator);
+        ev.AddMember(JSON_KEY_EVENT_CUR_TIME,tool_time::to_ms(ev_ptr->m_cur_time), allocator);
+
+        ev.AddMember(JSON_KEY_EVENT_LANDMARK_ID,ev_ptr->m_landmarkid, allocator);
+        ev.AddMember(JSON_KEY_EVENT_LANDMARK_DIRECTION,ev_ptr->m_landmarkdirect, allocator);
+        ev.AddMember(JSON_KEY_EVENT_LANDMARK_DISTANCE,ev_ptr->m_landmarkdist, allocator);
+
+        out_data.PushBack(ev, allocator);
+    }
+
+private:
+    static event_ptr create_event(OBJECT_TYPE obj_type, int obj_id, int type, EVENT_TYPE ev_type)
+    {
+        auto ev_ptr = std::make_shared<ya_event>(tool_time::now_to_us());
+
+        ev_ptr->m_ev_type = ev_type;
+        ev_ptr->m_obj_type = obj_type;
+        ev_ptr->m_obj_id = card_list::to_id64_str(type, static_cast<uint32_t>(obj_id) );
+
+        return ev_ptr;
+    }
+};
+
+#endif // YA_EVENT_H