package license import ( "backend/internal/dto" "backend/internal/model" "backend/utils" "errors" "time" ) // Verify 客户端 License 验证 // Logan.Li func (s *LicenseService) Verify(req dto.LicenseVerifyRequest) (*dto.LicenseVerifyResponse, error) { var lic model.License if err := s.db.Preload("Product").Where("license_key = ?", req.LicenseKey).First(&lic).Error; err != nil { return &dto.LicenseVerifyResponse{Valid: false, Message: "无效的 License"}, nil } // 校验产品归属 // Logan.Li if req.ProductID > 0 && lic.ProductID != req.ProductID { return &dto.LicenseVerifyResponse{Valid: false, Message: "License 与产品不匹配"}, nil } // 状态检查 // Logan.Li switch lic.Status { case model.LicenseStatusRevoked: return &dto.LicenseVerifyResponse{Valid: false, Message: "License 已被吊销"}, nil case model.LicenseStatusSuspended: return &dto.LicenseVerifyResponse{Valid: false, Message: "License 已被暂停"}, nil case model.LicenseStatusExpired: return &dto.LicenseVerifyResponse{Valid: false, Message: "License 已过期"}, nil } // 过期检查(惰性更新状态) // Logan.Li if utils.IsLicenseExpired(lic.EndDate) { lic.Status = model.LicenseStatusExpired s.db.Save(&lic) return &dto.LicenseVerifyResponse{Valid: false, Message: "License 已过期"}, nil } return &dto.LicenseVerifyResponse{ Valid: true, LicenseKey: lic.LicenseKey, ProductID: lic.ProductID, ProductName: lic.Product.Name, ProductCode: lic.Product.Code, Features: utils.ParseFeatures(lic.Product.Features), Status: lic.Status, ExpiresAt: lic.EndDate.Format("2006-01-02 15:04:05"), DaysLeft: utils.CalculateDaysLeft(lic.EndDate), MaxDevices: lic.MaxActivations, Message: "验证成功", }, nil } // Activate 客户端激活 License(机器绑定) // Logan.Li func (s *LicenseService) Activate(req dto.LicenseActivateRequest, clientIP string) (map[string]interface{}, error) { var lic model.License if err := s.db.Where("license_key = ?", req.LicenseKey).First(&lic).Error; err != nil { return nil, errors.New("无效的 License") } if lic.Status == model.LicenseStatusRevoked { return nil, errors.New("License 已被吊销") } if lic.Status == model.LicenseStatusExpired || utils.IsLicenseExpired(lic.EndDate) { return nil, errors.New("License 已过期") } // 同设备重复激活视为重新激活,不消耗额度 // Logan.Li var existing model.Activation if err := s.db.Where("license_id = ? AND device_id = ?", lic.ID, req.DeviceID).First(&existing).Error; err == nil { existing.LastSeenAt = time.Now() existing.IsOnline = true existing.DeviceName = req.DeviceName existing.DeviceInfo = req.DeviceInfo existing.IP = clientIP s.db.Save(&existing) return map[string]interface{}{ "expires_at": lic.EndDate.Format("2006-01-02 15:04:05"), "days_left": utils.CalculateDaysLeft(lic.EndDate), }, nil } // 检查激活额度 // Logan.Li if lic.CurrentActivations >= lic.MaxActivations { return nil, errors.New("已达到最大激活数量限制") } // 创建激活记录 // Logan.Li activation := model.Activation{ LicenseID: lic.ID, DeviceID: req.DeviceID, DeviceName: req.DeviceName, DeviceInfo: req.DeviceInfo, IP: clientIP, Status: "active", IsOnline: true, ActivatedAt: time.Now(), LastSeenAt: time.Now(), } if err := s.db.Create(&activation).Error; err != nil { return nil, errors.New("激活失败") } lic.CurrentActivations++ if lic.Status == model.LicenseStatusInactive { lic.Status = model.LicenseStatusActive } s.db.Save(&lic) return map[string]interface{}{ "expires_at": lic.EndDate.Format("2006-01-02 15:04:05"), "days_left": utils.CalculateDaysLeft(lic.EndDate), }, nil } // Deactivate 客户端停用 // Logan.Li func (s *LicenseService) Deactivate(req dto.LicenseDeactivateRequest) error { var lic model.License if err := s.db.Where("license_key = ?", req.LicenseKey).First(&lic).Error; err != nil { return errors.New("无效的 License") } result := s.db.Model(&model.Activation{}). Where("license_id = ? AND device_id = ?", lic.ID, req.DeviceID). Update("status", "inactive") if result.RowsAffected > 0 && lic.CurrentActivations > 0 { lic.CurrentActivations-- s.db.Save(&lic) } return nil } // Heartbeat 客户端心跳 // Logan.Li func (s *LicenseService) Heartbeat(req dto.LicenseHeartbeatRequest) (map[string]interface{}, error) { var lic model.License if err := s.db.Where("license_key = ?", req.LicenseKey).First(&lic).Error; err != nil { return nil, errors.New("无效的 License") } if lic.Status == model.LicenseStatusRevoked { return nil, errors.New("License 已被吊销") } if lic.Status == model.LicenseStatusExpired || utils.IsLicenseExpired(lic.EndDate) { return nil, errors.New("License 已过期") } // 更新心跳时间与在线状态 // Logan.Li s.db.Model(&model.Activation{}). Where("license_id = ? AND device_id = ?", lic.ID, req.DeviceID). Updates(map[string]interface{}{"last_seen_at": time.Now(), "is_online": true}) return map[string]interface{}{ "expires_at": lic.EndDate.Format("2006-01-02 15:04:05"), "days_left": utils.CalculateDaysLeft(lic.EndDate), }, nil }