Files
wangjia 23dff69c62 feat(backend): 授权改为时长兑换券体系 + 退役 ed25519/HMAC + 平台生码工具
- 新增 license_codes 码池表 + model.LicenseCode;licenses 加 tier 档位列
- LicenseService.Redeem:单事务 FOR UPDATE 校验码未用 → 时长叠加(可叠加,0=永久)
  → 写 type/tier/max_devices → 绑设备(超限整笔回滚) → 标记已用 → 即时失效 phase 缓存
  路由仍 POST /license/activate,客户端零破坏
- util.GenerateRedeemCode/NormalizeCode:JIUKU-XXXX-XXXX 短码(crypto/rand)
- cmd/gencode:平台批量生成兑换码并落库;删除 cmd/issue、cmd/genkey
- 退役 ed25519 + HMAC:删 util/license_key、GenerateKey、License 全部 config 字段
  及生产启动私钥校验;trial 改直接建行(无需私钥、去 Fatal)
- tier 档位钩子默认 standard,分档消费模式后续设计
- 测试:Redeem 全场景(叠加/过期重置/永久/一码一次/无效/设备上限回滚)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:14:27 +08:00

28 lines
1.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package model
import "time"
// LicenseCode 兑换券(激活码)。由平台方批量生成,用户购买/活动获得后在自己门店兑换。
// 每张码代表一段时长(duration_days),兑换时叠加到门店当前到期时间上;一码一次(status 控制)。
type LicenseCode struct {
ID uint64 `gorm:"primaryKey;autoIncrement" json:"id"`
Code string `gorm:"size:32;uniqueIndex;not null" json:"code"` // 归一化大写无连字符存储
Type string `gorm:"type:enum('trial','monthly','annual','lifetime');default:'annual'" json:"type"` // 计费/时长标签
// Tier 档位钩子(类似 pro/max)。当前只用 'standard' 一种,分档能力/消费模式后续设计。
Tier string `gorm:"size:32;not null;default:'standard'" json:"tier"`
DurationDays int `gorm:"not null;default:0" json:"duration_days"` // 授予时长;0 = 永久(lifetime
MaxDevices int `gorm:"not null;default:0" json:"max_devices"` // 授予设备上限;0 = 不改变现值
Status string `gorm:"type:enum('unused','redeemed','void');default:'unused';index" json:"status"`
RedeemedShopID *uint64 `gorm:"index" json:"redeemed_shop_id,omitempty"`
RedeemedAt *time.Time `json:"redeemed_at,omitempty"`
RedeemedDeviceID string `gorm:"size:255" json:"redeemed_device_id,omitempty"`
Batch string `gorm:"size:64" json:"batch,omitempty"` // 发放批次/活动名
Note string `gorm:"size:255" json:"note,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}