## MODIFIED Requirements ### Requirement: 统一资产解析入口 系统 SHALL 提供统一的资产查找接口,通过任意标识符定位卡或设备,并返回该资产的中等聚合信息。 **API 端点**: `GET /api/admin/assets/resolve/:identifier` **查找顺序(更新后)**: 1. **主路径**:查 `tb_asset_identifier` WHERE identifier = ? → 命中则得到 asset_type + asset_id,直接查对应表取完整记录 2. **Fallback 路径**(注册表未命中时): - 先查 `tb_device`(匹配 `virtual_no = ? OR imei = ? OR sn = ?`) - 未命中则查 `tb_iot_card`(匹配 `virtual_no = ? OR iccid = ? OR msisdn = ?`) 3. 两条路径均未命中 → 返回 HTTP 404 **数据权限规则**: - 代理用户:只能查看 `shop_id` 在自己及下级店铺范围内的资产 - 平台用户(SuperAdmin/Platform):可查看所有资产 - 企业账号:暂不支持此接口,调用时返回 HTTP 403 **响应结构(AssetResolveResponse)**: *通用字段(device 和 card 均有)*: - `asset_type`: 资产类型(`"device"` 或 `"card"`) - `asset_id`: 资产主键 ID - `identifier`: 本次查询所用的标识符(原样回传) - `virtual_no`: 虚拟号(设备/卡均使用此字段) - `status`: 资产状态(整型) - `asset_status`: 业务状态(1-在库 2-已销售 3-已换货 4-已停用) - `generation`: 资产世代编号 - `batch_no`: 批次号 - `shop_id`: 所属店铺 ID(平台库存时为空) - `shop_name`: 所属店铺名称 - `series_id`: 套餐系列 ID(未绑定时为空) - `series_name`: 套餐系列名称 - `first_commission_paid`: 一次性佣金是否已发放 - `accumulated_recharge`: 累计充值金额(分) - `activated_at`: 激活时间(未激活时为空) - `created_at`: 创建时间 - `updated_at`: 更新时间 *状态与套餐字段(device 和 card 均有)*: - `real_name_status`: 实名状态(整型) - `current_package`: 当前套餐名称(无套餐时返回空字符串) - `package_total_mb`、`package_used_mb`、`package_remain_mb`: 套餐流量信息 - `device_protect_status`: 保护期状态 *绑定关系字段*: - `iccid`: 仅 card 类型时有值 - `bound_device_id`、`bound_device_no`、`bound_device_name`: 仅 card 类型且绑定设备时有值 - `bound_card_count`、`cards`: 仅 device 类型时有值 #### Scenario: 通过注册表主路径精确解析 - **WHEN** 管理员输入 identifier 为已存在于 `tb_asset_identifier` 的 VirtualNo 或 ICCID - **THEN** 系统单次查询注册表命中,直接查对应表返回完整资产信息,响应时间 < 50ms #### Scenario: Fallback 路径解析 IMEI - **WHEN** 管理员输入 identifier 为设备 IMEI(不在注册表中) - **THEN** 注册表未命中,系统 fallback 查 tb_device 的 imei 字段,找到后返回资产信息 - **THEN** 响应中 `identifier` 字段原样回传该 IMEI 值 #### Scenario: Fallback 路径解析 MSISDN - **WHEN** 管理员输入 identifier 为 IoT 卡的手机号(MSISDN) - **THEN** 注册表未命中,fallback 查 tb_iot_card 的 msisdn 字段 - **THEN** 若存在多张卡的 MSISDN 相同,返回第一条匹配记录(MSISDN 非唯一,存在歧义,记录 warn 日志) #### Scenario: 标识符完全不存在 - **WHEN** 管理员输入的 identifier 在注册表和 fallback 均未找到 - **THEN** 返回 HTTP 404,错误消息"资产不存在"