# 手动进出场操作页面 — 设计文档

> 日期：2026-07-16 | 优先级：P0-2

## 1. 目标

为岗亭操作员提供手动进出场操作页面，作为 RFID 自动识别的备用兜底。当 UHF 标签损坏、无标签车辆进入、或 RFID 系统故障时，操作员手动输入车牌/RFID 完成进出场。

## 2. 使用场景

- **主要场景**：RFID 不可用时的备用操作（低频）
- **用户**：管理员（888）、操作员（618）
- **菜单位置**：停车管理 → 进出场操作

## 3. 页面结构

```
进出场操作
├── Tab：车辆进场 | 车辆出场
│
├── 输入区
│   ├── 车牌号输入框
│   ├── RFID 标签输入框
│   └── 查询按钮
│
├── 车辆详情卡片（查询后显示）
│   ├── 车牌号、车辆类型、车主名
│   ├── 当前在场状态
│   └── 进场/出场特有信息
│
└── 操作区
    ├── 进场：停车场下拉选择 + 确认进场按钮
    └── 出场：费用信息 + 收费方式 + 确认出场按钮
```

## 4. 进场流程

```
输入车牌/RFID → 查询车辆
  ├─ 找到车辆 → 显示详情，检查是否已入场
  │   ├─ 已入场 → 提示"该车辆已在场内"
  │   └─ 未入场 → 选择停车场 → 确认进场
  └─ 未找到 → 提示"未找到车辆，将按临时车入场"
      └─ 选择停车场 → 确认进场

确认进场 → POST /vehicle/entry
  ├─ 成功 → 提示"入场成功"，显示入场时间，清空表单
  └─ 失败 → 提示错误原因
```

### 涉及 API

| 接口 | 用途 |
|------|------|
| `GET /vehicle/get-by-plate?plate_number=` | 根据车牌查询车辆信息 |
| `GET /parking/lot/list` | 获取停车场下拉列表 |
| `POST /vehicle/entry` | 执行入场 |

## 5. 出场流程

```
输入车牌/RFID → 查询车辆
  ├─ 找到车辆 → 检查是否有未出场记录
  │   ├─ 无未出场记录 → 提示"该车辆不在场内"
  │   └─ 有未出场记录 → 显示计费信息
  │       ├─ 进场时间
  │       ├─ 停留时长
  │       ├─ 费用金额
  │       ├─ 收费方式选择（现金/扫码/免密，本次先做现金）
  │       └─ 确认出场
  └─ 未找到 → 提示"未找到车辆信息"

确认出场 → POST /vehicle/exit
  ├─ 成功 → 提示"出场成功"，显示费用，清空表单
  └─ 失败 → 提示错误原因
```

### 涉及 API

| 接口 | 用途 |
|------|------|
| `GET /vehicle/get-by-plate?plate_number=` | 根据车牌查询车辆信息 |
| `POST /vehicle/exit` | 执行出场（返回 fee、stayTime、entryTime、exitTime） |

## 6. 技术实现

### 前端

| 项 | 说明 |
|------|------|
| 框架 | Vue 3 + Composition API |
| 组件库 | Element Plus（el-tabs、el-form、el-input、el-select、el-button、el-descriptions） |
| API 封装 | 复用 `src/api/vehicle.js` 已有的 `vehicleEntry`、`vehicleAppear`、`obtainVehicleLicense` |
| 文件位置 | `frontend/src/view/parking/entryExit.vue` |
| 路由 | 后端菜单表中新增记录，前端通过动态路由自动加载 |

### 后端

无需修改。已有 API 全部就绪：
- `VehicleEntry` / `VehicleExit` handler 在 `internal/api/v1/vehicle/vehicle.go`
- 计费逻辑在 `internal/service/vehicle/vehicle.go` 的 `calculateFee()`
- `PassageService` 已抽取公共逻辑（`internal/service/parking/passage.go`）

### 涉及文件变更

| 文件 | 操作 | 说明 |
|------|------|------|
| `frontend/src/view/parking/entryExit.vue` | 新增 | 进出场操作页面 |
| `frontend/src/api/vehicle.js` | 不改 | 已有 entry/exit API |
| `internal/initialize/seed.go` | 修改 | 新增菜单记录 + Casbin 规则 |
| 后端其他文件 | 不改 | API 已就绪 |

## 7. 边界情况

| 场景 | 处理方式 |
|------|---------|
| 输入为空时点查询 | 前端校验，至少填一个（车牌或 RFID） |
| 车牌和 RFID 都填 | 优先用车牌号查询 |
| 查到的车辆已进场 | 进场 Tab：提示"车辆已入场，请切换到出场"；出场 Tab：正常显示费用 |
| 查到的车辆不在场内 | 进场 Tab：允许入场；出场 Tab：提示"车辆不在场内" |
| 车辆不存在（新临时车） | 进场 Tab：自动创建临时车记录后入场；出场 Tab：提示未找到 |
| 未选停车场点确认进场 | 前端校验，提示"请选择停车场" |
| API 调用失败 | 显示后端返回的错误信息 |

## 8. 后续扩展预留

- **关联 UHF 实时扫描**：页面预留"最近扫描"区域，显示 `DeviceManager` 推送的标签列表，点击自动填入
- **收费方式**：当前写死现金，后续对接 P0-3 收费模块后，支持扫码/免密
- **抓拍图片**：`VehicleEntry`/`VehicleExit` 已有 `EntryImage`/`ExitImage` 字段，页面后续可加拍照上传
