Files
app-api/internal/repository/device.go
T
yangy f3e3e82f52 feat(device): 增加设备信息持久化和OTA升级功能
- 新增设备持久化定时任务,每5分钟将Redis中采集的设备信息同步数据库
- 新增UserDevice和UserActive模型及相应数据库表和操作接口
- 设备信息上报中获取客户端公网IP,替代原X-Forwarded-For头部
- 新建OTA功能模块,实现OTA固件升级信息查询接口
- 支持OTA黑名单过滤与定向升级设备判断
- 设计OTA相关数据库结构:ota、black_list、ota_target_device表
- 缓存预热新增按品牌分组预热型号缓存
- 依赖注入新增OTA Repository及Handler路由配置
- 实现客户端公网IP提取逻辑,支持多种代理头部优先级识别
2026-05-28 18:26:20 +08:00

88 lines
2.6 KiB
Go

package repository
import (
"context"
"database/sql"
"fmt"
"github.com/luxsin/app-api/internal/model"
)
type DeviceRepository struct {
db *sql.DB
}
func NewDeviceRepository(db *sql.DB) *DeviceRepository {
return &DeviceRepository{db: db}
}
func (r *DeviceRepository) FindDeviceByMac(ctx context.Context, macAddr string) (*model.UserDevice, error) {
const query = `SELECT id, mac_addr, model, add_time, ver FROM user_device WHERE mac_addr = ?`
var d model.UserDevice
var ver sql.NullString
err := r.db.QueryRowContext(ctx, query, macAddr).Scan(&d.ID, &d.MacAddr, &d.Model, &d.AddTime, &ver)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("query user_device: %w", err)
}
if ver.Valid {
d.Ver = &ver.String
}
return &d, nil
}
func (r *DeviceRepository) InsertDevice(ctx context.Context, d model.UserDevice) error {
const query = `INSERT INTO user_device (mac_addr, model, ver) VALUES (?, ?, ?)`
_, err := r.db.ExecContext(ctx, query, d.MacAddr, d.Model, d.Ver)
if err != nil {
return fmt.Errorf("insert user_device: %w", err)
}
return nil
}
func (r *DeviceRepository) UpdateDeviceVer(ctx context.Context, id int, ver *string) error {
const query = `UPDATE user_device SET ver = ? WHERE id = ?`
_, err := r.db.ExecContext(ctx, query, ver, id)
if err != nil {
return fmt.Errorf("update user_device: %w", err)
}
return nil
}
func (r *DeviceRepository) FindActiveByMacAndDate(ctx context.Context, macAddr, activeDate string) (*model.UserActive, error) {
const query = `SELECT id, mac_addr, model, active_date, ip_addr, create_at FROM user_active WHERE mac_addr = ? AND active_date = ?`
var a model.UserActive
err := r.db.QueryRowContext(ctx, query, macAddr, activeDate).Scan(&a.ID, &a.MacAddr, &a.Model, &a.ActiveDate, &a.IpAddr, &a.CreateAt)
if err == sql.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("query user_active: %w", err)
}
return &a, nil
}
func (r *DeviceRepository) InsertActive(ctx context.Context, a model.UserActive) error {
const query = `INSERT INTO user_active (mac_addr, model, active_date, ip_addr) VALUES (?, ?, ?, ?)`
_, err := r.db.ExecContext(ctx, query, a.MacAddr, a.Model, a.ActiveDate, a.IpAddr)
if err != nil {
return fmt.Errorf("insert user_active: %w", err)
}
return nil
}
func (r *DeviceRepository) UpdateActiveIp(ctx context.Context, id int, ipAddr string) error {
const query = `UPDATE user_active SET ip_addr = ? WHERE id = ?`
_, err := r.db.ExecContext(ctx, query, ipAddr, id)
if err != nil {
return fmt.Errorf("update user_active: %w", err)
}
return nil
}