修复图表时间和查询区间不匹配问题
This commit is contained in:
135
backend/internal/device/device.go
Normal file
135
backend/internal/device/device.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Device 设备信息
|
||||
type Device struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IP string `json:"ip"`
|
||||
Token string `json:"token"` // 设备认证令牌
|
||||
Status string `json:"status"` // active, inactive, offline
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Storage 设备存储接口
|
||||
type Storage interface {
|
||||
// GetDevices 获取所有设备
|
||||
GetDevices() []Device
|
||||
// GetDevice 获取指定设备
|
||||
GetDevice(id string) (Device, bool)
|
||||
// GetDeviceByToken 通过令牌获取设备
|
||||
GetDeviceByToken(token string) (Device, bool)
|
||||
// AddDevice 添加设备
|
||||
AddDevice(device Device) error
|
||||
// UpdateDevice 更新设备
|
||||
UpdateDevice(device Device) error
|
||||
// DeleteDevice 删除设备
|
||||
DeleteDevice(id string) error
|
||||
// UpdateDeviceStatus 更新设备状态
|
||||
UpdateDeviceStatus(id string, status string) error
|
||||
}
|
||||
|
||||
// MemoryStorage 内存设备存储
|
||||
type MemoryStorage struct {
|
||||
devices map[string]Device
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewMemoryStorage 创建内存设备存储实例
|
||||
func NewMemoryStorage() *MemoryStorage {
|
||||
return &MemoryStorage{
|
||||
devices: make(map[string]Device),
|
||||
}
|
||||
}
|
||||
|
||||
// GetDevices 获取所有设备
|
||||
func (s *MemoryStorage) GetDevices() []Device {
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
devices := make([]Device, 0, len(s.devices))
|
||||
for _, device := range s.devices {
|
||||
devices = append(devices, device)
|
||||
}
|
||||
|
||||
return devices
|
||||
}
|
||||
|
||||
// GetDevice 获取指定设备
|
||||
func (s *MemoryStorage) GetDevice(id string) (Device, bool) {
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
device, ok := s.devices[id]
|
||||
return device, ok
|
||||
}
|
||||
|
||||
// AddDevice 添加设备
|
||||
func (s *MemoryStorage) AddDevice(device Device) error {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
// 检查设备是否已存在
|
||||
if _, ok := s.devices[device.ID]; ok {
|
||||
return nil // 设备已存在,不重复添加
|
||||
}
|
||||
|
||||
s.devices[device.ID] = device
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateDevice 更新设备
|
||||
func (s *MemoryStorage) UpdateDevice(device Device) error {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
// 检查设备是否存在
|
||||
if _, ok := s.devices[device.ID]; !ok {
|
||||
return nil // 设备不存在,不更新
|
||||
}
|
||||
|
||||
s.devices[device.ID] = device
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteDevice 删除设备
|
||||
func (s *MemoryStorage) DeleteDevice(id string) error {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
delete(s.devices, id)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDeviceByToken 通过令牌获取设备
|
||||
func (s *MemoryStorage) GetDeviceByToken(token string) (Device, bool) {
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
for _, device := range s.devices {
|
||||
if device.Token == token {
|
||||
return device, true
|
||||
}
|
||||
}
|
||||
|
||||
return Device{}, false
|
||||
}
|
||||
|
||||
// UpdateDeviceStatus 更新设备状态
|
||||
func (s *MemoryStorage) UpdateDeviceStatus(id string, status string) error {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
device, ok := s.devices[id]
|
||||
if !ok {
|
||||
return nil // 设备不存在,不更新
|
||||
}
|
||||
|
||||
device.Status = status
|
||||
s.devices[id] = device
|
||||
return nil
|
||||
}
|
||||
116
backend/internal/device/mysql_storage.go
Normal file
116
backend/internal/device/mysql_storage.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MySQLStorage MySQL设备存储
|
||||
|
||||
type MySQLStorage struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NewMySQLStorage 创建MySQL设备存储实例
|
||||
func NewMySQLStorage(db *sql.DB) (*MySQLStorage, error) {
|
||||
// 创建表
|
||||
if err := createDeviceTable(db); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &MySQLStorage{db: db}, nil
|
||||
}
|
||||
|
||||
// createDeviceTable 创建设备表
|
||||
func createDeviceTable(db *sql.DB) error {
|
||||
query := `
|
||||
CREATE TABLE IF NOT EXISTS devices (
|
||||
id VARCHAR(64) PRIMARY KEY,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
ip VARCHAR(64),
|
||||
token VARCHAR(64) NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'inactive',
|
||||
created_at BIGINT NOT NULL,
|
||||
updated_at BIGINT NOT NULL,
|
||||
UNIQUE KEY uk_token (token)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`
|
||||
_, err := db.Exec(query)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetDevices 获取所有设备
|
||||
func (s *MySQLStorage) GetDevices() []Device {
|
||||
query := "SELECT id, name, ip, token, status, created_at, updated_at FROM devices"
|
||||
rows, err := s.db.Query(query)
|
||||
if err != nil {
|
||||
return []Device{}
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
devices := make([]Device, 0)
|
||||
for rows.Next() {
|
||||
var device Device
|
||||
if err := rows.Scan(&device.ID, &device.Name, &device.IP, &device.Token, &device.Status, &device.CreatedAt, &device.UpdatedAt); err != nil {
|
||||
continue
|
||||
}
|
||||
devices = append(devices, device)
|
||||
}
|
||||
|
||||
return devices
|
||||
}
|
||||
|
||||
// GetDevice 获取指定设备
|
||||
func (s *MySQLStorage) GetDevice(id string) (Device, bool) {
|
||||
query := "SELECT id, name, ip, token, status, created_at, updated_at FROM devices WHERE id = ?"
|
||||
row := s.db.QueryRow(query, id)
|
||||
|
||||
var device Device
|
||||
err := row.Scan(&device.ID, &device.Name, &device.IP, &device.Token, &device.Status, &device.CreatedAt, &device.UpdatedAt)
|
||||
if err != nil {
|
||||
return Device{}, false
|
||||
}
|
||||
|
||||
return device, true
|
||||
}
|
||||
|
||||
// GetDeviceByToken 通过令牌获取设备
|
||||
func (s *MySQLStorage) GetDeviceByToken(token string) (Device, bool) {
|
||||
query := "SELECT id, name, ip, token, status, created_at, updated_at FROM devices WHERE token = ?"
|
||||
row := s.db.QueryRow(query, token)
|
||||
|
||||
var device Device
|
||||
err := row.Scan(&device.ID, &device.Name, &device.IP, &device.Token, &device.Status, &device.CreatedAt, &device.UpdatedAt)
|
||||
if err != nil {
|
||||
return Device{}, false
|
||||
}
|
||||
|
||||
return device, true
|
||||
}
|
||||
|
||||
// AddDevice 添加设备
|
||||
func (s *MySQLStorage) AddDevice(device Device) error {
|
||||
query := "INSERT INTO devices (id, name, ip, token, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE name = VALUES(name), ip = VALUES(ip), updated_at = VALUES(updated_at)"
|
||||
_, err := s.db.Exec(query, device.ID, device.Name, device.IP, device.Token, device.Status, device.CreatedAt, device.UpdatedAt)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateDevice 更新设备
|
||||
func (s *MySQLStorage) UpdateDevice(device Device) error {
|
||||
query := "UPDATE devices SET name = ?, ip = ?, status = ?, updated_at = ? WHERE id = ?"
|
||||
_, err := s.db.Exec(query, device.Name, device.IP, device.Status, device.UpdatedAt, device.ID)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteDevice 删除设备
|
||||
func (s *MySQLStorage) DeleteDevice(id string) error {
|
||||
query := "DELETE FROM devices WHERE id = ?"
|
||||
_, err := s.db.Exec(query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateDeviceStatus 更新设备状态
|
||||
func (s *MySQLStorage) UpdateDeviceStatus(id string, status string) error {
|
||||
query := "UPDATE devices SET status = ?, updated_at = ? WHERE id = ?"
|
||||
_, err := s.db.Exec(query, status, time.Now().Unix(), id)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user