Files
huang c665f32976
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 6m54s
feat: 套餐系统升级 - Worker 重构、流量重置、文档与规范更新
- 重构 Worker 启动流程,引入 bootstrap 模块统一管理依赖注入
- 实现套餐流量重置服务(日/月/年周期重置)
- 新增套餐激活排队、加油包绑定、囤货待实名激活逻辑
- 新增订单创建幂等性防重(Redis 业务键 + 分布式锁)
- 更新 AGENTS.md/CLAUDE.md:新增注释规范、幂等性规范,移除测试要求
- 添加套餐系统升级完整文档(API文档、使用指南、功能总结、运维指南)
- 归档 OpenSpec package-system-upgrade 变更,同步 specs 到主目录
- 新增 queue types 抽象和 Redis 常量定义
2026-02-12 14:24:15 +08:00

5.8 KiB
Raw Permalink Blame History

套餐系统升级 - 使用指南

场景一:囤货待实名激活

业务场景

代理商后台为未实名的卡/设备预先购买套餐,用户实名后自动激活。

操作流程

1. 代理商登录后台
2. 选择未实名的卡/设备
3. 购买套餐(选择支持实名激活的套餐)
4. 套餐状态待激活status=0, pending_realname_activation=true
5. 用户完成实名认证
6. 系统自动激活套餐

前置条件

  • 套餐必须启用 enable_realname_activation=true
  • 卡/设备当前未实名

注意事项

  • 囤货套餐在实名前不会计算有效期
  • 实名后,有效期从激活日期开始计算
  • 如果卡/设备已实名,套餐会立即激活

场景二:主套餐排队

业务场景

用户当前有生效中的主套餐,想提前购买下一个套餐。

操作流程

1. 用户购买新主套餐
2. 系统检测到已有生效中主套餐
3. 新套餐进入排队状态status=0, priority=N+1
4. 当前主套餐过期
5. 系统自动激活排队中的下一个套餐

排队规则

情况 新套餐状态
无生效中主套餐 立即激活status=1, priority=1
有生效中主套餐 排队等待status=0, priority=MAX+1

查看排队情况

GET /api/h5/packages/my-usage

// 响应
{
  "main_package": {
    "package_name": "月度套餐",
    "status": 1,  // 生效中
    "expires_at": "2025-03-31T23:59:59Z"
  },
  "queued_packages": [
    {
      "package_name": "季度套餐",
      "status": 0,  // 排队中
      "priority": 2
    }
  ]
}

场景三:加油包购买

业务场景

用户主套餐流量不够用,需要购买加油包补充流量。

操作流程

1. 确认用户有生效中或待生效的主套餐
2. 用户选择加油包
3. 系统自动绑定到当前主套餐
4. 加油包立即生效
5. 流量扣减时优先使用加油包

购买限制

限制项 说明
必须有主套餐 无主套餐无法购买加油包
混买禁止 同一订单不能同时购买主套餐和加油包

加油包生命周期

主套餐过期 → 加油包自动失效status=4

加油包有效期

类型 有效期计算
随主套餐 与主套餐同时过期has_independent_expiry=false
独立有效期 从购买日期开始计算has_independent_expiry=true

场景四:流量查询

客户端查询我的流量

GET /api/h5/packages/my-usage
Authorization: Bearer {token}

响应示例:

{
  "code": 0,
  "data": {
    "main_package": {
      "package_usage_id": 101,
      "package_name": "月度套餐 30G",
      "data_limit_mb": 30720,
      "data_usage_mb": 15360,
      "status": 1,
      "activated_at": "2025-02-01T00:00:00Z",
      "expires_at": "2025-02-28T23:59:59Z"
    },
    "addon_packages": [
      {
        "package_usage_id": 102,
        "package_name": "加油包 5G",
        "data_limit_mb": 5120,
        "data_usage_mb": 2048,
        "status": 1,
        "priority": 2
      }
    ],
    "total": {
      "total_mb": 35840,
      "used_mb": 17408,
      "remaining_mb": 18432
    }
  }
}

后台查询套餐流量详单

GET /api/admin/package-usage/101/daily-records?start_date=2025-02-01&end_date=2025-02-15
Authorization: Bearer {token}

响应示例:

{
  "code": 0,
  "data": {
    "package_usage_id": 101,
    "package_name": "月度套餐 30G",
    "records": [
      {
        "date": "2025-02-01",
        "daily_usage_mb": 1024,
        "cumulative_usage_mb": 1024
      },
      {
        "date": "2025-02-02",
        "daily_usage_mb": 512,
        "cumulative_usage_mb": 1536
      }
    ],
    "total_usage_mb": 15360
  }
}

套餐状态说明

状态码 名称 说明
0 待生效 排队中或待实名激活
1 生效中 正在使用
2 已用完 流量已耗尽
3 已过期 超过有效期
4 已失效 主套餐过期导致加油包失效

流量重置说明

重置类型

类型 套餐类型 重置时间 适用场景
日重置 所有 每天 00:00:00 日租卡
月重置 自然月 每月1号 00:00:00 自然月套餐
月重置 按天 从激活日起每30天 按天套餐
年重置 所有 每年1月1日 年度套餐
不重置 所有 不重置 一次性流量包

重置行为

重置前data_usage_mb = 25600
重置后data_usage_mb = 0
  • 重置只清空已用流量,不影响有效期
  • 流量用完的套餐status=2重置后恢复为生效中status=1

停复机说明

停机条件

所有生效套餐流量用完:

  • 主套餐 status=2
  • 所有加油包 status=2

复机条件

  • 购买新套餐
  • 套餐流量重置
  • 排队套餐激活

停机记录

-- 停机记录在 tb_iot_card 表
stopped_at: 停机时间
stop_reason: 停机原因(如 "流量耗尽"

-- 复机后
resumed_at: 复机时间

常见问题

Q: 为什么购买加油包提示"必须有主套餐"

A: 加油包必须绑定到主套餐,请先购买主套餐再购买加油包。

Q: 主套餐过期后加油包还能用吗?

A: 不能。主套餐过期后绑定的加油包会自动失效status=4

Q: 套餐排队后可以取消吗?

A: 目前不支持取消排队中的套餐,请联系客服处理。

Q: 流量重置后为什么还是停机状态?

A: 流量重置后系统会自动触发复机,如果仍是停机状态,请检查运营商接口是否正常。

Q: H5 端未实名用户如何购买套餐?

A: H5 端必须先完成实名认证才能购买套餐。代理商可在后台为未实名用户囤货。