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 }