# 套餐系统升级 - API 文档

## 客户端 API

### 查询我的流量使用情况

获取当前用户绑定的卡/设备的套餐流量使用情况。

**请求**

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

**响应**

```json
{
  "code": 0,
  "msg": "success",
  "data": {
    "main_package": {
      "package_usage_id": 101,
      "package_id": 1,
      "package_name": "月度套餐 30G",
      "data_limit_mb": 30720,
      "data_usage_mb": 15360,
      "status": 1,
      "priority": 1,
      "activated_at": "2025-02-01T00:00:00Z",
      "expires_at": "2025-02-28T23:59:59Z",
      "data_reset_cycle": "monthly",
      "last_reset_at": "2025-02-01T00:00:00Z",
      "next_reset_at": "2025-03-01T00:00:00Z"
    },
    "addon_packages": [
      {
        "package_usage_id": 102,
        "package_id": 5,
        "package_name": "加油包 5G",
        "data_limit_mb": 5120,
        "data_usage_mb": 2048,
        "status": 1,
        "priority": 2,
        "master_usage_id": 101,
        "activated_at": "2025-02-10T00:00:00Z",
        "expires_at": "2025-02-28T23:59:59Z"
      }
    ],
    "total": {
      "total_mb": 35840,
      "used_mb": 17408,
      "remaining_mb": 18432
    }
  },
  "timestamp": 1707667200
}
```

**响应字段说明**

| 字段 | 类型 | 说明 |
|------|------|------|
| `main_package` | object | 主套餐信息（可能为 null） |
| `addon_packages` | array | 加油包列表 |
| `total.total_mb` | int64 | 总流量（MB） |
| `total.used_mb` | int64 | 已用流量（MB） |
| `total.remaining_mb` | int64 | 剩余流量（MB） |

**套餐状态 status**

| 值 | 说明 |
|----|------|
| 0 | 待生效 |
| 1 | 生效中 |
| 2 | 已用完 |
| 3 | 已过期 |
| 4 | 已失效 |

---

## 后台管理 API

### 查询套餐流量详单

查询指定套餐的每日流量使用记录。

**请求**

```http
GET /api/admin/package-usage/{id}/daily-records
Authorization: Bearer {token}
```

**Query 参数**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `start_date` | string | 是 | 开始日期（YYYY-MM-DD） |
| `end_date` | string | 是 | 结束日期（YYYY-MM-DD） |

**响应**

```json
{
  "code": 0,
  "msg": "success",
  "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
      },
      {
        "date": "2025-02-03",
        "daily_usage_mb": 2048,
        "cumulative_usage_mb": 3584
      }
    ],
    "total_usage_mb": 15360
  },
  "timestamp": 1707667200
}
```

**错误码**

| 错误码 | 说明 |
|-------|------|
| 400 | 参数错误（日期格式不正确） |
| 403 | 无权限访问该套餐 |
| 404 | 套餐不存在 |

---

### 创建套餐（扩展字段）

创建套餐时支持的新字段。

**请求**

```http
POST /api/admin/packages
Authorization: Bearer {token}
Content-Type: application/json
```

**请求体**

```json
{
  "package_name": "月度套餐 30G",
  "package_type": "main",
  "data_limit_mb": 30720,
  "price": 9900,
  "calendar_type": "natural_month",
  "duration_months": 1,
  "data_reset_cycle": "monthly",
  "enable_realname_activation": false
}
```

**新增字段说明**

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `calendar_type` | string | 是 | 有效期类型：`natural_month`（自然月）、`by_day`（按天） |
| `duration_months` | int | 条件必填 | 自然月套餐的月数（calendar_type=natural_month 时必填） |
| `duration_days` | int | 条件必填 | 按天套餐的天数（calendar_type=by_day 时必填） |
| `data_reset_cycle` | string | 是 | 流量重置周期：`daily`、`monthly`、`yearly`、`none` |
| `enable_realname_activation` | bool | 否 | 是否需要实名后激活（默认 false） |

**calendar_type 取值**

| 值 | 说明 | 有效期计算 |
|----|------|-----------|
| `natural_month` | 自然月 | 激活月份 + N 个月，月末过期 |
| `by_day` | 按天 | 激活日期 + N 天 |

**data_reset_cycle 取值**

| 值 | 说明 | 重置时间 |
|----|------|---------|
| `daily` | 日重置 | 每天 00:00:00 |
| `monthly` | 月重置 | 自然月套餐：每月1号<br>按天套餐：每30天 |
| `yearly` | 年重置 | 每年1月1日 |
| `none` | 不重置 | 不重置 |

---

### 更新套餐（扩展字段）

更新套餐时支持的新字段。

**请求**

```http
PUT /api/admin/packages/{id}
Authorization: Bearer {token}
Content-Type: application/json
```

**请求体**

```json
{
  "calendar_type": "by_day",
  "duration_days": 30,
  "data_reset_cycle": "none",
  "enable_realname_activation": true
}
```

---

### 查询套餐详情（扩展字段）

获取套餐详情时返回的新字段。

**响应**

```json
{
  "code": 0,
  "data": {
    "id": 1,
    "package_name": "月度套餐 30G",
    "package_type": "main",
    "data_limit_mb": 30720,
    "price": 9900,
    "calendar_type": "natural_month",
    "duration_months": 1,
    "duration_days": 0,
    "data_reset_cycle": "monthly",
    "enable_realname_activation": false,
    "status": 1,
    "created_at": "2025-01-01T00:00:00Z",
    "updated_at": "2025-01-15T00:00:00Z"
  }
}
```

---

## 错误码汇总

| 错误码 | HTTP 状态码 | 说明 |
|-------|------------|------|
| `CodePackageActivationConflict` | 409 | 套餐正在激活中，请稍后重试 |
| `CodeNoMainPackage` | 400 | 必须有主套餐才能购买加油包 |
| `CodeRealnameRequired` | 403 | 设备/卡必须先完成实名认证才能购买套餐 |
| `CodeMixedOrderForbidden` | 400 | 同订单不能同时购买正式套餐和加油包 |

---

## 数据权限

### 客户端 API

- 只能查询当前用户绑定的卡/设备的套餐信息
- 用户身份通过 JWT Token 识别

### 后台管理 API

- 代理商：只能查询自己店铺及下级店铺的套餐
- 企业用户：只能查询自己企业的套餐
- 平台用户：可查询所有套餐
- 越权访问返回 403 错误
