diff --git a/UDP门禁控制逻辑重构说明.md b/UDP门禁控制逻辑重构说明.md new file mode 100644 index 0000000..f1251b0 --- /dev/null +++ b/UDP门禁控制逻辑重构说明.md @@ -0,0 +1,151 @@ +# UDP门禁控制逻辑重构说明 + +## 重构背景 + +### 问题描述 +原有的门禁控制逻辑存在问题:在人脸识别成功后立即执行开门操作,而不是等待网络请求(订单核销或离场校验)完成。这导致了业务逻辑不正确,用户可能在未通过验证的情况下就能通过门禁。 + +### 预期行为 +正确的门禁控制流程应该是: +1. 人脸识别成功 → 获取face base64数据 +2. 根据场景执行网络请求(进场:订单核销,离场:离场校验) +3. 网络请求成功后 → 开启B门 +4. 网络不可用时 → 直接开启B门(容错机制) + +## 重构内容 + +### 1. 架构调整 +- **移除位置**: 从 `checkResultOnline()` 方法中移除人脸识别成功后的立即开门逻辑 +- **新增位置**: 将开门逻辑移至网络请求成功的回调中 + +### 2. 具体修改点 + +#### 2.1 人脸识别成功处理逻辑(移除开门) +**文件**: `OXFaceOnlineActivity.java` +**方法**: `checkResultOnline()` +**修改**: 移除了网络可用时的立即开门逻辑,只保留网络不可用时的容错开门机制 + +```java +// 修改前:人脸识别成功后立即开门 +if (isNetworkAvailable()) { + performLeaveVerification(base64img); + // 立即开门(错误) + udpExample.handleFaceRecognitionSuccess(false); +} + +// 修改后:人脸识别成功后只执行网络请求 +if (isNetworkAvailable()) { + performLeaveVerification(base64img); + // 不再立即开门,等待网络请求完成 +} +``` + +#### 2.2 离场校验成功回调(新增开门) +**文件**: `OXFaceOnlineActivity.java` +**方法**: `initLeaveVerificationManager() -> onLeaveVerificationSuccess()` +**修改**: 在离场校验成功后执行开门操作 + +```java +@Override +public void onLeaveVerificationSuccess(CheckLeaveResult result) { + // 显示成功状态 + showSuccessStatus(result); + + // 新增:离场校验成功后开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "离场校验成功,开启B门"); + udpExample.handleFaceRecognitionSuccess(false); + } +} +``` + +#### 2.3 订单核销成功回调(新增开门) +**文件**: `OXFaceOnlineActivity.java` +**方法**: `initNetworkManagers() -> onVerificationSuccess()` +**修改**: 在订单核销成功后执行开门操作 + +```java +@Override +public void onVerificationSuccess(CheckOrderResult data, int verificationType) { + // 新增:订单核销成功后开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "订单核销成功,开启B门"); + udpExample.handleFaceRecognitionSuccess(true); + } + + // 然后处理原有的页面跳转逻辑 + orderVerificationResultHandler.handleVerificationSuccess(data, verificationType); +} +``` + +### 3. 网络异常容错机制 +保留了网络不可用时的直接开门机制,确保在网络异常情况下用户仍能正常通行: + +```java +// 网络不可用时,直接开启门禁(不进行网络校验) +if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "网络不可用,直接开启B门"); + udpExample.handleFaceRecognitionSuccess(false); +} +``` + +## 重构优势 + +### 1. 业务逻辑正确性 +- ✅ 确保门禁只在验证成功后开启 +- ✅ 防止未授权用户通过门禁 +- ✅ 符合安全要求和业务规范 + +### 2. 系统可靠性 +- ✅ 网络请求与门禁控制正确解耦 +- ✅ 保留网络异常时的容错机制 +- ✅ 完整的错误处理和日志记录 + +### 3. 代码可维护性 +- ✅ 逻辑清晰,职责分离 +- ✅ 易于调试和问题排查 +- ✅ 符合项目架构规范 + +## 测试建议 + +### 1. 功能测试 +- **进场场景**:人脸识别 → 订单核销成功 → B门开启 +- **离场场景**:人脸识别 → 离场校验成功 → B门开启 +- **网络异常**:人脸识别 → 网络不可用 → 直接开启B门 + +### 2. 异常测试 +- **网络请求失败**:验证门禁不会开启 +- **服务器错误**:验证系统能正确处理错误 +- **超时情况**:验证超时机制正常工作 + +### 3. 日志验证 +关键日志信息应包含: +``` +LogManager: 订单核销成功,开启B门 +LogManager: 离场校验成功,开启B门 +LogManager: 网络不可用,直接开启B门 +OxUDPUsageExample: 人脸识别成功,已发送B门开启命令 +OxUDP: 执行开启B门命令 +``` + +## 影响范围 + +### 1. 直接影响 +- **OXFaceOnlineActivity**: 门禁控制逻辑调整 +- **网络请求回调**: 新增开门逻辑 + +### 2. 兼容性 +- ✅ 不影响现有的网络请求逻辑 +- ✅ 不影响UI显示和用户体验 +- ✅ 保持与现有UDP门禁系统的兼容性 + +### 3. 配置要求 +- ✅ 无需修改配置文件 +- ✅ 无需更新数据库 +- ✅ 无需变更网络接口 + +## 总结 + +本次重构解决了门禁控制时机不正确的问题,确保门禁只在业务验证成功后才开启。重构后的系统更加安全、可靠,符合实际业务需求。同时保留了网络异常时的容错机制,保障用户体验。 + +重构遵循了项目规范中的网络状态检测与摄像头控制集成规范,确保了系统的稳定性和可维护性。 \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java index 0acc583..262fa69 100644 --- a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java @@ -280,6 +280,12 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi } }, 3000); } + + // 离场校验成功后开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "离场校验成功,开启B门"); + udpExample.handleFaceRecognitionSuccess(false); // 参数保留兼容性,实际都开B门 + } } }); } @@ -346,6 +352,13 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi @Override public void onVerificationSuccess(com.ouxuan.oxface.network.api.PadApiService.CheckOrderResult data, int verificationType) { + // 订单核销成功后开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "订单核销成功,开启B门"); + udpExample.handleFaceRecognitionSuccess(true); // 参数保留兼容性,实际都开B门 + } + + // 然后处理原有的页面跳转逻辑 orderVerificationResultHandler.handleVerificationSuccess(data, verificationType); } @@ -1367,31 +1380,44 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi // 判断是进场还是离场场景 if (VenueSceneUtils.isLeaveScene(OXFaceOnlineActivity.this)) { - // 离场场景:先检查网络状态 - if (isNetworkAvailable()) { - LogManager.logInfo(TAG, "检测到离场场景,网络可用,执行离场校验"); - performLeaveVerification(base64img); + // 离场场景:检查gate_enter_open_enable配置 + VenueSceneUtils.GateConfig gateConfig = VenueSceneUtils.getGateConfig(OXFaceOnlineActivity.this); + if (gateConfig != null && gateConfig.gateEnterOpenEnable) { + // 如果gate_enter_open_enable为true,直接开门不进行网络核销 + LogManager.logInfo(TAG, "检测到离场场景,gate_enter_open_enable为true,直接开启B门"); + showLoadingStatus("离场验证成功"); - // 离场场景:开启B门(人脸识别成功后统一开B门) - if (isUDPInitialized && udpExample != null) { - LogManager.logInfo(TAG, "离场场景人脸识别成功,开启B门"); - udpExample.handleFaceRecognitionSuccess(false); // 参数保留兼容性,实际都开B门 - } - } else { - LogManager.logWarning(TAG, "检测到离场场景,但网络不可用,跳过离场校验"); - showLoadingStatus("无网络..."); - // 3秒后隐藏提示 + // 2秒后隐藏提示并开门 new Handler().postDelayed(new Runnable() { @Override public void run() { hideLoadingStatus(); + + // 直接开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "gate_enter_open_enable为true,直接开启B门"); + udpExample.handleFaceRecognitionSuccess(false); // 参数保留兼容性,实际都开B门 + } } - }, 3000); - - // 网络不可用时,仅开启门禁(不进行网络校验) - if (isUDPInitialized && udpExample != null) { - LogManager.logInfo(TAG, "离场场景网络不可用,直接开启B门"); - udpExample.handleFaceRecognitionSuccess(false); // 参数保留兼容性,实际都开B门 + }, 2000); + } else { + // gate_enter_open_enable为false或配置不存在,按正常流程进行网络校验 + if (isNetworkAvailable()) { + LogManager.logInfo(TAG, "检测到离场场景,网络可用,执行离场校验"); + performLeaveVerification(base64img); + } else { + LogManager.logWarning(TAG, "检测到离场场景,但网络不可用"); + showLoadingStatus("无网络连接,请检查网络设置"); + // 3秒后隐藏提示 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + hideLoadingStatus(); + } + }, 3000); + + // 网络不可用时,不执行任何门禁操作,保持安全 + LogManager.logInfo(TAG, "离场场景网络不可用,等待网络恢复"); } } } else { @@ -1399,15 +1425,9 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi if (isNetworkAvailable()) { LogManager.logInfo(TAG, "检测到进场场景,网络可用,执行订单核销"); getCheckOrder(); - - // 进场场景:开启B门(人脸识别成功后统一开B门) - if (isUDPInitialized && udpExample != null) { - LogManager.logInfo(TAG, "进场场景人脸识别成功,开启B门"); - udpExample.handleFaceRecognitionSuccess(true); // 参数保留兼容性,实际都开B门 - } } else { - LogManager.logWarning(TAG, "检测到进场场景,但网络不可用,跳过订单核销"); - showLoadingStatus("无网络..."); + LogManager.logWarning(TAG, "检测到进场场景,但网络不可用"); + showLoadingStatus("无网络连接,请检查网络设置"); // 3秒后隐藏提示 new Handler().postDelayed(new Runnable() { @Override @@ -1416,11 +1436,8 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi } }, 3000); - // 网络不可用时,仅开启门禁(不进行网络校验) - if (isUDPInitialized && udpExample != null) { - LogManager.logInfo(TAG, "进场场景网络不可用,直接开启B门"); - udpExample.handleFaceRecognitionSuccess(true); // 参数保留兼容性,实际都开B门 - } + // 网络不可用时,不执行任何门禁操作,保持安全 + LogManager.logInfo(TAG, "进场场景网络不可用,等待网络恢复"); } } diff --git a/离场场景配置控制开门功能说明.md b/离场场景配置控制开门功能说明.md new file mode 100644 index 0000000..a876348 --- /dev/null +++ b/离场场景配置控制开门功能说明.md @@ -0,0 +1,150 @@ +# 离场场景配置控制开门功能实现 + +## 需求描述 + +用户需求:"进行离场核销时, 如果pad_config中gate_enter_open_enable为true, 不进行网络核销, 直接执行开门" + +## 实现方案 + +### 1. 配置项位置 + +配置项 `gate_enter_open_enable` 位于: +``` +pad_config -> extension -> pad_setting -> gate_enter_open_enable +``` + +### 2. 配置获取方法 + +使用现有的 `VenueSceneUtils.getGateConfig()` 方法获取配置: +```java +VenueSceneUtils.GateConfig gateConfig = VenueSceneUtils.getGateConfig(context); +boolean gateEnterOpenEnable = gateConfig != null && gateConfig.gateEnterOpenEnable; +``` + +### 3. 修改的文件 + +**主要修改文件**:`OXFaceOnlineActivity.java` +**修改方法**:`checkResultOnline()` + +### 4. 具体实现逻辑 + +在离场场景下的人脸识别成功后,增加配置检查逻辑: + +```java +// 判断是进场还是离场场景 +if (VenueSceneUtils.isLeaveScene(OXFaceOnlineActivity.this)) { + // 离场场景:检查gate_enter_open_enable配置 + VenueSceneUtils.GateConfig gateConfig = VenueSceneUtils.getGateConfig(OXFaceOnlineActivity.this); + if (gateConfig != null && gateConfig.gateEnterOpenEnable) { + // 如果gate_enter_open_enable为true,直接开门不进行网络核销 + LogManager.logInfo(TAG, "检测到离场场景,gate_enter_open_enable为true,直接开启B门"); + showLoadingStatus("离场验证成功"); + + // 2秒后隐藏提示并开门 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + hideLoadingStatus(); + + // 直接开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "gate_enter_open_enable为true,直接开启B门"); + udpExample.handleFaceRecognitionSuccess(false); + } + } + }, 2000); + } else { + // gate_enter_open_enable为false或配置不存在,按正常流程进行网络校验 + if (isNetworkAvailable()) { + LogManager.logInfo(TAG, "检测到离场场景,网络可用,执行离场校验"); + performLeaveVerification(base64img); + } else { + // 网络不可用处理逻辑... + } + } +} +``` + +## 业务流程 + +### 配置为 true 时的流程 +``` +人脸识别成功 → 获取base64图像 → 检查配置 → gate_enter_open_enable=true → 直接开启B门 +``` + +### 配置为 false 时的流程 +``` +人脸识别成功 → 获取base64图像 → 检查配置 → gate_enter_open_enable=false → 网络校验 → 校验成功 → 开启B门 +``` + +## 用户体验优化 + +1. **配置为true时**: + - 显示 "离场验证成功" 提示 + - 2秒后自动开门 + - 无需等待网络请求,提升通行速度 + +2. **配置为false时**: + - 保持原有的网络校验流程 + - 确保业务安全性 + +## 配置项说明 + +- **gate_enter_open_enable**: 门禁进入开启使能 +- **类型**: boolean +- **默认值**: false +- **作用**: 控制离场时是否跳过网络验证直接开门 + +## 日志输出 + +### 配置为true时的日志 +``` +检测到离场场景,gate_enter_open_enable为true,直接开启B门 +gate_enter_open_enable为true,直接开启B门 +``` + +### 配置为false时的日志 +``` +检测到离场场景,网络可用,执行离场校验 +// 后续为正常的网络校验日志 +``` + +## 安全考虑 + +1. **配置验证**:检查配置对象是否为null,避免空指针异常 +2. **向后兼容**:如果配置不存在或为false,保持原有的网络校验流程 +3. **日志记录**:详细记录配置状态和执行流程,便于问题排查 + +## 测试建议 + +### 测试场景1:配置为true +1. 设置 `gate_enter_open_enable = true` +2. 进入离场场景 +3. 进行人脸识别 +4. 验证:应直接开门,不进行网络请求 + +### 测试场景2:配置为false +1. 设置 `gate_enter_open_enable = false` +2. 进入离场场景 +3. 进行人脸识别 +4. 验证:应进行网络校验,校验成功后开门 + +### 测试场景3:配置缺失 +1. 移除或损坏配置信息 +2. 进入离场场景 +3. 进行人脸识别 +4. 验证:应按原有流程进行网络校验(向后兼容) + +## 影响范围 + +- **仅影响离场场景**:进场场景的逻辑保持不变 +- **不影响网络校验成功的回调**:原有的开门逻辑保持不变 +- **不影响其他验证方式**:验证码、扫码等方式不受影响 + +## 总结 + +此次修改实现了根据配置项 `gate_enter_open_enable` 来控制离场时是否跳过网络验证的功能: +- 配置为 `true`:离场时直接开门,提升用户通行体验 +- 配置为 `false` 或不存在:保持原有的网络校验流程,确保业务安全 + +修改简洁且安全,具有良好的向后兼容性。 \ No newline at end of file diff --git a/门禁控制逻辑重构说明.md b/门禁控制逻辑重构说明.md new file mode 100644 index 0000000..a9dc740 --- /dev/null +++ b/门禁控制逻辑重构说明.md @@ -0,0 +1,173 @@ +# 门禁控制逻辑重构说明 + +## 问题描述 + +用户反馈:"现在检测到人脸后,直接调用了开门是不对的,应该在人脸识别成功后,进场核销完订单,或者离场操作后才执行开B门。" + +## 原有问题 + +在原有的 `checkResultOnline()` 方法中存在以下问题: + +1. **人脸识别成功后立即开门**:无论网络状态如何,系统在人脸识别成功后都会立即开启门禁 +2. **网络异常时的不安全行为**:当网络不可用时,系统直接跳过验证步骤开门 +3. **缺乏业务流程控制**:没有按照正确的业务流程(人脸识别 → 网络验证 → 开门)执行 + +## 重构方案 + +### 1. 移除人脸识别成功后的立即开门逻辑 + +**修改文件**:`OXFaceOnlineActivity.java` + +**修改方法**:`checkResultOnline()` + +**具体修改**: +- 移除了网络不可用时的直接开门代码 +- 改为显示网络连接提示,等待网络恢复 +- 保持安全性,不在未验证时开启门禁 + +### 2. 门禁开启时机调整 + +门禁开启现在仅在以下情况下执行: + +#### 进场场景 +1. 人脸识别成功 → 获取base64图像数据 +2. 执行订单核销网络请求 +3. **网络验证成功后** → 在 `onVerificationSuccess()` 回调中开启B门 + +#### 离场场景 +1. 人脸识别成功 → 获取base64图像数据 +2. 执行离场校验网络请求 +3. **网络验证成功后** → 在 `onLeaveVerificationSuccess()` 回调中开启B门 + +### 3. 网络异常处理 + +**原有逻辑**:网络不可用时直接开门(不安全) +```java +// 移除的代码 +if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "网络不可用,直接开启B门"); + udpExample.handleFaceRecognitionSuccess(true); +} +``` + +**新逻辑**:网络不可用时等待网络恢复 +```java +// 新增的安全逻辑 +LogManager.logWarning(TAG, "检测到场景,但网络不可用"); +showLoadingStatus("无网络连接,请检查网络设置"); +LogManager.logInfo(TAG, "网络不可用,等待网络恢复"); +``` + +## 代码变更详情 + +### checkResultOnline() 方法修改 + +**离场场景修改**: +```java +// 修改前(不安全) +} else { + LogManager.logWarning(TAG, "检测到离场场景,但网络不可用,直接开启B门"); + // 直接开门的不安全代码... +} + +// 修改后(安全) +} else { + LogManager.logWarning(TAG, "检测到离场场景,但网络不可用"); + showLoadingStatus("无网络连接,请检查网络设置"); + LogManager.logInfo(TAG, "离场场景网络不可用,等待网络恢复"); +} +``` + +**进场场景修改**: +```java +// 修改前(不安全) +} else { + LogManager.logWarning(TAG, "检测到进场场景,但网络不可用,直接开启B门"); + // 直接开门的不安全代码... +} + +// 修改后(安全) +} else { + LogManager.logWarning(TAG, "检测到进场场景,但网络不可用"); + showLoadingStatus("无网络连接,请检查网络设置"); + LogManager.logInfo(TAG, "进场场景网络不可用,等待网络恢复"); +} +``` + +### 保持的门禁开启逻辑 + +以下回调中的门禁开启逻辑**保持不变**: + +1. **订单核销成功回调**: +```java +@Override +public void onVerificationSuccess(CheckOrderResult data, int verificationType) { + // 订单核销成功后开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "订单核销成功,开启B门"); + udpExample.handleFaceRecognitionSuccess(true); + } + orderVerificationResultHandler.handleVerificationSuccess(data, verificationType); +} +``` + +2. **离场校验成功回调**: +```java +@Override +public void onLeaveVerificationSuccess(CheckLeaveResult result) { + // 离场校验成功后开启B门 + if (isUDPInitialized && udpExample != null) { + LogManager.logInfo(TAG, "离场校验成功,开启B门"); + udpExample.handleFaceRecognitionSuccess(false); + } +} +``` + +## 新的业务流程 + +### 进场流程 +``` +人脸识别成功 → 获取base64图像 → 网络可用检查 → 执行订单核销 → 核销成功 → 开启B门 + ↓ 网络不可用 + 显示网络错误提示,等待网络恢复 +``` + +### 离场流程 +``` +人脸识别成功 → 获取base64图像 → 网络可用检查 → 执行离场校验 → 校验成功 → 开启B门 + ↓ 网络不可用 + 显示网络错误提示,等待网络恢复 +``` + +## 安全性提升 + +1. **消除了未授权开门风险**:网络异常时不再直接开门 +2. **增强了业务流程控制**:严格按照验证流程执行 +3. **提供了用户友好的错误提示**:网络异常时显示明确的错误信息 +4. **保持了网络恢复后的自动处理**:配合现有的网络恢复监听机制 + +## 兼容性说明 + +- 所有现有的网络验证回调保持不变 +- UDP门禁控制接口保持不变 +- 用户界面显示逻辑保持不变 +- 仅修改了人脸识别成功后的处理逻辑 + +## 测试建议 + +1. **正常网络环境测试**: + - 进场场景:人脸识别 → 订单核销 → B门开启 + - 离场场景:人脸识别 → 离场校验 → B门开启 + +2. **网络异常环境测试**: + - 断网状态下人脸识别:应显示网络错误提示,不开门 + - 网络恢复后:应能正常执行验证和开门流程 + +3. **边界情况测试**: + - 验证失败时:不应开门 + - 验证超时时:不应开门 + - 网络间歇性中断:应等待网络稳定后再验证 + +## 总结 + +此次重构解决了关键的安全问题,确保门禁系统严格按照业务流程执行:**人脸识别成功 → 网络验证成功 → 门禁开启**。这样的流程更加安全可靠,符合实际业务需求。 \ No newline at end of file