Browse Source

合并人卡考勤

daiyueteng 6 years ago
parent
commit
463904c12d
14 changed files with 432 additions and 305 deletions
  1. 1 0
      CMakeLists.txt
  2. 1 1
      CMakeLists.txt.user
  3. 93 0
      ant.cpp
  4. 138 120
      ant.h
  5. 25 18
      area.cpp
  6. 14 9
      area.h
  7. 23 4
      card.cpp
  8. 10 0
      card.h
  9. 68 103
      module_service/module_area.cpp
  10. 4 6
      module_service/module_attendance_person.h
  11. 35 25
      module_service/module_attendance_vehicle.h
  12. 2 2
      module_service/module_const.h
  13. 15 14
      site_area.cpp
  14. 3 3
      site_area.h

+ 1 - 0
CMakeLists.txt

@@ -53,6 +53,7 @@ set(SRC_YASL "ant.cpp" "ant.h" "base64.cpp" "base64.h" "card.cpp" "card.h" "cloc
 
     "landmark.h" "landmark.cpp" "area.h" "area.cpp"
     "site_area.h" "site_area.cpp"
+    "special_area.h" "special_area.cpp"
     )
 
 set(SRC_MODULE

+ 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-20T11:21:34. -->
+<!-- Written by QtCreator 4.7.0, 2018-09-20T15:06:48. -->
 <qtcreator>
  <data>
   <variable>EnvironmentId</variable>

+ 93 - 0
ant.cpp

@@ -3,6 +3,7 @@
 #include <string.h>
 #include <math.h>
 #include "ant.h"
+#include "db_api/CDBConnPool.h"
 
 template<> std::shared_ptr<sit_list> 
 single_base<sit_list, int, std::shared_ptr<site>>::m_instance=std::make_shared<sit_list>();
@@ -167,6 +168,98 @@ 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\
+            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 );
+    if (nCount > 0)
+    {
+        log_info( "init_site. The record count=%d\n", nCount );
+
+        while ( DBRes.GetNextRecod(Error) )
+        {
+            int reader_id  = 0;
+            DBRes.GetField( "reader_id",reader_id, Error );
+
+            auto site_ptr=sit_list::instance()->get(reader_id);
+            if(nullptr==site_ptr)
+            {
+                site_ptr = std::make_shared<site>(reader_id);
+                sit_list::instance()->add(reader_id,site_ptr);
+            }
+
+            int reader_type_id  = 0;
+            DBRes.GetField( "reader_type_id",reader_type_id, Error );
+
+            int map_id  = 0;
+            DBRes.GetField( "map_id",map_id, Error );
+
+            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 );
+
+            double scale= 0;
+            DBRes.GetField( "scale",scale, Error );
+
+            site_ptr->m_reader_type_id = reader_type_id;
+            site_ptr->m_map_id = map_id;
+            site_ptr->m_area_id = area_id;
+//            site_ptr->m_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;
+        }
+    }
+}
 
 
 loc_message::loc_message()

+ 138 - 120
ant.h

@@ -15,7 +15,7 @@
 
 struct path
 {
-    std::array<line_v,2>	m_line; 
+    std::array<line_v,2>	m_line;
     std::array<double,2>    m_slope;
     path()
     {
@@ -39,25 +39,25 @@ struct path
     {
         return m_line[i];
     }
-    const line_v & operator[](int i) const 
+    const line_v & operator[](int i) const
     {
         return m_line[i];
     }
-   
+
 };
 //?
 struct algo_config
 {
-	const char*desc;
-	int min_msg_cnt;
-	int best_msg_cnt;
-	double min_wait_time;
-	double max_wait_time;
+    const char*desc;
+    int min_msg_cnt;
+    int best_msg_cnt;
+    double min_wait_time;
+    double max_wait_time;
 };
 //
 struct ant :point
 {
-	std::vector<path> m_path;
+    std::vector<path> m_path;
     path & operator[](int i)
     {
         return m_path[i];
@@ -79,7 +79,7 @@ struct ant :point
             if(p.vaild())
             {
                 point pt;
-                if(dist <= p.m_line[0].length() || (dist > p.m_line[0].length() && p.m_line[1].empty()))        
+                if(dist <= p.m_line[0].length() || (dist > p.m_line[0].length() && p.m_line[1].empty()))
                 {
                     d += d*p.m_slope[0];
                     pt = point(p.m_line[0][0].x + d*p.m_line[0].cos() , p.m_line[0][0].y + d*p.m_line[0].sin());
@@ -104,43 +104,59 @@ struct ant :point
 /**
  * @brief 分站位置 1井上,2井下
  */
-enum UP_DOWN_SITE
+enum READER_TYPE_ID
 {
     ///井上分站
-    UP_SITE=1,
+    READER_TYPE_ID_UP=1,
     ///井下分站
-    DOWN_SITE=2
+    READER_TYPE_ID_DOWN=2
 };
 
 struct site:point
 {
-	static algo_config g_config[];
-	int      m_algo;			//TOF:0,TDOA:1
-	int      m_num_dims;	    //1维:0,2维:1,3维:2
+    static algo_config g_config[];
+    int      m_algo;			//TOF:0,TDOA:1
+    int      m_num_dims;	    //1维:0,2维:1,3维:2
     double  m_scale = 2.0;  // 地图比例尺
 
-	point    m_position;
-	int index()const;
-	const algo_config&config()const;
-	int id()const
-	{
-		return m_id;
-	}
-	site(int id=-1);
+    point    m_position;
+    int index()const;
+    const algo_config&config()const;
+    int id()const
+    {
+        return m_id;
+    }
+    site(int id=-1);
+
+    mutable double m_height=1.5;
+    int m_id;
+    bool m_path_empty;
+    std::array<ant,2> m_ant;
+
+    mutable double m_ant_dist=0;
+    mutable double m_ant_dist_sum_new=0;
+    mutable int m_ant_dist_cnt_new=0;
 
-	mutable double m_height=1.5;
-	int m_id;
-	bool m_path_empty;
-	std::array<ant,2> m_ant;
+    ///分站位置 READER_TYPE_ID
+    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 = "";
 
-	mutable double m_ant_dist=0;
-	mutable double m_ant_dist_sum_new=0;
-	mutable int m_ant_dist_cnt_new=0;
+    double m_angle;
+    /// 状态 0 正常, 1 故障
+    int m_state=0;
+    std::string m_ip="";
 
-    ///分站位置 UP_DOWN_SITE
-    int m_up_down;
+    /// 设备类型,分站、通信分站、交通灯等
+    int m_device_type_id=0;
+    /// 是否为特殊分站,定位结果与分站间距4米以内,如果是特殊分站就将定位点定位在分站附近,否则抛弃计算结果
+    int m_isSpecial=0;
+    /// 指定分站定位类型:一维定位,二维定位,三维定位
+    int m_dimension=0;
 
-    point get_dstp(const point pt) const 
+    point get_dstp(const point pt) const
     {
         point tmp;
         for(const auto & p : m_ant[0].m_path)
@@ -152,9 +168,9 @@ struct site:point
                     if(p[i].contain(pt,0.01))
                     {
                         //if(i==0)
-                         // return *this;
+                        // return *this;
                         //else
-                          tmp = p[i][0];
+                        tmp = p[i][0];
                     }
                 }
             }
@@ -162,51 +178,51 @@ struct site:point
         return tmp;
     }
 
-	void count_ant_dist(double dist_tof1, double dist_tof2)const
-	{
-		if(dist_tof1<10 || dist_tof2<10)
-			return;
-		double dist = fabs(dist_tof1 - dist_tof2);
-		if(dist>5)
-			return;
-		m_ant_dist_sum_new += dist;
-		m_ant_dist_cnt_new++;
-		
-		if(m_ant_dist_cnt_new >= 2500)
-		{
-			m_ant_dist = m_ant_dist_sum_new / m_ant_dist_cnt_new;
-			m_ant_dist_sum_new = 0;
-			m_ant_dist_cnt_new = 0;
-		}
-	}
+    void count_ant_dist(double dist_tof1, double dist_tof2)const
+    {
+        if(dist_tof1<10 || dist_tof2<10)
+            return;
+        double dist = fabs(dist_tof1 - dist_tof2);
+        if(dist>5)
+            return;
+        m_ant_dist_sum_new += dist;
+        m_ant_dist_cnt_new++;
+
+        if(m_ant_dist_cnt_new >= 2500)
+        {
+            m_ant_dist = m_ant_dist_sum_new / m_ant_dist_cnt_new;
+            m_ant_dist_sum_new = 0;
+            m_ant_dist_cnt_new = 0;
+        }
+    }
     void swap()
     {
-       auto v0 =  m_ant[0].m_path;
-       auto v1 =  m_ant[1].m_path;
-       std::copy (std::begin(v0),std::end(v0),std::back_inserter(m_ant[1].m_path));
-       std::copy (std::begin(v1),std::end(v1),std::back_inserter(m_ant[0].m_path));
+        auto v0 =  m_ant[0].m_path;
+        auto v1 =  m_ant[1].m_path;
+        std::copy (std::begin(v0),std::end(v0),std::back_inserter(m_ant[1].m_path));
+        std::copy (std::begin(v1),std::end(v1),std::back_inserter(m_ant[0].m_path));
+    }
+    double ant_dist()const
+    {
+        return m_ant[0].dist(m_ant[1]);
     }
-	double ant_dist()const
-	{
-		return m_ant[0].dist(m_ant[1]);
-	}
-	
-	bool is_path_empty()const
-	{
+
+    bool is_path_empty()const
+    {
         return m_path_empty;
-	}
+    }
 
-	bool have_valid_path()const
-	{
+    bool have_valid_path()const
+    {
         return m_id != -1 && ant_dist() > 0.1;
-	}
+    }
 
-	std::string to_string()const
-	{
+    std::string to_string()const
+    {
         std::stringstream ss;
         ss<<"site_id:"<<m_id<<"x:"<<x<<" y: "<<y<<" scale:"<<m_scale;
         for(const auto a:m_ant)
-        {  
+        {
             ss<<"<";
             for(const auto p:a.m_path)
             {
@@ -215,33 +231,33 @@ struct site:point
             ss<<">";
         }
         return ss.str();
-	}
+    }
 
-	const point&path(int i)const
-	{
+    const point&path(int i)const
+    {
         static point p;
         if(i>=(int)m_ant[0].m_path.size())
             return p ;
-		return m_ant[0].m_path[i].m_line[0][1];
-	}
+        return m_ant[0].m_path[i].m_line[0][1];
+    }
 
     std::vector<point> solving(int ant_id, double dist)const
-	{
+    {
         const ant &a = m_ant[ant_id];
         if(dist<50 && dist>0)
-		{
-			if(dist<m_height)
-			{
-				m_height=dist;
-				dist=0;				
-			}
-			else
-			{
-				dist=sqrt(dist*dist-m_height*m_height);
-			}
-		}
+        {
+            if(dist<m_height)
+            {
+                m_height=dist;
+                dist=0;
+            }
+            else
+            {
+                dist=sqrt(dist*dist-m_height*m_height);
+            }
+        }
         return std::move(a.getsol(dist));
-   	}
+    }
     ant operator[](int i)
     {
         return m_ant[i];
@@ -255,43 +271,45 @@ struct site:point
 
 struct sit_list:single_base<sit_list,int,std::shared_ptr<site>>
 {
-	void load(const char*ant_file,const char*path_file)
-	{
-		read_sit_list(ant_file);
-		read_ant_path(path_file);
-	}
+    void load(const char*ant_file,const char*path_file)
+    {
+        read_sit_list(ant_file);
+        read_ant_path(path_file);
+    }
 
-	void load_from_db()
-	{
-		load("data_reader_antenna.txt","path_tof.txt");
-	}
+    void load_from_db()
+    {
+        load("data_reader_antenna.txt","path_tof.txt");
+        init_site();
+    }
 
-	void read_sit_list(const char*fname);
-	void read_ant_path(const char*fname);
+    void read_sit_list(const char*fname);
+    void read_ant_path(const char*fname);
+    void init_site();
 };
 
 struct loc_message
 {
-	site     m_sit;
-	uint64_t m_num_ticks; //tof时间片m_tof或tdoa相对root时间
-	uint64_t m_loc_time;
-	uint32_t m_card_id;
-	int32_t	 m_card_ct;
-	int8_t   m_card_type;
-	int8_t   m_ant_id;
-	int16_t  m_rav;
-	int16_t  m_acc;
-	uint16_t m_sync_ct;
-	uint16_t m_rssi;
+    site     m_sit;
+    uint64_t m_num_ticks; //tof时间片m_tof或tdoa相对root时间
+    uint64_t m_loc_time;
+    uint32_t m_card_id;
+    int32_t	 m_card_ct;
+    int8_t   m_card_type;
+    int8_t   m_ant_id;
+    int16_t  m_rav;
+    int16_t  m_acc;
+    uint16_t m_sync_ct;
+    uint16_t m_rssi;
 
 
-	loc_message();
-	loc_message(site s,uint64_t num_ticks,uint64_t timestamp,
-			uint32_t cardid,int32_t ct,int8_t type,int8_t antid,	
-			int16_t rav,int16_t acc,uint16_t sync_ct,uint16_t rssi)
-		:m_sit(s)
-		 ,m_num_ticks(num_ticks)
-         ,m_loc_time(timestamp)
+    loc_message();
+    loc_message(site s,uint64_t num_ticks,uint64_t timestamp,
+                uint32_t cardid,int32_t ct,int8_t type,int8_t antid,
+                int16_t rav,int16_t acc,uint16_t sync_ct,uint16_t rssi)
+        :m_sit(s)
+        ,m_num_ticks(num_ticks)
+        ,m_loc_time(timestamp)
         ,m_card_id(cardid)
         ,m_card_ct(ct)
         ,m_card_type(type)
@@ -300,8 +318,8 @@ struct loc_message
         ,m_acc(acc)
         ,m_sync_ct(sync_ct)
         ,m_rssi(rssi)
-	{}
-	int tool_index()const;
+    {}
+    int tool_index()const;
 };
 
 #endif

+ 25 - 18
area.cpp

@@ -11,6 +11,8 @@
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/classification.hpp>
 
+//#include"module_service/module_area.h"
+
 template<> std::shared_ptr<area_list> 
 single_base<area_list, int, std::shared_ptr<area>>::m_instance=std::make_shared<area_list>();
 
@@ -18,35 +20,40 @@ void area::on_hover(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,u
  {
  	//check超时
 	log_info("on_hover..%d  areaId:%d",card_id,m_id);
- 	time_t now = time(NULL);
- 	if(now-c->m_enter_time>m_limit_time_second && !c->m_is_over_time)
- 	{
- 		c->m_is_over_time=true;
- 		//产生告警
- 	}
+// 	time_t now = time(NULL);
+// 	if(now-c->m_enter_time>m_limit_time_second && !c->m_is_over_time)
+// 	{
+// 		c->m_is_over_time=true;
+// 		//产生告警
+// 	}
+//    module_area::instance()->on_hover(card_id,c,speed,type);
  }
 
 void area::on_enter(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
 {
 	log_info("on_enter..%d  areaId:%d",card_id,m_id);
-	//入库 : 进入区域
-	int cu = m_card_count.load();
-	cu++;
-	m_card_count.store(cu);
-	//check超员
+//	//入库 : 进入区域
+//	int cu = m_card_count.load();
+//	cu++;
+//	m_card_count.store(cu);
+//	//check超员
+
+//    module_area::instance()->on_enter(card_id,c,speed,type);
 }
 
 void area::on_leave(int64_t card_id,std::shared_ptr<area_hover>&c,double speed,uint64_t type)
 {
 	log_info("on_leave..%d  areaId:%d",card_id,m_id);
 	//入库 : 出 区域
-	int cu = m_card_count.load();
-	m_card_count.store(cu--);
-	//check 超员
-	if(c->m_is_over_time)
-	{
-		//取消告警
-	}
+    //	//入库 : 出 区域
+    //	int cu = m_card_count.load();
+    //	m_card_count.store(cu--);
+    //	//check 超员
+    //	if(c->m_is_over_time)
+    //	{
+    //		//取消告警
+    //	}
+    //    module_area::instance()->on_leave(card_id,c,speed,type);
 }
 bool area::in_area(const point & p)
 {

+ 14 - 9
area.h

@@ -58,16 +58,21 @@ struct area
 		return m_area_type == AREA_TYPE_NO_COVER;
 	}
 	virtual ~area()
-	{}
-	std::vector<point> m_bound;
-private:
-	std::atomic<int> m_card_count;
-	int32_t    m_id;
+    {}
+    ///区域卡数
+    int card_count()const
+    {
+        return m_person_count + m_vehicle_count;
+    }
 
+    std::vector<point> m_bound;
+public:
+    //std::atomic<int> m_card_count;
+    int    m_id;
     ///区域类型  AREA_TYPE
-    int32_t m_area_type;
+    int m_area_type;
+
 
-    
     ///区域人卡数
     std::atomic<int> m_person_count;
     ///区域车卡数
@@ -81,8 +86,8 @@ private:
     ///速度门限
     double m_limit_speed;
 
-	double m_scale;
-	int32_t m_mapid;
+    double m_scale;
+    int32_t m_mapid;
 };
 
 struct area_list:single_base<area_list,int,std::shared_ptr<area>>

+ 23 - 4
card.cpp

@@ -199,14 +199,24 @@ struct person:card_location_base,private card_area
 	
 	virtual void site_hover(int sid)
 	{
-		m_site_area->on_point(m_id,sid,0);
+        if(m_time<=0)
+        {
+            return;
+        }
+        m_site_area->on_point(m_id,sid,nullptr, m_type);
 	}
+
+    virtual std::shared_ptr<area_hover> get_area_hover()
+    {
+        return m_area_tool->m_area_hover;
+    }
+
 	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_site_area->on_point(m_id,0,this, m_type);
 		//
 	}
 	//人卡升井后该线程要停掉
@@ -283,13 +293,22 @@ struct car:card_location_base,private card_area
 
 	virtual void site_hover(int sid)
 	{
-		m_site_area->on_point(m_id,sid,0);
+//        if(m_time<=0)
+//        {
+//            return;
+//        }
+//        m_site_area->on_point(m_id,sid,0, m_type);
 	}
 
+    virtual std::shared_ptr<area_hover> get_area_hover()
+    {
+        return m_area_tool->m_area_hover;
+    }
+
 	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_site_area->on_point(m_id,0,this, m_type);
 	}
 
 	void set(ev::dynamic_loop * loop)

+ 10 - 0
card.h

@@ -8,6 +8,8 @@
 #include "write-copy.h"
 #include "websocket/ws_common.h"
 #include "common.h"
+#include"area.h"
+
 #define CARD_LOST_TIME_OUT (30*1000)
 
 struct task;
@@ -28,6 +30,8 @@ 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;			//类型
@@ -38,6 +42,11 @@ 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
 {
@@ -53,6 +62,7 @@ struct card_location_base:card
 	virtual void do_business(const point &pt)=0;
 	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 void reset(std::shared_ptr<monkey_person> mp){}
 
     void on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history);

+ 68 - 103
module_service/module_area.cpp

@@ -1,122 +1,87 @@
-#include "module_area.h"
-#include"module_area_overman.h"
-#include"module_area_timeout.h"
-#include"module_attendance_vehicle.h"
-#include"module_const.h"
-#include"module_area_over_speed.h"
-
-
-void module_area::on_enter(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed)
-{
-    //与考勤,卡数统计,超员,超时无关的区域   直接返回
-    if(AT_OTHER == c->m_area->m_area_type)
-    {
-        return;
-    }
-
-    auto card_ptr=card_list::instance()->get(card_id);
-    if(!card_ptr)
-    {
-        log_error("卡不存在card_id=%d", card_id);
-        return;
-    }
+#ifndef MODULE_AREA_H
+#define MODULE_AREA_H
 
-    std::lock_guard<std::mutex> lock(_mutex);
+/**
+ * @brief 与区域相关的业务模块总接口
+ * @author 戴月腾
+ * @date 2018-08-25
+ */
 
-    //c->m_enter_time = std::chrono::system_clock::now();
-
-    if(CT_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(CT_VEHICLE == card_ptr->m_type)//统计车卡
-    {
-        c->m_area->m_vehicle_count++;
-
-        //区域车卡超速
-        module_area_over_speed::instance()->on_enter(card_ptr, c, speed);
-        //车卡考勤
-        module_attendance_vehicle::instance()->on_enter(card_ptr, c, speed);
-    }
-}
+#include"area.h"
+#include"module_const.h"
+//#include"module_web.h"
 
-void module_area::on_hover(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed)
+class module_area:public i_thread, public singleton_base<module_area>
 {
-    //与考勤,卡数统计,超员,超时无关的区域   直接返回
-    if(AT_OTHER == c->m_area->m_area_type)
+private:
+    friend class singleton_base<module_area>;
+    module_area()
     {
-        return;
     }
 
-    auto card_ptr=card_list::instance()->get(card_id);
-    if(!card_ptr)
+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()
     {
-        log_error("卡不存在card_id=%d", card_id);
-        return;
-    }
+        //        std::vector<std::shared_ptr<ya_event>> arr;
+        //        get_all_events(arr);
 
-    std::lock_guard<std::mutex> lock(_mutex);
+        //        if(!arr.empty())//发送给web端
+        //        {
+        //            return tool_json::evs_to_json(arr);
+        //        }
 
-    if(CT_PERSON == card_ptr->m_type)//统计人卡
-    {
-        //区域人卡超员
-        module_area_overman::instance()->on_hover(card_ptr, c, speed, _map);
-        //区域人卡超时
-        module_area_timeout::instance()->on_hover(card_ptr, c, speed, _map);
+        //        return "";
     }
-
-    if(CT_VEHICLE == card_ptr->m_type)//统计车卡
+private:
+    /**
+     * @brief 线程函数
+     */
+    void run()
     {
-        //区域车卡超速
-        module_area_over_speed::instance()->on_hover(card_ptr, c, speed, _map);
-        //车卡考勤
-        module_attendance_vehicle::instance()->on_hover(card_ptr, c, speed, _map);
-    }
-}
+        //        std::vector<std::shared_ptr<ya_event>> arr;
+        //        get_all_events(arr);
 
-void module_area::on_leave(uint64_t card_id,std::shared_ptr<area_hover>&c,double speed)
-{
-    //与考勤,卡数统计,超员,超时无关的区域   直接返回
-    if(AT_OTHER == c->m_area->m_area_type)
-    {
-        return;
+        //        if(!arr.empty())//发送给web端
+        //        {
+        //            swsClientMgr.send(JSON_CMD_VALUE_PUSH, tool_json::evs_to_json(arr));
+        //        }
     }
 
-    auto card_ptr=card_list::instance()->get(card_id);
-    if(!card_ptr)
+    /**
+     * @brief 获取所有的告警事件
+     * @param out_data
+     */
+    void get_all_events(std::vector<std::shared_ptr<ya_event>>& arr)
     {
-        log_error("卡不存在card_id=%d", card_id);
-        return;
+        {
+            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--);
+                }
+            }
+        }
     }
 
-    std::lock_guard<std::mutex> lock(_mutex);
-
-    if(CT_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(CT_VEHICLE == card_ptr->m_type)//统计车卡
-    {
-        c->m_area->m_vehicle_count--;
-
-        //区域车卡超速
-        module_area_over_speed::instance()->on_leave(card_ptr, c, speed);
-        //车卡考勤
-        module_attendance_vehicle::instance()->on_leave(card_ptr, c, speed);
-    }
-}
-
-
+    std::map<uint64_t, std::shared_ptr<ya_event>> _map;
+};
 
+#endif // MODULE_AREA_H

+ 4 - 6
module_service/module_attendance_person.h

@@ -37,8 +37,7 @@ public:
      * @param card_id
      * @param enter_site
      */
-    void enter_site(uint64_t card_id,int enter_site,uint64_t type,
-                    const std::shared_ptr<area_hover> area_hover_ptr)
+    void enter_site(uint64_t card_id,int enter_site,uint64_t type)
     {
         auto card_ptr=card_list::instance()->get(tool_other::to_uint64_cardid(type, card_id));
         if(!card_ptr)
@@ -63,7 +62,7 @@ public:
                 card_ptr->m_stat_attendance=AS_NOT_ATTENDANCE;
 
                 //作为一条结束考勤记录保存到数据库
-                tool_db::save_attendance(card_ptr, area_hover_ptr);
+                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);
@@ -82,7 +81,7 @@ public:
                 card_ptr->m_attendance_start_time=std::chrono::system_clock::from_time_t(start);
 
                 //作为一条开始考勤记录保存到数据库
-                tool_db::save_attendance(card_ptr, area_hover_ptr);
+                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);
@@ -95,8 +94,7 @@ public:
      * @param card_id
      * @param enter_site
      */
-    void leave_site(uint64_t card_id,int enter_site,uint64_t type,
-                    const std::shared_ptr<area_hover> area_hover_ptr)
+    void leave_site(uint64_t card_id,int enter_site,uint64_t type)
     {
 
     }

+ 35 - 25
module_service/module_attendance_vehicle.h

@@ -32,40 +32,50 @@ public:
     void on_enter(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed)
     {
         //card_ptr->m_attendance_start_time=std::chrono::system_clock::now();
-    }
 
-    void on_hover(std::shared_ptr<card_location_base> card_ptr,std::shared_ptr<area_hover>&c,double speed,
-                  event_map& ev_map)
-    {
-//        auto area_ptr = c->m_area;
+        auto area_ptr = c->m_area;
+
+        //从考勤状态转换为结束考勤
+        if(!tool_other::is_attendance_area(area_ptr->m_id, card_ptr->m_id))
+        {
+            if(tool_other::is_attendance(card_ptr->m_stat_attendance))
+            {
+                //考勤结束
+                card_ptr->m_stat_attendance=AS_NOT_ATTENDANCE;
+
+                //作为一条结束考勤记录保存到数据库
+                tool_db::save_attendance(card_ptr);
 
-//        //从考勤状态转换为结束考勤
-//        if(AT_NOT_ATTENDANCE == area_ptr->m_area_type)
-//        {
-//            if(AS_ATTENDANCE == card_ptr->m_stat_attendance)
-//            {
-//                card_ptr->m_stat_attendance = AS_NOT_ATTENDANCE;
+                log_debug("车卡考勤结束:area_id=%d,card_id=%d,stat_attendance=%d",
+                          area_ptr->m_id,card_ptr->m_id,card_ptr->m_stat_attendance);
+            }
+        }
+        else //没在考勤状态转换为考勤状态
+        {
+            if(!tool_other::is_attendance(card_ptr->m_stat_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);
 
-//                //作为一条结束考勤记录保存到数据库
-//                tool_db::save_attendance(card_ptr);
-//            }
-//        }
-//        else //没在考勤状态转换为考勤状态
-//        {
-//            if(AS_ATTENDANCE != card_ptr->m_stat_attendance)
-//            {
-//                card_ptr->m_stat_attendance = AS_ATTENDANCE;
+                //作为一条开始考勤记录保存到数据库
+                tool_db::save_attendance(card_ptr);
 
-//                //作为一条考勤记录保存到数据库
-//                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);
+            }
+        }
+    }
+
+    void on_hover(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,double speed)
     {
-
     }
 };
 typedef std::shared_ptr<module_attendance_vehicle>  module_attendance_vehicle_ptr;

+ 2 - 2
module_service/module_const.h

@@ -432,8 +432,7 @@ public:
         PushAsync(sql);
     }
 
-    static void save_attendance(const std::shared_ptr<card_location_base> card_ptr,
-                                const std::shared_ptr<area_hover> area_hover_ptr)
+    static void save_attendance(const std::shared_ptr<card_location_base> card_ptr)
     {
         char sql[LENGTH_SQL] = {0};
 
@@ -457,6 +456,7 @@ public:
         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;

+ 15 - 14
site_area.cpp

@@ -1,7 +1,7 @@
 
 #include "site_area.h"
-
 #include "card.h"
+#include "module_service/module_attendance_person.h"
 
 //每张卡包含这样一个对象,保存最后一个分站区域
 //1、记录卡进出分站的时间,地点
@@ -13,7 +13,7 @@ site_area_hover::site_area_hover()
 {
 }
 
-void site_area_hover::on_point(uint64_t card_id,int site_id,const point*pt)
+void site_area_hover::on_point(uint64_t card_id,int site_id,const point*pt,uint64_t type)
 {
 	if(pt!=nullptr)
 	{
@@ -26,27 +26,28 @@ void site_area_hover::on_point(uint64_t card_id,int site_id,const point*pt)
 	{
 		if(m_site_id==site_id) 
 			return;
+        int last_id = m_site_id;
+        m_site_id = site_id;
 
-		//离开现有分站处理,记录现有分站的进出时间和地点
-        leave_site(card_id,m_site_id);
+        //离开现有分站处理,记录现有分站的进出时间和地点
+        leave_site(card_id,last_id,type);
 
-		//进入分站覆盖区域处理,考勤
-		enter_site(card_id,site_id);
+        //进入分站覆盖区域处理,考勤
+        enter_site(card_id,site_id,type);
 
-		m_site_id=site_id;
-		m_enter_time=m_last_time=time(nullptr);
-		m_enter_point.set(0,0);
-		m_last_point.set(0,0);
+        //m_site_id=site_id;
+        m_enter_time=m_last_time=time(nullptr);
+        m_enter_point.set(0,0);
+        m_last_point.set(0,0);
 	}
 }
 
-void site_area_hover::enter_site(uint64_t card_id,int enter_site)
+void site_area_hover::enter_site(uint64_t card_id,int enter_site,uint64_t type)
 {
-
-
+    module_attendance_person::instance()->enter_site(card_id, enter_site, type);
 }
 
-void site_area_hover::leave_site(uint64_t card_id,int enter_site)
+void site_area_hover::leave_site(uint64_t card_id,int enter_site,uint64_t type)
 {
 
 

+ 3 - 3
site_area.h

@@ -10,10 +10,10 @@ struct site_area_hover
 	//调用时机:
 	//1、tof一维收到第一个数据点时,以pt=0调用
 	//2、数据点解析完毕之后调用
-    void on_point(uint64_t card_id,int site_id,const point*pt);
+    void on_point(uint64_t card_id,int site_id,const point*pt,uint64_t type);
 private:
-    void enter_site(uint64_t card_id,int enter_site);
-    void leave_site(uint64_t card_id,int enter_site);
+    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);
 
 	int    m_site_id;
 	time_t m_enter_time,m_last_time;