722 lines
17 KiB
Go
722 lines
17 KiB
Go
|
package service
|
|||
|
|
|||
|
import (
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
|
|||
|
"licserver/internal/model"
|
|||
|
|
|||
|
"time"
|
|||
|
|
|||
|
"gorm.io/gorm"
|
|||
|
)
|
|||
|
|
|||
|
type DeviceService struct {
|
|||
|
db *gorm.DB
|
|||
|
|
|||
|
licenseService *LicenseService
|
|||
|
}
|
|||
|
|
|||
|
func NewDeviceService(db *gorm.DB, licenseService *LicenseService) *DeviceService {
|
|||
|
|
|||
|
return &DeviceService{
|
|||
|
|
|||
|
db: db,
|
|||
|
|
|||
|
licenseService: licenseService,
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
type DeviceRegisterInput struct {
|
|||
|
UID string `json:"uid" binding:"required"`
|
|||
|
DeviceModel string `json:"device_model" binding:"required"`
|
|||
|
LicenseCode string `json:"license_code"`
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) RegisterDevice(input *DeviceRegisterInput, ip string) error {
|
|||
|
// 检查设备型号是否存在且处于启用状态
|
|||
|
var deviceModel model.DeviceModel
|
|||
|
if err := s.db.Where("model_name = ? AND status = ?", input.DeviceModel, "active").First(&deviceModel).Error; err != nil {
|
|||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|||
|
return errors.New("设备型号不存在或已禁用")
|
|||
|
}
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
// 检查设备是否已注册
|
|||
|
var count int64
|
|||
|
s.db.Model(&model.Device{}).Where("uid = ?", input.UID).Count(&count)
|
|||
|
if count > 0 {
|
|||
|
return errors.New("设备已注册")
|
|||
|
}
|
|||
|
|
|||
|
// 创建设备记录
|
|||
|
device := &model.Device{
|
|||
|
UID: input.UID,
|
|||
|
DeviceType: deviceModel.DeviceType,
|
|||
|
DeviceModel: input.DeviceModel,
|
|||
|
Company: deviceModel.Company,
|
|||
|
RegisterTime: time.Now(),
|
|||
|
Status: "inactive",
|
|||
|
LastActiveAt: time.Now(),
|
|||
|
StartCount: 0,
|
|||
|
}
|
|||
|
|
|||
|
// 如果提供了授权码,进行授权绑定
|
|||
|
if input.LicenseCode != "" {
|
|||
|
license, err := s.licenseService.GetLicenseByCode(input.LicenseCode)
|
|||
|
if err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
if license.Status != "unused" {
|
|||
|
return errors.New("授权码已被使用")
|
|||
|
}
|
|||
|
|
|||
|
device.Status = "active"
|
|||
|
device.LicenseCode = license.Code
|
|||
|
device.LicenseType = license.LicenseType
|
|||
|
device.MaxUses = license.MaxUses
|
|||
|
device.Duration = license.Duration
|
|||
|
|
|||
|
if license.LicenseType == "time" {
|
|||
|
device.ExpireTime = time.Now().Add(time.Duration(license.Duration) * time.Minute)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Transaction(func(tx *gorm.DB) error {
|
|||
|
// 创建设备记录
|
|||
|
if err := tx.Create(device).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
// 如果有授权码,更新授权码状态
|
|||
|
if device.LicenseCode != "" {
|
|||
|
if err := tx.Model(&model.LicenseCode{}).Where("code = ?", device.LicenseCode).
|
|||
|
Updates(map[string]interface{}{
|
|||
|
"status": "used",
|
|||
|
"used_by": input.UID,
|
|||
|
"used_at": time.Now(),
|
|||
|
}).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 记录设备日志
|
|||
|
logMsg := "设备注册成功"
|
|||
|
if device.LicenseCode != "" {
|
|||
|
logMsg += fmt.Sprintf(",使用授权码: %s", device.LicenseCode)
|
|||
|
}
|
|||
|
log := model.DeviceLog{
|
|||
|
DeviceUID: input.UID,
|
|||
|
Action: "register",
|
|||
|
Message: logMsg,
|
|||
|
Status: "success",
|
|||
|
}
|
|||
|
if err := tx.Create(&log).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) ValidateDevice(uid string) error {
|
|||
|
var device model.Device
|
|||
|
if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
|
|||
|
return errors.New("设备未注册")
|
|||
|
}
|
|||
|
|
|||
|
// 更新最后活跃时间
|
|||
|
device.LastActiveAt = time.Now()
|
|||
|
|
|||
|
// 如果设备已激活,检查授权状态
|
|||
|
if device.Status == "active" {
|
|||
|
if device.LicenseCode != "" {
|
|||
|
if err := s.licenseService.CheckLicenseValidity(device.LicenseCode); err != nil {
|
|||
|
device.Status = "expired"
|
|||
|
s.db.Save(&device)
|
|||
|
return errors.New("设备授权已过期")
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Save(&device).Error
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) GetDevices(params *DeviceQueryParams) ([]model.Device, int64, error) {
|
|||
|
|
|||
|
var devices []model.Device
|
|||
|
|
|||
|
var total int64
|
|||
|
|
|||
|
query := s.db.Model(&model.Device{})
|
|||
|
|
|||
|
if params.UID != "" {
|
|||
|
|
|||
|
query = query.Where("uid LIKE ?", "%"+params.UID+"%")
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if params.DeviceType != "" {
|
|||
|
|
|||
|
query = query.Where("device_type = ?", params.DeviceType)
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if params.Company != "" {
|
|||
|
|
|||
|
query = query.Where("company LIKE ?", "%"+params.Company+"%")
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if params.LicenseType != "" {
|
|||
|
|
|||
|
query = query.Where("license_type = ?", params.LicenseType)
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if params.Status != "" {
|
|||
|
|
|||
|
query = query.Where("status = ?", params.Status)
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
query.Count(&total)
|
|||
|
|
|||
|
if params.Page > 0 && params.PageSize > 0 {
|
|||
|
|
|||
|
offset := (params.Page - 1) * params.PageSize
|
|||
|
|
|||
|
query = query.Offset(offset).Limit(params.PageSize)
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
err := query.Find(&devices).Error
|
|||
|
|
|||
|
return devices, total, err
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) UpdateStartCount(uid string) error {
|
|||
|
var device model.Device
|
|||
|
if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
// 更新启动次数和最后活跃时间
|
|||
|
device.StartCount++
|
|||
|
device.LastActiveAt = time.Now()
|
|||
|
|
|||
|
// 如果设备已激活,检查授权状态
|
|||
|
if device.Status == "active" {
|
|||
|
// 检查授权码有效性
|
|||
|
if device.LicenseCode != "" {
|
|||
|
if err := s.licenseService.CheckLicenseValidity(device.LicenseCode); err != nil {
|
|||
|
device.Status = "expired"
|
|||
|
}
|
|||
|
}
|
|||
|
// 检查次数限制
|
|||
|
if device.LicenseType == "count" && device.StartCount >= device.MaxUses {
|
|||
|
device.Status = "expired"
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 记录设备日志
|
|||
|
log := model.DeviceLog{
|
|||
|
DeviceUID: uid,
|
|||
|
Action: "start",
|
|||
|
Message: fmt.Sprintf("设备启动,当前次数:%d", device.StartCount),
|
|||
|
Status: "success",
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Transaction(func(tx *gorm.DB) error {
|
|||
|
if err := tx.Save(&device).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
return tx.Create(&log).Error
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) UpdateDevice(uid string, updates map[string]interface{}) error {
|
|||
|
|
|||
|
return s.db.Model(&model.Device{}).Where("uid = ?", uid).Updates(updates).Error
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) DeleteDevice(uid string) error {
|
|||
|
|
|||
|
return s.db.Where("uid = ?", uid).Delete(&model.Device{}).Error
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) GetLicenseInfo(deviceUID string) (*model.Device, error) {
|
|||
|
|
|||
|
var device model.Device
|
|||
|
|
|||
|
if err := s.db.Where("uid = ?", deviceUID).First(&device).Error; err != nil {
|
|||
|
|
|||
|
return nil, errors.New("设备不存在")
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return &device, nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) CheckLicenseStatus(deviceUID string) (string, error) {
|
|||
|
|
|||
|
var device model.Device
|
|||
|
|
|||
|
if err := s.db.Where("uid = ?", deviceUID).First(&device).Error; err != nil {
|
|||
|
|
|||
|
return "", errors.New("设备不存在")
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if device.LicenseCode == "" {
|
|||
|
|
|||
|
return "未授权", nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if device.Status != "active" {
|
|||
|
|
|||
|
return device.Status, nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
switch device.LicenseType {
|
|||
|
|
|||
|
case "时间段":
|
|||
|
|
|||
|
if time.Now().After(device.ExpireTime) {
|
|||
|
|
|||
|
device.Status = "expired"
|
|||
|
|
|||
|
s.db.Save(&device)
|
|||
|
|
|||
|
return "已过期", nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
case "启动次数":
|
|||
|
|
|||
|
if device.StartCount >= device.MaxUses {
|
|||
|
|
|||
|
device.Status = "expired"
|
|||
|
|
|||
|
s.db.Save(&device)
|
|||
|
|
|||
|
return "已达到使用上限", nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
return "正常", nil
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
type DeviceQueryParams struct {
|
|||
|
UID string
|
|||
|
DeviceType string
|
|||
|
Company string
|
|||
|
LicenseType string
|
|||
|
Status string
|
|||
|
Page int
|
|||
|
PageSize int
|
|||
|
}
|
|||
|
|
|||
|
type DeviceCreateInput struct {
|
|||
|
UID string `json:"uid" binding:"required"`
|
|||
|
DeviceType string `json:"device_type" binding:"required"`
|
|||
|
DeviceModel string `json:"device_model" binding:"required"`
|
|||
|
Company string `json:"company"`
|
|||
|
}
|
|||
|
|
|||
|
func (s *DeviceService) CreateDevice(input *DeviceCreateInput) error {
|
|||
|
// 检查设备UID是否已存在
|
|||
|
var count int64
|
|||
|
if err := s.db.Model(&model.Device{}).Where("uid = ?", input.UID).Count(&count).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
if count > 0 {
|
|||
|
return errors.New("设备UID已存在")
|
|||
|
}
|
|||
|
|
|||
|
// 创建设备记录
|
|||
|
device := &model.Device{
|
|||
|
UID: input.UID,
|
|||
|
DeviceType: input.DeviceType,
|
|||
|
DeviceModel: input.DeviceModel,
|
|||
|
Company: input.Company,
|
|||
|
RegisterTime: time.Now(),
|
|||
|
Status: "inactive", // 初始状态为未激活
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Create(device).Error
|
|||
|
}
|
|||
|
|
|||
|
// 添加更新检查方法
|
|||
|
func (s *DeviceService) CheckUpdate(deviceUID, currentVersion string) (*model.FileUpload, error) {
|
|||
|
// 获取设备信息
|
|||
|
var device model.Device
|
|||
|
if err := s.db.Where("uid = ?", deviceUID).First(&device).Error; err != nil {
|
|||
|
return nil, errors.New("设备不存在")
|
|||
|
}
|
|||
|
|
|||
|
// 检查设备状态
|
|||
|
if device.Status != "active" {
|
|||
|
return nil, errors.New("设备未激活或已过期")
|
|||
|
}
|
|||
|
|
|||
|
// 查找最新的更新文件
|
|||
|
var update model.FileUpload
|
|||
|
err := s.db.Where("device_model = ? AND is_update = ?", device.DeviceModel, true).
|
|||
|
Order("created_at DESC").
|
|||
|
First(&update).Error
|
|||
|
|
|||
|
if err != nil {
|
|||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|||
|
return nil, nil // 没有可用更新
|
|||
|
}
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
// 比较版本
|
|||
|
if update.Version <= currentVersion && !update.ForceUpdate {
|
|||
|
return nil, nil // 当前版本已是最新
|
|||
|
}
|
|||
|
|
|||
|
return &update, nil
|
|||
|
}
|
|||
|
|
|||
|
// 添加设备型号相关的方法
|
|||
|
|
|||
|
// CreateDeviceModel 创建设备型号
|
|||
|
func (s *DeviceService) CreateDeviceModel(model_ *model.DeviceModel) error {
|
|||
|
// 检查型号名称是否已存在
|
|||
|
var count int64
|
|||
|
s.db.Model(&model.DeviceModel{}).Where("model_name = ?", model_.ModelName).Count(&count)
|
|||
|
if count > 0 {
|
|||
|
return errors.New("设备型号已存在")
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Create(model_).Error
|
|||
|
}
|
|||
|
|
|||
|
// UpdateDeviceModel 更新设备型号
|
|||
|
func (s *DeviceService) UpdateDeviceModel(id uint, model_ *model.DeviceModel) error {
|
|||
|
// 检查型号名称是否被其他型号使用
|
|||
|
var count int64
|
|||
|
s.db.Model(&model.DeviceModel{}).Where("model_name = ? AND id != ?", model_.ModelName, id).Count(&count)
|
|||
|
if count > 0 {
|
|||
|
return errors.New("设备型号已存在")
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Model(&model.DeviceModel{}).Where("id = ?", id).Updates(model_).Error
|
|||
|
}
|
|||
|
|
|||
|
// DeleteDeviceModel 删除设备型号
|
|||
|
func (s *DeviceService) DeleteDeviceModel(id uint) error {
|
|||
|
// 检查是否有设备使用此型号
|
|||
|
var count int64
|
|||
|
s.db.Model(&model.DeviceModel{}).Where("device_model = ?", id).Count(&count)
|
|||
|
if count > 0 {
|
|||
|
return errors.New("该型号下存在设备,无法删除")
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Delete(&model.DeviceModel{}, id).Error
|
|||
|
}
|
|||
|
|
|||
|
// GetDeviceModels 获取设备型号列表
|
|||
|
func (s *DeviceService) GetDeviceModels(modelName, deviceType, company string, page, pageSize int) ([]model.DeviceModel, int64, error) {
|
|||
|
var models []model.DeviceModel
|
|||
|
var total int64
|
|||
|
|
|||
|
query := s.db.Model(&model.DeviceModel{})
|
|||
|
|
|||
|
if modelName != "" {
|
|||
|
query = query.Where("model_name LIKE ?", "%"+modelName+"%")
|
|||
|
}
|
|||
|
if deviceType != "" {
|
|||
|
query = query.Where("device_type = ?", deviceType)
|
|||
|
}
|
|||
|
if company != "" {
|
|||
|
query = query.Where("company LIKE ?", "%"+company+"%")
|
|||
|
}
|
|||
|
|
|||
|
// 获取总数
|
|||
|
query.Count(&total)
|
|||
|
|
|||
|
// 分页查询
|
|||
|
if page > 0 && pageSize > 0 {
|
|||
|
offset := (page - 1) * pageSize
|
|||
|
query = query.Offset(offset).Limit(pageSize)
|
|||
|
}
|
|||
|
|
|||
|
// 查询设备型号列表
|
|||
|
if err := query.Find(&models).Error; err != nil {
|
|||
|
return nil, 0, err
|
|||
|
}
|
|||
|
|
|||
|
// 查询每个型号下的设备数量
|
|||
|
for i := range models {
|
|||
|
var count int64
|
|||
|
s.db.Model(&model.Device{}).Where("device_model = ?", models[i].ModelName).Count(&count)
|
|||
|
models[i].DeviceCount = int(count)
|
|||
|
}
|
|||
|
|
|||
|
return models, total, nil
|
|||
|
}
|
|||
|
|
|||
|
// BatchDeleteDeviceModels 批量删除设备型号
|
|||
|
func (s *DeviceService) BatchDeleteDeviceModels(ids []uint) error {
|
|||
|
// 检查是否有设备使用这些型号
|
|||
|
var count int64
|
|||
|
s.db.Model(&model.Device{}).Where("device_model IN (?)", ids).Count(&count)
|
|||
|
if count > 0 {
|
|||
|
return errors.New("选中的型号中存在正在使用的型号,无法删除")
|
|||
|
}
|
|||
|
|
|||
|
return s.db.Delete(&model.DeviceModel{}, ids).Error
|
|||
|
}
|
|||
|
|
|||
|
// GetRegisteredDevices 获取已注册设备列表
|
|||
|
func (s *DeviceService) GetRegisteredDevices(uid, deviceModel, status string, page, pageSize int) ([]model.Device, int64, error) {
|
|||
|
var devices []model.Device
|
|||
|
var total int64
|
|||
|
|
|||
|
query := s.db.Model(&model.Device{})
|
|||
|
|
|||
|
if uid != "" {
|
|||
|
query = query.Where("uid LIKE ?", "%"+uid+"%")
|
|||
|
}
|
|||
|
if deviceModel != "" {
|
|||
|
query = query.Where("device_model = ?", deviceModel)
|
|||
|
}
|
|||
|
if status != "" {
|
|||
|
query = query.Where("status = ?", status)
|
|||
|
}
|
|||
|
|
|||
|
// 获取总数
|
|||
|
query.Count(&total)
|
|||
|
|
|||
|
// 分页查询
|
|||
|
if page > 0 && pageSize > 0 {
|
|||
|
offset := (page - 1) * pageSize
|
|||
|
query = query.Offset(offset).Limit(pageSize)
|
|||
|
}
|
|||
|
|
|||
|
err := query.Order("created_at DESC").Find(&devices).Error
|
|||
|
return devices, total, err
|
|||
|
}
|
|||
|
|
|||
|
// BindLicense 绑定授权码
|
|||
|
func (s *DeviceService) BindLicense(uid string, licenseCode string) error {
|
|||
|
var device model.Device
|
|||
|
if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
|
|||
|
return errors.New("设备不存在")
|
|||
|
}
|
|||
|
|
|||
|
// 检查设备当前状态
|
|||
|
if device.LicenseCode != "" {
|
|||
|
return errors.New("设备已绑定授权码,请先解绑")
|
|||
|
}
|
|||
|
|
|||
|
// 验证授权码
|
|||
|
license, err := s.licenseService.GetLicenseByCode(licenseCode)
|
|||
|
if err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
if license.Status != "unused" {
|
|||
|
return errors.New("授权码已被使用")
|
|||
|
}
|
|||
|
|
|||
|
// 根据授权类型处理
|
|||
|
switch license.LicenseType {
|
|||
|
case "time":
|
|||
|
if license.Duration <= 0 {
|
|||
|
return errors.New("无效的授权时长")
|
|||
|
}
|
|||
|
device.ExpireTime = time.Now().Add(time.Duration(license.Duration) * time.Minute)
|
|||
|
device.Duration = license.Duration
|
|||
|
device.MaxUses = 0
|
|||
|
case "count":
|
|||
|
if license.MaxUses <= 0 {
|
|||
|
return errors.New("无效的使用次数")
|
|||
|
}
|
|||
|
device.ExpireTime = time.Time{} // 清空过期时间
|
|||
|
device.Duration = 0
|
|||
|
device.MaxUses = license.MaxUses
|
|||
|
device.StartCount = 0 // 重置启动次数
|
|||
|
case "permanent":
|
|||
|
device.ExpireTime = time.Time{} // 清空过期时间
|
|||
|
device.Duration = 0
|
|||
|
device.MaxUses = 0
|
|||
|
default:
|
|||
|
return errors.New("无效的授权类型")
|
|||
|
}
|
|||
|
|
|||
|
// 更新设备基本信息
|
|||
|
device.LicenseCode = licenseCode
|
|||
|
device.LicenseType = license.LicenseType
|
|||
|
device.Status = "active"
|
|||
|
device.LastActiveAt = time.Now()
|
|||
|
|
|||
|
return s.db.Transaction(func(tx *gorm.DB) error {
|
|||
|
// 更新设备信息
|
|||
|
if err := tx.Save(&device).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
// 更新授权码状态
|
|||
|
if err := tx.Model(&model.LicenseCode{}).Where("code = ?", licenseCode).
|
|||
|
Updates(map[string]interface{}{
|
|||
|
"status": "used",
|
|||
|
"used_by": uid,
|
|||
|
"used_at": time.Now(),
|
|||
|
}).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
// 记录设备日志
|
|||
|
log := model.DeviceLog{
|
|||
|
DeviceUID: uid,
|
|||
|
Action: "bind_license",
|
|||
|
Message: fmt.Sprintf("绑定%s授权码: %s", getLicenseTypeText(license.LicenseType), licenseCode),
|
|||
|
Status: "success",
|
|||
|
}
|
|||
|
if err := tx.Create(&log).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
// 获取授权类型的中文描述
|
|||
|
func getLicenseTypeText(licenseType string) string {
|
|||
|
switch licenseType {
|
|||
|
case "time":
|
|||
|
return "时间"
|
|||
|
case "count":
|
|||
|
return "次数"
|
|||
|
case "permanent":
|
|||
|
return "永久"
|
|||
|
default:
|
|||
|
return "未知"
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// UnbindLicense 解绑授权码
|
|||
|
func (s *DeviceService) UnbindLicense(uid string) error {
|
|||
|
var device model.Device
|
|||
|
if err := s.db.Where("uid = ?", uid).First(&device).Error; err != nil {
|
|||
|
return errors.New("设备不存在")
|
|||
|
}
|
|||
|
|
|||
|
if device.LicenseCode == "" {
|
|||
|
return errors.New("设备未绑定授权码")
|
|||
|
}
|
|||
|
|
|||
|
oldLicenseCode := device.LicenseCode
|
|||
|
|
|||
|
return s.db.Transaction(func(tx *gorm.DB) error {
|
|||
|
// 更新设备信息
|
|||
|
if err := tx.Model(&device).Updates(map[string]interface{}{
|
|||
|
"license_code": "",
|
|||
|
"license_type": "",
|
|||
|
"status": "inactive",
|
|||
|
"expire_time": nil,
|
|||
|
"max_uses": 0,
|
|||
|
"duration": 0,
|
|||
|
}).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
// 更新授权码状态
|
|||
|
if err := tx.Model(&model.LicenseCode{}).Where("code = ?", oldLicenseCode).
|
|||
|
Updates(map[string]interface{}{
|
|||
|
"status": "unused",
|
|||
|
"used_by": "",
|
|||
|
"used_at": nil,
|
|||
|
}).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
// 记录设备日志
|
|||
|
log := model.DeviceLog{
|
|||
|
DeviceUID: uid,
|
|||
|
Action: "unbind_license",
|
|||
|
Message: fmt.Sprintf("解绑授权码: %s", oldLicenseCode),
|
|||
|
Status: "success",
|
|||
|
}
|
|||
|
if err := tx.Create(&log).Error; err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
// GetDeviceLogs 获取设备日志
|
|||
|
func (s *DeviceService) GetDeviceLogs(uid string, page, pageSize int) ([]model.DeviceLog, int64, error) {
|
|||
|
var logs []model.DeviceLog
|
|||
|
var total int64
|
|||
|
|
|||
|
query := s.db.Model(&model.DeviceLog{}).Where("device_uid = ?", uid)
|
|||
|
|
|||
|
// 获取总数
|
|||
|
query.Count(&total)
|
|||
|
|
|||
|
// 分页查询
|
|||
|
if page > 0 && pageSize > 0 {
|
|||
|
offset := (page - 1) * pageSize
|
|||
|
query = query.Offset(offset).Limit(pageSize)
|
|||
|
}
|
|||
|
|
|||
|
err := query.Order("created_at DESC").Find(&logs).Error
|
|||
|
return logs, total, err
|
|||
|
}
|
|||
|
|
|||
|
// DashboardStats 仪表盘统计数据
|
|||
|
type DashboardStats struct {
|
|||
|
TotalDevices int64 `json:"total_devices"` // 设备总数
|
|||
|
TotalLicenses int64 `json:"total_licenses"` // 授权码总数
|
|||
|
TodayNew int64 `json:"today_new"` // 今日新增
|
|||
|
OnlineDevices int64 `json:"online_devices"` // 在线设备
|
|||
|
ActiveDevices int64 `json:"active_devices"` // 激活设备
|
|||
|
ExpiredDevices int64 `json:"expired_devices"` // 过期设备
|
|||
|
}
|
|||
|
|
|||
|
// GetDashboardStats 获取仪表盘统计数据
|
|||
|
func (s *DeviceService) GetDashboardStats() (*DashboardStats, error) {
|
|||
|
var stats DashboardStats
|
|||
|
|
|||
|
// 获取设备总数
|
|||
|
s.db.Model(&model.Device{}).Count(&stats.TotalDevices)
|
|||
|
|
|||
|
// 获取授权码总数
|
|||
|
s.db.Model(&model.LicenseCode{}).Count(&stats.TotalLicenses)
|
|||
|
|
|||
|
// 获取今日新增设备数
|
|||
|
today := time.Now().Format("2006-01-02")
|
|||
|
s.db.Model(&model.Device{}).Where("DATE(register_time) = ?", today).Count(&stats.TodayNew)
|
|||
|
|
|||
|
// 获取在线设备数(最近30分钟内有活动的设备)
|
|||
|
thirtyMinutesAgo := time.Now().Add(-30 * time.Minute)
|
|||
|
s.db.Model(&model.Device{}).Where("last_active_at > ?", thirtyMinutesAgo).Count(&stats.OnlineDevices)
|
|||
|
|
|||
|
// 获取激活设备数
|
|||
|
s.db.Model(&model.Device{}).Where("status = ?", "active").Count(&stats.ActiveDevices)
|
|||
|
|
|||
|
// 获取过期设备数
|
|||
|
s.db.Model(&model.Device{}).Where("status = ?", "expired").Count(&stats.ExpiredDevices)
|
|||
|
|
|||
|
return &stats, nil
|
|||
|
}
|