Status: ready-for-human

## Parent

`.scratch/enterprise-auth-and-asset-enhancements/PRD.md`

## What to build

将企业设备授权和收回接口升级为支持 list/filter 两种模式批量选取设备，替代原来只接受精确设备号列表的方式。

**涉及接口：**
- `POST /api/admin/enterprises/{id}/allocate-devices`
- `POST /api/admin/enterprises/{id}/recall-devices`

**`AllocateDevicesReq` 重构为：**
- `selection_type string`（必填，`list` 或 `filter`）
- list 模式：`device_nos []string`（设备虚拟号列表）
- filter 模式过滤字段：`virtual_no string`（模糊）、`batch_no string`、`shop_id *uint`

**`RecallDevicesReq` 重构为：**
- `selection_type string`（必填，`list` 或 `filter`）
- list 模式：`device_nos []string`
- filter 模式过滤字段：`virtual_no string`（模糊）、`batch_no string`

filter 模式下，allocate 操作的候选设备集受操作者权限约束（代理用户只能授权自己店铺的设备）。filter 模式命中的设备数量无硬性上限，但单次事务处理建议分批，超大批次需记录日志。

## Acceptance criteria

- [x] `allocate-devices` 接口接受 `selection_type=list` + `device_nos` 列表，行为与改动前一致
- [x] `allocate-devices` 接口接受 `selection_type=filter` + 过滤条件，批量授权所有匹配设备
- [x] `recall-devices` 接口接受 `selection_type=list` + `device_nos` 列表，行为与改动前一致
- [x] `recall-devices` 接口接受 `selection_type=filter` + 过滤条件，批量收回所有匹配设备
- [x] filter 模式下代理用户只能操作自己店铺的设备，超出范围的设备进入失败列表
- [x] 响应中 `success_count`、`fail_count`、`failed_items` 准确反映实际执行结果

## Blocked by

None - can start immediately
