Jelajahi Sumber

智慧交流-车速统计

sixian 2 tahun lalu
induk
melakukan
5ba7fbadb3

+ 45 - 1
app/operation/controller/captureController.go

@@ -117,7 +117,7 @@ func (c captureCtl) VehicleTypeEx(ctx *gin.Context) {
 	ctx.JSON(http.StatusOK, common.SuccessResponse(common.Succeeded, records))
 }
 
-// 车型 line线图数据
+// VehicleTypeList 车型 line线图数据
 func (c captureCtl) VehicleTypeList(ctx *gin.Context) {
 	value, _ := ctx.Get(middleware.Authorization)
 	claims := value.(*middleware.Claims)
@@ -136,3 +136,47 @@ func (c captureCtl) VehicleTypeList(ctx *gin.Context) {
 	}
 	ctx.JSON(http.StatusOK, common.SuccessResponse(common.Succeeded, records))
 }
+
+// SpeedList 车速统计
+func (c captureCtl) SpeedList(ctx *gin.Context) {
+	value, _ := ctx.Get(middleware.Authorization)
+	claims := value.(*middleware.Claims)
+	var req model.RequestCaptureFilter
+	err := ctx.ShouldBindQuery(&req)
+	if err != nil {
+		ctx.JSON(http.StatusOK, err)
+		return
+	}
+	var records interface{}
+	records, err = service.CaptureSpeedService.GetList(claims.TenantId, req)
+
+	if err != nil {
+		ctx.JSON(http.StatusOK, err)
+		return
+	}
+	ctx.JSON(http.StatusOK, common.SuccessResponse(common.Succeeded, records))
+}
+
+// OverSpeedRecord 超速明细
+func (c captureCtl) OverSpeedRecord(ctx *gin.Context) {
+	var req model.RequestCaptureOverSpeed
+	_ = ctx.ShouldBindQuery(&req)
+	var records interface{}
+	records, err := service.CaptureSpeedService.GetOverSpeedRecord(req)
+	if err != nil {
+		ctx.JSON(http.StatusOK, err)
+		return
+	}
+	ctx.JSON(http.StatusOK, common.SuccessResponse(common.Succeeded, records))
+}
+
+// OverSpeedRecordSync 同步超速明细记录
+func (c captureCtl) OverSpeedRecordSync(ctx *gin.Context) {
+	var req model.RequestCaptureFilter
+	_ = ctx.ShouldBindQuery(&req)
+	if err := service.CaptureSpeedService.SyncOverSpeedRecord(req.StartTime, req.EndTime); err != nil {
+		ctx.JSON(http.StatusOK, err)
+		return
+	}
+	ctx.JSON(http.StatusOK, common.SuccessResponse(common.Succeeded, nil))
+}

+ 55 - 0
app/operation/dao/captureOverSpeedDao.go

@@ -0,0 +1,55 @@
+package dao
+
+import (
+	"errors"
+	"gorm.io/gorm"
+	"iot_manager_service/app/operation/model"
+	"iot_manager_service/util/common"
+)
+
+type CaptureOverSpeed struct {
+	ID        int         `gorm:"comment:ID" json:"id"`
+	CaptureSn string      `gorm:"comment:抓拍单元SN" json:"code"`
+	Time      common.Time `gorm:"comment:抓拍时间;type:datetime" json:"time"`
+	Vtype     int         `gorm:"comment:车类型" json:"vtype"`
+	Plate     string      `gorm:"comment:车牌号" json:"plate"`
+	Speed     int         `gorm:"comment:速度" json:"speed"`
+	Sflag     int         `gorm:"comment:速度比率" json:"sflag"`
+}
+
+func (c CaptureOverSpeed) TableName() string {
+	return "data_capture_over_speed"
+}
+
+// GetMaxIdAndUpDateTime 得到最大同步 ID
+func (c CaptureOverSpeed) GetMaxIdAndUpDateTime() (int64, string) {
+	var captureOverSpeed CaptureOverSpeed
+	err := Db.Debug().Model(&c).Last(&captureOverSpeed).Error
+	if err != nil {
+		return 0, ""
+	}
+	return int64(captureOverSpeed.ID), captureOverSpeed.Time.String()
+}
+
+// BatchCreate 批量插入
+func (c CaptureOverSpeed) BatchCreate(his []CaptureOverSpeed) error {
+	return Db.Debug().Model(&c).CreateInBatches(his, 1000).Error
+}
+
+// Gets 记录列表
+func (c CaptureOverSpeed) Gets(captureSn string, req model.RequestCaptureOverSpeed) ([]CaptureOverSpeed, int64, error) {
+	//fmt.Printf("size = %v \n", size)
+	//fmt.Printf("current = %v \n", current)
+	var list []CaptureOverSpeed
+	db := Db.Debug().Model(&c).Where(&CaptureOverSpeed{CaptureSn: captureSn})
+	db.Where("time between ? and ?", req.StartTime+" 00:00:00", req.EndTime+" 23:59:59")
+	var count int64
+	db.Count(&count)
+	db = db.Scopes(common.Paginate(req.Current, req.Size))
+	err := db.Order("id desc").Find(&list).Error
+	if errors.Is(err, gorm.ErrRecordNotFound) {
+		err = nil
+	}
+	//fmt.Printf("count = %v", count)
+	return list, count, err
+}

+ 3 - 1
app/operation/dao/common.go

@@ -10,7 +10,9 @@ var Db *gorm.DB
 
 func InitDB(db *gorm.DB) {
 	Db = db
-	models := []common.TableModelAuto{}
+	models := []common.TableModelAuto{
+		{&CaptureOverSpeed{}, "超速车牌数据明细"},
+	}
 	for _, val := range models {
 		//fmt.Println(val.Model)
 		err := Db.Set("gorm:table_options", "comment '"+val.Comment+"'").AutoMigrate(val.Model)

+ 79 - 0
app/operation/edge_service/forCaptureItsService.go

@@ -2,10 +2,13 @@ package edge_service
 
 import (
 	"encoding/json"
+	"fmt"
 	"io/ioutil"
 	"iot_manager_service/config"
 	"net/http"
+	url2 "net/url"
 	"strings"
+	"time"
 )
 
 // CaptureIts 获取设备能耗数据
@@ -62,6 +65,18 @@ func (f ForCaptureIts) Vehicletypeex(reqPostData ForCaptureItsReq) ([]ForCapture
 	return f.pubPost(reqPostData, api)
 }
 
+// Vehiclespeedtotal 车速区间统计 日月
+func (f ForCaptureIts) VehicleSpeedTotal(reqPostData ForCaptureItsReq) ([]ForCaptureItsData, error) {
+	api := "/data/v1/its/vehiclespeedtotal"
+	return f.pubPost(reqPostData, api)
+}
+
+// Vehicleoverspeedtotal 车速超速区间统计
+func (f ForCaptureIts) VehicleOverSpeedTotal(reqPostData ForCaptureItsReq) ([]ForCaptureItsData, error) {
+	api := "/data/v1/its/vehicleoverspeedtotal"
+	return f.pubPost(reqPostData, api)
+}
+
 //公用 post请求
 func (f ForCaptureIts) pubPost(reqPostData ForCaptureItsReq, api string) ([]ForCaptureItsData, error) {
 	cfg := config.Instance()
@@ -99,3 +114,67 @@ func (f ForCaptureIts) pubPost(reqPostData ForCaptureItsReq, api string) ([]ForC
 	//fmt.Printf("result.Data = %v", result.Data)
 	return result.Data, nil
 }
+
+// SyncOverSpeedRecordData 同步超速车牌数据结构
+type SyncOverSpeedRecordData struct {
+	ID    int    `json:"id"`
+	Code  string `json:"code"`
+	Time  string `json:"time"`
+	Vtype int    `json:"vtype"`
+	Plate string `json:"plate"`
+	Speed int    `json:"speed"`
+	Flag  int    `json:"flag"`
+}
+
+//同步超速车牌号返回数据
+type syncOverSpeedRecordDataRes struct {
+	Code int                       `json:"code"`
+	Msg  string                    `json:"msg"`
+	Data []SyncOverSpeedRecordData `json:"data"`
+}
+
+func (r *ForCaptureIts) SyncOverSpeedRecord(maxId int64, maxUpDateTime string, start, end string) ([]SyncOverSpeedRecordData, error) {
+	maxId += 1
+	if maxUpDateTime == "" {
+		maxUpDateTime = time.Now().AddDate(-1, 0, 0).Format("2006-01-02 15:04:05")
+	}
+	cfg := config.Instance()
+	api := cfg.Foreign.IotEdgeUrl + "/data/v1/its/overspeed/sync"
+	url := fmt.Sprintf("%v?id=%d&start=%v&end=%v", api, maxId, url2.QueryEscape(maxUpDateTime), url2.QueryEscape(time.Now().Format("2006-01-02 15:04:05")))
+	if start != "" {
+		parse, err := time.Parse("2006-01-02", start)
+		if err != nil {
+			parse = time.Now().AddDate(-1, 0, 0)
+		}
+		startStr := parse.Format("2006-01-02 15:04:05")
+		url = fmt.Sprintf("%v?id=%d&start=%v&end=%v", api, maxId, url2.QueryEscape(startStr), url2.QueryEscape(time.Now().Format("2006-01-02 15:04:05")))
+	}
+	//fmt.Printf("url = %v", url)
+	method := "GET"
+	client := &http.Client{}
+	req, err := http.NewRequest(method, url, nil)
+
+	if err != nil {
+		return nil, err
+	}
+	res, err := client.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		return nil, err
+	}
+	//fmt.Printf("body = %v", string(body))
+	result := syncOverSpeedRecordDataRes{}
+	err = json.Unmarshal(body, &result)
+	if err != nil {
+		return nil, err
+	}
+	if result.Code != 0 {
+		panic(result.Msg)
+	}
+	//fmt.Printf("result.Data = %v", result.Data)
+	return result.Data, nil
+}

+ 34 - 0
app/operation/model/captureSpeed.go

@@ -0,0 +1,34 @@
+package model
+
+type ResponseCaptureSpeed struct {
+	CountTime string `json:"countTime"` //统一时间
+	V1        int    `json:"v1"`
+	V2        int    `json:"v2"`
+	V3        int    `json:"v3"`
+	V4        int    `json:"v4"`
+	V5        int    `json:"v5"`
+	V6        int    `json:"v6"`
+	V7        int    `json:"v7"`
+
+	V11 int `json:"v11"`
+	V13 int `json:"v13"`
+	V14 int `json:"v14"`
+	V15 int `json:"v15"`
+	V16 int `json:"v16"`
+}
+
+type RequestCaptureOverSpeed struct {
+	StartTime string `form:"queryStartDate"`
+	EndTime   string `form:"queryEndDate"`
+	CaptureId int    `form:"captureId"` //抓拍单元
+	Current   int    `form:"current"`   //当前分页
+	Size      int    `form:"size"`      //每页数量
+}
+
+type ResponseCaptureOverSpeedRecord struct {
+	Records interface{} `json:"records"` //记录列表
+	Current int         `json:"current"` //当前分页
+	Size    int         `json:"size"`    //每页数量
+	Total   int64       `json:"total"`   //总数
+	Pages   int         `json:"pages"`   //总页数
+}

+ 181 - 0
app/operation/service/captureSpeedService.go

@@ -0,0 +1,181 @@
+package service
+
+import (
+	"iot_manager_service/app/device/dao"
+	operationDao "iot_manager_service/app/operation/dao"
+	"iot_manager_service/app/operation/edge_service"
+	"iot_manager_service/app/operation/model"
+	"iot_manager_service/util/common"
+	"math"
+	"strconv"
+)
+
+var CaptureSpeedService = new(captureSpeedService)
+
+type captureSpeedService struct{}
+
+// GetList 车速统计
+func (s captureSpeedService) GetList(tenantId int, req model.RequestCaptureFilter) (map[string]interface{}, error) {
+	//sectionSpeed 区间车速数据
+	data := make(map[string]interface{})
+	speed, err := s.getSectionSpeed(tenantId, req)
+	data["sectionSpeed"] = s.viewData(req, speed, "sectionSpeed")
+	//overSpeed //超速数据
+	speed, err = s.getOverSpeed(tenantId, req)
+	data["overSpeed"] = s.viewData(req, speed, "overSpeed")
+	return data, err
+}
+
+// 区间车速数据
+func (s captureSpeedService) getSectionSpeed(tenantId int, req model.RequestCaptureFilter) ([]edge_service.ForCaptureItsData, error) {
+	//区分按月或按日
+	flag := 0
+	if req.QueryType == "month" {
+		flag = 1
+	}
+	//查出抓拍单元sn
+	unit := dao.CaptureUnit{
+		TenantId: tenantId,
+		ID:       req.CaptureId,
+	}
+	unit.GetDevice()
+	var codes []string
+	codes = append(codes, unit.CaptureSn)
+	forCaptureIts := edge_service.ForCaptureIts{}
+	speedTotal, err := forCaptureIts.VehicleSpeedTotal(edge_service.ForCaptureItsReq{
+		Codes: codes,
+		Start: req.StartTime,
+		End:   req.EndTime,
+		Flag:  flag,
+	})
+	if err != nil {
+		return nil, err
+	}
+	return speedTotal, nil
+}
+
+// 超速数据
+func (s captureSpeedService) getOverSpeed(tenantId int, req model.RequestCaptureFilter) ([]edge_service.ForCaptureItsData, error) {
+	//区分按月或按日
+	flag := 0
+	if req.QueryType == "month" {
+		flag = 1
+	}
+	//查出抓拍单元sn
+	unit := dao.CaptureUnit{
+		TenantId: tenantId,
+		ID:       req.CaptureId,
+	}
+	unit.GetDevice()
+	var codes []string
+	codes = append(codes, unit.CaptureSn)
+	forCaptureIts := edge_service.ForCaptureIts{}
+	speedTotal, err := forCaptureIts.VehicleOverSpeedTotal(edge_service.ForCaptureItsReq{
+		Codes: codes,
+		Start: req.StartTime,
+		End:   req.EndTime,
+		Flag:  flag,
+	})
+	if err != nil {
+		return nil, err
+	}
+	return speedTotal, nil
+}
+
+// 前端数据格式渲染
+func (s captureSpeedService) viewData(req model.RequestCaptureFilter, speeds []edge_service.ForCaptureItsData, cate string) []model.ResponseCaptureSpeed {
+	//区分按月或按日
+	flag := 0
+	if req.QueryType == "month" {
+		flag = 1
+	}
+	data := make(map[string]int)
+	for _, speed := range speeds {
+		time := speed.Time
+		if flag == 1 {
+			time += "-01"
+		}
+		sflag := strconv.Itoa(speed.Sflag)
+		data[time+"--"+sflag] += speed.Total
+	}
+	//时间范围内的月份或天的明细列表
+	var countTimes []string
+	if flag == 1 {
+		countTimes = common.GetTimeMonths(req.StartTime, req.EndTime) //时间范围 月
+	} else {
+		countTimes = common.GetTimeDays(req.StartTime, req.EndTime) //时间范围 天
+	}
+	var list []model.ResponseCaptureSpeed
+	for _, time := range countTimes {
+		if cate == "sectionSpeed" {
+			list = append(list, model.ResponseCaptureSpeed{
+				CountTime: time,
+				V1:        data[time+"--0"],
+				V2:        data[time+"--1"],
+				V3:        data[time+"--2"],
+				V4:        data[time+"--3"],
+				V5:        data[time+"--4"],
+				V6:        data[time+"--5"],
+				V7:        data[time+"--6"],
+			})
+		} else {
+			list = append(list, model.ResponseCaptureSpeed{
+				CountTime: time,
+				V11:       data[time+"--100"],
+				V13:       data[time+"--101"],
+				V14:       data[time+"--102"],
+				V15:       data[time+"--103"],
+				V16:       data[time+"--104"],
+			})
+		}
+	}
+	return list
+}
+
+// SyncOverSpeedRecord 同步超速车牌记录
+func (s captureSpeedService) SyncOverSpeedRecord(start, end string) error {
+	speed := operationDao.CaptureOverSpeed{}
+	maxId, maxTime := speed.GetMaxIdAndUpDateTime()
+	forCaptureIts := edge_service.ForCaptureIts{}
+	record, err := forCaptureIts.SyncOverSpeedRecord(maxId, maxTime, start, end)
+	if err != nil {
+		return err
+	}
+	var list []operationDao.CaptureOverSpeed
+	for _, data := range record {
+		list = append(list, operationDao.CaptureOverSpeed{
+			ID:        data.ID,
+			CaptureSn: data.Code,
+			Time:      common.Time(common.TimeStringToGoTime(data.Time)),
+			Vtype:     data.Vtype,
+			Plate:     data.Plate,
+			Speed:     data.Speed,
+			Sflag:     data.Flag,
+		})
+	}
+	return speed.BatchCreate(list)
+}
+
+func (s captureSpeedService) GetOverSpeedRecord(req model.RequestCaptureOverSpeed) (*model.ResponseCaptureOverSpeedRecord, error) {
+	//查出抓拍单元sn
+	unit := dao.CaptureUnit{
+		ID: req.CaptureId,
+	}
+	if req.Size <= 0 {
+		req.Size = 10
+	}
+	unit.GetDevice()
+	speed := operationDao.CaptureOverSpeed{}
+	records, total, err := speed.Gets(unit.CaptureSn, req)
+	if err != nil {
+		return nil, err
+	}
+	pages := math.Ceil(float64(total) / float64(req.Size))
+	return &model.ResponseCaptureOverSpeedRecord{
+		Records: records,
+		Current: req.Current,
+		Size:    req.Size,
+		Total:   total,
+		Pages:   int(pages),
+	}, nil
+}

+ 7 - 0
router/router.go

@@ -609,12 +609,19 @@ func InitRouter(engine *gin.Engine) {
 	//智慧交通
 	captureGroup := operationGroup.Group("/capture")
 	{
+		//车流汇总
 		captureGroup.GET("affiliation/count-list", operation.Capture.CountList)
 		captureGroup.POST("speed/getSuggestSpeed", operation.Capture.SuggestSpeed)
+		//归属地统计
 		captureGroup.GET("affiliation/list", operation.Capture.AreaList)
 		captureGroup.GET("affiliation/type-list", operation.Capture.AreaTypeList)
+		//车型统计
 		captureGroup.GET("model/list", operation.Capture.VehicleTypeEx)
 		captureGroup.GET("model/type-list", operation.Capture.VehicleTypeList)
+		//车速统计
+		captureGroup.GET("speed/list", operation.Capture.SpeedList)
+		captureGroup.GET("speed/over-speed-record", operation.Capture.OverSpeedRecord)
+		captureGroup.GET("speed/over-speed-record-sync", operation.Capture.OverSpeedRecordSync)
 	}
 
 }

+ 4 - 15
util/common/common.go

@@ -239,24 +239,13 @@ func GetTimeDays(start_time, stop_time string) []string {
 
 // GetTimeMonths 时间区间的所有月份
 func GetTimeMonths(start_time, stop_time string) []string {
-	tm1, _ := time.Parse("2006-01", start_time)
-	tm2, _ := time.Parse("2006-01", stop_time)
-	sInt := tm1.Unix()
-	eInt := tm2.Unix()
-	var args []string
-	for {
-		sInt += 86400
-		st := time.Unix(sInt, 0).Format("20060102")
-		args = append(args, st)
-		if sInt > eInt {
-			break
-		}
-	}
+	star := []rune(start_time)
+	end := []rune(stop_time)
 	var months []string
 	i := 0
 	for {
-		parse, _ := time.Parse("2006-01-02", start_time)
-		endStr, _ := time.Parse("2006-01-02", stop_time)
+		parse, _ := time.Parse("2006-01", string(star[:7]))
+		endStr, _ := time.Parse("2006-01", string(end[:7]))
 		month := parse.AddDate(0, i, 0).Format("2006-01")
 		month = month + "-01"
 		months = append(months, month)