Files
zmkgC/api/video_hat/ws2/ws2.2.go
2025-07-07 20:11:59 +08:00

195 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package ws2
import (
"encoding/json"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gorilla/websocket"
"github.com/tiger1103/gfast/v3/api/constant"
"log"
"time"
)
// 获取实时、状态等心跳包的请求
func SendHeartbeat(conn *websocket.Conn) {
activeDevicesMessage := map[string]string{
"act": "ma_get_active_devices",
}
conn.WriteJSON(activeDevicesMessage)
}
// 定时任务
func SendHeartbeatTime(Conn *websocket.Conn) {
// 使用匿名函数创建一个定时器每隔60秒执行一次
ticker := time.NewTicker(60 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
SendHeartbeat(Conn)
}
}
}
// Response 包含从服务器获取的设备数据
type LocationAndHeart struct {
Cmd string `json:"cmd"`
Status bool `json:"status"`
Message string `json:"msg"`
Data []DeviceData `json:"data"`
MsgCode string `json:"msg_code"`
}
// UserInfo 包含有关用户的信息
type UserInfo struct {
UserID string `json:"user_id" dc:"用户id"`
CAVersion string `json:"ca_ver"`
DeviceID string `json:"device_id" dc:"设备id"`
Mobile string `json:"mobile"`
SIM string `json:"sim"`
CTime string `json:"c_time" dc:"创建时间"`
CALastLoginTime string `json:"ca_last_login_time"`
UserName string `json:"user_name" dc:"用户名字"`
UserImg string `json:"user_img"`
Department string `json:"department"`
Role string `json:"role"`
FID string `json:"f_id"`
CapType string `json:"cap_type"`
B1 string `json:"b1"`
B2 string `json:"b2"`
SOSHeight string `json:"sos_height"`
CUserID string `json:"c_user_id"`
VoicePkg string `json:"voice_pkg"`
AppVersion string `json:"app_version"`
Headset string `json:"headset"`
UploadVideoNum string `json:"upload_video_num"`
NotUploadedVideos string `json:"notuploaded_video_count"`
GID string `json:"g_id"`
SIPID int `json:"sip_id"`
}
// LocationInfo 包含有关位置信息的数据
type LocationInfo struct {
Act string `json:"act"`
BatteryLevel string `json:"bat_l" dc:"电量百分比"`
BatteryVoltage string `json:"bat_v" dc:"电池电压"`
Charging string `json:"charging"`
GPS string `json:"gps"`
GPSLevel string `json:"gps_level"`
InUse string `json:"in_use"`
IsWorn string `json:"is_weared"`
NetStrength string `json:"net_strenth"`
NetType string `json:"net_type"`
NotUploadedVideos string `json:"notuploaded_video_count"`
OnlineType string `json:"online_type"`
PhoneNumber string `json:"phoneNumber"`
RailStatus string `json:"rail_status"`
SIMDataNum string `json:"sim_data_num"`
SIMStatus string `json:"sim_status"`
TCardStatus string `json:"tcard_status"`
TempData string `json:"tempdata"`
UserID string `json:"user_id"`
XPoint string `json:"x_point"`
YPoint string `json:"y_point"`
CTime int64 `json:"ctime"`
CapType string `json:"cap_type"`
}
// DeviceData 包含用户信息和位置信息
type DeviceData struct {
UserInfo UserInfo `json:"user_info"`
LocationInfo LocationInfo `json:"location_info"`
}
// 处理收到的心跳和实时数据信息
func HandleLocation(jsonString string) {
var response LocationAndHeart
// 解析 JSON 字符串到结构体
err := json.Unmarshal([]byte(jsonString), &response)
if err != nil {
log.Fatal("Error decoding JSON to struct:", err)
}
var IsLowBattery int
// 用来跟踪当前活跃的设备编号
activeDevices := make(map[string]bool)
// 获取当前时间,格式化为 YYYY-MM-DD
currentTime := time.Now()
todayDate := currentTime.Format("2006-01-02")
for _, v := range response.Data {
// 标记此设备ID为活跃
activeDevices[v.UserInfo.DeviceID] = true
// 将 Unix 时间戳(秒)转换为 time.Time 类型
createTime := time.Unix(gconv.Int64(v.UserInfo.CTime), 0)
// 判断电量是否低于20%,如果是,则标记为低电量
if gconv.Int(v.LocationInfo.BatteryLevel) <= constant.BatteryLevel {
IsLowBattery = 1
}
// 检查数据库中是否存在该设备
IfExists, _ := g.Model("device_video_hat").Where("dev_num", v.UserInfo.DeviceID).Count()
if IfExists == 0 {
// 如果设备不存在,则插入新设备数据(不包括设备名称)
devHat := g.Map{
"dev_num": v.UserInfo.DeviceID,
"status": v.LocationInfo.InUse,
"uid": v.UserInfo.UserID,
"battery_level": v.LocationInfo.BatteryLevel,
"is_low_battery": IsLowBattery,
"create_time": createTime,
"longitude": v.LocationInfo.XPoint,
"latitude": v.LocationInfo.YPoint,
"sip_id": v.UserInfo.SIPID,
}
g.Model("device_video_hat").Data(devHat).Save()
} else {
// 更新已存在的设备数据
updateData := g.Map{
"status": v.LocationInfo.InUse,
"uid": v.UserInfo.UserID,
"battery_level": v.LocationInfo.BatteryLevel,
"is_low_battery": IsLowBattery,
"create_time": createTime,
"longitude": v.LocationInfo.XPoint,
"latitude": v.LocationInfo.YPoint,
"sip_id": v.UserInfo.SIPID,
}
g.Model("device_video_hat").Data(updateData).Where("dev_num", v.UserInfo.DeviceID).Update()
}
// 检查 device_data_time 表是否已有当天的记录
count, err := g.Model("device_data_time").Where("dev_num = ? AND data_time = ?", v.UserInfo.DeviceID, todayDate).Count()
if err != nil {
log.Println("Error checking device_data_time:", err)
continue
}
if count == 0 {
// 如果没有记录,则插入新数据
g.Model("device_data_time").Data(g.Map{
"dev_num": v.UserInfo.DeviceID,
"data_time": todayDate,
}).Insert()
}
}
// 从数据库中检索所有设备
var allDevices []struct{ DevNum string }
err = g.Model("device_video_hat").Fields("dev_num AS DevNum").Scan(&allDevices)
if err != nil {
log.Fatal("Error retrieving all devices:", err)
}
// 为不活跃的设备设置状态为0
for _, device := range allDevices {
if _, isActive := activeDevices[device.DevNum]; !isActive {
g.Model("device_video_hat").Data(g.Map{"status": 0}).Where("dev_num", device.DevNum).Update()
}
}
}