## MODIFIED Requirements ### Requirement: 套餐历史列表查询 系统 SHALL 提供资产的全量套餐记录查询接口,包含历史和当前生效套餐。 **API 端点**: `GET /api/admin/assets/:asset_type/:id/packages` **排序**: 按 `created_at` 倒序(最新套餐在前) **分页**: 不分页,全量返回 **范围**: 包含所有状态(含 status=4 已失效的历史套餐) **按 asset_type 区分查询**: - card:查询 `PackageUsage.iot_card_id = :id` - device:查询 `PackageUsage.device_id = :id` **每条记录响应字段**: - `package_usage_id`: 套餐使用记录 ID - `package_name`: 套餐名称 - `package_type`: 套餐类型(formal/addon) - `master_usage_id`: 主套餐 ID(加油包时有值,主套餐时为 null) - `real_data_mb`: 真总流量(MB) - `virtual_data_mb`: 虚总流量/停机阈值(MB) - `package_used_mb`: 展示已使用流量(经虚流量换算) - `package_remain_mb`: 展示剩余流量 - `activated_at`: 生效时间 - `expires_at`: 过期时间 - `status`: 套餐状态(0-待生效 1-生效中 2-已用完 3-已过期 4-已失效) - `paid_amount`: 购买时实付金额(分),线下支付或无订单分配时为 null **[新增]** #### Scenario: 查询卡的套餐历史 - **WHEN** 管理员调用 `GET /api/admin/assets/card/123/packages`,该卡有 3 条套餐记录(含 1 条已失效) - **THEN** 系统返回全部 3 条记录,按创建时间倒序排列,每条记录含 `paid_amount` 字段 #### Scenario: 查询设备的套餐历史 - **WHEN** 管理员调用 `GET /api/admin/assets/device/456/packages` - **THEN** 系统返回该设备 device_id 下的所有套餐记录,含 `paid_amount` 字段 #### Scenario: 资产无套餐记录 - **WHEN** 管理员查询一张从未购买过套餐的卡 - **THEN** 系统返回空数组,不报错 #### Scenario: 线下支付套餐的 paid_amount 为 null - **WHEN** 管理员查询一张通过线下支付购买套餐的卡 - **THEN** 对应套餐记录的 `paid_amount` 字段缺省(omitempty),不展示 --- ### Requirement: 当前主套餐详情查询 系统 SHALL 提供查询资产当前生效主套餐的接口,用于展示套餐详细信息。 **API 端点**: `GET /api/admin/assets/:asset_type/:id/current-package` **查询条件**: `status = 1(生效中)AND master_usage_id IS NULL` **多套餐同时生效时**:只返回主套餐(master_usage_id IS NULL),不返回加油包 **响应字段**: - 完整套餐信息(同套餐历史列表中的单条记录字段) - `paid_amount`: 购买时实付金额(分),线下支付或无订单分配时为 null **[新增]** - 当无生效主套餐时,返回 HTTP 404 #### Scenario: 返回当前主套餐(含实付金额) - **WHEN** 管理员调用 `GET /api/admin/assets/card/123/current-package`,该卡有 1 个生效主套餐和 1 个加油包,主套餐 `paid_amount = 9900` - **THEN** 系统只返回主套餐信息,响应中包含 `paid_amount: 9900`,不包含加油包 #### Scenario: 无当前生效主套餐 - **WHEN** 管理员查询没有生效中主套餐的资产 - **THEN** 系统返回 HTTP 404