|
|
@@ -0,0 +1,620 @@
|
|
|
+package com.grkj.ui_base.business
|
|
|
+
|
|
|
+import androidx.appcompat.app.AppCompatActivity
|
|
|
+import com.clj.fastble.BleManager
|
|
|
+import com.clj.fastble.data.BleDevice
|
|
|
+import com.clj.fastble.exception.BleException
|
|
|
+import com.google.gson.Gson
|
|
|
+import com.grkj.data.HardwareRepository
|
|
|
+import com.grkj.data.StepRepository
|
|
|
+import com.grkj.data.TicketRepository
|
|
|
+import com.grkj.domain.entity.local.DeviceTakeUpdate
|
|
|
+import com.grkj.domain.entity.local.UpdateKeyReturn
|
|
|
+import com.grkj.domain.entity.local.WorkTicketGet
|
|
|
+import com.grkj.domain.entity.local.WorkTicketSend
|
|
|
+import com.grkj.domain.entity.local.WorkTicketSend.LockListBO
|
|
|
+import com.grkj.domain.entity.req.LockPointUpdateReq
|
|
|
+import com.grkj.domain.entity.res.CommonDictRes
|
|
|
+import com.grkj.domain.entity.res.TicketDetailRes
|
|
|
+import com.grkj.domain.repository.IHardwareRepository
|
|
|
+import com.grkj.domain.repository.IStepRepository
|
|
|
+import com.grkj.domain.repository.ITicketRepository
|
|
|
+import com.grkj.ui_base.R
|
|
|
+import com.grkj.ui_base.data.Constants
|
|
|
+import com.grkj.ui_base.data.DictConstants
|
|
|
+import com.grkj.ui_base.dialog.TipDialog
|
|
|
+import com.grkj.ui_base.utils.CommonUtils
|
|
|
+import com.grkj.ui_base.utils.Executor
|
|
|
+import com.grkj.ui_base.utils.SPUtils
|
|
|
+import com.grkj.ui_base.utils.event.CurrentModeEvent
|
|
|
+import com.grkj.ui_base.utils.event.DeviceExceptionEvent
|
|
|
+import com.grkj.ui_base.utils.event.LoadingEvent
|
|
|
+import com.grkj.ui_base.utils.event.UpdateTicketProgressEvent
|
|
|
+import com.grkj.ui_base.utils.extension.serialNo
|
|
|
+import com.grkj.ui_base.utils.modbus.DeviceConst
|
|
|
+import com.grkj.ui_base.utils.modbus.ModBusController
|
|
|
+import com.grkj.ui_base.utils.ble.BleCmdManager
|
|
|
+import com.grkj.ui_base.utils.ble.BleConnectionManager
|
|
|
+import com.grkj.ui_base.utils.ble.BleConst
|
|
|
+import com.grkj.ui_base.utils.ble.CustomBleWriteCallback
|
|
|
+import com.kongzue.dialogx.dialogs.PopTip
|
|
|
+import com.sik.sikcore.SIKCore
|
|
|
+import com.sik.sikcore.thread.ThreadUtils
|
|
|
+import kotlinx.coroutines.Dispatchers
|
|
|
+import kotlinx.coroutines.async
|
|
|
+import kotlinx.coroutines.withContext
|
|
|
+import org.slf4j.LoggerFactory
|
|
|
+
|
|
|
+/**
|
|
|
+ * 蓝牙业务
|
|
|
+ */
|
|
|
+object BleBusinessManager {
|
|
|
+ private val logger = LoggerFactory.getLogger(BleBusinessManager::class.java)
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 硬件仓储
|
|
|
+ */
|
|
|
+ private val hardwareRepository: IHardwareRepository by lazy { HardwareRepository() }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 步骤仓储
|
|
|
+ */
|
|
|
+ private val stepRepository: IStepRepository by lazy { StepRepository() }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 工作票仓储
|
|
|
+ */
|
|
|
+ private val ticketRepository: ITicketRepository by lazy { TicketRepository() }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理工作票完成情况
|
|
|
+ */
|
|
|
+ fun handleTicketStatus(
|
|
|
+ bleDevice: BleDevice, byteArray: ByteArray, isNeedLoading: Boolean = false
|
|
|
+ ) {
|
|
|
+ BleCmdManager.handleTicketStatus(bleDevice, byteArray) { ticketJson ->
|
|
|
+ if (ticketJson.isNullOrEmpty()) {
|
|
|
+ return@handleTicketStatus
|
|
|
+ }
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent("工作票完成状态读取完成", true)
|
|
|
+ logger.info("Get ticket status complete : ${bleDevice.mac}")
|
|
|
+ // TD:Ticket Done
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent("TD$ticketJson}", true)
|
|
|
+
|
|
|
+ val workTicketGet = Gson().fromJson(ticketJson, WorkTicketGet::class.java)
|
|
|
+
|
|
|
+ // 判断WorkTicketGet里是否有未完成的
|
|
|
+ if (workTicketGet.hasFinished()) {
|
|
|
+ Executor.delayOnMain(500) {
|
|
|
+ handleKeyReturn(bleDevice, workTicketGet)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 当前策略:作业票未完成禁止归还钥匙
|
|
|
+ TipDialog.show(
|
|
|
+ msg = CommonUtils.getStr(R.string.key_return_tip)!!,
|
|
|
+ onConfirmClick = {
|
|
|
+ LoadingEvent.sendLoadingEvent()
|
|
|
+ PopTip.tip(CommonUtils.getStr(R.string.continue_the_ticket))
|
|
|
+ BleManager.getInstance().disconnect(bleDevice)
|
|
|
+ // 打开卡扣,防止初始化的时候选择不处理钥匙导致无法使用
|
|
|
+ val dock = ModBusController.getDockByKeyMac(bleDevice.mac)
|
|
|
+ val keyBean = dock?.getKeyList()?.find { it.mac == bleDevice.mac }
|
|
|
+ keyBean?.let {
|
|
|
+ ModBusController.controlKeyBuckle(true, keyBean.idx, dock.addr)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理钥匙归还
|
|
|
+ */
|
|
|
+ private fun handleKeyReturn(bleDevice: BleDevice, workTicketGet: WorkTicketGet?) {
|
|
|
+ val dock = ModBusController.getDockByKeyMac(bleDevice.mac)
|
|
|
+ val keyBean = dock?.getKeyList()?.find { it.mac == bleDevice.mac }
|
|
|
+ keyBean?.let {
|
|
|
+ ModBusController.controlKeyBuckle(false, keyBean.idx, dock.addr)
|
|
|
+ }
|
|
|
+ // 上报隔离点状态
|
|
|
+ val keyNfc = ModBusController.getKeyByMac(bleDevice.mac)?.rfid
|
|
|
+ workTicketGet?.data?.forEach { data ->
|
|
|
+ val updateList = mutableListOf<LockPointUpdateReq>()
|
|
|
+ data.dataList?.forEach { dataListDTO ->
|
|
|
+ data.taskCode?.toLong()?.let {
|
|
|
+ SPUtils.returnKey(it)
|
|
|
+ }
|
|
|
+ val updateVO = LockPointUpdateReq(
|
|
|
+ data.taskCode?.toLong(),
|
|
|
+ dataListDTO.infoRfidNo,
|
|
|
+ dataListDTO.equipRfidNo,
|
|
|
+ keyNfc!!,
|
|
|
+ dataListDTO.target,
|
|
|
+ dataListDTO.status
|
|
|
+ )
|
|
|
+ updateList.add(updateVO)
|
|
|
+ }
|
|
|
+
|
|
|
+ LoadingEvent.sendLoadingEvent()
|
|
|
+ PopTip.tip(R.string.key_return_success)
|
|
|
+ if (hardwareRepository.canReturn()) {
|
|
|
+ // 上报点位钥匙绑定
|
|
|
+ hardwareRepository.updateLockPointBatch(updateList) { isSuccess, msg ->
|
|
|
+ if (isSuccess || msg == CommonUtils.getStr(R.string.lock_nfc_lost)) {
|
|
|
+ data.taskCode?.toLong()?.let {
|
|
|
+ UpdateTicketProgressEvent.sendUpdateTicketProgressEvent(it)
|
|
|
+ }
|
|
|
+ // 确认归还,切换为待机模式
|
|
|
+ switchReadyMode(bleDevice)
|
|
|
+ } else if (msg != CommonUtils.getStr(R.string.lock_nfc_lost)) {
|
|
|
+ SPUtils.saveUpdateLockPoint(SIKCore.getApplication(), updateList)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 上报钥匙归还
|
|
|
+ hardwareRepository.updateKeyReturn(
|
|
|
+ data.taskCode?.toLong()!!, keyNfc!!, SIKCore.getApplication().serialNo()
|
|
|
+ ) { isSuccess, msg ->
|
|
|
+ if (!isSuccess && msg != CommonUtils.getStr(R.string.ticket_lost)) {
|
|
|
+ SPUtils.saveUpdateKeyReturn(
|
|
|
+ SIKCore.getApplication(),
|
|
|
+ UpdateKeyReturn(data.taskCode?.toLong()!!, keyNfc!!)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ SPUtils.saveUpdateLockPoint(SIKCore.getApplication(), updateList)
|
|
|
+ SPUtils.saveUpdateKeyReturn(
|
|
|
+ SIKCore.getApplication(), UpdateKeyReturn(data.taskCode?.toLong()!!, keyNfc!!)
|
|
|
+ )
|
|
|
+ // 保存待发数据,切换为待机模式
|
|
|
+ switchReadyMode(bleDevice)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理虚拟钥匙取出,如果作业的全部点位已经上锁更新钥匙的状态使用
|
|
|
+ */
|
|
|
+ fun handleVirtualKeyGive(taskCode: Long, keyNfc: String, done: () -> Unit) {
|
|
|
+ // 上报钥匙取出
|
|
|
+ hardwareRepository.updateKeyTake(
|
|
|
+ taskCode,
|
|
|
+ keyNfc,
|
|
|
+ SIKCore.getApplication().serialNo()
|
|
|
+ ) { isSuccess ->
|
|
|
+ if (isSuccess) {
|
|
|
+ done()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理虚拟钥匙归还,如果作业的全部点位已经上锁更新钥匙的状态使用
|
|
|
+ */
|
|
|
+ fun handleVirtualKeyReturn(taskCode: Long, keyNfc: String, done: () -> Unit) {
|
|
|
+ // 上报钥匙归还
|
|
|
+ hardwareRepository.updateKeyReturn(
|
|
|
+ taskCode, keyNfc, SIKCore.getApplication().serialNo()
|
|
|
+ ) { isSuccess, msg ->
|
|
|
+ if (!isSuccess && msg != CommonUtils.getStr(R.string.ticket_lost)
|
|
|
+ ) {
|
|
|
+ SPUtils.saveUpdateKeyReturn(
|
|
|
+ SIKCore.getApplication(), UpdateKeyReturn(taskCode, keyNfc)
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ done()
|
|
|
+ UpdateTicketProgressEvent.sendUpdateTicketProgressEvent(taskCode)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 切换待机模式
|
|
|
+ */
|
|
|
+ fun switchReadyMode(bleDevice: BleDevice) {
|
|
|
+ BleCmdManager.switchMode(
|
|
|
+ BleConst.STATUS_READY,
|
|
|
+ bleDevice,
|
|
|
+ object : CustomBleWriteCallback() {
|
|
|
+ override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
|
|
|
+ logger.info("switch mode ready success : ${bleDevice.mac}")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onWriteFailure(exception: BleException?) {
|
|
|
+ logger.error("switch mode ready fail : ${bleDevice.mac}")
|
|
|
+ Executor.delayOnMain(300) {
|
|
|
+ switchReadyMode(bleDevice)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取工作票完成情况
|
|
|
+ */
|
|
|
+ private fun getTicketStatus(
|
|
|
+ bleDevice: BleDevice,
|
|
|
+ isNeedLoading: Boolean = false,
|
|
|
+ processCallback: ((Boolean) -> Unit)? = null
|
|
|
+ ) {
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent("开始获取工作票", true)
|
|
|
+ BleCmdManager.getTicketStatus(bleDevice, object : CustomBleWriteCallback() {
|
|
|
+ override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent("工作票获取成功", true)
|
|
|
+ logger.info("getTicketStatus success")
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onWriteFailure(exception: BleException?) {
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent("工作票获取失败", true)
|
|
|
+ processCallback?.invoke(false)
|
|
|
+ logger.error("getTicketStatus fail")
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据当前模式进行处理
|
|
|
+ */
|
|
|
+ private fun handleCurrentMode(currentModeEvent: CurrentModeEvent) {
|
|
|
+ when (currentModeEvent.mode) {
|
|
|
+ // 工作模式
|
|
|
+ 0x01.toByte() -> {
|
|
|
+ // 读工作票
|
|
|
+ getTicketStatusBusiness(currentModeEvent.bleBean.bleDevice.mac)
|
|
|
+ }
|
|
|
+ // 待机模式
|
|
|
+ 0x02.toByte() -> {
|
|
|
+ // 根据情况看是否需要下发工作票
|
|
|
+ ModBusController.getKeyByMac(currentModeEvent.bleBean.bleDevice.mac)?.let { key ->
|
|
|
+ // 判断是否有待取的钥匙
|
|
|
+ val updateBo =
|
|
|
+ ModbusBusinessManager.mDeviceTakeList.find { it.deviceType == DeviceConst.DEVICE_TYPE_KEY && key.rfid == it.nfc }
|
|
|
+ updateBo?.let { itBO ->
|
|
|
+ stepRepository.getStepDetail(itBO.ticketId) {
|
|
|
+ var step = 0
|
|
|
+ it?.filter { it.stepStatus == "1" }
|
|
|
+ ?.maxByOrNull { it.stepIndex!! }?.stepIndex?.let {
|
|
|
+ step = it
|
|
|
+ }
|
|
|
+ ticketRepository.getTicketDetail(itBO.ticketId) { ticketDetail ->
|
|
|
+ val role = ticketDetail?.ticketUserVOList?.find {
|
|
|
+ it.userId == SPUtils.getLoginUser(SIKCore.getApplication())?.userId && it.userType == Constants.USER_TYPE_LOCKER
|
|
|
+ }
|
|
|
+ if (role == null) {
|
|
|
+ PopTip.tip(CommonUtils.getStr(R.string.you_are_not_locker_tip))
|
|
|
+ return@getTicketDetail
|
|
|
+ }
|
|
|
+ if (step == 4) { // 上锁工作票
|
|
|
+ sendTicketBusiness(
|
|
|
+ true,
|
|
|
+ currentModeEvent.bleBean.bleDevice.mac,
|
|
|
+ ticketDetail,
|
|
|
+ ticketDetail.ticketLockVOList?.filter { it.lockStatus != "2" }
|
|
|
+ ?.map { it.lockNfc }?.toMutableList(),
|
|
|
+ true
|
|
|
+ )
|
|
|
+ } else if (step == 7) { // 解锁工作票
|
|
|
+ sendTicketBusiness(
|
|
|
+ false,
|
|
|
+ currentModeEvent.bleBean.bleDevice.mac,
|
|
|
+ ticketDetail,
|
|
|
+ null,
|
|
|
+ true
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } ?: let {
|
|
|
+ ModBusController.updateKeyReadyStatus(
|
|
|
+ currentModeEvent.bleBean.bleDevice.mac, true, 4
|
|
|
+ )
|
|
|
+ ModBusController.controlKeyBuckle(
|
|
|
+ false, currentModeEvent.bleBean.bleDevice.mac
|
|
|
+ )
|
|
|
+ LoadingEvent.sendLoadingEvent()
|
|
|
+ //连上之后没有工作票要下发就断开
|
|
|
+ BleManager.getInstance().disconnect(currentModeEvent.bleBean.bleDevice)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 故障模式
|
|
|
+ 0x03.toByte() -> {
|
|
|
+ // TODO 上报?
|
|
|
+ PopTip.tip(
|
|
|
+ "${currentModeEvent.bleBean.bleDevice.mac} : " + "${CommonUtils.getStr(R.string.key_is_in_failure_mode)}"
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分配钥匙
|
|
|
+ */
|
|
|
+ fun handleGiveKey(deviceTakeUpdateBO: DeviceTakeUpdate) {
|
|
|
+ BleConnectionManager.getBleDeviceByMac(ModBusController.getKeyByRfid(deviceTakeUpdateBO.nfc)?.mac)
|
|
|
+ ?.let {
|
|
|
+ BleConnectionManager.getCurrentStatus(
|
|
|
+ 2,
|
|
|
+ BleConnectionManager.getBleDeviceByMac(
|
|
|
+ ModBusController.getKeyByRfid(
|
|
|
+ deviceTakeUpdateBO.nfc
|
|
|
+ )?.mac
|
|
|
+ )!!.bleDevice
|
|
|
+ ) {
|
|
|
+ if (!it) {
|
|
|
+ return@getCurrentStatus
|
|
|
+ }
|
|
|
+ logger.warn("handleGiveKey timeout")
|
|
|
+ ModbusBusinessManager.removeDeviceTake(
|
|
|
+ DeviceConst.DEVICE_TYPE_KEY,
|
|
|
+ deviceTakeUpdateBO.nfc
|
|
|
+ )
|
|
|
+ ModbusBusinessManager.checkEquipCount(0, true) { keyPair, lockMap ->
|
|
|
+ if (keyPair == null) {
|
|
|
+ TipDialog.show(
|
|
|
+ msg = CommonUtils.getStr(R.string.key_take_error_tip).toString(),
|
|
|
+ onConfirmClick = {
|
|
|
+ DeviceExceptionEvent.sendDeviceExceptionEvent(
|
|
|
+ DeviceConst.DEVICE_TYPE_KEY,
|
|
|
+ deviceTakeUpdateBO.nfc
|
|
|
+ )
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ ModbusBusinessManager.addDeviceTake(
|
|
|
+ DeviceConst.DEVICE_TYPE_KEY,
|
|
|
+ deviceTakeUpdateBO.ticketId,
|
|
|
+ keyPair.second?.rfid!!
|
|
|
+ )
|
|
|
+ handleGiveKey(
|
|
|
+ DeviceTakeUpdate(
|
|
|
+ DeviceConst.DEVICE_TYPE_KEY,
|
|
|
+ deviceTakeUpdateBO.ticketId,
|
|
|
+ keyPair.second?.rfid!!
|
|
|
+ )
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } ?: run {
|
|
|
+ TipDialog.show(
|
|
|
+ msg = CommonUtils.getStr(R.string.key_take_error_tip).toString(),
|
|
|
+ onConfirmClick = {
|
|
|
+ DeviceExceptionEvent.sendDeviceExceptionEvent(
|
|
|
+ DeviceConst.DEVICE_TYPE_KEY,
|
|
|
+ deviceTakeUpdateBO.nfc
|
|
|
+ )
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取工作票完成情况
|
|
|
+ */
|
|
|
+ private fun getTicketStatusBusiness(
|
|
|
+ mac: String, isNeedLoading: Boolean = false
|
|
|
+ ) {
|
|
|
+ BleConnectionManager.registerConnectListener(mac) { isDone, bleBean ->
|
|
|
+ if (isDone) {
|
|
|
+ Executor.delayOnMain(500) {
|
|
|
+ getTicketStatusWithRetry(bleBean!!.bleDevice, isNeedLoading)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun getTicketStatusWithRetry(
|
|
|
+ bleDevice: BleDevice,
|
|
|
+ isNeedLoading: Boolean = false,
|
|
|
+ maxRetries: Int = 3,
|
|
|
+ delayMillis: Long = 500
|
|
|
+ ) {
|
|
|
+ var retryCount = 0
|
|
|
+
|
|
|
+ fun attemptSend() {
|
|
|
+ getTicketStatus(bleDevice, isNeedLoading) { sendRst ->
|
|
|
+ if (!sendRst && retryCount < maxRetries) {
|
|
|
+ retryCount++
|
|
|
+ // 等待一段时间后再次尝试
|
|
|
+ Executor.delayOnMain(delayMillis) {
|
|
|
+ logger.info("Retry attempt, mac : ${bleDevice.mac}, retryCount : $retryCount")
|
|
|
+ attemptSend()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ attemptSend()
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 连接一把存在的可连接的钥匙
|
|
|
+ */
|
|
|
+ fun connectExistsKey(exceptKeyMac: String) {
|
|
|
+ ThreadUtils.runOnIO {
|
|
|
+ // —— 串行请求1 & 2 ——
|
|
|
+ val slotsPage = DataBusiness.getSlotsPage()
|
|
|
+ val keyPage = DataBusiness.getKeyPage()
|
|
|
+ // —— 并行加载字典(或按需串行也行) ——
|
|
|
+ val slotStatus =
|
|
|
+ async { DataBusiness.fetchDict<CommonDictRes>(DictConstants.KEY_SLOT_STATUS) }
|
|
|
+ val keyStatus =
|
|
|
+ async { DataBusiness.fetchDict<CommonDictRes>(DictConstants.KEY_KEY_STATUS) }
|
|
|
+ val slotType =
|
|
|
+ async { DataBusiness.fetchDict<CommonDictRes>(DictConstants.KEY_SLOT_TYPE) }
|
|
|
+
|
|
|
+ // 等待字典加载完成
|
|
|
+ val slotStatusList = slotStatus.await()
|
|
|
+ val keyStatusList = keyStatus.await()
|
|
|
+ val slotTypeList = slotType.await()
|
|
|
+ withContext(Dispatchers.Default) {
|
|
|
+ ModBusController.getOneKey(
|
|
|
+ slotsPage?.records
|
|
|
+ ?.filter {
|
|
|
+ it.slotType == slotTypeList.find { d -> d.dictLabel == "钥匙" }?.dictValue &&
|
|
|
+ it.status == slotStatusList.find { d -> d.dictLabel == "异常" }?.dictValue
|
|
|
+ }?.toMutableList() ?: mutableListOf(),
|
|
|
+ (keyPage?.records
|
|
|
+ ?.filter { it.exStatus == keyStatusList.find { d -> d.dictLabel == "异常" }?.dictValue }
|
|
|
+ ?.map { it.keyNfc ?: "" }
|
|
|
+ ?.toMutableList() ?: mutableListOf()),
|
|
|
+ mutableListOf(exceptKeyMac)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 下发工作票
|
|
|
+ */
|
|
|
+ private fun sendTicketBusiness(
|
|
|
+ isLock: Boolean,
|
|
|
+ mac: String,
|
|
|
+ ticketDetail: TicketDetailRes,
|
|
|
+ lockList: MutableList<String?>?,
|
|
|
+ isNeedLoading: Boolean = false,
|
|
|
+ ) {
|
|
|
+ BleConnectionManager.registerConnectListener(mac) { isDone, bleBean ->
|
|
|
+ if (!isDone) {
|
|
|
+ sendTicketBusiness(isLock, mac, ticketDetail, lockList, isNeedLoading)
|
|
|
+ return@registerConnectListener
|
|
|
+ }
|
|
|
+ if (bleBean == null) {
|
|
|
+// ToastUtils.tip(R.string.simple_key_is_not_connected)
|
|
|
+ logger.error("sendTicketBusiness fail : $mac, bleBean is null")
|
|
|
+ return@registerConnectListener
|
|
|
+ }
|
|
|
+ // 单bleBean json赋值
|
|
|
+ bleBean.retryCount = 0
|
|
|
+ bleBean.ticketSend = generateTicketSendJson(isLock, ticketDetail, lockList)
|
|
|
+ bleBean.ticketSend?.let { itJson ->
|
|
|
+ sendTicketWithRetry(itJson, bleBean.bleDevice, isNeedLoading)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成下发工作票Json
|
|
|
+ *
|
|
|
+ * @param vo 工作票详情
|
|
|
+ */
|
|
|
+ private fun generateTicketSendJson(
|
|
|
+ isLock: Boolean, vo: TicketDetailRes, lockList: MutableList<String?>?
|
|
|
+ ): String {
|
|
|
+ logger.info("generateTicketSendJson : $lockList")
|
|
|
+ val bo = WorkTicketSend(
|
|
|
+ cardNo = SPUtils.getLoginUser(SIKCore.getApplication())?.userCardList?.get(0),
|
|
|
+ )
|
|
|
+ CommonUtils.getDiffHours(vo.ticketEndTime)?.let {
|
|
|
+ bo.effectiveTime = it
|
|
|
+ }
|
|
|
+ // 有配置则用配置,没用则填充默认密码
|
|
|
+ bo.password =
|
|
|
+ SPUtils.getLoginUser(SIKCore.getApplication())?.keyCode ?: "123456"
|
|
|
+ val dataBO = WorkTicketSend.DataBO(
|
|
|
+ taskCode = vo.ticketId.toString(), codeId = 1
|
|
|
+ )
|
|
|
+ val taskList = ArrayList<WorkTicketSend.DataBO.DataListBO>()
|
|
|
+ vo.ticketPointsVOList?.let { itList ->
|
|
|
+ itList.forEach { pointVO ->
|
|
|
+ if (vo.noUnlockTicketPointsVOSet?.any { it.pointId == pointVO.pointId } == true) {
|
|
|
+ return@forEach
|
|
|
+ }
|
|
|
+ val task = WorkTicketSend.DataBO.DataListBO(
|
|
|
+ dataId = pointVO.pointId?.toInt(),
|
|
|
+ equipRfidNo = pointVO.pointNfc,
|
|
|
+ equipName = pointVO.pointName,
|
|
|
+ target = if (isLock) 0 else 1
|
|
|
+ )
|
|
|
+ if (!isLock) {
|
|
|
+ task.infoRfidNo = pointVO.lockNfc
|
|
|
+ }
|
|
|
+ pointVO.prePointId?.let {
|
|
|
+ task.prevId = it.toInt()
|
|
|
+ }
|
|
|
+ // TODO partCode待补充
|
|
|
+ taskList.add(task)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataBO.dataList = taskList
|
|
|
+ bo.data = mutableListOf(dataBO)
|
|
|
+ if (isLock) {
|
|
|
+ // TODO 挂锁数组
|
|
|
+ if (!lockList.isNullOrEmpty()) {
|
|
|
+ bo.lockList = mutableListOf()
|
|
|
+ lockList.forEachIndexed { index, s ->
|
|
|
+ if (s.isNullOrEmpty()) {
|
|
|
+ logger.warn("Lock nfc is null or empty")
|
|
|
+ return@forEachIndexed
|
|
|
+ }
|
|
|
+ bo.lockList?.add(LockListBO(index + 1, s))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // TODO partList 待补充
|
|
|
+ val jsonStr = Gson().toJson(bo)
|
|
|
+ logger.info("json : $jsonStr")
|
|
|
+ return jsonStr
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 带重试的下发工作票,重试次数3,间隔500ms
|
|
|
+ */
|
|
|
+ private fun sendTicketWithRetry(
|
|
|
+ json: String,
|
|
|
+ bleDevice: BleDevice,
|
|
|
+ isNeedLoading: Boolean = false,
|
|
|
+ maxRetries: Int = 3,
|
|
|
+ delayMillis: Long = 500
|
|
|
+ ) {
|
|
|
+ var retryCount = 0
|
|
|
+
|
|
|
+ fun attemptSend() {
|
|
|
+ sendTicket(json, bleDevice, isNeedLoading) { sendRst ->
|
|
|
+ if (!sendRst && retryCount < maxRetries) {
|
|
|
+ retryCount++
|
|
|
+ // 等待一段时间后再次尝试
|
|
|
+ Executor.delayOnMain(delayMillis) {
|
|
|
+ logger.info("Retry attempt, mac : ${bleDevice.mac}, retryCount : $retryCount")
|
|
|
+ attemptSend()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ attemptSend()
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun sendTicket(
|
|
|
+ jsonStr: String,
|
|
|
+ bleDevice: BleDevice,
|
|
|
+ isNeedLoading: Boolean = false,
|
|
|
+ processCallback: ((Boolean) -> Unit)? = null
|
|
|
+ ) {
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent(
|
|
|
+ CommonUtils.getStr(R.string.start_to_send_ticket),
|
|
|
+ true
|
|
|
+ )
|
|
|
+ BleCmdManager.sendWorkTicket(
|
|
|
+ jsonStr, bleDevice = bleDevice, callback = object : CustomBleWriteCallback() {
|
|
|
+ override fun onWriteSuccess(current: Int, total: Int, justWrite: ByteArray?) {
|
|
|
+ logger.info("sendTicket success")
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent(
|
|
|
+ CommonUtils.getStr(R.string.sending_ticket),
|
|
|
+ true
|
|
|
+ )
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onWriteFailure(exception: BleException?) {
|
|
|
+ logger.error("sendTicket fail : ${bleDevice.mac}")
|
|
|
+ if (isNeedLoading) LoadingEvent.sendLoadingEvent(
|
|
|
+ CommonUtils.getStr(R.string.send_ticket_fail),
|
|
|
+ true
|
|
|
+ )
|
|
|
+ processCallback?.invoke(false)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|