All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m54s
- 重构 Worker 启动流程,引入 bootstrap 模块统一管理依赖注入 - 实现套餐流量重置服务(日/月/年周期重置) - 新增套餐激活排队、加油包绑定、囤货待实名激活逻辑 - 新增订单创建幂等性防重(Redis 业务键 + 分布式锁) - 更新 AGENTS.md/CLAUDE.md:新增注释规范、幂等性规范,移除测试要求 - 添加套餐系统升级完整文档(API文档、使用指南、功能总结、运维指南) - 归档 OpenSpec package-system-upgrade 变更,同步 specs 到主目录 - 新增 queue types 抽象和 Redis 常量定义
115 lines
6.2 KiB
Markdown
115 lines
6.2 KiB
Markdown
# Proposal: 套餐系统升级 - 支持自然月/按天套餐与多套餐管理
|
||
|
||
## Why
|
||
|
||
现有套餐系统仅支持简单的按月计算模式,无法满足业务方提出的复杂套餐需求。具体痛点包括:(1) 代理商囤货场景无法支持 - 需要提前为未实名设备低价采购套餐,等待首次实名时自动激活;(2) 套餐类型单一 - 缺少自然月套餐(按月边界计算)和按天套餐(灵活天数);(3) 多套餐管理混乱 - 主套餐可同时多个生效、加油包无生命周期管理、流量扣减无优先级;(4) 流量统计不精细 - 客户无法区分主套餐和加油包用量,缺少套餐维度的流量详单。这些限制直接影响运营效率和用户体验。
|
||
|
||
## What Changes
|
||
|
||
### 套餐模型扩展
|
||
- 新增 `calendar_type` 字段:支持 `natural_month`(自然月套餐)和 `by_day`(按天套餐)
|
||
- 新增 `data_reset_cycle` 字段:支持 `daily`、`monthly`、`yearly`、`none` 四种流量重置周期
|
||
- 新增 `enable_realname_activation` 字段:标识是否需要首次实名激活(后台囤货场景)
|
||
|
||
### 套餐使用记录扩展
|
||
- PackageUsage 表 `status` 字段扩展:
|
||
- 0 - 待生效(等待实名或排队中)
|
||
- 1 - 生效中
|
||
- 2 - 已用完
|
||
- 3 - 已过期
|
||
- 4 - 已失效(加油包跟随主套餐失效)
|
||
- 新增 `priority` 字段:主套餐排队顺序(数字越小优先级越高)
|
||
- 新增 `master_usage_id` 字段:加油包关联的主套餐ID
|
||
- 新增 `has_independent_expiry` 字段:加油包是否有独立有效期
|
||
- 新增 `pending_realname_activation` 字段:是否等待实名激活
|
||
- 新增流量重置相关字段:`data_reset_cycle`、`last_reset_at`、`next_reset_at`
|
||
|
||
### 新增套餐流量日记录表
|
||
- 创建 `PackageUsageDailyRecord` 表,按套餐维度记录每日流量增量
|
||
- 字段:`package_usage_id`、`date`、`daily_usage_mb`、`cumulative_usage_mb`
|
||
- 索引:`package_usage_id + date` 联合唯一索引
|
||
|
||
### 业务逻辑改造
|
||
- **首次实名激活**:轮询系统检测到首次实名时,触发 Asynq 任务激活待生效套餐
|
||
- **主套餐排队**:订单服务购买主套餐时,自动分配 priority,当前主套餐过期后调度器自动激活下一个
|
||
- **加油包生命周期**:主套餐过期时,轮询系统级联失效其关联的所有加油包
|
||
- **流量扣减优先级**:轮询系统更新流量时,优先扣减加油包(按 priority),再扣主套餐
|
||
- **停机条件**:轮询系统检查主套餐 + 所有加油包流量都用完才触发停机
|
||
- **流量重置调度**:定时任务根据 `data_reset_cycle` 定期重置套餐流量
|
||
|
||
### API 改造
|
||
- **套餐管理 API** (`/api/admin/packages`):
|
||
- POST/PUT 支持新增字段(calendar_type, data_reset_cycle, enable_realname_activation)
|
||
- GET 返回包含新增字段
|
||
- **订单 API** (`/api/admin/orders` 和 `/api/h5/orders`):
|
||
- POST 支持主套餐排队逻辑(自动分配 priority)
|
||
- POST 支持加油包购买限制(必须有主套餐)
|
||
- 客户端未实名时购买套餐返回错误
|
||
- **流量查询 API**(新增):
|
||
- `GET /api/h5/packages/my-usage` - 客户视图(主套餐、每个加油包、总计)
|
||
- `GET /api/admin/package-usage/:id/daily-records` - 套餐流量详单(按日)
|
||
- 现有卡流量详单继续按卡维度统计
|
||
|
||
### 轮询系统扩展
|
||
- 新增套餐激活检查任务(HandlePackageActivation)
|
||
- 新增流量重置调度任务(HandleDataReset)
|
||
- 扩展流量检查任务(HandleCarddataCheck)支持新的扣减优先级和停机条件
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
- `package-calendar-type` - 套餐周期类型管理(自然月/按天)
|
||
- `package-data-reset` - 套餐流量重置周期管理
|
||
- `package-realname-activation` - 首次实名激活机制
|
||
- `package-queue-activation` - 主套餐排队生效机制
|
||
- `addon-package-lifecycle` - 加油包生命周期管理
|
||
- `package-usage-priority` - 流量扣减优先级机制
|
||
- `package-usage-daily-record` - 套餐流量日记录
|
||
- `package-usage-customer-view` - 客户视图流量查询
|
||
|
||
### Modified Capabilities
|
||
- `package-management` - 套餐管理能力扩展(新增字段支持)
|
||
- `order-management` - 订单管理能力扩展(主套餐排队、加油包购买限制)
|
||
- `iot-card` - IoT卡轮询系统扩展(流量扣减优先级、停机条件)
|
||
|
||
## Impact
|
||
|
||
### 数据库
|
||
- 修改 `tb_package` 表(新增 3 个字段)
|
||
- 修改 `tb_package_usage` 表(新增 7 个字段,扩展 status 枚举)
|
||
- 新增 `tb_package_usage_daily_record` 表
|
||
- 需要数据库迁移脚本
|
||
|
||
### 代码模块
|
||
- `internal/model/package.go` - Package 和 PackageUsage 模型扩展
|
||
- `internal/model/package_usage_daily_record.go` - 新增模型
|
||
- `internal/service/order/` - 订单服务改造(主套餐排队、加油包限制)
|
||
- `internal/service/package/` - 套餐服务改造(支持新字段)
|
||
- `internal/polling/` - 轮询系统扩展(激活调度、流量扣减优先级、重置调度)
|
||
- `internal/handler/admin/package.go` - Handler 层 API 改造
|
||
- `internal/handler/h5/package_usage.go` - 新增客户视图 Handler
|
||
- `internal/store/postgres/package*.go` - Store 层查询逻辑扩展
|
||
- `pkg/errors/codes.go` - 新增错误码
|
||
|
||
### API
|
||
- **BREAKING** - `POST /api/admin/packages` 请求体新增可选字段
|
||
- **BREAKING** - `GET /api/admin/packages/:id` 响应体新增字段
|
||
- **NEW** - `GET /api/h5/packages/my-usage` - 客户视图
|
||
- **NEW** - `GET /api/admin/package-usage/:id/daily-records` - 套餐流量详单
|
||
- **BREAKING** - `POST /api/admin/orders` 和 `POST /api/h5/orders` 行为变更(主套餐排队、加油包限制)
|
||
|
||
### 依赖系统
|
||
- **Asynq 任务队列** - 新增套餐激活任务类型、流量重置任务类型
|
||
- **轮询系统** - 扩展流量检查、新增激活检查、新增重置调度
|
||
- **OpenAPI 文档生成器** - 需要更新以支持新增 Handler
|
||
|
||
### 性能
|
||
- 套餐激活调度延迟目标 < 1分钟
|
||
- 流量查询 API P95 < 200ms(现有要求保持)
|
||
- 轮询系统千万级卡规模支持不退化
|
||
|
||
### 测试
|
||
- 核心业务逻辑单元测试覆盖率 ≥ 90%
|
||
- 所有 Spec Scenarios 有对应的验收测试
|
||
- 需要编写集成测试验证完整流程(囤货 → 实名 → 激活 → 扣减 → 重置)
|