qixiaoning
2025-08-21 e38654fe9eff4562da4f18f8f018aed7879d493c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package model
 
import (
    "fmt"
    "gorm.io/gorm"
    "strconv"
    "strings"
    "time"
)
 
type Device struct {
    gorm.Model
    Type        string  `json:"type"`      // 设备类型
    Vendor      string  `json:"vendor"`    // 厂商
    SN          string  `json:"device_sn"` // 编码
    Lng         float64 `json:"lng"`
    Lat         float64 `json:"lat"`
    Battery     float64 `json:"battery"`
    High        float64 `json:"high"`
    GpsType     string  `json:"gps_type"`
    LocateState string  `json:"locate_state"`
    Mac         string  `json:"mac"`
    Ip          string  `json:"ip"`
    IsOutBound  int     `json:"isOutBound" gorm:"default:1"` // 0 没出界 1 有出界
    BoundId     uint    `json:"bound_id"`                    // 所处的电子围栏
}
 
func (obj *Device) FindAll() []Device {
    list := []Device{}
    err := DB.Table("devices").Find(&list).Error
    if err != nil {
        return nil
    }
 
    return list
}
 
func (obj *Device) FindByBoundID(bound_id uint) ([]Device, int64) {
    list := []Device{}
    var total int64
    err := DB.Table("devices").Where("bound_id = ?", bound_id).Find(&list).Error
    err = DB.Table("devices").Where("bound_id = ?", bound_id).Count(&total).Error
    if err != nil {
        return nil, 0
    }
    return list, total
}
 
func (obj *Device) Update() (err error) {
    if isExistDevice(obj.SN) {
        var err error
 
        // 坐标为0时不更新位置
        dev := Device{Battery: obj.Battery}
        dev.UpdatedAt = time.Now()
 
        if obj.Lat == 0 {
            err = DB.Table("devices").Where("sn = ?", obj.SN).Select("battery").Updates(dev).Error
        } else {
            dev.High = obj.High
            dev.Lat = obj.Lat
            dev.Lng = obj.Lng
 
            err = DB.Table("devices").Where("sn = ?", obj.SN).Select("lng", "lat", "battery", "high").Updates(dev).Error
        }
 
        if err != nil {
            fmt.Println("修改数据出错")
            return err
        }
    } else {
        err := DB.Table("devices").Create(&obj).Error
        if err != nil {
            return err
        }
        // fmt.Println("新增安全帽数据")
    }
 
    hasZone, zoneId := CheckInBound(obj)
    if hasZone {
        if zoneId > 0 {
            DB.Table("devices").Where("sn=?", obj.SN).Update(Device{BoundId: zoneId, IsOutBound: 0})
        } else {
            DB.Table("devices").Where("sn=?", obj.SN).Update(Device{IsOutBound: 1})
        }
    }
    return nil
}
 
func isExistDevice(sn string) bool {
    var count int64
    DB.Table("devices").Where("sn = ?", sn).Count(&count)
    return count > 0
}
 
func CheckInBound(dv *Device) (bool, uint) {
    obj := DrawZone{}
    zones := obj.FindAll()
    if zones == nil {
        return false, 0
    }
    pointToCheck := Point{Lng: dv.Lng, Lat: dv.Lat}
    for i := 0; i < len(zones); i++ {
        zone := zones[i]
        arr := strings.Split(zone.Dots, "&")
        pointArr := []Point{}
        for i := 0; i < len(arr); i++ {
            str := arr[i]
            subArr := strings.Split(str, ",")
            f1, _ := strconv.ParseFloat(subArr[0], 64)
            f2, _ := strconv.ParseFloat(subArr[1], 64)
            newPoint := Point{Lng: f1, Lat: f2}
            pointArr = append(pointArr, newPoint)
        }
        if IsPointInPolygon(pointToCheck, pointArr) {
            return true, zone.ID
        }
    }
    return true, 0
}