1 车辆管理页
▶
2 拍摄引导
▶
3 预览确认
▶
4 回填上传
*行驶证主页
+ 引导拍摄
*行驶证副页
+ 引导拍摄
*行驶证车辆照片
+ 引导拍摄
*车头照
+
车牌号
（OCR自动回填）
车辆类别
请选择
请将车辆对准取景框
从卡套内拿出，避免反光
车辆照片
四角入框
平放正向
避免反光
点击拍照
原型说明 — 调度App H5行驶证拍摄取景引导（基于现有流程改造）
交互流程
设计规范
流程对接
业务规则
点击左侧手机中"行驶证主页"上传槽位，即可体验完整流程：车辆管理页 → 拍摄引导页 → 预览确认 → 回填上传。

#### 第1步：车辆管理页（现有页面）

- 页面为现有的 `vehicleAdd.vue`，展示行驶证三个上传槽位
- 行驶证槽位标注蓝色"引导拍摄"角标，表示点击后会进入拍摄引导
- 车头照槽位无角标，点击后保持现有 `van-uploader` 直接调起系统选择器的逻辑

#### 第2步：拍摄引导页（新增）

- 点击行驶证槽位 → 拦截 `van-uploader` 默认行为 → 进入拍摄引导页
- 底层为 WebRTC `getUserMedia` 相机预览（原型中为模拟背景）
- 叠加半透明遮罩 + 镂空引导框（约 1.43:1 横向比例）
- 四角 L 形青色角标辅助对齐证件边缘
- 引导框内叠加证件模板轮廓（半透明）：标题位置、照片区域、信息区域、印章位置，帮助用户确认证件方向和位置
- 三种页面展示不同模板：主页（标题+分隔线+照片位+信息区+底部日期区+左下印章）、副页（三栏字段+检验记录+条形码）、车辆照片（车辆轮廓）
- 上方提示："请将行驶证从卡套内取出后拍摄，避免反光"
- 下方提示："请将证件对准框内，确保边缘完整、文字清晰"
- 点击底部白色圆形"拍摄"按钮 → 捕获画面

#### 第3步：预览确认页（新增）

- 展示刚拍摄的照片
- 重拍：返回拍摄引导页重新拍摄
- 确认使用：将照片传回现有流程

#### 第4步：回填上传（现有流程，完全不变）

- 确认使用后，构造 `{ file: File, content: dataURL }` 对象
- 传入现有的 `after-read` Handler（如 `vehicleLicenseFrontHandler`）
- → `compressFileItem()` 压缩
- → `uploadImage()` 上传（`POST /order/uploadImage`）
- → `ocrHandler()` OCR 识别（`POST /agg-api/tencent-ocr/unifiedOCR`）
- → 回填表单字段（车牌号、车架号等）
- 槽位显示拍摄的照片缩略图

#### 三页差异化（标题+模板不同）

- 行驶证主页：标题"拍摄行驶证主页" → 极简模板：标题+分隔线+左侧照片位+右侧信息区+底部日期区+左下印章 → 对应 `vehicleLicenseFrontHandler`
- 行驶证副页：标题"拍摄行驶证副页" → 模板：三栏字段（号牌号码/核定载人数/整备质量 + 档案编号/总质量 + 检验记录）+条形码 → 对应 `vehicleLicenseBackHandler`
- 行驶证车辆照片：标题"拍摄行驶证车辆照片" → 模板：车辆SVG轮廓 → 对应 `vehicleLicenseCarHandler`

#### 引导框规格

项目 | 规格
--- | ---
引导框宽高比 | 约 1.43:1（横向，匹配行驶证实物比例）
引导框宽度 | 占屏幕宽度的 80%（约 300px @375px屏）
遮罩透明度 | rgba(0,0,0,0.55)（约55%黑色）
遮罩实现方式 | box-shadow: 0 0 0 9999px rgba(0,0,0,0.55)
角标颜色 | #4fc3f7（浅青色，高对比度）
角标粗细 | 3px solid
角标尺寸 | 22px × 22px
提示文字颜色 | #fff（白色）
提示文字阴影 | 0 1px 4px rgba(0,0,0,0.6)
拍摄按钮 | 72px 圆环，4px白边，中心58px白点
证件模板叠层 | 引导框内叠加行驶证轮廓（标题/字段/印章），透明度约20%-35%
主页模板 | 极简：标题+分隔线+左侧照片位+右侧信息区+底部日期区+左下印章（不展示具体字段标签）
副页模板 | 标题+三栏字段（号牌/载人数/质量 + 档案编号/总质量 + 检验记录）+条形码
车辆照片模板 | 车辆SVG轮廓（车身/车窗/车轮），引导居中拍摄

#### 屏幕适配

- 320px - 430px 宽度范围自适应缩放
- 竖屏：引导框为横向矩形（行驶证横向放置）
- 横屏：引导框自适应为纵向矩形（可选适配）
- 提示文字自动换行，不截断
- 底部拍摄按钮始终在安全区域内（避开 Home 指示条）

#### 降级方案

若设备不支持 `getUserMedia`（部分低版本 Android WebView 或非 HTTPS 环境）：
→ 降级为 `van-uploader` 直接调起系统选择器
→ 不展示引导框
→ 后续压缩→上传→OCR流程正常执行

#### 现有代码流程（改造前）

van-uploader 点击 │ ▼ 系统选择器（accept="image/*"） │ ▼ after-read 回调 │ vehicleLicenseFrontHandler() │ vehicleLicenseBackHandler() │ vehicleLicenseCarHandler() ▼ compressFileItem() ← 前端压缩 │ ▼ uploadImage() ← POST /order/uploadImage │ ▼ ocrHandler() ← POST /agg-api/.../unifiedOCR │ ▼ 回填表单字段

#### 改造后流程

van-uploader 点击（行驶证槽位） │ ▼ ← 新增：拦截点击 拍摄引导页（CameraGuide.vue） │ · WebRTC getUserMedia 相机预览 │ · 半透明遮罩 + 引导框 + 角标 │ · 文字提示 ▼ 点击拍摄 → Canvas 捕获帧 │ ▼ ← 新增：预览确认 预览确认页 │ · 重拍 → 返回拍摄引导页 │ · 确认使用 ↓ ▼ 构造 { file: File, content: dataURL } │ ▼ ← 传入现有 Handler vehicleLicenseFrontHandler(file) │ ▼ ── 以下流程完全不变 ── compressFileItem() ← 前端压缩 │ ▼ uploadImage() ← POST /order/uploadImage │ ▼ ocrHandler() ← POST /agg-api/.../unifiedOCR │ ▼ 回填表单字段

核心改造点：拍摄确认后，将 Canvas 捕获的 Blob 构造为 `{ file: File, content: dataURL }` 格式，调用对应槽位的现有 Handler 方法。后续 `compressFileItem` → `uploadImage` → `ocrHandler` 链路完全复用，零改动。

#### 涉及文件

文件 | 变更
--- | ---
`vehicleAdd.vue` | 改造：行驶证三个槽位增加点击拦截
`CameraGuide.vue` | 新增：拍摄引导+预览确认组件
`mine.js` | 不变：uploadImage / ocrHandler
后端 | 不变

#### 触发规则

- 仅行驶证三个槽位（主页/副页/车辆照片）进入拍摄引导页
- 车头照、保单等其他槽位保持现有 `van-uploader` 直接调起选择器逻辑
- 首次上传和重新上传均触发引导页
- 修改车辆时重新上传行驶证同样进入引导页

#### 拍摄规则

- 引导框仅做视觉辅助，不强制拦截拍摄
- 用户未对准引导框也可点击拍摄，进入预览后可重拍
- 拍摄后仍走原有压缩 → 上传 → OCR识别流程

#### 降级规则

- 设备不支持 `getUserMedia` → 降级为 `van-uploader` 系统选择器
- iOS 微信内置浏览器权限受限 → 降级为系统选择器
- 降级后引导框不展示，用户走原有流程
- 降级后压缩→上传→OCR流程正常

#### 权限规则

- 进入拍摄引导页前检测相机权限
- 未授权时提示用户开启权限，并提供"从相册选择"降级入口

核心原则：引导框是"辅助提示"而非"强制校验"，目标是提升照片质量，而非增加用户操作门槛。所有拦截和校验仍由后端OCR完成。后续的上传和OCR流程完全不变。