mirror of
https://github.com/lkmio/gb-cms.git
synced 2025-12-24 11:51:52 +08:00
346 lines
11 KiB
Go
346 lines
11 KiB
Go
package dao
|
||
|
||
import (
|
||
"gb-cms/common"
|
||
"gb-cms/log"
|
||
"gorm.io/gorm"
|
||
"net"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
DefaultCatalogInterval = 3600 // 默认目录刷新间隔,单位秒
|
||
)
|
||
|
||
type DeviceModel struct {
|
||
GBModel
|
||
DeviceID string `json:"device_id" gorm:"index"`
|
||
Name string `json:"name" gorm:"index"`
|
||
RemoteIP string `json:"remote_ip"`
|
||
RemotePort int `json:"remote_port"`
|
||
RemoteRegion string `json:"remote_region"`
|
||
Transport string `json:"transport"` // 信令传输模式 UDP/TCP
|
||
Status common.OnlineStatus `json:"status"` // 在线状态 ON-在线/OFF-离线
|
||
Manufacturer string `json:"manufacturer"`
|
||
UserAgent string `json:"user_agent"`
|
||
Model string `json:"model"`
|
||
Firmware string `json:"firmware"`
|
||
RegisterTime time.Time `json:"register_time"` // 注册时间
|
||
LastHeartbeat time.Time `json:"last_heartbeat"` // 最后心跳时间
|
||
|
||
ChannelsTotal int `json:"total_channels"` // 通道总数
|
||
ChannelsOnline int `json:"online_channels"` // 通道在线数量
|
||
Setup common.SetupType
|
||
|
||
CatalogInterval int // 录像目录刷新间隔,单位秒, 默认3600每小时刷新
|
||
LastRefreshCatalog time.Time `gorm:"type:datetime"` // 最后刷新目录时间
|
||
//ScheduleRecord [7]uint64 // 录像计划,0-6表示周一至周日,一天的时间刻度用一个uint64表示,从高位开始代表0点,每bit半小时,共占用48位, 1表示录像,0表示不录像
|
||
CatalogSubscribe bool `json:"catalog_subscribe"` // 是否开启目录订阅
|
||
AlarmSubscribe bool `json:"alarm_subscribe"` // 是否开启报警订阅
|
||
PositionSubscribe bool `json:"position_subscribe"` // 是否开启位置订阅
|
||
Longitude float64
|
||
Latitude float64
|
||
DropChannelType string
|
||
}
|
||
|
||
func (d *DeviceModel) TableName() string {
|
||
return "lkm_device"
|
||
}
|
||
|
||
func (d *DeviceModel) Online() bool {
|
||
return d.Status == common.ON
|
||
}
|
||
|
||
func (d *DeviceModel) GetID() string {
|
||
return d.DeviceID
|
||
}
|
||
|
||
func (d *DeviceModel) GetSetup() common.SetupType {
|
||
if d.Setup == 0 || d.Setup > common.SetupTypeActive {
|
||
return common.String2SetupType(common.Config.DeviceDefaultMediaTransport)
|
||
}
|
||
return d.Setup
|
||
}
|
||
|
||
type daoDevice struct {
|
||
}
|
||
|
||
func (d *daoDevice) LoadOnlineDevices() (map[string]*DeviceModel, error) {
|
||
//TODO implement me
|
||
panic("implement me")
|
||
}
|
||
|
||
func (d *daoDevice) LoadDevices() (map[string]*DeviceModel, error) {
|
||
var devices []*DeviceModel
|
||
tx := db.Find(&devices)
|
||
if tx.Error != nil {
|
||
return nil, tx.Error
|
||
}
|
||
|
||
deviceMap := make(map[string]*DeviceModel)
|
||
for _, device := range devices {
|
||
deviceMap[device.DeviceID] = device
|
||
}
|
||
|
||
return deviceMap, nil
|
||
}
|
||
|
||
func (d *daoDevice) SaveDevice(device *DeviceModel) error {
|
||
old := DeviceModel{}
|
||
if db.Select("id", "remote_ip", "remote_region").Where("device_id =?", device.DeviceID).Take(&old).Error == nil {
|
||
device.ID = old.ID
|
||
}
|
||
|
||
if common.Config.IP2RegionEnable && (old.RemoteRegion == "" || (old.RemoteIP != "" && old.RemoteIP != device.RemoteIP)) {
|
||
region, err := common.IP2Region(device.RemoteIP)
|
||
if err != nil {
|
||
log.Sugar.Errorf("IP2Region failed. err: %s", err.Error())
|
||
}
|
||
|
||
device.RemoteRegion = region
|
||
}
|
||
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
if device.ID == 0 {
|
||
//return tx.Create(&old).Error
|
||
return tx.Save(device).Error
|
||
} else {
|
||
return tx.Model(device).Select("transport", "remote_ip", "remote_port", "status", "register_time", "last_heartbeat", "remote_region").Updates(*device).Error
|
||
}
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) UpdateDeviceInfo(deviceId string, device *DeviceModel) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
var condition = make(map[string]interface{})
|
||
if device.Manufacturer != "" {
|
||
condition["manufacturer"] = device.Manufacturer
|
||
}
|
||
if device.Model != "" {
|
||
condition["model"] = device.Model
|
||
}
|
||
if device.Firmware != "" {
|
||
condition["firmware"] = device.Firmware
|
||
}
|
||
if device.Name != "" {
|
||
condition["name"] = device.Name
|
||
}
|
||
return tx.Model(&DeviceModel{}).Where("device_id =?", deviceId).Updates(condition).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) UpdateDeviceStatus(deviceId string, status common.OnlineStatus) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Model(&DeviceModel{}).Where("device_id =?", deviceId).Update("status", status).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) RefreshHeartbeat(deviceId string, now time.Time, addr string) error {
|
||
old := DeviceModel{}
|
||
if tx := db.Select("id", "remote_ip", "remote_region").Take(&old, "device_id =?", deviceId); tx.Error != nil {
|
||
return tx.Error
|
||
}
|
||
|
||
host, p, _ := net.SplitHostPort(addr)
|
||
var region = old.RemoteRegion
|
||
if common.Config.IP2RegionEnable && (old.RemoteRegion == "" || (old.RemoteIP != "" && old.RemoteIP != host)) {
|
||
var err error
|
||
region, err = common.IP2Region(host)
|
||
if err != nil {
|
||
log.Sugar.Errorf("IP2Region failed. err: %s", err.Error())
|
||
}
|
||
}
|
||
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
port, _ := strconv.Atoi(p)
|
||
return tx.Model(&DeviceModel{}).Select("last_heartbeat", "status", "remote_ip", "remote_port", "remote_region").Where("device_id =?", deviceId).Updates(&DeviceModel{
|
||
LastHeartbeat: now,
|
||
Status: common.ON,
|
||
RemoteIP: host,
|
||
RemotePort: port,
|
||
RemoteRegion: region,
|
||
}).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) QueryDevice(id string) (*DeviceModel, error) {
|
||
var device DeviceModel
|
||
tx := db.Where("device_id =?", id).Take(&device)
|
||
if tx.Error != nil {
|
||
return nil, tx.Error
|
||
}
|
||
|
||
return &device, nil
|
||
}
|
||
|
||
// QueryDeviceByAddr 根据地址查询设备
|
||
func (d *daoDevice) QueryDeviceByAddr(addr string) (*DeviceModel, error) {
|
||
host, p, _ := net.SplitHostPort(addr)
|
||
port, _ := strconv.Atoi(p)
|
||
var device DeviceModel
|
||
tx := db.Where("remote_ip = ? and remote_port = ?", host, port).Take(&device)
|
||
if tx.Error != nil {
|
||
return nil, tx.Error
|
||
}
|
||
|
||
return &device, nil
|
||
}
|
||
|
||
func (d *daoDevice) QueryDevices(page int, size int, status string, keyword string, order string) ([]*DeviceModel, int, error) {
|
||
var cond = make(map[string]interface{})
|
||
if status != "" {
|
||
cond["status"] = status
|
||
}
|
||
|
||
devicesTx := db.Where(cond).Limit(size).Offset((page - 1) * size)
|
||
if keyword != "" {
|
||
devicesTx.Where("device_id like ? or name like ?", "%"+keyword+"%", "%"+keyword+"%")
|
||
}
|
||
|
||
var devices []*DeviceModel
|
||
if tx := devicesTx.Order("device_id " + order).Find(&devices); tx.Error != nil {
|
||
return nil, 0, tx.Error
|
||
}
|
||
|
||
countTx := db.Where(cond).Model(&DeviceModel{})
|
||
if keyword != "" {
|
||
countTx.Where("device_id like ? or name like ?", "%"+keyword+"%", "%"+keyword+"%")
|
||
}
|
||
|
||
var total int64
|
||
if tx := countTx.Count(&total); tx.Error != nil {
|
||
return nil, 0, tx.Error
|
||
}
|
||
|
||
for _, device := range devices {
|
||
count, _ := Channel.QueryChanelCount(device.DeviceID, true)
|
||
online, _ := Channel.QueryOnlineChanelCount(device.DeviceID, true)
|
||
device.ChannelsOnline = online
|
||
device.ChannelsTotal = count
|
||
}
|
||
|
||
return devices, int(total), nil
|
||
}
|
||
|
||
func (d *daoDevice) UpdateOfflineDevices(deviceIds []string) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Model(&DeviceModel{}).Where("device_id in ?", deviceIds).Update("status", common.OFF).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) ExistDevice(deviceId string) bool {
|
||
var device DeviceModel
|
||
tx := db.Select("id").Where("device_id =?", deviceId).Take(&device)
|
||
if tx.Error != nil {
|
||
return false
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
func (d *daoDevice) UpdateMediaTransport(deviceId string, setupType common.SetupType) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Model(&DeviceModel{}).Where("device_id =?", deviceId).Update("setup", setupType).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) DeleteDevice(deviceId string) error {
|
||
err := DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Where("device_id =?", deviceId).Unscoped().Delete(&DeviceModel{}).Error
|
||
})
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return Channel.DeleteChannels(deviceId)
|
||
}
|
||
|
||
func (d *daoDevice) DeleteDevicesByIP(ip string) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Where("remote_ip =?", ip).Unscoped().Delete(&DeviceModel{}).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) DeleteDevicesByUA(ua string) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Where("user_agent =?", ua).Unscoped().Delete(&DeviceModel{}).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) Count() (int, error) {
|
||
var count int64
|
||
db.Model(&DeviceModel{}).Count(&count)
|
||
return int(count), nil
|
||
}
|
||
|
||
func (d *daoDevice) UpdateRefreshCatalogTime(deviceId string, now time.Time) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Model(&DeviceModel{}).Where("device_id =?", deviceId).Update("last_refresh_catalog", now.Format("2006-01-02 15:04:05")).Error
|
||
})
|
||
}
|
||
|
||
// QueryRefreshCatalogExpiredDevices 查询刷新目录到期的设备列表
|
||
func (d *daoDevice) QueryRefreshCatalogExpiredDevices(now time.Time) ([]*DeviceModel, error) {
|
||
var devices []*DeviceModel
|
||
tx := db.Where(
|
||
"(datetime(last_refresh_catalog, '+'||IFNULL(catalog_interval, ?)||' seconds') < ? OR last_refresh_catalog IS NULL) AND status = ?",
|
||
DefaultCatalogInterval,
|
||
now,
|
||
common.ON,
|
||
).Find(&devices)
|
||
if tx.Error != nil {
|
||
return nil, tx.Error
|
||
}
|
||
|
||
return devices, nil
|
||
}
|
||
|
||
// QueryNeedRefreshCatalog 查询设备是否需要刷新目录
|
||
func (d *daoDevice) QueryNeedRefreshCatalog(deviceId string, now time.Time) bool {
|
||
var devices int64
|
||
_ = db.Model(&DeviceModel{}).Where(
|
||
"device_id = ? AND (datetime(last_refresh_catalog, '+'||IFNULL(catalog_interval, ?)||' seconds') < ? OR last_refresh_catalog IS NULL)",
|
||
deviceId,
|
||
DefaultCatalogInterval,
|
||
now,
|
||
).Count(&devices)
|
||
|
||
return devices > 0
|
||
}
|
||
|
||
func (d *daoDevice) UpdateCatalogInterval(id string, interval int) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Model(&DeviceModel{}).Where("device_id =?", id).Update("catalog_interval", interval).Error
|
||
})
|
||
}
|
||
|
||
func (d *daoDevice) UpdateDevice(deviceId string, conditions map[string]interface{}) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
return tx.Model(&DeviceModel{}).Where("device_id =?", deviceId).Updates(conditions).Error
|
||
})
|
||
}
|
||
|
||
// QueryDeviceName 查询设备名
|
||
func (d *daoDevice) QueryDeviceName(deviceId string) (string, error) {
|
||
var device DeviceModel
|
||
tx := db.Select("name").Where("device_id =?", deviceId).Take(&device)
|
||
if tx.Error != nil {
|
||
return "", tx.Error
|
||
}
|
||
|
||
return device.Name, nil
|
||
}
|
||
|
||
func (d *daoDevice) SetDropChannelType(deviceId string, dropChannelTypes []string) error {
|
||
return DBTransaction(func(tx *gorm.DB) error {
|
||
err := tx.Model(&DeviceModel{}).Where("device_id =?", deviceId).Update("drop_channel_type", strings.Join(dropChannelTypes, ",")).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return Channel.DropChannel(deviceId, dropChannelTypes, tx)
|
||
})
|
||
}
|