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>
This commit is contained in:
@@ -107,6 +107,7 @@ CREATE TABLE IF NOT EXISTS `licenses` (
|
||||
`license_key` VARCHAR(768) NOT NULL COMMENT 'Ed25519 signed token',
|
||||
`device_id` VARCHAR(255) DEFAULT NULL COMMENT 'deprecated: use license_devices',
|
||||
`type` ENUM('trial','monthly','annual','lifetime') NOT NULL DEFAULT 'trial',
|
||||
`tier` VARCHAR(32) NOT NULL DEFAULT 'standard' COMMENT '权益档位钩子(pro/max-like),当前默认 standard',
|
||||
`expires_at` DATETIME DEFAULT NULL COMMENT 'NULL=永久',
|
||||
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
|
||||
`max_devices` INT NOT NULL DEFAULT 3 COMMENT '最大绑定设备数',
|
||||
@@ -134,6 +135,28 @@ CREATE TABLE IF NOT EXISTS `license_devices` (
|
||||
KEY `idx_license_id` (`license_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='许可证设备绑定';
|
||||
|
||||
-- 兑换券(激活码)码池:平台方批量生成,用户兑换后叠加时长到门店授权
|
||||
CREATE TABLE IF NOT EXISTS `license_codes` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(32) NOT NULL COMMENT '归一化大写无连字符',
|
||||
`type` ENUM('trial','monthly','annual','lifetime') NOT NULL DEFAULT 'annual' COMMENT '计费/时长标签',
|
||||
`tier` VARCHAR(32) NOT NULL DEFAULT 'standard' COMMENT '档位钩子(pro/max-like),当前默认 standard',
|
||||
`duration_days` INT NOT NULL DEFAULT 0 COMMENT '授予时长;0=永久(lifetime)',
|
||||
`max_devices` INT NOT NULL DEFAULT 0 COMMENT '授予设备上限;0=不改变现值',
|
||||
`status` ENUM('unused','redeemed','void') NOT NULL DEFAULT 'unused',
|
||||
`redeemed_shop_id` BIGINT UNSIGNED DEFAULT NULL COMMENT '被哪个门店兑换',
|
||||
`redeemed_at` DATETIME DEFAULT NULL,
|
||||
`redeemed_device_id` VARCHAR(255) DEFAULT NULL COMMENT '兑换设备(审计)',
|
||||
`batch` VARCHAR(64) DEFAULT NULL COMMENT '发放批次/活动名',
|
||||
`note` VARCHAR(255) DEFAULT NULL,
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_code` (`code`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_redeemed_shop` (`redeemed_shop_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='兑换券码池';
|
||||
|
||||
-- ------------------------------------------------------------
|
||||
-- 商品分类
|
||||
-- ------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user