AML/docs/KYC/Scanner/Scanner_Integration.md

311 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 扫描仪集成分析
## 前端扫描仪架构
```
ViewerScanModalComponent (UI组件)
PassportService (扫描服务层)
PassportReader.js (扫描仪SDK/驱动 - 位于 assets/js/)
WebSocket 连接
```
## 当前实现的 PassportReader.js
### WebSocket 连接
- **地址**: `ws://127.0.0.1:90`
- **消息协议**: JSON
### 请求格式
```javascript
{ Type: "Request", Command: "Get/Set", Operand: "OnLineStatus", Param: "True/False" }
{ Type: "Notify", Command: "Trigger", Operand: "ManualRecog", Param: "2" }
```
### 响应格式
```javascript
{ Type: "Notify", Operand: "CardContentText", Param: { ... } } // 文字结果
{ Type: "Notify", Operand: "Images", Param: { ... } } // 图片结果
{ Type: "Reply", Command: "Get", Operand: "OnLineStatus", Succeeded: "Y/N" }
```
---
## 第二款SDK: DKePassport (智能读证终端)
### WebSocket 连接
- **地址**: `ws://127.0.0.1:9090`
- **消息协议**: JSON
### 请求格式
```javascript
{ "command": "get", "operand": "name" } // 获取设备名称
{ "command": "set", "operand": "auto", "param": 1 } // 设置自动模式
{ "command": "scan", "param": "{\"timeout\":5}" } // 扫描证件
{ "command": "getPhoto", "param": 5 } // 获取照片
```
### 响应格式
```javascript
{
"data": {
"guestType": "100", // 旅客类型
"name": "张三", // 姓名
"sex": "1", // 性别
"birthday": "1990-01-01", // 出生日期
"cardType": "11", // 证件类型
"cardNo": "123456789012345678", // 证件号码
"nation": "01", // 民族
"nationalityArea": "CHN", // 国籍/地区
"curPhoto": "base64...", // 证件头像
"photo": "base64...", // 现场头像
...
}
}
```
### 支持的命令
| command | operand/param | 说明 |
|---------|----------------|------|
| get | name | 获取设备名称 |
| get | serialNo | 获取序列号 |
| get | model | 获取型号 |
| get | type | 获取类型 |
| set | auto=1 | 设置自动模式 |
| set | timeout=5 | 设置超时 |
| scan | timeout=5 | 扫描证件 |
| read | 5 | 读取数据 |
| readCode | 5 | 读取条码 |
| getPhoto | 5 | 获取照片 |
| scanRaw | - | 高级扫描 |
### 证件类型映射 (cardType)
```javascript
// 国内旅客
'11': '身份证'
'12': '居住证'
'13': '户口本'
'55': '港澳台居民居住证'
'93': '国内护照'
'95': '港澳通行证'
// 港澳台旅客
'16': '台湾居民来往大陆通行证'
'60': '港澳居民来往内地通行证'
// 国外旅客
'14': '国外护照'
'34': '外国人永久居留身份证'
```
### 旅客类型映射 (guestType)
```javascript
'100': '国内旅客'
'200': '港澳台旅客'
'300': '国外旅客'
```
## 关键差异对比
| 项目 | 当前SDK (Sinosecu) | 新SDK (DKePassport) |
|------|-------------------|---------------------|
| WebSocket端口 | 90 | 9090 |
| 请求格式 | `{Type, Command, Operand, Param}` | `{command, operand, param}` |
| 响应格式 | `{Type, Operand, Param}` | `{data: {...}}` |
| 图片字段 | `Param` (通过 onImageResult) | `curPhoto`, `photo` (在data内) |
| 触发扫描 | `triggerManualRead()` | `scan` 命令 |
## 替换影响分析
### 情况新SDK (DKePassport) 替代当前SDK
**需要修改的文件**:
| 文件 | 改动程度 | 说明 |
|------|----------|------|
| `assets/js/PassportReader.js` | **完全重写** | 新SDK命令格式完全不同 |
| `passport.service.ts` | **需要调整** | 回调适配新响应格式 |
| `viewer-scan-modal.component.ts` | **大概率不变** | UI逻辑不变 |
| 后端 | **大概率不变** | 前端传过来的数据格式需确认 |
### 适配层设计建议
为了最小化改动,建议创建适配层:
```javascript
// 新的 DKePassportReader.js
export class DKePassportReader {
constructor(options = {}) {
this.host = options.host || "ws://127.0.0.1:9090"
// ... 新SDK实现
}
// 适配现有接口
connect() {
// WebSocket连接
}
setParameter(param, value) {
// 转换: VIZ -> auto, RFID -> ?
}
onTextResult(data) {
// 将新格式转换为旧格式
}
onImageResult(images) {
// 从 data.curPhoto 获取图片
}
}
```
### PassportService 接口兼容方案
新SDK需要适配 `passport.service.ts` 的期望接口:
```typescript
// passport.service.ts 期望的接口
passportReader.onTextResult = (result) => { ... }
passportReader.onImageResult = (images) => { ... }
```
需要 `DKePassportReader` 在收到 `{data: {...}}` 时:
1.`data` 解析为符合现有期望的格式
2. 触发 `onTextResult``onImageResult` 回调
## 建议实施步骤
1. **创建新文件**: `assets/js/DKePassportReader.js`
2. **实现适配层**: 将DKePassport响应格式转换为现有格式
3. **修改 `passport.service.ts`**: 使用新Reader类
4. **测试**: 验证扫描流程完整性
## 相关文件路径
### 前端
| 文件 | 说明 |
|------|------|
| `AML_Frontend/src/assets/js/PassportReader.js` | 当前扫描仪SDK |
| `AML_Frontend/src/app/components/components-viewer/viewer-scan-modal/viewer-scan-modal.component.ts` | 扫描弹窗UI |
| `AML_Frontend/src/app/components/components-viewer/viewer-scan-modal/services/passport.service.ts` | 扫描服务层 |
| `AML_Frontend/src/app/modules/configuration/components/set-scan/set-scan.component.ts` | 扫描设置组件 |
### 新SDK参考
| 文件 | 说明 |
|------|------|
| `docs/KYC/Scanner/DKePassport-release-1.3.0/智能读证终端网页.html` | DKePassport SDK演示页面 |
## 版本信息
**文档版本**: v1.2
**创建日期**: 2026-04-30
**更新日期**: 2026-04-30
---
## 后端配置映射说明
### 扫描仪数据流向
```
扫描仪硬件 (返回特定格式的数据)
CertificateMappings/*.json (定义 ScanerMainCertificateCode 等硬件指令码)
appsettings.json - KYCConfig (定义 XiangyunAPI OCR映射 和 CertificateEntityColumParseRules 字段解析规则)
后端 KYCService 处理
```
### 关键配置文件
#### 1. CertificateMappings/*.json
定义每种证件类型的字段映射:
| 字段 | 说明 |
|------|------|
| `ScanerMainCertificateCode` | 扫描仪主证件类型代码 (如 "2"=身份证正面) |
| `ScanerBackCertificateCode` | 扫描仪背面证件类型代码 |
| `OCRCode` / `OCRCodeBack` | 祥云OCR API的证件类型代码 |
| `Columns[].VIZ` | 视读区字段名 |
| `Columns[].MRZ` | 机读码字段名 |
| `Columns[].OCR` | OCR识别字段名 |
| `Columns[].RFID` | 芯片读取字段名 |
#### 2. appsettings.json - KYCConfig
**CertificateEntityColumParseRules** - 字段解析规则:
```json
{
"AMLCode": "*",
"EntityColumn": "Name",
"EntityColumnNames": [ "姓名", "本国姓名", "名称", "Name", "name" ]
}
```
将扫描仪返回的原始字段名映射到系统标准字段名。
**XiangyunAPI.CertificateCodeMappings** - OCR映射
```json
{
"AMLCode": "IDCard_CHN",
"OCRCode": "2",
"Remark": "二代身份证正面"
}
```
### 当前扫描仪字段来源
| 字段来源 | 说明 |
|---------|------|
| `VIZ` | 视读区 (Visual Inspection Zone) |
| `MRZ` | 机读码 (Machine Readable Zone) |
| `OCR` | OCR识别结果 (通过祥云API) |
| `RFID` | 芯片读取数据 |
### 新SDK (DKePassport) 返回的字段名
根据演示页面DKePassport返回字段包括
- `name`, `sex`, `birthday`, `cardType`, `cardNo`, `nation`, `nationalityArea`
- `curPhoto`, `photo` (Base64图片)
- `guestType`, `adminDivision`, `address`
### 换扫描仪后的配置修改
| 配置项 | 当前位置 | 需要修改的内容 |
|--------|----------|---------------|
| 扫描仪指令码 | `CertificateMappings/*.json``ScanerMainCertificateCode` | **这套配置是给当前扫描仪用的,新扫描仪可能不需要或需要重新映射** |
| 字段解析规则 | `appsettings.json``CertificateEntityColumParseRules` | `EntityColumnNames` 需要对应新SDK返回的字段名 |
| OCR映射 | `appsettings.json``XiangyunAPI.CertificateCodeMappings` | AMLCode/OCRCode 可能需要调整 |
### 证件类型代码对比
| 证件类型 | 当前SDK (Sinosecu) | 新SDK (DKePassport) |
|---------|-------------------|---------------------|
| 身份证正面 | `2` | `11` |
| 身份证背面 | `3` | - |
| 护照 | `13` | `14` (国外护照) |
| 港澳居民来往内地通行证-照片页 | `14` | `60` |
| 港澳居民来往内地通行证-机读码页 | `15` | - |
### 注意事项
1. **DKePassport的 `cardType` 代码体系**与当前的 `ScanerMainCertificateCode` 不同
2. 新SDK返回的字段名`name`, `cardNo`)与当前系统期望的字段名(如 `Name`, `Number`)需要通过 `CertificateEntityColumParseRules` 映射
3. 如果DKePassport不提供MRZ/RFID区分可能需要调整 `Columns` 中的字段映射策略