mirror of
https://github.com/lkmio/gb-cms.git
synced 2025-12-24 11:51:52 +08:00
feat: 支持设备上下线统计
This commit is contained in:
@@ -302,6 +302,8 @@ func StartApiServer(addr string) {
|
||||
apiServer.router.HandleFunc("/api/v1/log/list", withVerify(common.WithQueryStringParams(apiServer.OnLogList, QueryDeviceChannel{}))) // 操作日志
|
||||
apiServer.router.HandleFunc("/api/v1/log/clear", withVerify(common.WithQueryStringParams(apiServer.OnLogClear, Empty{}))) // 操作日志
|
||||
|
||||
apiServer.router.HandleFunc("/api/v1/device/statuslog", withVerify(common.WithQueryStringParams(apiServer.OnStatusLogList, QueryDeviceChannel{}))) // 设备上下线统计
|
||||
|
||||
// 暂未开发
|
||||
apiServer.router.HandleFunc("/api/v1/sms/list", withVerify(func(w http.ResponseWriter, req *http.Request) {})) // 流媒体服务器列表
|
||||
apiServer.router.HandleFunc("/api/v1/cloudrecord/querychannels", withVerify(func(w http.ResponseWriter, req *http.Request) {})) // 云端录像
|
||||
@@ -310,6 +312,9 @@ func StartApiServer(addr string) {
|
||||
apiServer.router.HandleFunc("/api/v1/setbaseconfig", withVerify(common.WithFormDataParams(apiServer.OnSetBaseConfig, Empty{})))
|
||||
apiServer.router.HandleFunc("/api/v1/gm/cert/list", withVerify(func(w http.ResponseWriter, req *http.Request) {}))
|
||||
apiServer.router.HandleFunc("/api/v1/getrequestkey", withVerify(func(w http.ResponseWriter, req *http.Request) {}))
|
||||
apiServer.router.HandleFunc("/api/v1/getrequestkey", withVerify(func(w http.ResponseWriter, req *http.Request) {}))
|
||||
apiServer.router.HandleFunc("/api/v1/device/positionlog", withVerify(func(w http.ResponseWriter, req *http.Request) {}))
|
||||
apiServer.router.HandleFunc("/api/v1/device/streamlog", withVerify(func(w http.ResponseWriter, req *http.Request) {}))
|
||||
|
||||
apiServer.registerStatisticsHandler("开始录制", "/api/v1/record/start", withVerify(apiServer.OnRecordStart)) // 开启录制
|
||||
apiServer.registerStatisticsHandler("结束录制", "/api/v1/record/stop", withVerify(apiServer.OnRecordStop)) // 关闭录制
|
||||
|
||||
@@ -444,3 +444,26 @@ func (api *ApiServer) OnPTZControl(v *QueryRecordParams, _ http.ResponseWriter,
|
||||
|
||||
return "OK", nil
|
||||
}
|
||||
|
||||
func (api *ApiServer) OnStatusLogList(q *QueryDeviceChannel, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
||||
if q.Limit < 1 {
|
||||
q.Limit = 10
|
||||
}
|
||||
|
||||
v := struct {
|
||||
LogCount int
|
||||
LogList interface{}
|
||||
LogReserveDays int
|
||||
}{
|
||||
LogReserveDays: common.Config.LogReserveDays,
|
||||
}
|
||||
|
||||
logList, count, err := dao.StatusLog.QueryBySerial(q.DeviceID, q.Limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v.LogCount = count
|
||||
v.LogList = logList
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
// GBModel 解决`Model`变量名与gorm.Model冲突
|
||||
type GBModel struct {
|
||||
ID uint `gorm:"primarykey" xml:"-"`
|
||||
CreatedAt time.Time `json:"created_at" xml:"-"`
|
||||
CreatedAt time.Time `json:"-" xml:"-"`
|
||||
UpdatedAt time.Time `json:"-" xml:"-"`
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,6 @@ func (l *daoLog) Clear() error {
|
||||
|
||||
func (l *daoLog) DeleteExpired(expireTime time.Time) error {
|
||||
return DBTransaction(func(tx *gorm.DB) error {
|
||||
tx.Delete(&LogModel{}, "created_at < ?", expireTime.Format("2006-01-02 15:04:05"))
|
||||
return nil
|
||||
return tx.Where("created_at < ?", expireTime).Delete(&LogModel{}).Unscoped().Error
|
||||
})
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ var (
|
||||
Position = &daoPosition{}
|
||||
Alarm = &daoAlarm{}
|
||||
Log = &daoLog{}
|
||||
StatusLog = &daoStatusLog{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -90,6 +91,8 @@ func init() {
|
||||
panic(err)
|
||||
} else if err = db.AutoMigrate(&LogModel{}); err != nil {
|
||||
panic(err)
|
||||
} else if err = db.AutoMigrate(&StatusLogModel{}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
StartSaveTask()
|
||||
|
||||
54
dao/status_log.go
Normal file
54
dao/status_log.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package dao
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StatusLogModel 设备上下线记录
|
||||
type StatusLogModel struct {
|
||||
GBModel
|
||||
Serial string `json:"Serial"`
|
||||
Code string `json:"Code"`
|
||||
Status string `json:"Status"`
|
||||
Description string `json:"Description"`
|
||||
CreatedAt_ string `json:"CreatedAt" gorm:"-"`
|
||||
}
|
||||
|
||||
func (s *StatusLogModel) TableName() string {
|
||||
return "lkm_status_log"
|
||||
}
|
||||
|
||||
type daoStatusLog struct {
|
||||
}
|
||||
|
||||
func (s *daoStatusLog) Save(model *StatusLogModel) error {
|
||||
return db.Create(model).Error
|
||||
}
|
||||
|
||||
func (s *daoStatusLog) QueryBySerial(serial string, limit int) ([]*StatusLogModel, int, error) {
|
||||
// 统计总数
|
||||
var count int64
|
||||
err := db.Model(&StatusLogModel{}).Where("serial = ?", serial).Select("id").Count(&count).Error
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
} else if count < 1 {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
var logs []*StatusLogModel
|
||||
err = db.Where("serial = ?", serial).Order("created_at desc").Limit(limit).Find(&logs).Error
|
||||
|
||||
// 格式化时间
|
||||
for _, log := range logs {
|
||||
log.CreatedAt_ = log.CreatedAt.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
return logs, int(count), err
|
||||
}
|
||||
|
||||
func (s *daoStatusLog) DeleteExpired(time time.Time) error {
|
||||
return DBTransaction(func(tx *gorm.DB) error {
|
||||
return tx.Where("created_at < ?", time).Delete(&StatusLogModel{}).Unscoped().Error
|
||||
})
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"gb-cms/common"
|
||||
"gb-cms/dao"
|
||||
"gb-cms/log"
|
||||
"sync"
|
||||
@@ -91,15 +92,27 @@ func NewOnlineDeviceManager() *onlineDeviceManager {
|
||||
// OnExpires Redis设备ID到期回调
|
||||
func OnExpires(db int, id string) {
|
||||
log.Sugar.Infof("设备心跳过期 device: %s", id)
|
||||
CloseDevice(id)
|
||||
CloseDevice(id, "设备超时离线 OFF")
|
||||
}
|
||||
|
||||
func CloseDevice(id string) {
|
||||
func CloseDevice(id string, reason string) {
|
||||
device, _ := dao.Device.QueryDevice(id)
|
||||
if device == nil {
|
||||
log.Sugar.Errorf("设备不存在 device: %s", id)
|
||||
return
|
||||
}
|
||||
|
||||
// 保存设备状态日志
|
||||
err := dao.StatusLog.Save(&dao.StatusLogModel{
|
||||
Serial: id,
|
||||
Code: "*",
|
||||
Status: common.OFF.String(),
|
||||
Description: reason,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("保存设备状态日志失败 device: %s err: %s", id, err.Error())
|
||||
}
|
||||
|
||||
(&Device{DeviceModel: device}).Close()
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ func updateDevicesStatus() {
|
||||
}
|
||||
|
||||
for _, device := range offlineDevices {
|
||||
CloseDevice(device)
|
||||
CloseDevice(device, "服务重启时离线 OFF")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,6 +246,12 @@ func Start() {
|
||||
log.Sugar.Errorf("删除过期的操作记录失败 err: %s", err.Error())
|
||||
}
|
||||
|
||||
// 删除过期的设备上下线记录
|
||||
err = dao.StatusLog.DeleteExpired(logExpireTime)
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("删除过期的设备上下线记录失败 err: %s", err.Error())
|
||||
}
|
||||
|
||||
// 删除过期的报警记录
|
||||
err = dao.Alarm.DeleteExpired(alarmExpireTime)
|
||||
if err != nil {
|
||||
|
||||
@@ -35,7 +35,7 @@ type EventHandler struct {
|
||||
}
|
||||
|
||||
func (e *EventHandler) OnUnregister(id string) {
|
||||
CloseDevice(id)
|
||||
CloseDevice(id, "设备注销 OFF")
|
||||
}
|
||||
|
||||
// OnRegister 处理设备注册请求
|
||||
@@ -72,8 +72,24 @@ func (e *EventHandler) OnRegister(id, transport, addr, userAgent string) (int, G
|
||||
|
||||
// 级联通知通道上线
|
||||
device := &Device{model}
|
||||
if count > 0 && !alreadyOnline {
|
||||
go device.PushCatalog()
|
||||
|
||||
// 新注册
|
||||
if !alreadyOnline {
|
||||
err := dao.StatusLog.Save(&dao.StatusLogModel{
|
||||
Serial: id,
|
||||
Code: "*",
|
||||
Status: common.ON.String(),
|
||||
Description: "设备注册上线 ON",
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("保存设备状态日志失败 device: %s err: %s", id, err.Error())
|
||||
}
|
||||
|
||||
// 通道不为空, 通知上级
|
||||
if count > 0 {
|
||||
go device.PushCatalog()
|
||||
}
|
||||
}
|
||||
|
||||
return 3600, device, count < 1 || dao.Device.QueryNeedRefreshCatalog(id, now)
|
||||
|
||||
Reference in New Issue
Block a user