package models import "time" // License Pro 授权。 // Source: hmac(旧本地签发,迁移窗口内仍接受)| opsx(opsx-licence LIC-/LICOFF-)。 // Plan: free | pro; Edition: personal | team(opsx 侧用 plan_type 映射)。 type License struct { Plan string `json:"plan"` // free | pro Edition string `json:"edition"` // personal | team Seats int `json:"seats"` // 登录席位(历史字段; opsx 按实例计,映射到 Instances) Instances int `json:"instances"` // 部署实例上限(0 = 不限) Customer string `json:"customer"` // 客户标识 // ExpiresAt 0 = 永久;否则 Unix 秒 ExpiresAt int64 `json:"expiresAt"` IssuedAt time.Time `json:"issuedAt"` ActivatedAt time.Time `json:"activatedAt"` // --- opsx-licence 对接字段(JSON 向后兼容,缺省为零值) --- Source string `json:"source,omitempty"` // hmac | opsx LicenseKey string `json:"licenseKey,omitempty"` // 完整密钥(周检/心跳需要;Sanitized 不外泄) InstanceID string `json:"instanceId,omitempty"` // 机器指纹,无 PII PlanType string `json:"planType,omitempty"` // trial | yearly | perpetual MaxDevices int `json:"maxDevices,omitempty"` // 服务端 max_devices(实例数) LastVerifiedAt int64 `json:"lastVerifiedAt,omitempty"` // unix 秒 LastServerTime int64 `json:"lastServerTime,omitempty"` // 防时钟回拨 ActivationToken string `json:"activationToken,omitempty"` // 解绑令牌 DeprecationNotice string `json:"deprecationNotice,omitempty"` // 旧 HMAC 迁移提示 InGrace bool `json:"inGrace,omitempty"` GraceDaysLeft int `json:"graceDaysLeft,omitempty"` } func (l *License) Sanitized() map[string]interface{} { if l == nil { return map[string]interface{}{"plan": "free"} } expired := l.ExpiresAt > 0 && l.ExpiresAt < time.Now().Unix() plan := l.Plan if expired && !l.InGrace { plan = "free" } out := map[string]interface{}{ "plan": plan, "edition": l.Edition, "seats": l.Seats, "instances": l.Instances, "customer": l.Customer, "expiresAt": l.ExpiresAt, "expired": expired, } if l.Source != "" { out["source"] = l.Source } if l.PlanType != "" { out["planType"] = l.PlanType } if l.MaxDevices > 0 { out["maxDevices"] = l.MaxDevices out["instances"] = l.MaxDevices } if l.DeprecationNotice != "" { out["deprecationNotice"] = l.DeprecationNotice } if l.InGrace { out["inGrace"] = true out["graceDaysLeft"] = l.GraceDaysLeft } if l.LastVerifiedAt > 0 { out["lastVerifiedAt"] = l.LastVerifiedAt } if l.InstanceID != "" { out["instanceId"] = l.InstanceID } return out }