fix: NfcTaskManager 重写修复编译错误

之前 python 脚本修复乱码时破坏了文件结构(花括号错位导致
private 方法变成 local function)。完整重写文件。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-05-06 12:17:52 +09:30
parent df1e80fe33
commit 1df7981318

View File

@@ -5,7 +5,12 @@ import com.xiaoqu.watch.device.sensor.VibrationController
import com.xiaoqu.watch.network.ApiResult import com.xiaoqu.watch.network.ApiResult
import com.xiaoqu.watch.network.api.TaskApi import com.xiaoqu.watch.network.api.TaskApi
import com.xiaoqu.watch.network.safeApiCall import com.xiaoqu.watch.network.safeApiCall
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@@ -15,11 +20,11 @@ import javax.inject.Singleton
* *
* 统一处理三种 NFC 打卡场景: * 统一处理三种 NFC 打卡场景:
* 1. 任务单个打卡(任务详情页"开启打卡"按钮) * 1. 任务单个打卡(任务详情页"开启打卡"按钮)
* 2. 主动批量打卡返回键触发checkNfcType nfcBatchBeginTask * 2. 主动批量打卡返回键触发checkNfcType -> nfcBatchBeginTask
* 3. 硬件开锁返回键触发checkNfcType 根据 status 播放语音) * 3. 硬件开锁返回键触发checkNfcType -> 根据 status 播放语音)
* *
* 与 PunchViewModel考勤打卡独立互不干扰。 * 与 PunchViewModel考勤打卡独立互不干扰。
* 通过 isScanning 防止两者同时操作 NFC。 * 通过 isScanning + nfcController.isOpen() 防止两者同时操作 NFC。
*/ */
@Singleton @Singleton
class NfcTaskManager @Inject constructor( class NfcTaskManager @Inject constructor(
@@ -28,9 +33,7 @@ class NfcTaskManager @Inject constructor(
private val taskApi: TaskApi private val taskApi: TaskApi
) { ) {
companion object { companion object {
/** 默认 NFC 超时(毫秒),可被 MQTT type=4 的 nfcOpenTime 覆盖 */
private const val DEFAULT_NFC_TIMEOUT_MS = 20_000L private const val DEFAULT_NFC_TIMEOUT_MS = 20_000L
// 震动方案 planId
private const val PLAN_PUNCH_SUCCESS = 4 private const val PLAN_PUNCH_SUCCESS = 4
private const val PLAN_PUNCH_FAIL = 7 private const val PLAN_PUNCH_FAIL = 7
private const val PLAN_NFC_OPEN = 8 private const val PLAN_NFC_OPEN = 8
@@ -49,18 +52,11 @@ class NfcTaskManager @Inject constructor(
/** NFC 超时时间(毫秒),通过 MQTT type=4 更新 */ /** NFC 超时时间(毫秒),通过 MQTT type=4 更新 */
var nfcTimeoutMs: Long = DEFAULT_NFC_TIMEOUT_MS var nfcTimeoutMs: Long = DEFAULT_NFC_TIMEOUT_MS
/** 协程作用域 */
private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
/** 超时 Job */
private var timeoutJob: Job? = null private var timeoutJob: Job? = null
/** /**
* 场景 1任务单个打卡 * 场景 1任务单个打卡
* 开启 NFC → 读卡 → POST nfcToBeginTask → 回调结果
*
* @param taskId 任务 ID
* @param onResult 结果回调主线程success + message
*/ */
fun startTaskPunch(taskId: Long, onResult: (success: Boolean, message: String) -> Unit) { fun startTaskPunch(taskId: Long, onResult: (success: Boolean, message: String) -> Unit) {
if (isScanning || nfcController.isOpen()) { if (isScanning || nfcController.isOpen()) {
@@ -68,20 +64,17 @@ class NfcTaskManager @Inject constructor(
return return
} }
isScanning = true isScanning = true
Timber.d("NFC任<EFBFBD><EFBFBD>打卡: 开启单个打卡, taskId=%d", taskId) Timber.d("NFC任打卡: 开启单个打卡, taskId=%d", taskId)
// 开启 NFC + 音效
vibrationController.executeByPlanId(PLAN_NFC_OPEN) vibrationController.executeByPlanId(PLAN_NFC_OPEN)
nfcController.open() nfcController.open()
// 开始扫描
nfcController.startScan { nfcId -> nfcController.startScan { nfcId ->
Timber.d("NFC任务打卡: 读到卡号 %s", nfcId) Timber.d("NFC任务打卡: 读到卡号 %s", nfcId)
cancelTimeout() cancelTimeout()
nfcController.stopScan() nfcController.stopScan()
nfcController.close() nfcController.close()
// 调用打卡 API
scope.launch { scope.launch {
val params = hashMapOf<String, Any>("id" to taskId, "nfcId" to nfcId) val params = hashMapOf<String, Any>("id" to taskId, "nfcId" to nfcId)
val result = safeApiCall { taskApi.nfcToBeginTask(params) } val result = safeApiCall { taskApi.nfcToBeginTask(params) }
@@ -94,7 +87,7 @@ class NfcTaskManager @Inject constructor(
is ApiResult.Error -> { is ApiResult.Error -> {
Timber.w("NFC任务打卡: 打卡失败 - %s", result.message) Timber.w("NFC任务打卡: 打卡失败 - %s", result.message)
vibrationController.executeByPlanId(PLAN_PUNCH_FAIL) vibrationController.executeByPlanId(PLAN_PUNCH_FAIL)
onResult(false, result.message ?: "<EFBFBD><EFBFBD>卡失败") onResult(false, result.message ?: "卡失败")
} }
is ApiResult.NetworkError -> { is ApiResult.NetworkError -> {
Timber.w(result.exception, "NFC任务打卡: 网络异常") Timber.w(result.exception, "NFC任务打卡: 网络异常")
@@ -106,49 +99,42 @@ class NfcTaskManager @Inject constructor(
} }
} }
// 启动超时
startTimeout { startTimeout {
Timber.d("NFC任务打卡: 超时自动关闭") Timber.d("NFC任务打卡: 超时自动关闭")
closeNfc() closeNfc()
onResult(false, "<EFBFBD><EFBFBD><EFBFBD>") vibrationController.executeByPlanId(PLAN_NFC_CLOSE)
onResult(false, "超时")
isScanning = false isScanning = false
} }
} }
/** /**
* 场景 2+3主动打卡<EFBFBD><EFBFBD><EFBFBD>回键触发) * 场景 2+3主动打卡回键触发)
* 开启 NFC → 读卡 → checkNfcType → 批量打卡 or 硬件开锁
*
* @param onResult 结果回调主线程success + message
*/ */
fun startActivePunch(onResult: (success: Boolean, message: String) -> Unit) { fun startActivePunch(onResult: (success: Boolean, message: String) -> Unit) {
if (isScanning) {
if (isScanning || nfcController.isOpen()) { if (isScanning || nfcController.isOpen()) {
Timber.d("NFC主动打卡: NFC 正在使用中,忽略") Timber.d("NFC主动打卡: NFC 正在使用中,忽略")
return
} }
isScanning = true isScanning = true
Timber.d("NFC主动<EFBFBD><EFBFBD>卡: 开启(返回键触发)") Timber.d("NFC主动卡: 开启(返回键触发)")
// 开启 NFC + <20><>
vibrationController.executeByPlanId(PLAN_NFC_OPEN) vibrationController.executeByPlanId(PLAN_NFC_OPEN)
nfcController.open() nfcController.open()
// 开始扫描
nfcController.startScan { nfcId -> nfcController.startScan { nfcId ->
Timber.d("NFC主动打卡: 读到<EFBFBD><EFBFBD><EFBFBD>号 %s", nfcId) Timber.d("NFC主动打卡: 读到号 %s", nfcId)
cancelTimeout() cancelTimeout()
nfcController.stopScan() nfcController.stopScan()
nfcController.close() nfcController.close()
vibrationController.executeByPlanId(PLAN_NFC_CLOSE) vibrationController.executeByPlanId(PLAN_NFC_CLOSE)
// 判断类型:批量打卡 or 硬件开锁
scope.launch { scope.launch {
handleNfcType(nfcId, onResult) handleNfcType(nfcId, onResult)
isScanning = false isScanning = false
} }
} }
// 启动超时
startTimeout { startTimeout {
Timber.d("NFC主动打卡: 超时自动关闭") Timber.d("NFC主动打卡: 超时自动关闭")
closeNfc() closeNfc()
@@ -168,11 +154,7 @@ class NfcTaskManager @Inject constructor(
isScanning = false isScanning = false
} }
/** /** 判断 NFC 类型并处理 */
* 判断 NFC 类型并处理
* hardwareNfcFlag=true → 硬件开锁<EFBC88><E692AD><EFBFBD>语音
* hardwareNfcFlag=false → 批量任务打卡(调 API
*/
private suspend fun handleNfcType(nfcId: String, onResult: (Boolean, String) -> Unit) { private suspend fun handleNfcType(nfcId: String, onResult: (Boolean, String) -> Unit) {
val result = safeApiCall { taskApi.checkNfcType(nfcId) } val result = safeApiCall { taskApi.checkNfcType(nfcId) }
when (result) { when (result) {
@@ -182,12 +164,9 @@ class NfcTaskManager @Inject constructor(
onResult(false, "数据异常") onResult(false, "数据异常")
return return
} }
if (data.hardwareNfcFlag) { if (data.hardwareNfcFlag) {
// 硬件开锁
handleHardwareUnlock(data.status, onResult) handleHardwareUnlock(data.status, onResult)
} else { } else {
// 批量任务打卡
handleBatchPunch(nfcId, onResult) handleBatchPunch(nfcId, onResult)
} }
} }
@@ -206,7 +185,7 @@ class NfcTaskManager @Inject constructor(
/** 硬件开锁:根据 status 播放对应语音 */ /** 硬件开锁:根据 status 播放对应语音 */
private fun handleHardwareUnlock(status: Int, onResult: (Boolean, String) -> Unit) { private fun handleHardwareUnlock(status: Int, onResult: (Boolean, String) -> Unit) {
Timber.d("NFC<EFBFBD><EFBFBD>动打卡: 硬件开锁, status=%d", status) Timber.d("NFC动打卡: 硬件开锁, status=%d", status)
when (status) { when (status) {
0 -> { 0 -> {
vibrationController.executeByPlanId(PLAN_OPENING) vibrationController.executeByPlanId(PLAN_OPENING)
@@ -224,9 +203,7 @@ class NfcTaskManager @Inject constructor(
vibrationController.executeByPlanId(PLAN_NO_AUTH) vibrationController.executeByPlanId(PLAN_NO_AUTH)
onResult(false, "无开锁权限") onResult(false, "无开锁权限")
} }
else -> { else -> onResult(false, "未知状态")
onResult(false, "<EFBFBD><EFBFBD>知状态")
}
} }
} }
@@ -247,20 +224,18 @@ class NfcTaskManager @Inject constructor(
onResult(false, result.message ?: "打卡失败") onResult(false, result.message ?: "打卡失败")
} }
is ApiResult.NetworkError -> { is ApiResult.NetworkError -> {
Timber.w(result.exception, "NFC主动打卡: 网络<EFBFBD><EFBFBD>") Timber.w(result.exception, "NFC主动打卡: 网络")
vibrationController.executeByPlanId(PLAN_PUNCH_FAIL) vibrationController.executeByPlanId(PLAN_PUNCH_FAIL)
onResult(false, "网络异常") onResult(false, "网络异常")
} }
} }
} }
/** 关闭 NFC 硬件 */
private fun closeNfc() { private fun closeNfc() {
nfcController.stopScan() nfcController.stopScan()
nfcController.close() nfcController.close()
} }
/** 启动超时协程 */
private fun startTimeout(onTimeout: () -> Unit) { private fun startTimeout(onTimeout: () -> Unit) {
timeoutJob = scope.launch { timeoutJob = scope.launch {
delay(nfcTimeoutMs) delay(nfcTimeoutMs)
@@ -268,7 +243,6 @@ class NfcTaskManager @Inject constructor(
} }
} }
/** 取消超时协程 */
private fun cancelTimeout() { private fun cancelTimeout() {
timeoutJob?.cancel() timeoutJob?.cancel()
timeoutJob = null timeoutJob = null