# 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 有对应的验收测试 - 需要编写集成测试验证完整流程(囤货 → 实名 → 激活 → 扣减 → 重置)