Browse Source

refactor(更新)
- 抽出待办事项相关扩展函数到data模块
- RepositoryManager修改为LogicManager
- 增加控制钥匙断开功能

周文健 3 tháng trước cách đây
mục cha
commit
3935804af2
20 tập tin đã thay đổi với 210 bổ sung179 xóa
  1. 2 18
      app/src/main/java/com/grkj/iscs/ISCSApplication.kt
  2. 2 2
      app/src/main/java/com/grkj/iscs/features/main/activity/MainActivity.kt
  3. 7 24
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/MainViewModel.kt
  4. 2 2
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/home/HomeViewModel.kt
  5. 5 8
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobExecuteViewModel.kt
  6. 2 2
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobManageHomeViewModel.kt
  7. 3 3
      app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/MyTodoViewModel.kt
  8. 1 0
      app/src/main/java/com/grkj/iscs/service/CheckKeyInfoTask.kt
  9. 3 3
      data/src/main/java/com/grkj/data/check_data/impl/ForceMultiLockMode.kt
  10. 3 3
      data/src/main/java/com/grkj/data/check_data/impl/ForceSharedLockMode.kt
  11. 11 11
      data/src/main/java/com/grkj/data/di/AppEntryPoint.kt
  12. 47 0
      data/src/main/java/com/grkj/data/di/LogicManager.kt
  13. 0 47
      data/src/main/java/com/grkj/data/di/RepositoryManager.kt
  14. 2 1
      data/src/main/java/com/grkj/data/model/extension/TodoDataExtension.kt
  15. 2 2
      data/src/main/java/com/grkj/data/model/local/WorkTicketGet.kt
  16. 32 28
      ui-base/src/main/java/com/grkj/ui_base/business/BleBusinessManager.kt
  17. 54 8
      ui-base/src/main/java/com/grkj/ui_base/business/DataBusiness.kt
  18. 14 9
      ui-base/src/main/java/com/grkj/ui_base/business/ModbusBusinessManager.kt
  19. 0 0
      ui-base/src/main/java/com/grkj/ui_base/utils/ble/BleIndicateListener.kt
  20. 18 8
      ui-base/src/main/java/com/grkj/ui_base/utils/modbus/ModBusController.kt

+ 2 - 18
app/src/main/java/com/grkj/iscs/ISCSApplication.kt

@@ -6,20 +6,12 @@ import android.app.PendingIntent
 import android.content.Context
 import android.content.Intent
 import android.content.res.Configuration
-import android.util.Log
 import android.util.TypedValue
-import androidx.work.Constraints
-import androidx.work.ExistingPeriodicWorkPolicy
-import androidx.work.PeriodicWorkRequestBuilder
-import androidx.work.WorkManager
 import ch.qos.logback.classic.Level
 import com.drake.statelayout.StateConfig
 import com.grkj.data.data.EventConstants
-import com.grkj.data.database.RoomBackupWorker
-import com.grkj.data.di.RepositoryManager
-import com.grkj.iscs.common.GlobalManager
+import com.grkj.data.di.LogicManager
 import com.grkj.iscs.features.splash.activity.SplashActivity
-import com.grkj.iscs.service.CheckKeyInfoTask
 import com.grkj.shared.model.EventBean
 import com.grkj.shared.utils.ArcSoftUtil
 import com.grkj.ui_base.business.ModbusBusinessManager
@@ -30,13 +22,6 @@ import com.kongzue.dialogx.DialogX
 import com.scwang.smart.refresh.footer.ClassicsFooter
 import com.scwang.smart.refresh.header.ClassicsHeader
 import com.scwang.smart.refresh.layout.SmartRefreshLayout
-import com.scwang.smart.refresh.layout.api.RefreshFooter
-import com.scwang.smart.refresh.layout.api.RefreshHeader
-import com.scwang.smart.refresh.layout.api.RefreshLayout
-import com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator
-import com.scwang.smart.refresh.layout.listener.DefaultRefreshHeaderCreator
-import com.sik.cronjob.managers.CronJobManager
-import com.sik.cronjob.managers.CronJobScanner
 import com.sik.sikcore.SIKCore
 import com.sik.sikcore.crash.GlobalCrashCatch
 import com.sik.sikcore.log.LogUtils
@@ -48,7 +33,6 @@ import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
-import java.util.concurrent.TimeUnit
 
 
 /**
@@ -84,7 +68,7 @@ class ISCSApplication : Application() {
         AutoSizeConfig.getInstance().isCustomFragment = true
         ThreadUtils.runOnIO {
             ModbusBusinessManager.registerMainListener()
-            RepositoryManager.init(this@ISCSApplication)
+            LogicManager.init(this@ISCSApplication)
         }
         StateConfig.emptyLayout = com.grkj.ui_base.R.layout.layout_empty
     }

+ 2 - 2
app/src/main/java/com/grkj/iscs/features/main/activity/MainActivity.kt

@@ -139,7 +139,7 @@ class MainActivity() : BaseActivity<ActivityMainBinding>() {
                 val firstId = binding.navBar.menu[0].itemId
                 binding.navBar.selectedItemId = firstId
                 MainDomainData.fromQuickEntry = false
-                viewModel.checkMyTodoForHandleKey()
+                viewModel.checkMyTodoForHandleKey().observe(this){}
             }
             binding.navBar.isVisible = bottomNavDestinations.contains(destination.id)
         }
@@ -177,7 +177,7 @@ class MainActivity() : BaseActivity<ActivityMainBinding>() {
 
     override fun initData() {
         super.initData()
-        viewModel.checkMyTodoForHandleKey()
+        viewModel.checkMyTodoForHandleKey().observe(this){}
         viewModel.bleIndicate()
         viewModel.registerStatusListener()
     }

+ 7 - 24
app/src/main/java/com/grkj/iscs/features/main/viewmodel/MainViewModel.kt

@@ -6,11 +6,13 @@ import com.clj.fastble.BleManager
 import com.grkj.data.data.MainDomainData
 import com.grkj.data.logic.IJobTicketLogic
 import com.grkj.data.model.local.isMyTodo
-import com.grkj.iscs.features.main.entity.splitTodoSteps
-import com.grkj.iscs.features.main.entity.toTodoVo
+import com.grkj.data.model.extension.splitTodoSteps
+import com.grkj.data.model.extension.toTodoVo
 import com.grkj.shared.utils.extension.startsWith
 import com.grkj.ui_base.base.BaseViewModel
 import com.grkj.ui_base.business.BleBusinessManager
+import com.grkj.ui_base.business.BleBusinessManager.connectExistsKey
+import com.grkj.ui_base.business.DataBusiness
 import com.grkj.ui_base.business.ModbusBusinessManager
 import com.grkj.ui_base.config.ISCSConfig
 import com.grkj.ui_base.utils.CommonUtils
@@ -73,29 +75,10 @@ class MainViewModel @Inject constructor(
     /**
      * 获取我的待办的作业
      */
-    fun checkMyTodoForHandleKey(mac: String? = null): LiveData<Int> {
+    fun checkMyTodoForHandleKey(mac: String? = null): LiveData<Boolean> {
         return liveData(Dispatchers.IO) {
-            val userInfo = MainDomainData.userInfo
-            if (userInfo == null) {
-                emit(0) // or emit(false) 根据语义定义
-                return@liveData
-            }
-
-            val userId = userInfo.userId
-            val userName = userInfo.userName
-            val todoItemData = jobTicketRepository.getMyTodoList()
-            val myTodoStepJoin = todoItemData.filter { it.isMyTodo(userId, userName) }
-            val todoItemVos =
-                myTodoStepJoin.map { it.toTodoVo(todoItemData.filter { temp -> it.ticketId == temp.ticketId }) }
-                    .toMutableList()
-            val todoData = splitTodoSteps(todoItemVos, 1)
-            if (BleManager.getInstance().allConnectedDevice.isEmpty() && (todoData.first.any { it.enableLock || it.enableUnlock } || todoData.second.any { it.enableLock || it.enableUnlock })) {
-                BleBusinessManager.connectExistsKey()
-            } else {
-                mac?.let {
-                    BleConnectionManager.launchDisconnectJob(it)
-                }
-            }
+            val result = DataBusiness.checkMyTodoForHandleKey()
+            emit(result)
         }
     }
 

+ 2 - 2
app/src/main/java/com/grkj/iscs/features/main/viewmodel/home/HomeViewModel.kt

@@ -13,8 +13,8 @@ import com.grkj.data.logic.IJobTicketLogic
 import com.grkj.data.logic.IUserLogic
 import com.grkj.data.logic.IWorkflowLogic
 import com.grkj.data.logic.IWorkstationLogic
-import com.grkj.iscs.features.main.entity.splitTodoSteps
-import com.grkj.iscs.features.main.entity.toTodoVo
+import com.grkj.data.model.extension.splitTodoSteps
+import com.grkj.data.model.extension.toTodoVo
 import com.grkj.ui_base.base.BaseViewModel
 import com.grkj.ui_base.business.BleBusinessManager
 import dagger.hilt.android.lifecycle.HiltViewModel

+ 5 - 8
app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobExecuteViewModel.kt

@@ -4,10 +4,9 @@ import androidx.lifecycle.LiveData
 import androidx.lifecycle.liveData
 import com.clj.fastble.BleManager
 import com.grkj.data.data.MainDomainData
-import com.grkj.data.di.RepositoryManager
+import com.grkj.data.di.LogicManager
 import com.grkj.data.enums.JobTicketStatusEnum
 import com.grkj.data.enums.RoleEnum
-import com.grkj.data.enums.StepAction
 import com.grkj.data.model.dos.IsJobTicketStep
 import com.grkj.data.model.dos.WorkflowMode
 import com.grkj.data.model.local.DeviceTakeUpdate
@@ -24,12 +23,10 @@ import com.grkj.data.model.vo.SysBiometricDataVo
 import com.grkj.data.logic.IJobTicketLogic
 import com.grkj.data.logic.IWorkflowLogic
 import com.grkj.data.logic.impl.standard.UserLogic
-import com.grkj.data.model.local.TodoStepJoin
-import com.grkj.data.model.local.hasAnyHardwareOperationFunction
 import com.grkj.data.model.local.isMyTodo
 import com.grkj.iscs.R
-import com.grkj.iscs.features.main.entity.splitTodoSteps
-import com.grkj.iscs.features.main.entity.toTodoVo
+import com.grkj.data.model.extension.splitTodoSteps
+import com.grkj.data.model.extension.toTodoVo
 import com.grkj.ui_base.base.BaseViewModel
 import com.grkj.ui_base.business.BleBusinessManager
 import com.grkj.ui_base.business.ModbusBusinessManager
@@ -248,7 +245,7 @@ class JobExecuteViewModel @Inject constructor(
                     hideLoading()
                 }
             }
-            val ticketDetail = RepositoryManager.jobTicketRepo.getTicketDetail(ticketId)
+            val ticketDetail = LogicManager.jobTicketLogic.getTicketDetail(ticketId)
             val role =
                 ticketDetail?.ticketUserVOList?.filter { it.userRole == RoleEnum.JTLOCKER.roleKey }
                     ?.find {
@@ -366,7 +363,7 @@ class JobExecuteViewModel @Inject constructor(
                     hideLoading()
                 }
             }
-            val ticketDetail = RepositoryManager.jobTicketRepo.getTicketDetail(ticketId)
+            val ticketDetail = LogicManager.jobTicketLogic.getTicketDetail(ticketId)
             val role =
                 ticketDetail?.ticketUserVOList?.filter { it.userRole == RoleEnum.JTLOCKER.roleKey }
                     ?.find {

+ 2 - 2
app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/JobManageHomeViewModel.kt

@@ -7,8 +7,8 @@ import com.grkj.data.data.MainDomainData
 import com.grkj.data.model.local.isMyTodo
 import com.grkj.data.model.vo.TodoItemVo
 import com.grkj.data.logic.IJobTicketLogic
-import com.grkj.iscs.features.main.entity.splitTodoSteps
-import com.grkj.iscs.features.main.entity.toTodoVo
+import com.grkj.data.model.extension.splitTodoSteps
+import com.grkj.data.model.extension.toTodoVo
 import com.grkj.ui_base.base.BaseViewModel
 import com.grkj.ui_base.business.BleBusinessManager
 import dagger.hilt.android.lifecycle.HiltViewModel

+ 3 - 3
app/src/main/java/com/grkj/iscs/features/main/viewmodel/job_manage/MyTodoViewModel.kt

@@ -15,9 +15,9 @@ import com.grkj.data.model.vo.TodoItemVo
 import com.grkj.data.logic.IJobTicketLogic
 import com.grkj.data.logic.IUserLogic
 import com.grkj.iscs.R
-import com.grkj.iscs.features.main.entity.actionKey
-import com.grkj.iscs.features.main.entity.findPredecessors
-import com.grkj.iscs.features.main.entity.toTodoVo
+import com.grkj.data.model.extension.actionKey
+import com.grkj.data.model.extension.findPredecessors
+import com.grkj.data.model.extension.toTodoVo
 import com.grkj.ui_base.base.BaseViewModel
 import com.grkj.ui_base.business.BleBusinessManager
 import com.grkj.ui_base.business.DataBusiness

+ 1 - 0
app/src/main/java/com/grkj/iscs/service/CheckKeyInfoTask.kt

@@ -56,6 +56,7 @@ class CheckKeyInfoTask {
                             if (checkedKey.joinToString(",") == existsKey.joinToString(",") {
                                     it.mac ?: ""
                                 }) {
+                                BleConnectionManager.removeBleIndicateListener(this)
                                 isCheckInfo = false
                             }
                         }

+ 3 - 3
data/src/main/java/com/grkj/data/check_data/impl/ForceMultiLockMode.kt

@@ -1,7 +1,7 @@
 package com.grkj.data.check_data.impl
 
 import com.grkj.data.check_data.ICheckDataMode
-import com.grkj.data.di.RepositoryManager
+import com.grkj.data.di.LogicManager
 import com.grkj.data.model.req.LockPointUpdateReq
 import com.grkj.data.model.vo.IsJobTicketPointsDataVo
 
@@ -15,10 +15,10 @@ class ForceMultiLockMode :
         isTicketPoint: List<IsJobTicketPointsDataVo>
     ): String {
         val pointNfcDataList =
-            RepositoryManager.hardwareRepo.getPointNfcDataByPointIds(isTicketPoint.map { it.pointId })
+            LogicManager.hardwareLogic.getPointNfcDataByPointIds(isTicketPoint.map { it.pointId })
         val pointData = pointNfcDataList.first { it.pointNfc == updateReq.pointNfc }
         val lockNfcDataList =
-            RepositoryManager.hardwareRepo.getJobTicketPointLockNfcDataListByPointId(pointData.pointId)
+            LogicManager.hardwareLogic.getJobTicketPointLockNfcDataListByPointId(pointData.pointId)
         if (updateReq.lockNfc in lockNfcDataList.map { it.lockNfc }) {
             return "点位的锁不能与已存在的锁相同"
         }

+ 3 - 3
data/src/main/java/com/grkj/data/check_data/impl/ForceSharedLockMode.kt

@@ -1,7 +1,7 @@
 package com.grkj.data.check_data.impl
 
 import com.grkj.data.check_data.ICheckDataMode
-import com.grkj.data.di.RepositoryManager
+import com.grkj.data.di.LogicManager
 import com.grkj.data.model.req.LockPointUpdateReq
 import com.grkj.data.model.vo.IsJobTicketPointsDataVo
 
@@ -15,10 +15,10 @@ class ForceSharedLockMode :
         isTicketPoint: List<IsJobTicketPointsDataVo>
     ): String {
         val pointNfcDataList =
-            RepositoryManager.hardwareRepo.getPointNfcDataByPointIds(isTicketPoint.map { it.pointId })
+            LogicManager.hardwareLogic.getPointNfcDataByPointIds(isTicketPoint.map { it.pointId })
         val pointData = pointNfcDataList.first { it.pointNfc == updateReq.pointNfc }
         val lockNfcDataList =
-            RepositoryManager.hardwareRepo.getJobTicketPointLockNfcDataListByPointId(pointData.pointId)
+            LogicManager.hardwareLogic.getJobTicketPointLockNfcDataListByPointId(pointData.pointId)
         if (updateReq.lockNfc !in lockNfcDataList.map { it.lockNfc }) {
             return "点位的锁必须与已存在的锁相同"
         }

+ 11 - 11
data/src/main/java/com/grkj/data/di/AppEntryPoint.kt

@@ -18,15 +18,15 @@ import dagger.hilt.components.SingletonComponent
 @EntryPoint
 @InstallIn(SingletonComponent::class)
 interface AppEntryPoint {
-    fun hardwareRepo(): IHardwareLogic
-    fun isolationPointRepo(): IIsolationPointLogic
-    fun jobTicketRepo(): IJobTicketLogic
-    fun rfidTokenRepo(): IRfidTokenLogic
-    fun roleRepo(): IRoleLogic
-    fun sopRepo(): ISopLogic
-    fun userRepo(): IUserLogic
-    fun workstationRepo(): IWorkstationLogic
-    fun sysMenuRepo(): ISysMenuLogic
-    fun workflowRepo(): IWorkflowLogic
-    fun exceptionRepo(): IExceptionLogic
+    fun hardwareLogic(): IHardwareLogic
+    fun isolationPointLogic(): IIsolationPointLogic
+    fun jobTicketLogic(): IJobTicketLogic
+    fun rfidTokenLogic(): IRfidTokenLogic
+    fun roleLogic(): IRoleLogic
+    fun sopLogic(): ISopLogic
+    fun userLogic(): IUserLogic
+    fun workstationLogic(): IWorkstationLogic
+    fun sysMenuLogic(): ISysMenuLogic
+    fun workflowLogic(): IWorkflowLogic
+    fun exceptionLogic(): IExceptionLogic
 }

+ 47 - 0
data/src/main/java/com/grkj/data/di/LogicManager.kt

@@ -0,0 +1,47 @@
+package com.grkj.data.di
+
+import android.app.Application
+import com.grkj.data.logic.IExceptionLogic
+import com.grkj.data.logic.IHardwareLogic
+import com.grkj.data.logic.IIsolationPointLogic
+import com.grkj.data.logic.IJobTicketLogic
+import com.grkj.data.logic.IRfidTokenLogic
+import com.grkj.data.logic.IRoleLogic
+import com.grkj.data.logic.ISopLogic
+import com.grkj.data.logic.ISysMenuLogic
+import com.grkj.data.logic.IUserLogic
+import com.grkj.data.logic.IWorkflowLogic
+import com.grkj.data.logic.IWorkstationLogic
+import dagger.hilt.android.EntryPointAccessors
+
+/**
+ * 业务层管理
+ */
+object LogicManager {
+    lateinit var hardwareLogic: IHardwareLogic
+    lateinit var isolationPointLogic: IIsolationPointLogic
+    lateinit var jobTicketLogic: IJobTicketLogic
+    lateinit var rfidTokenLogic: IRfidTokenLogic
+    lateinit var roleLogic: IRoleLogic
+    lateinit var sopLogic: ISopLogic
+    lateinit var userLogic: IUserLogic
+    lateinit var workstationLogic: IWorkstationLogic
+    lateinit var sysMenuLogic: ISysMenuLogic
+    lateinit var workflowLogic: IWorkflowLogic
+    lateinit var exceptionLogic: IExceptionLogic
+
+    fun init(app: Application) {
+        val ep = EntryPointAccessors.fromApplication(app, AppEntryPoint::class.java)
+        hardwareLogic = ep.hardwareLogic()
+        isolationPointLogic = ep.isolationPointLogic()
+        jobTicketLogic = ep.jobTicketLogic()
+        rfidTokenLogic = ep.rfidTokenLogic()
+        roleLogic = ep.roleLogic()
+        sopLogic = ep.sopLogic()
+        userLogic = ep.userLogic()
+        workstationLogic = ep.workstationLogic()
+        sysMenuLogic = ep.sysMenuLogic()
+        workflowLogic = ep.workflowLogic()
+        exceptionLogic = ep.exceptionLogic()
+    }
+}

+ 0 - 47
data/src/main/java/com/grkj/data/di/RepositoryManager.kt

@@ -1,47 +0,0 @@
-package com.grkj.data.di
-
-import android.app.Application
-import com.grkj.data.logic.IExceptionLogic
-import com.grkj.data.logic.IHardwareLogic
-import com.grkj.data.logic.IIsolationPointLogic
-import com.grkj.data.logic.IJobTicketLogic
-import com.grkj.data.logic.IRfidTokenLogic
-import com.grkj.data.logic.IRoleLogic
-import com.grkj.data.logic.ISopLogic
-import com.grkj.data.logic.ISysMenuLogic
-import com.grkj.data.logic.IUserLogic
-import com.grkj.data.logic.IWorkflowLogic
-import com.grkj.data.logic.IWorkstationLogic
-import dagger.hilt.android.EntryPointAccessors
-
-/**
- * 业务层管理
- */
-object RepositoryManager {
-    lateinit var hardwareRepo: IHardwareLogic
-    lateinit var isolationPointRepo: IIsolationPointLogic
-    lateinit var jobTicketRepo: IJobTicketLogic
-    lateinit var rfidTokenRepo: IRfidTokenLogic
-    lateinit var roleRepo: IRoleLogic
-    lateinit var sopRepo: ISopLogic
-    lateinit var userRepo: IUserLogic
-    lateinit var workstationRepo: IWorkstationLogic
-    lateinit var sysMenuRepository: ISysMenuLogic
-    lateinit var workflowRepository: IWorkflowLogic
-    lateinit var exceptionRepository: IExceptionLogic
-
-    fun init(app: Application) {
-        val ep = EntryPointAccessors.fromApplication(app, AppEntryPoint::class.java)
-        hardwareRepo = ep.hardwareRepo()
-        isolationPointRepo = ep.isolationPointRepo()
-        jobTicketRepo = ep.jobTicketRepo()
-        rfidTokenRepo = ep.rfidTokenRepo()
-        roleRepo = ep.roleRepo()
-        sopRepo = ep.sopRepo()
-        userRepo = ep.userRepo()
-        workstationRepo = ep.workstationRepo()
-        sysMenuRepository = ep.sysMenuRepo()
-        workflowRepository = ep.workflowRepo()
-        exceptionRepository = ep.exceptionRepo()
-    }
-}

+ 2 - 1
app/src/main/java/com/grkj/iscs/features/main/entity/TodoDataExtension.kt → data/src/main/java/com/grkj/data/model/extension/TodoDataExtension.kt

@@ -1,4 +1,4 @@
-package com.grkj.iscs.features.main.entity
+package com.grkj.data.model.extension
 
 import com.grkj.data.data.MainDomainData
 import com.grkj.data.enums.JobTicketStatusEnum
@@ -7,6 +7,7 @@ import com.grkj.data.enums.TodoStatusEnum
 import com.grkj.data.model.local.TodoStepJoin
 import com.grkj.data.model.vo.TodoItemVo
 import kotlin.collections.contains
+import kotlin.collections.iterator
 
 /**
  * 转换todo数据

+ 2 - 2
data/src/main/java/com/grkj/data/model/local/WorkTicketGet.kt

@@ -1,6 +1,6 @@
 package com.grkj.data.model.local
 
-import com.grkj.data.di.RepositoryManager
+import com.grkj.data.di.LogicManager
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import kotlin.coroutines.resume
@@ -106,7 +106,7 @@ class WorkTicketGet {
         for (item in data) {
             // 1. 调用回调接口获取远程的 ticketStatus,并根据情况设置两个标志
             val (localTicketFinish, remoteTicketFinished) = suspendCoroutine<Pair<Boolean, Boolean>> { cont ->
-                RepositoryManager.jobTicketRepo.getTicketDetail(
+                LogicManager.jobTicketLogic.getTicketDetail(
                     item.taskCode?.toLong() ?: 0
                 ) { res ->
                     logger.info("作业票状态: ${res?.ticketStatus}")

+ 32 - 28
ui-base/src/main/java/com/grkj/ui_base/business/BleBusinessManager.kt

@@ -6,7 +6,7 @@ import com.clj.fastble.exception.BleException
 import com.google.gson.Gson
 import com.grkj.data.data.DictConstants
 import com.grkj.data.data.MainDomainData
-import com.grkj.data.di.RepositoryManager
+import com.grkj.data.di.LogicManager
 import com.grkj.data.enums.JobTicketStatusEnum
 import com.grkj.data.enums.RoleEnum
 import com.grkj.data.model.dos.IsJobTicketStep
@@ -337,7 +337,7 @@ object BleBusinessManager {
                     updateBo?.let { itBO ->
                         ThreadUtils.runOnIO {
                             val jobTicketData =
-                                RepositoryManager.jobTicketRepo.getJobTicketDataByTicketId(itBO.ticketId)
+                                LogicManager.jobTicketLogic.getJobTicketDataByTicketId(itBO.ticketId)
                             if (jobTicketData == null) {
                                 ModBusController.updateKeyReadyStatus(
                                     currentModeEvent.bleBean.bleDevice.mac, true, 4
@@ -349,11 +349,11 @@ object BleBusinessManager {
                                 logger.info("作业票数据为空")
                                 return@runOnIO
                             }
-                            RepositoryManager.jobTicketRepo.getStepDetail(itBO.ticketId) {
+                            LogicManager.jobTicketLogic.getStepDetail(itBO.ticketId) {
                                 logger.info("步骤数据:${it.toJson()}")
                                 val step = it?.firstOrNull { it.stepStatus == "0" }
                                 logger.info("当前步骤:${step.toJson()}")
-                                RepositoryManager.jobTicketRepo.getTicketDetail(itBO.ticketId) { ticketDetail ->
+                                LogicManager.jobTicketLogic.getTicketDetail(itBO.ticketId) { ticketDetail ->
                                     logger.info("步骤详情:${ticketDetail.toJson()}")
                                     val role =
                                         ticketDetail?.ticketUserVOList?.filter { it.userRole == RoleEnum.JTLOCKER.roleKey }
@@ -402,6 +402,9 @@ object BleBusinessManager {
                         )
                         LoadingEvent.sendLoadingEvent()
                         //连上之后没有工作票要下发就断开 看是否还有设备等待连接并且连接数是否大于等于预期,没有就不断开,有就让路,一般是初始化的时候
+                        ThreadUtils.runOnIO {
+                            DataBusiness.checkMyTodoForHandleKey(currentModeEvent.bleBean.bleDevice.mac)
+                        }
                     }
                 }
             }
@@ -553,35 +556,35 @@ object BleBusinessManager {
     fun handleUnlockVirtualKeyReturn(ticketId: Long, groupId: Long) {
         SPUtils.returnKey(ticketId)
         // 上报钥匙归还
-        RepositoryManager.jobTicketRepo.updateKeyTake(
+        LogicManager.jobTicketLogic.updateKeyTake(
             ticketId,
             "virtualKey",
             SIKCore.getApplication().serialNo(), true
         ) {
             logger.info("虚拟钥匙取出:${it}")
-            RepositoryManager.jobTicketRepo.updateKeyReturn(
+            LogicManager.jobTicketLogic.updateKeyReturn(
                 ticketId, "virtualKey", groupId, SIKCore.getApplication().serialNo(), true
             ) { isSuccess, msg, code ->
                 logger.info("虚拟钥匙归还:${isSuccess},${msg},${code}")
                 //更新作业票的状态
                 val jobTicketData =
-                    RepositoryManager.jobTicketRepo.getTicketDataByTicketId(ticketId)
+                    LogicManager.jobTicketLogic.getTicketDataByTicketId(ticketId)
                 if (jobTicketData == null) {
                     TicketFinishedEvent.sendTicketFinishedEvent(ticketId)
                     PopTip.build().tip(R.string.key_return_success)
                     return@updateKeyReturn
                 }
                 val ticketStepDataVo =
-                    RepositoryManager.jobTicketRepo.getJobTicketStepDataByTicketId(
+                    LogicManager.jobTicketLogic.getJobTicketStepDataByTicketId(
                         jobTicketData.ticketId
                     ).firstOrNull { it.stepStatus == "0" }
                 val workflowSteps =
-                    RepositoryManager.workflowRepository.getStepsByMode(
+                    LogicManager.workflowLogic.getStepsByMode(
                         jobTicketData.modeId!!
                     )
                 var currentWorkflowStep = ticketStepDataVo
                 val ticketPoints =
-                    RepositoryManager.jobTicketRepo.getTicketDetail(jobTicketData.ticketId)?.ticketPointsVOList
+                    LogicManager.jobTicketLogic.getTicketDetail(jobTicketData.ticketId)?.ticketPointsVOList
                 if (currentWorkflowStep?.enableReleaseColock == true && currentWorkflowStep.enableUnlock ||
                     ticketPoints?.all { it.pointStatus == ticketPoints.firstOrNull()?.pointStatus } == false
                 ) {
@@ -595,14 +598,14 @@ object BleBusinessManager {
                     )
                     isTicketStepData?.let {
                         logger.info("更新步骤:${it}")
-                        RepositoryManager.jobTicketRepo.updateTicketStepData(it)
+                        LogicManager.jobTicketLogic.updateTicketStepData(it)
                     }
                     val ticketStep =
-                        RepositoryManager.jobTicketRepo.getJobTicketStepDataByTicketId(
+                        LogicManager.jobTicketLogic.getJobTicketStepDataByTicketId(
                             jobTicketData.ticketId
                         )
                     currentWorkflowStep = ticketStep.firstOrNull { it.stepStatus == "0" }
-                    RepositoryManager.jobTicketRepo.updateTicketDataStatus(
+                    LogicManager.jobTicketLogic.updateTicketDataStatus(
                         ticketId,
                         currentWorkflowStep?.getTicketStatus()?.toInt()
                             ?: JobTicketStatusEnum.PROGRESSING.status.toInt()
@@ -655,14 +658,14 @@ object BleBusinessManager {
                 LoadingEvent.sendLoadingEvent()
                 val ticketId = data.taskCode?.toLong()
                 val pointId =
-                    RepositoryManager.hardwareRepo.getPointIdByPointNfc(data.dataList?.first()?.equipRfidNo)
+                    LogicManager.hardwareLogic.getPointIdByPointNfc(data.dataList?.first()?.equipRfidNo)
                 val groupId =
-                    RepositoryManager.jobTicketRepo.getGroupIdByPointIdAndTicketId(
+                    LogicManager.jobTicketLogic.getGroupIdByPointIdAndTicketId(
                         pointId,
                         data.taskCode?.toLong()!!
                     )
                 // 上报点位钥匙绑定
-                RepositoryManager.jobTicketRepo.updateLockPointBatch(
+                LogicManager.jobTicketLogic.updateLockPointBatch(
                     updateList,
                     ticketId,
                     groupId
@@ -670,7 +673,7 @@ object BleBusinessManager {
                     logger.info("还锁操作:${isSuccess},${msg},${code}")
                     if (isSuccess) {
                         // 上报钥匙归还
-                        RepositoryManager.jobTicketRepo.updateKeyReturn(
+                        LogicManager.jobTicketLogic.updateKeyReturn(
                             data.taskCode?.toLong()!!,
                             keyNfc!!,
                             groupId,
@@ -691,7 +694,7 @@ object BleBusinessManager {
                             } else {
                                 //更新作业票的状态
                                 val jobTicketData =
-                                    RepositoryManager.jobTicketRepo.getTicketDataByTicketId(data.taskCode?.toLong()!!)
+                                    LogicManager.jobTicketLogic.getTicketDataByTicketId(data.taskCode?.toLong()!!)
                                 if (jobTicketData == null) {
                                     data.taskCode?.let {
                                         TicketFinishedEvent.sendTicketFinishedEvent(it.toLong())
@@ -700,15 +703,15 @@ object BleBusinessManager {
                                     return@updateKeyReturn
                                 }
                                 val ticketStepDataVo =
-                                    RepositoryManager.jobTicketRepo.getJobTicketStepDataByTicketId(
+                                    LogicManager.jobTicketLogic.getJobTicketStepDataByTicketId(
                                         jobTicketData.ticketId
                                     ).firstOrNull { it.stepStatus == "0" }
                                 val workflowSteps =
-                                    RepositoryManager.workflowRepository.getStepsByMode(
+                                    LogicManager.workflowLogic.getStepsByMode(
                                         jobTicketData.modeId!!
                                     )
                                 val ticketPoints =
-                                    RepositoryManager.jobTicketRepo.getTicketDetail(data.taskCode?.toLong()!!)?.ticketPointsVOList
+                                    LogicManager.jobTicketLogic.getTicketDetail(data.taskCode?.toLong()!!)?.ticketPointsVOList
                                 var currentWorkflowStep = ticketStepDataVo
                                 if ((currentWorkflowStep?.enableLock == true && currentWorkflowStep.enableColock) || (currentWorkflowStep?.enableReleaseColock == true && currentWorkflowStep.enableUnlock || ticketPoints?.all { it.pointStatus == ticketPoints.firstOrNull()?.pointStatus } == false)
                                 ) {
@@ -722,15 +725,15 @@ object BleBusinessManager {
                                     )
                                     isTicketStepData?.let {
                                         logger.info("更新步骤:${it}")
-                                        RepositoryManager.jobTicketRepo.updateTicketStepData(it)
+                                        LogicManager.jobTicketLogic.updateTicketStepData(it)
                                     }
                                     val ticketStep =
-                                        RepositoryManager.jobTicketRepo.getJobTicketStepDataByTicketId(
+                                        LogicManager.jobTicketLogic.getJobTicketStepDataByTicketId(
                                             jobTicketData.ticketId
                                         )
                                     currentWorkflowStep =
                                         ticketStep.firstOrNull { it.stepStatus == "0" }
-                                    RepositoryManager.jobTicketRepo.updateTicketDataStatus(
+                                    LogicManager.jobTicketLogic.updateTicketDataStatus(
                                         data.taskCode?.toLong()!!,
                                         currentWorkflowStep?.getTicketStatus()?.toInt()
                                             ?: JobTicketStatusEnum.PROGRESSING.status.toInt()
@@ -793,13 +796,13 @@ object BleBusinessManager {
      * 检查步骤和作业票详情并且下发作业票
      */
     private fun checkStepAndTicketDetailThenSendTicket(ticketId: Long, mac: String) {
-        RepositoryManager.jobTicketRepo.getStepDetail(ticketId) {
-            val jobTicketData = RepositoryManager.jobTicketRepo.getJobTicketDataByTicketId(ticketId)
+        LogicManager.jobTicketLogic.getStepDetail(ticketId) {
+            val jobTicketData = LogicManager.jobTicketLogic.getJobTicketDataByTicketId(ticketId)
             if (jobTicketData == null) {
                 return@getStepDetail
             }
             val step = it?.firstOrNull { it.stepStatus == "0" }
-            RepositoryManager.jobTicketRepo.getTicketDetail(ticketId) { ticketDetail ->
+            LogicManager.jobTicketLogic.getTicketDetail(ticketId) { ticketDetail ->
                 if (ticketDetail == null) {
                     return@getTicketDetail
                 }
@@ -906,6 +909,7 @@ object BleBusinessManager {
      */
     fun connectExistsKey(exceptKeyMac: List<String> = listOf()) {
         ThreadUtils.runOnIO {
+            BleConnectionManager.cancelDisconnectAllJob()
             val connectedDevice = BleManager.getInstance().allConnectedDevice
             if (connectedDevice.isNotEmpty() && connectedDevice.subtract(exceptKeyMac.toSet())
                     .isNotEmpty()
@@ -977,7 +981,7 @@ object BleBusinessManager {
     ): String {
         logger.info("generateTicketSendJson : $lockList")
         val groupId = MainDomainData.deviceTakeTicketGroupBound[vo.ticketId]
-        val isUnlockFirst = RepositoryManager.jobTicketRepo.isUnLockBeforeLock(vo.ticketId)
+        val isUnlockFirst = LogicManager.jobTicketLogic.isUnLockBeforeLock(vo.ticketId)
         logger.info("当前作业票分组数据:${vo.ticketId}-${groupId}")
         val bo = WorkTicketSend(
             cardNo = MainDomainData.userCardList.getOrNull(0)?.cardNfc ?: "123456",

+ 54 - 8
ui-base/src/main/java/com/grkj/ui_base/business/DataBusiness.kt

@@ -1,9 +1,19 @@
 package com.grkj.ui_base.business
 
-import com.grkj.data.di.RepositoryManager
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.liveData
+import com.clj.fastble.BleManager
+import com.grkj.data.data.MainDomainData
+import com.grkj.data.di.LogicManager
+import com.grkj.data.model.extension.splitTodoSteps
+import com.grkj.data.model.extension.toTodoVo
+import com.grkj.data.model.local.isMyTodo
 import com.grkj.data.model.res.CabinetSlotsRes
 import com.grkj.data.model.res.KeyPageRes
 import com.grkj.data.model.res.LockPageRes
+import com.grkj.ui_base.business.BleBusinessManager.connectExistsKey
+import com.grkj.ui_base.utils.ble.BleConnectionManager
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.suspendCancellableCoroutine
 import kotlin.coroutines.resume
 
@@ -14,7 +24,7 @@ object DataBusiness {
 
     // 1. 把 NetApi.get…Page 包成 suspend 函数
     suspend fun getSlotsPage(): CabinetSlotsRes? = suspendCancellableCoroutine { cont ->
-        RepositoryManager.hardwareRepo.getIsLockCabinetSlotsPage { slots ->
+        LogicManager.hardwareLogic.getIsLockCabinetSlotsPage { slots ->
             if (cont.isActive) {
                 cont.resume(slots)
             }
@@ -22,7 +32,7 @@ object DataBusiness {
     }
 
     suspend fun getLocksPage(): LockPageRes? = suspendCancellableCoroutine { cont ->
-        RepositoryManager.hardwareRepo.getIsLockPage { locks ->
+        LogicManager.hardwareLogic.getIsLockPage { locks ->
             if (cont.isActive) {
                 cont.resume(locks)
             }
@@ -30,7 +40,7 @@ object DataBusiness {
     }
 
     suspend fun getKeyPage(): KeyPageRes? = suspendCancellableCoroutine { cont ->
-        RepositoryManager.hardwareRepo.getIsKeyPage { keys ->
+        LogicManager.hardwareLogic.getIsKeyPage { keys ->
             if (cont.isActive) {
                 cont.resume(keys)
             }
@@ -38,11 +48,47 @@ object DataBusiness {
     }
 
     // 2. 把原本同步的字典查询留在 IO 线程
-    suspend fun fetchDict(key: String): List<com.grkj.data.model.res.CommonDictRes> =suspendCancellableCoroutine { cont ->
-        RepositoryManager.hardwareRepo.getDictData(key) { dictData ->
-            if (cont.isActive) {
-                cont.resume(dictData)
+    suspend fun fetchDict(key: String): List<com.grkj.data.model.res.CommonDictRes> =
+        suspendCancellableCoroutine { cont ->
+            LogicManager.hardwareLogic.getDictData(key) { dictData ->
+                if (cont.isActive) {
+                    cont.resume(dictData)
+                }
             }
         }
+
+    /**
+     * 获取我的待办的作业
+     */
+    fun checkMyTodoForHandleKey(mac: String? = null): Boolean {
+        val userInfo = MainDomainData.userInfo
+        if (userInfo == null) {
+            return false
+        }
+
+        val userId = userInfo.userId
+        val userName = userInfo.userName
+        val todoItemData = LogicManager.jobTicketLogic.getMyTodoList()
+        val myTodoStepJoin = todoItemData.filter { it.isMyTodo(userId, userName) }
+        val todoItemVos =
+            myTodoStepJoin.map { it.toTodoVo(todoItemData.filter { temp -> it.ticketId == temp.ticketId }) }
+                .toMutableList()
+        val todoData = splitTodoSteps(todoItemVos, 1)
+        if (BleManager.getInstance().allConnectedDevice.isEmpty() && (todoData.first.any { it.enableLock || it.enableUnlock } || todoData.second.any { it.enableLock || it.enableUnlock })) {
+            val maxPowerMac = ModbusBusinessManager.getMaxPowerKey().mac
+            if (maxPowerMac != mac) {
+                connectExistsKey(listOf(mac ?: ""))
+                BleConnectionManager.launchDisconnectJob(mac ?: "")
+            }
+        } else {
+            mac?.let {
+                BleConnectionManager.launchDisconnectJob(it)
+            }
+        }
+        return true
+    }
+
+    override fun equals(other: Any?): Boolean {
+        return super.equals(other)
     }
 }

+ 14 - 9
ui-base/src/main/java/com/grkj/ui_base/business/ModbusBusinessManager.kt

@@ -1,7 +1,6 @@
 package com.grkj.ui_base.business
 
-import com.clj.fastble.BleManager
-import com.grkj.data.di.RepositoryManager
+import com.grkj.data.di.LogicManager
 import com.grkj.data.model.local.DeviceTakeUpdate
 import com.grkj.data.model.req.LockTakeUpdateReq
 import com.grkj.ui_base.R
@@ -13,7 +12,6 @@ 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.ble.BleConnectionManager
-import com.grkj.ui_base.utils.ble.BleConst
 import com.grkj.ui_base.utils.event.DeviceTakeUpdateEvent
 import com.grkj.ui_base.utils.event.LoadingEvent
 import com.grkj.ui_base.utils.event.UpdateTicketProgressEvent
@@ -130,7 +128,7 @@ object ModbusBusinessManager {
                     ?.let { info ->
                         LoadingEvent.sendLoadingEvent()
                         SPUtils.takeKey(info.ticketId)
-                        RepositoryManager.jobTicketRepo.updateKeyTake(
+                        LogicManager.jobTicketLogic.updateKeyTake(
                             info.ticketId, info.nfc, SIKCore.getApplication().serialNo()!!
                         ) { isSuccess ->
                             if (isSuccess) {
@@ -154,7 +152,7 @@ object ModbusBusinessManager {
             DeviceConst.DEVICE_TYPE_LOCK -> {
                 mDeviceTakeList.find { it.deviceType == DeviceConst.DEVICE_TYPE_LOCK && it.nfc == deviceTakeUpdateBO.nfc }
                     ?.let { info ->
-                        RepositoryManager.hardwareRepo.updateLockTake(
+                        LogicManager.hardwareLogic.updateLockTake(
                             mutableListOf(
                                 LockTakeUpdateReq(
                                     info.ticketId, info.nfc, SIKCore.getApplication().serialNo()!!
@@ -419,7 +417,7 @@ object ModbusBusinessManager {
                     val slotsPage = slotsPageReq.await()
                     val slotStatusList = slotStatus.await()
                     val slotTypeList = slotType.await()
-                    RepositoryManager.hardwareRepo.getIsLockPage { lockData ->
+                    LogicManager.hardwareLogic.getIsLockPage { lockData ->
                         //锁rfid未异常正常请求锁数据,关锁
                         if (rfid in (lockData?.records?.filter { it.exStatus == lockStatus.find { it.dictLabel == "异常" }?.dictValue }
                                 ?.map { it.lockNfc }?.toMutableList()
@@ -433,7 +431,7 @@ object ModbusBusinessManager {
                             PopTip.build().tip(R.string.slot_exception_tag)
                         } else {
                             logger.info("挂锁归还:${lockBean.rfid}")
-                            RepositoryManager.hardwareRepo.getLockInfo(rfid) {
+                            LogicManager.hardwareLogic.getLockInfo(rfid) {
                                 logger.info("挂锁信息:${it}")
                                 if (it != null && it.lockNfc?.isNotEmpty() == true) {
                                     // TODO 考虑快速拿取
@@ -442,7 +440,7 @@ object ModbusBusinessManager {
                                     ) { itRst ->
                                         if (itRst.isNotEmpty()) {
                                             // 上报锁具信息
-                                            RepositoryManager.jobTicketRepo.updateLockReturn(
+                                            LogicManager.jobTicketLogic.updateLockReturn(
                                                 rfid,
                                                 SIKCore.getApplication().serialNo()
                                             ) {}
@@ -529,7 +527,7 @@ object ModbusBusinessManager {
                         ModBusController.controlKeyBuckle(
                             false, keyBean.idx, dockBean.addr
                         ) {
-                            RepositoryManager.hardwareRepo.getKeyInfo(rfid) {
+                            LogicManager.hardwareLogic.getKeyInfo(rfid) {
                                 logger.info("钥匙:${rfid},${it}")
                                 if (it != null && !it.macAddress.isNullOrEmpty()) {
                                     ModBusController.updateKeyMac(
@@ -624,4 +622,11 @@ object ModbusBusinessManager {
         return dockData.filter { it.type == DeviceConst.DOCK_TYPE_KEY }.flatMap { it.deviceList }
             .filterIsInstance<DockBean.KeyBean>()
     }
+
+    /**
+     * 获取电量最多的钥匙
+     */
+    fun getMaxPowerKey(): DockBean.KeyBean {
+        return ModBusController.getMaxPowerKey()
+    }
 }

+ 0 - 0
ui-base/src/main/java/com/grkj/ui_base/utils/ble/BleListener.kt → ui-base/src/main/java/com/grkj/ui_base/utils/ble/BleIndicateListener.kt


+ 18 - 8
ui-base/src/main/java/com/grkj/ui_base/utils/modbus/ModBusController.kt

@@ -1,7 +1,7 @@
 package com.grkj.ui_base.utils.modbus
 
 import com.clj.fastble.BleManager
-import com.grkj.data.di.RepositoryManager
+import com.grkj.data.di.LogicManager
 import com.grkj.data.model.res.CabinetSlotsRecord
 import com.grkj.shared.utils.extension.isPureZero
 import com.grkj.shared.utils.extension.removeLeadingZeros
@@ -9,13 +9,10 @@ import com.grkj.shared.utils.extension.toHexStrings
 import com.grkj.ui_base.R
 import com.grkj.ui_base.config.ISCSConfig
 import com.grkj.ui_base.utils.CommonUtils
-import com.grkj.ui_base.utils.Executor
 import com.grkj.ui_base.utils.ble.BleConnectionManager
 import com.grkj.ui_base.utils.event.ModbusInitCompleteEvent
 import com.grkj.ui_base.utils.extension.tip
 import com.kongzue.dialogx.dialogs.PopTip
-import com.sik.sikcore.thread.ThreadUtils
-import kotlinx.coroutines.delay
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import java.util.concurrent.atomic.AtomicInteger
@@ -191,7 +188,7 @@ object ModBusController {
                         logger.info("初始化锁具 RFID : $rfid")
                         updateLockRfid(dockBean.addr, idx, rfid)
                         //todo 为设备录入增加
-                        RepositoryManager.hardwareRepo.getLockInfo(rfid) {
+                        LogicManager.hardwareLogic.getLockInfo(rfid) {
                             updateLockNewHardware(
                                 dockBean.addr,
                                 idx,
@@ -226,7 +223,7 @@ object ModBusController {
                             // 更新rfid
                             updateKeyRfid(dockBean.addr, key.idx, rfid)
                             // 蓝牙准备操作
-                            RepositoryManager.hardwareRepo.getKeyInfo(rfid) { keyInfo ->
+                            LogicManager.hardwareLogic.getKeyInfo(rfid) { keyInfo ->
                                 logger.info("getKeyInfo : $rfid - ${keyInfo?.macAddress}")
                                 updateKeyNewHardware(
                                     dockBean.addr,
@@ -343,7 +340,7 @@ object ModBusController {
         }
         res.forEach { bytes ->
             val dockBean = updateExtraLockStatus(bytes) ?: return@forEach
-            if (!RepositoryManager.hardwareRepo.canReturn()) {
+            if (!LogicManager.hardwareLogic.canReturn()) {
                 return@forEach
             }
             when (dockBean.type) {
@@ -398,7 +395,7 @@ object ModBusController {
 
         res.forEach { bytes ->
             val dockBean = updateLockStatus(bytes) ?: return@forEach
-            if (!RepositoryManager.hardwareRepo.canReturn()) {
+            if (!LogicManager.hardwareLogic.canReturn()) {
                 return@forEach
             }
             when (dockBean.type) {
@@ -1202,4 +1199,17 @@ object ModBusController {
         return dockList.filter { it.type == DeviceConst.DOCK_TYPE_LOCK || it.type == DeviceConst.DOCK_TYPE_PORTABLE }
             .flatMap { it.getLockList() }.find { it.rfid == rfid }
     }
+
+    /**
+     * 获取电量最多的钥匙
+     */
+    fun getMaxPowerKey(): DockBean.KeyBean {
+        return dockList.filter {
+            it.type in listOf(
+                DeviceConst.DOCK_TYPE_KEY,
+                DeviceConst.DOCK_TYPE_PORTABLE
+            )
+        }
+            .flatMap { it.deviceList }.filterIsInstance<DockBean.KeyBean>().maxBy { it.power }
+    }
 }